History

add hg and python

cinap_lenrek committed 15 years ago

Commit 4bb9e221 parent 987265c3706 files · +1228772 −-233Browse files

Showing the changes to sys/src/cmd/python/Modules (314 of 3706 files). Show all

Unified · Split

314 files
  1. sys/src/cmd/python/Modules/Setup +488 −0
  2. sys/src/cmd/python/Modules/Setup.config +13 −0
  3. sys/src/cmd/python/Modules/Setup.config.in +13 −0
  4. sys/src/cmd/python/Modules/Setup.dist +487 −0
  5. sys/src/cmd/python/Modules/Setup.local +1 −0
  6. sys/src/cmd/python/Modules/_bisectmodule.c +235 −0
  7. sys/src/cmd/python/Modules/_bsddb.c +6047 −0
  8. sys/src/cmd/python/Modules/_codecsmodule.c +934 −0
  9. sys/src/cmd/python/Modules/_csv.c +1604 −0
  10. sys/src/cmd/python/Modules/_ctypes/_ctypes.c +4859 −0
  11. sys/src/cmd/python/Modules/_ctypes/_ctypes_test.c +548 −0
  12. sys/src/cmd/python/Modules/_ctypes/_ctypes_test.h +1 −0
  13. sys/src/cmd/python/Modules/_ctypes/callbacks.c +499 −0
  14. sys/src/cmd/python/Modules/_ctypes/callproc.c +1581 −0
  15. sys/src/cmd/python/Modules/_ctypes/cfield.c +1668 −0
  16. sys/src/cmd/python/Modules/_ctypes/ctypes.h +407 −0
  17. sys/src/cmd/python/Modules/_ctypes/ctypes_dlfcn.h +31 −0
  18. sys/src/cmd/python/Modules/_ctypes/darwin/LICENSE +31 −0
  19. sys/src/cmd/python/Modules/_ctypes/darwin/README +95 −0
  20. sys/src/cmd/python/Modules/_ctypes/darwin/README.ctypes +11 −0
  21. sys/src/cmd/python/Modules/_ctypes/darwin/dlfcn.h +84 −0
  22. sys/src/cmd/python/Modules/_ctypes/darwin/dlfcn_simple.c +272 −0
  23. sys/src/cmd/python/Modules/_ctypes/libffi/LICENSE +20 −0
  24. sys/src/cmd/python/Modules/_ctypes/libffi/README +500 −0
  25. sys/src/cmd/python/Modules/_ctypes/libffi/aclocal.m4 +92 −0
  26. sys/src/cmd/python/Modules/_ctypes/libffi/config.guess +1453 −0
  27. sys/src/cmd/python/Modules/_ctypes/libffi/config.sub +1569 −0
  28. sys/src/cmd/python/Modules/_ctypes/libffi/configure +6864 −0
  29. sys/src/cmd/python/Modules/_ctypes/libffi/configure.ac +243 −0
  30. sys/src/cmd/python/Modules/_ctypes/libffi/fficonfig.h.in +148 −0
  31. sys/src/cmd/python/Modules/_ctypes/libffi/fficonfig.py.in +45 −0
  32. sys/src/cmd/python/Modules/_ctypes/libffi/include/ffi.h.in +313 −0
  33. sys/src/cmd/python/Modules/_ctypes/libffi/include/ffi_common.h +95 −0
  34. sys/src/cmd/python/Modules/_ctypes/libffi/install-sh +294 −0
  35. sys/src/cmd/python/Modules/_ctypes/libffi/src/alpha/ffi.c +252 −0
  36. sys/src/cmd/python/Modules/_ctypes/libffi/src/alpha/ffitarget.h +48 −0
  37. sys/src/cmd/python/Modules/_ctypes/libffi/src/alpha/osf.S +359 −0
  38. sys/src/cmd/python/Modules/_ctypes/libffi/src/arm/ffi.c +185 −0
  39. sys/src/cmd/python/Modules/_ctypes/libffi/src/arm/ffitarget.h +47 −0
  40. sys/src/cmd/python/Modules/_ctypes/libffi/src/arm/sysv.S +209 −0
  41. sys/src/cmd/python/Modules/_ctypes/libffi/src/cris/ffi.c +381 −0
  42. sys/src/cmd/python/Modules/_ctypes/libffi/src/cris/ffitarget.h +50 −0
  43. sys/src/cmd/python/Modules/_ctypes/libffi/src/cris/sysv.S +215 −0
  44. sys/src/cmd/python/Modules/_ctypes/libffi/src/darwin/ffitarget.h +25 −0
  45. sys/src/cmd/python/Modules/_ctypes/libffi/src/frv/eabi.S +130 −0
  46. sys/src/cmd/python/Modules/_ctypes/libffi/src/frv/ffi.c +287 −0
  47. sys/src/cmd/python/Modules/_ctypes/libffi/src/frv/ffitarget.h +60 −0
  48. sys/src/cmd/python/Modules/_ctypes/libffi/src/ia64/ffi.c +562 −0
  49. sys/src/cmd/python/Modules/_ctypes/libffi/src/ia64/ffitarget.h +49 −0
  50. sys/src/cmd/python/Modules/_ctypes/libffi/src/ia64/ia64_flags.h +39 −0
  51. sys/src/cmd/python/Modules/_ctypes/libffi/src/ia64/unix.S +555 −0
  52. sys/src/cmd/python/Modules/_ctypes/libffi/src/m32r/ffi.c +247 −0
  53. sys/src/cmd/python/Modules/_ctypes/libffi/src/m32r/ffitarget.h +48 −0
  54. sys/src/cmd/python/Modules/_ctypes/libffi/src/m32r/sysv.S +121 −0
  55. sys/src/cmd/python/Modules/_ctypes/libffi/src/m68k/ffi.c +176 −0
  56. sys/src/cmd/python/Modules/_ctypes/libffi/src/m68k/ffitarget.h +47 −0
  57. sys/src/cmd/python/Modules/_ctypes/libffi/src/m68k/sysv.S +97 −0
  58. sys/src/cmd/python/Modules/_ctypes/libffi/src/mips/ffi.c +648 −0
  59. sys/src/cmd/python/Modules/_ctypes/libffi/src/mips/ffitarget.h +167 −0
  60. sys/src/cmd/python/Modules/_ctypes/libffi/src/mips/n32.S +320 −0
  61. sys/src/cmd/python/Modules/_ctypes/libffi/src/mips/o32.S +377 −0
  62. sys/src/cmd/python/Modules/_ctypes/libffi/src/pa/ffi.c +625 −0
  63. sys/src/cmd/python/Modules/_ctypes/libffi/src/pa/ffitarget.h +59 −0
  64. sys/src/cmd/python/Modules/_ctypes/libffi/src/pa/linux.S +307 −0
  65. sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/aix.S +225 −0
  66. sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/aix_closure.S +247 −0
  67. sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/asm.h +125 −0
  68. sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/darwin.S +247 −0
  69. sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/darwin_closure.S +319 −0
  70. sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/ffi.c +1249 −0
  71. sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c +771 −0
  72. sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/ffitarget.h +100 −0
  73. sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/linux64.S +180 −0
  74. sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/linux64_closure.S +206 −0
  75. sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/ppc_closure.S +323 −0
  76. sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/sysv.S +217 −0
  77. sys/src/cmd/python/Modules/_ctypes/libffi/src/prep_cif.c +210 −0
  78. sys/src/cmd/python/Modules/_ctypes/libffi/src/s390/ffi.c +751 −0
  79. sys/src/cmd/python/Modules/_ctypes/libffi/src/s390/ffitarget.h +59 −0
  80. sys/src/cmd/python/Modules/_ctypes/libffi/src/s390/sysv.S +429 −0
  81. sys/src/cmd/python/Modules/_ctypes/libffi/src/sh/ffi.c +728 −0
  82. sys/src/cmd/python/Modules/_ctypes/libffi/src/sh/ffitarget.h +48 −0
  83. sys/src/cmd/python/Modules/_ctypes/libffi/src/sh/sysv.S +845 −0
  84. sys/src/cmd/python/Modules/_ctypes/libffi/src/sh64/ffi.c +451 −0
  85. sys/src/cmd/python/Modules/_ctypes/libffi/src/sh64/ffitarget.h +52 −0
  86. sys/src/cmd/python/Modules/_ctypes/libffi/src/sh64/sysv.S +525 −0
  87. sys/src/cmd/python/Modules/_ctypes/libffi/src/sparc/ffi.c +608 −0
  88. sys/src/cmd/python/Modules/_ctypes/libffi/src/sparc/ffitarget.h +65 −0
  89. sys/src/cmd/python/Modules/_ctypes/libffi/src/sparc/v8.S +267 −0
  90. sys/src/cmd/python/Modules/_ctypes/libffi/src/sparc/v9.S +302 −0
  91. sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/darwin.S +243 −0
  92. sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/ffi.c +469 −0
  93. sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/ffi64.c +569 −0
  94. sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/ffi_darwin.c +594 −0
  95. sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/ffitarget.h +81 −0
  96. sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/sysv.S +382 −0
  97. sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/unix64.S +412 −0
  98. sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/win32.S +373 −0
  99. sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/debug.c +59 −0
  100. sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/ffi.c +310 −0
  101. sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/ffi.h +317 −0
  102. sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/ffi_common.h +111 −0
  103. sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/fficonfig.h +152 −0
  104. sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/ffitarget.h +49 −0
  105. sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/prep_cif.c +175 −0
  106. sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/sysv.asm +228 −0
  107. sys/src/cmd/python/Modules/_ctypes/libffi_msvc/LICENSE +20 −0
  108. sys/src/cmd/python/Modules/_ctypes/libffi_msvc/README +500 −0
  109. sys/src/cmd/python/Modules/_ctypes/libffi_msvc/README.ctypes +7 −0
  110. sys/src/cmd/python/Modules/_ctypes/libffi_msvc/ffi.c +394 −0
  111. sys/src/cmd/python/Modules/_ctypes/libffi_msvc/ffi.h +317 −0
  112. sys/src/cmd/python/Modules/_ctypes/libffi_msvc/ffi_common.h +77 −0
  113. sys/src/cmd/python/Modules/_ctypes/libffi_msvc/fficonfig.h +96 −0
  114. sys/src/cmd/python/Modules/_ctypes/libffi_msvc/ffitarget.h +79 −0
  115. sys/src/cmd/python/Modules/_ctypes/libffi_msvc/prep_cif.c +175 −0
  116. sys/src/cmd/python/Modules/_ctypes/libffi_msvc/types.c +104 −0
  117. sys/src/cmd/python/Modules/_ctypes/libffi_msvc/win32.S +243 −0
  118. sys/src/cmd/python/Modules/_ctypes/libffi_msvc/win32.c +267 −0
  119. sys/src/cmd/python/Modules/_ctypes/malloc_closure.c +110 −0
  120. sys/src/cmd/python/Modules/_ctypes/stgdict.c +494 −0
  121. sys/src/cmd/python/Modules/_curses_panel.c +480 −0
  122. sys/src/cmd/python/Modules/_cursesmodule.c +2760 −0
  123. sys/src/cmd/python/Modules/_elementtree.c +2815 −0
  124. sys/src/cmd/python/Modules/_functoolsmodule.c +277 −0
  125. sys/src/cmd/python/Modules/_hashopenssl.c +487 −0
  126. sys/src/cmd/python/Modules/_heapqmodule.c +619 −0
  127. sys/src/cmd/python/Modules/_hotshot.c +1647 −0
  128. sys/src/cmd/python/Modules/_localemodule.c +788 −0
  129. sys/src/cmd/python/Modules/_lsprof.c +875 −0
  130. sys/src/cmd/python/Modules/_randommodule.c +580 −0
  131. sys/src/cmd/python/Modules/_sqlite/cache.c +375 −0
  132. sys/src/cmd/python/Modules/_sqlite/cache.h +73 −0
  133. sys/src/cmd/python/Modules/_sqlite/connection.c +1255 −0
  134. sys/src/cmd/python/Modules/_sqlite/connection.h +129 −0
  135. sys/src/cmd/python/Modules/_sqlite/cursor.c +1057 −0
  136. sys/src/cmd/python/Modules/_sqlite/cursor.h +71 −0
  137. sys/src/cmd/python/Modules/_sqlite/microprotocols.c +142 −0
  138. sys/src/cmd/python/Modules/_sqlite/microprotocols.h +59 −0
  139. sys/src/cmd/python/Modules/_sqlite/module.c +409 −0
  140. sys/src/cmd/python/Modules/_sqlite/module.h +57 −0
  141. sys/src/cmd/python/Modules/_sqlite/prepare_protocol.c +84 −0
  142. sys/src/cmd/python/Modules/_sqlite/prepare_protocol.h +41 −0
  143. sys/src/cmd/python/Modules/_sqlite/row.c +202 −0
  144. sys/src/cmd/python/Modules/_sqlite/row.h +39 −0
  145. sys/src/cmd/python/Modules/_sqlite/sqlitecompat.h +34 −0
  146. sys/src/cmd/python/Modules/_sqlite/statement.c +432 −0
  147. sys/src/cmd/python/Modules/_sqlite/statement.h +59 −0
  148. sys/src/cmd/python/Modules/_sqlite/util.c +96 −0
  149. sys/src/cmd/python/Modules/_sqlite/util.h +38 −0
  150. sys/src/cmd/python/Modules/_sre.c +3429 −0
  151. sys/src/cmd/python/Modules/_ssl.c +726 −0
  152. sys/src/cmd/python/Modules/_struct.c +1896 −0
  153. sys/src/cmd/python/Modules/_testcapimodule.c +898 −0
  154. sys/src/cmd/python/Modules/_tkinter.c +3165 −0
  155. sys/src/cmd/python/Modules/_typesmodule.c +94 −0
  156. sys/src/cmd/python/Modules/_weakref.c +112 −0
  157. sys/src/cmd/python/Modules/addrinfo.h +176 −0
  158. sys/src/cmd/python/Modules/almodule.c +3226 −0
  159. sys/src/cmd/python/Modules/ar_beos +73 −0
  160. sys/src/cmd/python/Modules/arraymodule.c +2141 −0
  161. sys/src/cmd/python/Modules/audioop.c +1612 −0
  162. sys/src/cmd/python/Modules/binascii.c +1350 −0
  163. sys/src/cmd/python/Modules/bsddbmodule.c +858 −0
  164. sys/src/cmd/python/Modules/bz2module.c +2230 −0
  165. sys/src/cmd/python/Modules/cPickle.c +5757 −0
  166. sys/src/cmd/python/Modules/cStringIO.c +745 −0
  167. sys/src/cmd/python/Modules/cdmodule.c +796 −0
  168. sys/src/cmd/python/Modules/cgen.py +520 −0
  169. sys/src/cmd/python/Modules/cgensupport.c +310 −0
  170. sys/src/cmd/python/Modules/cgensupport.h +64 −0
  171. sys/src/cmd/python/Modules/cjkcodecs/README +79 −0
  172. sys/src/cmd/python/Modules/cjkcodecs/_codecs_cn.c +443 −0
  173. sys/src/cmd/python/Modules/cjkcodecs/_codecs_hk.c +143 −0
  174. sys/src/cmd/python/Modules/cjkcodecs/_codecs_iso2022.c +1131 −0
  175. sys/src/cmd/python/Modules/cjkcodecs/_codecs_jp.c +731 −0
  176. sys/src/cmd/python/Modules/cjkcodecs/_codecs_kr.c +355 −0
  177. sys/src/cmd/python/Modules/cjkcodecs/_codecs_tw.c +132 −0
  178. sys/src/cmd/python/Modules/cjkcodecs/alg_jisx0201.h +24 −0
  179. sys/src/cmd/python/Modules/cjkcodecs/cjkcodecs.h +398 −0
  180. sys/src/cmd/python/Modules/cjkcodecs/emu_jisx0213_2000.h +43 −0
  181. sys/src/cmd/python/Modules/cjkcodecs/mappings_cn.h +4103 −0
  182. sys/src/cmd/python/Modules/cjkcodecs/mappings_hk.h +2340 −0
  183. sys/src/cmd/python/Modules/cjkcodecs/mappings_jisx0213_pair.h +59 −0
  184. sys/src/cmd/python/Modules/cjkcodecs/mappings_jp.h +4765 −0
  185. sys/src/cmd/python/Modules/cjkcodecs/mappings_kr.h +3251 −0
  186. sys/src/cmd/python/Modules/cjkcodecs/mappings_tw.h +2633 −0
  187. sys/src/cmd/python/Modules/cjkcodecs/multibytecodec.c +1793 −0
  188. sys/src/cmd/python/Modules/cjkcodecs/multibytecodec.h +138 −0
  189. sys/src/cmd/python/Modules/clmodule.c +2559 −0
  190. sys/src/cmd/python/Modules/cmathmodule.c +426 −0
  191. sys/src/cmd/python/Modules/collectionsmodule.c +1370 −0
  192. sys/src/cmd/python/Modules/config +54 −0
  193. sys/src/cmd/python/Modules/config.c.in +66 −0
  194. sys/src/cmd/python/Modules/cryptmodule.c +49 −0
  195. sys/src/cmd/python/Modules/cstubs +1364 −0
  196. sys/src/cmd/python/Modules/datetimemodule.c +4988 −0
  197. sys/src/cmd/python/Modules/dbmmodule.c +370 −0
  198. sys/src/cmd/python/Modules/dlmodule.c +278 −0
  199. sys/src/cmd/python/Modules/errnomodule.c +788 −0
  200. sys/src/cmd/python/Modules/expat/amigaconfig.h +96 −0
  201. sys/src/cmd/python/Modules/expat/ascii.h +85 −0
  202. sys/src/cmd/python/Modules/expat/asciitab.h +36 −0
  203. sys/src/cmd/python/Modules/expat/expat.h +1013 −0
  204. sys/src/cmd/python/Modules/expat/expat_config.h +19 −0
  205. sys/src/cmd/python/Modules/expat/expat_external.h +119 −0
  206. sys/src/cmd/python/Modules/expat/iasciitab.h +37 −0
  207. sys/src/cmd/python/Modules/expat/internal.h +73 −0
  208. sys/src/cmd/python/Modules/expat/latin1tab.h +36 −0
  209. sys/src/cmd/python/Modules/expat/macconfig.h +53 −0
  210. sys/src/cmd/python/Modules/expat/nametab.h +150 −0
  211. sys/src/cmd/python/Modules/expat/pyexpatns.h +124 −0
  212. sys/src/cmd/python/Modules/expat/utf8tab.h +37 −0
  213. sys/src/cmd/python/Modules/expat/winconfig.h +30 −0
  214. sys/src/cmd/python/Modules/expat/xmlparse.c +6268 −0
  215. sys/src/cmd/python/Modules/expat/xmlrole.c +1330 −0
  216. sys/src/cmd/python/Modules/expat/xmlrole.h +114 −0
  217. sys/src/cmd/python/Modules/expat/xmltok.c +1639 −0
  218. sys/src/cmd/python/Modules/expat/xmltok.h +316 −0
  219. sys/src/cmd/python/Modules/expat/xmltok_impl.c +1779 −0
  220. sys/src/cmd/python/Modules/expat/xmltok_impl.h +46 −0
  221. sys/src/cmd/python/Modules/expat/xmltok_ns.c +106 −0
  222. sys/src/cmd/python/Modules/fcntlmodule.c +607 −0
  223. sys/src/cmd/python/Modules/flmodule.c +2139 −0
  224. sys/src/cmd/python/Modules/fmmodule.c +264 −0
  225. sys/src/cmd/python/Modules/fpectlmodule.c +303 −0
  226. sys/src/cmd/python/Modules/fpetestmodule.c +186 −0
  227. sys/src/cmd/python/Modules/gc_weakref.txt +219 −0
  228. sys/src/cmd/python/Modules/gcmodule.c +1390 −0
  229. sys/src/cmd/python/Modules/gdbmmodule.c +515 −0
  230. sys/src/cmd/python/Modules/getaddrinfo.c +638 −0
  231. sys/src/cmd/python/Modules/getbuildinfo.c +48 −0
  232. sys/src/cmd/python/Modules/getnameinfo.c +214 −0
  233. sys/src/cmd/python/Modules/getpath.c +694 −0
  234. sys/src/cmd/python/Modules/glmodule.c +7628 −0
  235. sys/src/cmd/python/Modules/grpmodule.c +194 −0
  236. sys/src/cmd/python/Modules/imageop.c +785 −0
  237. sys/src/cmd/python/Modules/imgfile.c +504 −0
  238. sys/src/cmd/python/Modules/itertoolsmodule.c +2550 −0
  239. sys/src/cmd/python/Modules/ld_so_aix +187 −0
  240. sys/src/cmd/python/Modules/ld_so_beos +78 −0
  241. sys/src/cmd/python/Modules/linuxaudiodev.c +502 −0
  242. sys/src/cmd/python/Modules/main.c +584 −0
  243. sys/src/cmd/python/Modules/makesetup +297 −0
  244. sys/src/cmd/python/Modules/makexp_aix +81 −0
  245. sys/src/cmd/python/Modules/mathmodule.c +376 −0
  246. sys/src/cmd/python/Modules/md5.c +381 −0
  247. sys/src/cmd/python/Modules/md5.h +91 −0
  248. sys/src/cmd/python/Modules/md5module.c +312 −0
  249. sys/src/cmd/python/Modules/mkfile +135 −0
  250. sys/src/cmd/python/Modules/mmapmodule.c +1186 −0
  251. sys/src/cmd/python/Modules/nismodule.c +444 −0
  252. sys/src/cmd/python/Modules/operator.c +602 −0
  253. sys/src/cmd/python/Modules/ossaudiodev.c +1138 −0
  254. sys/src/cmd/python/Modules/parsermodule.c +3279 −0
  255. sys/src/cmd/python/Modules/posixmodule.c +8752 −0
  256. sys/src/cmd/python/Modules/puremodule.c +988 −0
  257. sys/src/cmd/python/Modules/pwdmodule.c +198 −0
  258. sys/src/cmd/python/Modules/pyexpat.c +2149 −0
  259. sys/src/cmd/python/Modules/python.c +24 −0
  260. sys/src/cmd/python/Modules/readline.c +941 −0
  261. sys/src/cmd/python/Modules/resource.c +325 −0
  262. sys/src/cmd/python/Modules/rgbimgmodule.c +780 −0
  263. sys/src/cmd/python/Modules/rotatingtree.c +121 −0
  264. sys/src/cmd/python/Modules/rotatingtree.h +27 −0
  265. sys/src/cmd/python/Modules/selectmodule.c +734 −0
  266. sys/src/cmd/python/Modules/sgimodule.c +55 −0
  267. sys/src/cmd/python/Modules/sha256module.c +701 −0
  268. sys/src/cmd/python/Modules/sha512module.c +769 −0
  269. sys/src/cmd/python/Modules/shamodule.c +593 −0
  270. sys/src/cmd/python/Modules/signalmodule.c +676 −0
  271. sys/src/cmd/python/Modules/socketmodule.c +5100 −0
  272. sys/src/cmd/python/Modules/socketmodule.h +252 −0
  273. sys/src/cmd/python/Modules/spwdmodule.c +183 −0
  274. sys/src/cmd/python/Modules/sre.h +94 −0
  275. sys/src/cmd/python/Modules/sre_constants.h +86 −0
  276. sys/src/cmd/python/Modules/stropmodule.c +1248 −0
  277. sys/src/cmd/python/Modules/sunaudiodev.c +465 −0
  278. sys/src/cmd/python/Modules/svmodule.c +966 −0
  279. sys/src/cmd/python/Modules/symtablemodule.c +84 −0
  280. sys/src/cmd/python/Modules/syslogmodule.c +223 −0
  281. sys/src/cmd/python/Modules/termios.c +926 −0
  282. sys/src/cmd/python/Modules/testcapi_long.h +166 −0
  283. sys/src/cmd/python/Modules/threadmodule.c +720 −0
  284. sys/src/cmd/python/Modules/timemodule.c +1030 −0
  285. sys/src/cmd/python/Modules/timing.h +67 −0
  286. sys/src/cmd/python/Modules/timingmodule.c +58 −0
  287. sys/src/cmd/python/Modules/tkappinit.c +149 −0
  288. sys/src/cmd/python/Modules/unicodedata.c +1223 −0
  289. sys/src/cmd/python/Modules/unicodedata_db.h +5135 −0
  290. sys/src/cmd/python/Modules/unicodename_db.h +12543 −0
  291. sys/src/cmd/python/Modules/xxmodule.c +376 −0
  292. sys/src/cmd/python/Modules/xxsubtype.c +299 −0
  293. sys/src/cmd/python/Modules/yuv.h +99 −0
  294. sys/src/cmd/python/Modules/yuvconvert.c +118 −0
  295. sys/src/cmd/python/Modules/zipimport.c +1191 −0
  296. sys/src/cmd/python/Modules/zlib/ChangeLog +855 −0
  297. sys/src/cmd/python/Modules/zlib/FAQ +339 −0
  298. sys/src/cmd/python/Modules/zlib/INDEX +51 −0
  299. sys/src/cmd/python/Modules/zlib/Makefile +154 −0
  300. sys/src/cmd/python/Modules/zlib/Makefile.in +154 −0
  301. sys/src/cmd/python/Modules/zlib/README +125 −0
  302. sys/src/cmd/python/Modules/zlib/adler32.c +149 −0
  303. sys/src/cmd/python/Modules/zlib/algorithm.txt +209 −0
  304. sys/src/cmd/python/Modules/zlib/compress.c +79 −0
  305. sys/src/cmd/python/Modules/zlib/configure +459 −0
  306. sys/src/cmd/python/Modules/zlib/crc32.c +423 −0
  307. sys/src/cmd/python/Modules/zlib/crc32.h +441 −0
  308. sys/src/cmd/python/Modules/zlib/deflate.c +1736 −0
  309. sys/src/cmd/python/Modules/zlib/deflate.h +331 −0
  310. sys/src/cmd/python/Modules/zlib/example.c +565 −0
  311. sys/src/cmd/python/Modules/zlib/gzio.c +1026 −0
  312. sys/src/cmd/python/Modules/zlib/infback.c +623 −0
  313. sys/src/cmd/python/Modules/zlib/inffast.c +318 −0
  314. sys/src/cmd/python/Modules/zlib/inffast.h +11 −0
sys/src/cmd/python/Modules/Setup+488−0
@@ -0,0 +1,488 @@
1+# -*- makefile -*-
2+# The file Setup is used by the makesetup script to construct the files
3+# Makefile and config.c, from Makefile.pre and config.c.in,
4+# respectively. The file Setup itself is initially copied from
5+# Setup.dist; once it exists it will not be overwritten, so you can edit
6+# Setup to your heart's content. Note that Makefile.pre is created
7+# from Makefile.pre.in by the toplevel configure script.
8+
9+# (VPATH notes: Setup and Makefile.pre are in the build directory, as
10+# are Makefile and config.c; the *.in and *.dist files are in the source
11+# directory.)
12+
13+# Each line in this file describes one or more optional modules.
14+# Modules enabled here will not be compiled by the setup.py script,
15+# so the file can be used to override setup.py's behavior.
16+
17+# Lines have the following structure:
18+#
19+# <module> ... [<sourcefile> ...] [<cpparg> ...] [<library> ...]
20+#
21+# <sourcefile> is anything ending in .c (.C, .cc, .c++ are C++ files)
22+# <cpparg> is anything starting with -I, -D, -U or -C
23+# <library> is anything ending in .a or beginning with -l or -L
24+# <module> is anything else but should be a valid Python
25+# identifier (letters, digits, underscores, beginning with non-digit)
26+#
27+# (As the makesetup script changes, it may recognize some other
28+# arguments as well, e.g. *.so and *.sl as libraries. See the big
29+# case statement in the makesetup script.)
30+#
31+# Lines can also have the form
32+#
33+# <name> = <value>
34+#
35+# which defines a Make variable definition inserted into Makefile.in
36+#
37+# Finally, if a line contains just the word "*shared*" (without the
38+# quotes but with the stars), then the following modules will not be
39+# built statically. The build process works like this:
40+#
41+# 1. Build all modules that are declared as static in Modules/Setup,
42+# combine them into libpythonxy.a, combine that into python.
43+# 2. Build all modules that are listed as shared in Modules/Setup.
44+# 3. Invoke setup.py. That builds all modules that
45+# a) are not builtin, and
46+# b) are not listed in Modules/Setup, and
47+# c) can be build on the target
48+#
49+# Therefore, modules declared to be shared will not be
50+# included in the config.c file, nor in the list of objects to be
51+# added to the library archive, and their linker options won't be
52+# added to the linker options. Rules to create their .o files and
53+# their shared libraries will still be added to the Makefile, and
54+# their names will be collected in the Make variable SHAREDMODS. This
55+# is used to build modules as shared libraries. (They can be
56+# installed using "make sharedinstall", which is implied by the
57+# toplevel "make install" target.) (For compatibility,
58+# *noconfig* has the same effect as *shared*.)
59+#
60+# In addition, *static* explicitly declares the following modules to
61+# be static. Lines containing "*static*" and "*shared*" may thus
62+# alternate throughout this file.
63+
64+# NOTE: As a standard policy, as many modules as can be supported by a
65+# platform should be present. The distribution comes with all modules
66+# enabled that are supported by most platforms and don't require you
67+# to ftp sources from elsewhere.
68+
69+
70+# Some special rules to define PYTHONPATH.
71+# Edit the definitions below to indicate which options you are using.
72+# Don't add any whitespace or comments!
73+
74+# Directories where library files get installed.
75+# DESTLIB is for Python modules; MACHDESTLIB for shared libraries.
76+DESTLIB=$(LIBDEST)
77+MACHDESTLIB=$(BINLIBDEST)
78+
79+# NOTE: all the paths are now relative to the prefix that is computed
80+# at run time!
81+
82+# Standard path -- don't edit.
83+# No leading colon since this is the first entry.
84+# Empty since this is now just the runtime prefix.
85+DESTPATH=
86+
87+# Site specific path components -- should begin with : if non-empty
88+SITEPATH=
89+
90+# Standard path components for test modules
91+TESTPATH=
92+
93+# Path components for machine- or system-dependent modules and shared libraries
94+MACHDEPPATH=:plat-$(MACHDEP)
95+EXTRAMACHDEPPATH=
96+
97+# Path component for the Tkinter-related modules
98+# The TKPATH variable is always enabled, to save you the effort.
99+TKPATH=:lib-tk
100+
101+COREPYTHONPATH=$(DESTPATH)$(SITEPATH)$(TESTPATH)$(MACHDEPPATH)$(EXTRAMACHDEPPATH)$(TKPATH)
102+PYTHONPATH=$(COREPYTHONPATH)
103+
104+
105+# The modules listed here can't be built as shared libraries for
106+# various reasons; therefore they are listed here instead of in the
107+# normal order.
108+
109+# This only contains the minimal set of modules required to run the
110+# setup.py script in the root of the Python source tree.
111+
112+posix posixmodule.c # posix (UNIX) system calls
113+errno errnomodule.c # posix (UNIX) errno values
114+pwd pwdmodule.c # this is needed to find out the user's home dir
115+ # if $HOME is not set
116+_sre _sre.c # Fredrik Lundh's new regular expressions
117+_codecs _codecsmodule.c # access to the builtin codecs and codec registry
118+_ssl _ssl.c
119+
120+# The zipimport module is always imported at startup. Having it as a
121+# builtin module avoids some bootstrapping problems and reduces overhead.
122+zipimport zipimport.c
123+
124+# The rest of the modules listed in this file are all commented out by
125+# default. Usually they can be detected and built as dynamically
126+# loaded modules by the new setup.py script added in Python 2.1. If
127+# you're on a platform that doesn't support dynamic loading, want to
128+# compile modules statically into the Python binary, or need to
129+# specify some odd set of compiler switches, you can uncomment the
130+# appropriate lines below.
131+
132+# ======================================================================
133+
134+# The Python symtable module depends on .h files that setup.py doesn't track
135+_symtable symtablemodule.c
136+
137+# The SGI specific GL module:
138+
139+GLHACK=-Dclear=__GLclear
140+#gl glmodule.c cgensupport.c -I$(srcdir) $(GLHACK) -lgl -lX11
141+
142+# Pure module. Cannot be linked dynamically.
143+# -DWITH_QUANTIFY, -DWITH_PURIFY, or -DWITH_ALL_PURE
144+#WHICH_PURE_PRODUCTS=-DWITH_ALL_PURE
145+#PURE_INCLS=-I/usr/local/include
146+#PURE_STUBLIBS=-L/usr/local/lib -lpurify_stubs -lquantify_stubs
147+#pure puremodule.c $(WHICH_PURE_PRODUCTS) $(PURE_INCLS) $(PURE_STUBLIBS)
148+
149+# Uncommenting the following line tells makesetup that all following
150+# modules are to be built as shared libraries (see above for more
151+# detail; also note that *static* reverses this effect):
152+
153+#*shared*
154+
155+# GNU readline. Unlike previous Python incarnations, GNU readline is
156+# now incorporated in an optional module, configured in the Setup file
157+# instead of by a configure script switch. You may have to insert a
158+# -L option pointing to the directory where libreadline.* lives,
159+# and you may have to change -ltermcap to -ltermlib or perhaps remove
160+# it, depending on your system -- see the GNU readline instructions.
161+# It's okay for this to be a shared library, too.
162+
163+#readline readline.c -lreadline -ltermcap
164+
165+
166+# Modules that should always be present (non UNIX dependent):
167+
168+#array arraymodule.c # array objects
169+#cmath cmathmodule.c # -lm # complex math library functions
170+#math mathmodule.c # -lm # math library functions, e.g. sin()
171+#_struct _struct.c # binary structure packing/unpacking
172+#time timemodule.c # -lm # time operations and variables
173+#operator operator.c # operator.add() and similar goodies
174+#_weakref _weakref.c # basic weak reference support
175+#_testcapi _testcapimodule.c # Python C API test module
176+#_random _randommodule.c # Random number generator
177+#collections collectionsmodule.c # Container types
178+#itertools itertoolsmodule.c # Functions creating iterators for efficient looping
179+#strop stropmodule.c # String manipulations
180+
181+#unicodedata unicodedata.c # static Unicode character database
182+
183+# access to ISO C locale support
184+#_locale _localemodule.c # -lintl
185+
186+
187+# Modules with some UNIX dependencies -- on by default:
188+# (If you have a really backward UNIX, select and socket may not be
189+# supported...)
190+
191+#fcntl fcntlmodule.c # fcntl(2) and ioctl(2)
192+#spwd spwdmodule.c # spwd(3)
193+#grp grpmodule.c # grp(3)
194+#select selectmodule.c # select(2); not on ancient System V
195+
196+# Memory-mapped files (also works on Win32).
197+#mmap mmapmodule.c
198+
199+# CSV file helper
200+#_csv _csv.c
201+
202+# Socket module helper for socket(2)
203+#_socket socketmodule.c
204+
205+# Socket module helper for SSL support; you must comment out the other
206+# socket line above, and possibly edit the SSL variable:
207+#SSL=/usr/local/ssl
208+#_ssl _ssl.c \
209+# -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
210+# -L$(SSL)/lib -lssl -lcrypto
211+
212+# The crypt module is now disabled by default because it breaks builds
213+# on many systems (where -lcrypt is needed), e.g. Linux (I believe).
214+#
215+# First, look at Setup.config; configure may have set this for you.
216+
217+#crypt cryptmodule.c # -lcrypt # crypt(3); needs -lcrypt on some systems
218+
219+
220+# Some more UNIX dependent modules -- off by default, since these
221+# are not supported by all UNIX systems:
222+
223+#nis nismodule.c -lnsl # Sun yellow pages -- not everywhere
224+#termios termios.c # Steen Lumholt's termios module
225+#resource resource.c # Jeremy Hylton's rlimit interface
226+
227+
228+# Multimedia modules -- off by default.
229+# These don't work for 64-bit platforms!!!
230+# #993173 says audioop works on 64-bit platforms, though.
231+# These represent audio samples or images as strings:
232+
233+#audioop audioop.c # Operations on audio samples
234+#imageop imageop.c # Operations on images
235+#rgbimg rgbimgmodule.c # Read SGI RGB image files (but coded portably)
236+
237+
238+# Note that the _md5 and _sha modules are normally only built if the
239+# system does not have the OpenSSL libs containing an optimized version.
240+
241+# The _md5 module implements the RSA Data Security, Inc. MD5
242+# Message-Digest Algorithm, described in RFC 1321. The necessary files
243+# md5.c and md5.h are included here.
244+
245+#_md5 md5module.c md5.c
246+
247+
248+# The _sha module implements the SHA checksum algorithm.
249+# (NIST's Secure Hash Algorithm.)
250+#_sha shamodule.c
251+
252+
253+# SGI IRIX specific modules -- off by default.
254+
255+# These module work on any SGI machine:
256+
257+# *** gl must be enabled higher up in this file ***
258+#fm fmmodule.c $(GLHACK) -lfm -lgl # Font Manager
259+#sgi sgimodule.c # sgi.nap() and a few more
260+
261+# This module requires the header file
262+# /usr/people/4Dgifts/iristools/include/izoom.h:
263+#imgfile imgfile.c -limage -lgutil -lgl -lm # Image Processing Utilities
264+
265+
266+# These modules require the Multimedia Development Option (I think):
267+
268+#al almodule.c -laudio # Audio Library
269+#cd cdmodule.c -lcdaudio -lds -lmediad # CD Audio Library
270+#cl clmodule.c -lcl -lawareaudio # Compression Library
271+#sv svmodule.c yuvconvert.c -lsvideo -lXext -lX11 # Starter Video
272+
273+
274+# The FORMS library, by Mark Overmars, implements user interface
275+# components such as dialogs and buttons using SGI's GL and FM
276+# libraries. You must ftp the FORMS library separately from
277+# ftp://ftp.cs.ruu.nl/pub/SGI/FORMS. It was tested with FORMS 2.2a.
278+# NOTE: if you want to be able to use FORMS and curses simultaneously
279+# (or both link them statically into the same binary), you must
280+# compile all of FORMS with the cc option "-Dclear=__GLclear".
281+
282+# The FORMS variable must point to the FORMS subdirectory of the forms
283+# toplevel directory:
284+
285+#FORMS=/ufs/guido/src/forms/FORMS
286+#fl flmodule.c -I$(FORMS) $(GLHACK) $(FORMS)/libforms.a -lfm -lgl
287+
288+
289+# SunOS specific modules -- off by default:
290+
291+#sunaudiodev sunaudiodev.c
292+
293+
294+# A Linux specific module -- off by default; this may also work on
295+# some *BSDs.
296+
297+#linuxaudiodev linuxaudiodev.c
298+
299+
300+# George Neville-Neil's timing module:
301+
302+#timing timingmodule.c
303+
304+
305+# The _tkinter module.
306+#
307+# The command for _tkinter is long and site specific. Please
308+# uncomment and/or edit those parts as indicated. If you don't have a
309+# specific extension (e.g. Tix or BLT), leave the corresponding line
310+# commented out. (Leave the trailing backslashes in! If you
311+# experience strange errors, you may want to join all uncommented
312+# lines and remove the backslashes -- the backslash interpretation is
313+# done by the shell's "read" command and it may not be implemented on
314+# every system.
315+
316+# *** Always uncomment this (leave the leading underscore in!):
317+# _tkinter _tkinter.c tkappinit.c -DWITH_APPINIT \
318+# *** Uncomment and edit to reflect where your Tcl/Tk libraries are:
319+# -L/usr/local/lib \
320+# *** Uncomment and edit to reflect where your Tcl/Tk headers are:
321+# -I/usr/local/include \
322+# *** Uncomment and edit to reflect where your X11 header files are:
323+# -I/usr/X11R6/include \
324+# *** Or uncomment this for Solaris:
325+# -I/usr/openwin/include \
326+# *** Uncomment and edit for Tix extension only:
327+# -DWITH_TIX -ltix8.1.8.2 \
328+# *** Uncomment and edit for BLT extension only:
329+# -DWITH_BLT -I/usr/local/blt/blt8.0-unoff/include -lBLT8.0 \
330+# *** Uncomment and edit for PIL (TkImaging) extension only:
331+# (See http://www.pythonware.com/products/pil/ for more info)
332+# -DWITH_PIL -I../Extensions/Imaging/libImaging tkImaging.c \
333+# *** Uncomment and edit for TOGL extension only:
334+# -DWITH_TOGL togl.c \
335+# *** Uncomment and edit to reflect your Tcl/Tk versions:
336+# -ltk8.2 -ltcl8.2 \
337+# *** Uncomment and edit to reflect where your X11 libraries are:
338+# -L/usr/X11R6/lib \
339+# *** Or uncomment this for Solaris:
340+# -L/usr/openwin/lib \
341+# *** Uncomment these for TOGL extension only:
342+# -lGL -lGLU -lXext -lXmu \
343+# *** Uncomment for AIX:
344+# -lld \
345+# *** Always uncomment this; X11 libraries to link with:
346+# -lX11
347+
348+# Lance Ellinghaus's syslog module
349+#syslog syslogmodule.c # syslog daemon interface
350+
351+
352+# Curses support, requring the System V version of curses, often
353+# provided by the ncurses library. e.g. on Linux, link with -lncurses
354+# instead of -lcurses).
355+#
356+# First, look at Setup.config; configure may have set this for you.
357+
358+#_curses _cursesmodule.c -lcurses -ltermcap
359+# Wrapper for the panel library that's part of ncurses and SYSV curses.
360+#_curses_panel _curses_panel.c -lpanel -lncurses
361+
362+
363+# Generic (SunOS / SVR4) dynamic loading module.
364+# This is not needed for dynamic loading of Python modules --
365+# it is a highly experimental and dangerous device for calling
366+# *arbitrary* C functions in *arbitrary* shared libraries:
367+
368+#dl dlmodule.c
369+
370+
371+# Modules that provide persistent dictionary-like semantics. You will
372+# probably want to arrange for at least one of them to be available on
373+# your machine, though none are defined by default because of library
374+# dependencies. The Python module anydbm.py provides an
375+# implementation independent wrapper for these; dumbdbm.py provides
376+# similar functionality (but slower of course) implemented in Python.
377+
378+# The standard Unix dbm module has been moved to Setup.config so that
379+# it will be compiled as a shared library by default. Compiling it as
380+# a built-in module causes conflicts with the pybsddb3 module since it
381+# creates a static dependency on an out-of-date version of db.so.
382+#
383+# First, look at Setup.config; configure may have set this for you.
384+
385+#dbm dbmmodule.c # dbm(3) may require -lndbm or similar
386+
387+# Anthony Baxter's gdbm module. GNU dbm(3) will require -lgdbm:
388+#
389+# First, look at Setup.config; configure may have set this for you.
390+
391+#gdbm gdbmmodule.c -I/usr/local/include -L/usr/local/lib -lgdbm
392+
393+
394+# Sleepycat Berkeley DB interface.
395+#
396+# This requires the Sleepycat DB code, see http://www.sleepycat.com/
397+# The earliest supported version of that library is 3.0, the latest
398+# supported version is 4.0 (4.1 is specifically not supported, as that
399+# changes the semantics of transactional databases). A list of available
400+# releases can be found at
401+#
402+# http://www.sleepycat.com/update/index.html
403+#
404+# Edit the variables DB and DBLIBVERto point to the db top directory
405+# and the subdirectory of PORT where you built it.
406+#DB=/usr/local/BerkeleyDB.4.0
407+#DBLIBVER=4.0
408+#DBINC=$(DB)/include
409+#DBLIB=$(DB)/lib
410+#_bsddb _bsddb.c -I$(DBINC) -L$(DBLIB) -ldb-$(DBLIBVER)
411+
412+# Historical Berkeley DB 1.85
413+#
414+# This module is deprecated; the 1.85 version of the Berkeley DB library has
415+# bugs that can cause data corruption. If you can, use later versions of the
416+# library instead, available from <http://www.sleepycat.com/>.
417+
418+#DB=/depot/sundry/src/berkeley-db/db.1.85
419+#DBPORT=$(DB)/PORT/irix.5.3
420+#bsddb185 bsddbmodule.c -I$(DBPORT)/include -I$(DBPORT) $(DBPORT)/libdb.a
421+
422+
423+
424+# Helper module for various ascii-encoders
425+#binascii binascii.c
426+
427+# Fred Drake's interface to the Python parser
428+#parser parsermodule.c
429+
430+# cStringIO and cPickle
431+#cStringIO cStringIO.c
432+#cPickle cPickle.c
433+
434+
435+# Lee Busby's SIGFPE modules.
436+# The library to link fpectl with is platform specific.
437+# Choose *one* of the options below for fpectl:
438+
439+# For SGI IRIX (tested on 5.3):
440+#fpectl fpectlmodule.c -lfpe
441+
442+# For Solaris with SunPro compiler (tested on Solaris 2.5 with SunPro C 4.2):
443+# (Without the compiler you don't have -lsunmath.)
444+#fpectl fpectlmodule.c -R/opt/SUNWspro/lib -lsunmath -lm
445+
446+# For other systems: see instructions in fpectlmodule.c.
447+#fpectl fpectlmodule.c ...
448+
449+# Test module for fpectl. No extra libraries needed.
450+#fpetest fpetestmodule.c
451+
452+# Andrew Kuchling's zlib module.
453+# This require zlib 1.1.3 (or later).
454+# See http://www.gzip.org/zlib/
455+#zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz
456+
457+# Interface to the Expat XML parser
458+#
459+# Expat was written by James Clark and is now maintained by a group of
460+# developers on SourceForge; see www.libexpat.org for more
461+# information. The pyexpat module was written by Paul Prescod after a
462+# prototype by Jack Jansen. Source of Expat 1.95.2 is included in
463+# Modules/expat/. Usage of a system shared libexpat.so/expat.dll is
464+# not advised.
465+#
466+# More information on Expat can be found at www.libexpat.org.
467+#
468+#EXPAT_DIR=/usr/local/src/expat-1.95.2
469+#pyexpat pyexpat.c -DHAVE_EXPAT_H -I$(EXPAT_DIR)/lib -L$(EXPAT_DIR) -lexpat
470+
471+
472+# Hye-Shik Chang's CJKCodecs
473+
474+# multibytecodec is required for all the other CJK codec modules
475+#_multibytecodec cjkcodecs/multibytecodec.c
476+
477+#_codecs_cn cjkcodecs/_codecs_cn.c
478+#_codecs_hk cjkcodecs/_codecs_hk.c
479+#_codecs_iso2022 cjkcodecs/_codecs_iso2022.c
480+#_codecs_jp cjkcodecs/_codecs_jp.c
481+#_codecs_kr cjkcodecs/_codecs_kr.c
482+#_codecs_tw cjkcodecs/_codecs_tw.c
483+
484+# Example -- included for reference only:
485+# xx xxmodule.c
486+
487+# Another example -- the 'xxsubtype' module shows C-level subtyping in action
488+xxsubtype xxsubtype.c
sys/src/cmd/python/Modules/Setup.config+13−0
@@ -0,0 +1,13 @@
1+# This file is transmogrified into Setup.config by config.status.
2+
3+# The purpose of this file is to conditionally enable certain modules
4+# based on configure-time options.
5+
6+# Threading
7+#thread threadmodule.c
8+
9+# The signal module
10+signal signalmodule.c
11+
12+# The rest of the modules previously listed in this file are built
13+# by the setup.py script in Python 2.1 and later.
sys/src/cmd/python/Modules/Setup.config.in+13−0
@@ -0,0 +1,13 @@
1+# This file is transmogrified into Setup.config by config.status.
2+
3+# The purpose of this file is to conditionally enable certain modules
4+# based on configure-time options.
5+
6+# Threading
7+@USE_THREAD_MODULE@thread threadmodule.c
8+
9+# The signal module
10+@USE_SIGNAL_MODULE@signal signalmodule.c
11+
12+# The rest of the modules previously listed in this file are built
13+# by the setup.py script in Python 2.1 and later.
sys/src/cmd/python/Modules/Setup.dist+487−0
@@ -0,0 +1,487 @@
1+# -*- makefile -*-
2+# The file Setup is used by the makesetup script to construct the files
3+# Makefile and config.c, from Makefile.pre and config.c.in,
4+# respectively. The file Setup itself is initially copied from
5+# Setup.dist; once it exists it will not be overwritten, so you can edit
6+# Setup to your heart's content. Note that Makefile.pre is created
7+# from Makefile.pre.in by the toplevel configure script.
8+
9+# (VPATH notes: Setup and Makefile.pre are in the build directory, as
10+# are Makefile and config.c; the *.in and *.dist files are in the source
11+# directory.)
12+
13+# Each line in this file describes one or more optional modules.
14+# Modules enabled here will not be compiled by the setup.py script,
15+# so the file can be used to override setup.py's behavior.
16+
17+# Lines have the following structure:
18+#
19+# <module> ... [<sourcefile> ...] [<cpparg> ...] [<library> ...]
20+#
21+# <sourcefile> is anything ending in .c (.C, .cc, .c++ are C++ files)
22+# <cpparg> is anything starting with -I, -D, -U or -C
23+# <library> is anything ending in .a or beginning with -l or -L
24+# <module> is anything else but should be a valid Python
25+# identifier (letters, digits, underscores, beginning with non-digit)
26+#
27+# (As the makesetup script changes, it may recognize some other
28+# arguments as well, e.g. *.so and *.sl as libraries. See the big
29+# case statement in the makesetup script.)
30+#
31+# Lines can also have the form
32+#
33+# <name> = <value>
34+#
35+# which defines a Make variable definition inserted into Makefile.in
36+#
37+# Finally, if a line contains just the word "*shared*" (without the
38+# quotes but with the stars), then the following modules will not be
39+# built statically. The build process works like this:
40+#
41+# 1. Build all modules that are declared as static in Modules/Setup,
42+# combine them into libpythonxy.a, combine that into python.
43+# 2. Build all modules that are listed as shared in Modules/Setup.
44+# 3. Invoke setup.py. That builds all modules that
45+# a) are not builtin, and
46+# b) are not listed in Modules/Setup, and
47+# c) can be build on the target
48+#
49+# Therefore, modules declared to be shared will not be
50+# included in the config.c file, nor in the list of objects to be
51+# added to the library archive, and their linker options won't be
52+# added to the linker options. Rules to create their .o files and
53+# their shared libraries will still be added to the Makefile, and
54+# their names will be collected in the Make variable SHAREDMODS. This
55+# is used to build modules as shared libraries. (They can be
56+# installed using "make sharedinstall", which is implied by the
57+# toplevel "make install" target.) (For compatibility,
58+# *noconfig* has the same effect as *shared*.)
59+#
60+# In addition, *static* explicitly declares the following modules to
61+# be static. Lines containing "*static*" and "*shared*" may thus
62+# alternate throughout this file.
63+
64+# NOTE: As a standard policy, as many modules as can be supported by a
65+# platform should be present. The distribution comes with all modules
66+# enabled that are supported by most platforms and don't require you
67+# to ftp sources from elsewhere.
68+
69+
70+# Some special rules to define PYTHONPATH.
71+# Edit the definitions below to indicate which options you are using.
72+# Don't add any whitespace or comments!
73+
74+# Directories where library files get installed.
75+# DESTLIB is for Python modules; MACHDESTLIB for shared libraries.
76+DESTLIB=$(LIBDEST)
77+MACHDESTLIB=$(BINLIBDEST)
78+
79+# NOTE: all the paths are now relative to the prefix that is computed
80+# at run time!
81+
82+# Standard path -- don't edit.
83+# No leading colon since this is the first entry.
84+# Empty since this is now just the runtime prefix.
85+DESTPATH=
86+
87+# Site specific path components -- should begin with : if non-empty
88+SITEPATH=
89+
90+# Standard path components for test modules
91+TESTPATH=
92+
93+# Path components for machine- or system-dependent modules and shared libraries
94+MACHDEPPATH=:plat-$(MACHDEP)
95+EXTRAMACHDEPPATH=
96+
97+# Path component for the Tkinter-related modules
98+# The TKPATH variable is always enabled, to save you the effort.
99+TKPATH=:lib-tk
100+
101+COREPYTHONPATH=$(DESTPATH)$(SITEPATH)$(TESTPATH)$(MACHDEPPATH)$(EXTRAMACHDEPPATH)$(TKPATH)
102+PYTHONPATH=$(COREPYTHONPATH)
103+
104+
105+# The modules listed here can't be built as shared libraries for
106+# various reasons; therefore they are listed here instead of in the
107+# normal order.
108+
109+# This only contains the minimal set of modules required to run the
110+# setup.py script in the root of the Python source tree.
111+
112+posix posixmodule.c # posix (UNIX) system calls
113+errno errnomodule.c # posix (UNIX) errno values
114+pwd pwdmodule.c # this is needed to find out the user's home dir
115+ # if $HOME is not set
116+_sre _sre.c # Fredrik Lundh's new regular expressions
117+_codecs _codecsmodule.c # access to the builtin codecs and codec registry
118+
119+# The zipimport module is always imported at startup. Having it as a
120+# builtin module avoids some bootstrapping problems and reduces overhead.
121+zipimport zipimport.c
122+
123+# The rest of the modules listed in this file are all commented out by
124+# default. Usually they can be detected and built as dynamically
125+# loaded modules by the new setup.py script added in Python 2.1. If
126+# you're on a platform that doesn't support dynamic loading, want to
127+# compile modules statically into the Python binary, or need to
128+# specify some odd set of compiler switches, you can uncomment the
129+# appropriate lines below.
130+
131+# ======================================================================
132+
133+# The Python symtable module depends on .h files that setup.py doesn't track
134+_symtable symtablemodule.c
135+
136+# The SGI specific GL module:
137+
138+GLHACK=-Dclear=__GLclear
139+#gl glmodule.c cgensupport.c -I$(srcdir) $(GLHACK) -lgl -lX11
140+
141+# Pure module. Cannot be linked dynamically.
142+# -DWITH_QUANTIFY, -DWITH_PURIFY, or -DWITH_ALL_PURE
143+#WHICH_PURE_PRODUCTS=-DWITH_ALL_PURE
144+#PURE_INCLS=-I/usr/local/include
145+#PURE_STUBLIBS=-L/usr/local/lib -lpurify_stubs -lquantify_stubs
146+#pure puremodule.c $(WHICH_PURE_PRODUCTS) $(PURE_INCLS) $(PURE_STUBLIBS)
147+
148+# Uncommenting the following line tells makesetup that all following
149+# modules are to be built as shared libraries (see above for more
150+# detail; also note that *static* reverses this effect):
151+
152+#*shared*
153+
154+# GNU readline. Unlike previous Python incarnations, GNU readline is
155+# now incorporated in an optional module, configured in the Setup file
156+# instead of by a configure script switch. You may have to insert a
157+# -L option pointing to the directory where libreadline.* lives,
158+# and you may have to change -ltermcap to -ltermlib or perhaps remove
159+# it, depending on your system -- see the GNU readline instructions.
160+# It's okay for this to be a shared library, too.
161+
162+#readline readline.c -lreadline -ltermcap
163+
164+
165+# Modules that should always be present (non UNIX dependent):
166+
167+#array arraymodule.c # array objects
168+#cmath cmathmodule.c # -lm # complex math library functions
169+#math mathmodule.c # -lm # math library functions, e.g. sin()
170+#_struct _struct.c # binary structure packing/unpacking
171+#time timemodule.c # -lm # time operations and variables
172+#operator operator.c # operator.add() and similar goodies
173+#_weakref _weakref.c # basic weak reference support
174+#_testcapi _testcapimodule.c # Python C API test module
175+#_random _randommodule.c # Random number generator
176+#collections collectionsmodule.c # Container types
177+#itertools itertoolsmodule.c # Functions creating iterators for efficient looping
178+#strop stropmodule.c # String manipulations
179+
180+#unicodedata unicodedata.c # static Unicode character database
181+
182+# access to ISO C locale support
183+#_locale _localemodule.c # -lintl
184+
185+
186+# Modules with some UNIX dependencies -- on by default:
187+# (If you have a really backward UNIX, select and socket may not be
188+# supported...)
189+
190+#fcntl fcntlmodule.c # fcntl(2) and ioctl(2)
191+#spwd spwdmodule.c # spwd(3)
192+#grp grpmodule.c # grp(3)
193+#select selectmodule.c # select(2); not on ancient System V
194+
195+# Memory-mapped files (also works on Win32).
196+#mmap mmapmodule.c
197+
198+# CSV file helper
199+#_csv _csv.c
200+
201+# Socket module helper for socket(2)
202+#_socket socketmodule.c
203+
204+# Socket module helper for SSL support; you must comment out the other
205+# socket line above, and possibly edit the SSL variable:
206+#SSL=/usr/local/ssl
207+#_ssl _ssl.c \
208+# -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
209+# -L$(SSL)/lib -lssl -lcrypto
210+
211+# The crypt module is now disabled by default because it breaks builds
212+# on many systems (where -lcrypt is needed), e.g. Linux (I believe).
213+#
214+# First, look at Setup.config; configure may have set this for you.
215+
216+#crypt cryptmodule.c # -lcrypt # crypt(3); needs -lcrypt on some systems
217+
218+
219+# Some more UNIX dependent modules -- off by default, since these
220+# are not supported by all UNIX systems:
221+
222+#nis nismodule.c -lnsl # Sun yellow pages -- not everywhere
223+#termios termios.c # Steen Lumholt's termios module
224+#resource resource.c # Jeremy Hylton's rlimit interface
225+
226+
227+# Multimedia modules -- off by default.
228+# These don't work for 64-bit platforms!!!
229+# #993173 says audioop works on 64-bit platforms, though.
230+# These represent audio samples or images as strings:
231+
232+#audioop audioop.c # Operations on audio samples
233+#imageop imageop.c # Operations on images
234+#rgbimg rgbimgmodule.c # Read SGI RGB image files (but coded portably)
235+
236+
237+# Note that the _md5 and _sha modules are normally only built if the
238+# system does not have the OpenSSL libs containing an optimized version.
239+
240+# The _md5 module implements the RSA Data Security, Inc. MD5
241+# Message-Digest Algorithm, described in RFC 1321. The necessary files
242+# md5.c and md5.h are included here.
243+
244+#_md5 md5module.c md5.c
245+
246+
247+# The _sha module implements the SHA checksum algorithm.
248+# (NIST's Secure Hash Algorithm.)
249+#_sha shamodule.c
250+
251+
252+# SGI IRIX specific modules -- off by default.
253+
254+# These module work on any SGI machine:
255+
256+# *** gl must be enabled higher up in this file ***
257+#fm fmmodule.c $(GLHACK) -lfm -lgl # Font Manager
258+#sgi sgimodule.c # sgi.nap() and a few more
259+
260+# This module requires the header file
261+# /usr/people/4Dgifts/iristools/include/izoom.h:
262+#imgfile imgfile.c -limage -lgutil -lgl -lm # Image Processing Utilities
263+
264+
265+# These modules require the Multimedia Development Option (I think):
266+
267+#al almodule.c -laudio # Audio Library
268+#cd cdmodule.c -lcdaudio -lds -lmediad # CD Audio Library
269+#cl clmodule.c -lcl -lawareaudio # Compression Library
270+#sv svmodule.c yuvconvert.c -lsvideo -lXext -lX11 # Starter Video
271+
272+
273+# The FORMS library, by Mark Overmars, implements user interface
274+# components such as dialogs and buttons using SGI's GL and FM
275+# libraries. You must ftp the FORMS library separately from
276+# ftp://ftp.cs.ruu.nl/pub/SGI/FORMS. It was tested with FORMS 2.2a.
277+# NOTE: if you want to be able to use FORMS and curses simultaneously
278+# (or both link them statically into the same binary), you must
279+# compile all of FORMS with the cc option "-Dclear=__GLclear".
280+
281+# The FORMS variable must point to the FORMS subdirectory of the forms
282+# toplevel directory:
283+
284+#FORMS=/ufs/guido/src/forms/FORMS
285+#fl flmodule.c -I$(FORMS) $(GLHACK) $(FORMS)/libforms.a -lfm -lgl
286+
287+
288+# SunOS specific modules -- off by default:
289+
290+#sunaudiodev sunaudiodev.c
291+
292+
293+# A Linux specific module -- off by default; this may also work on
294+# some *BSDs.
295+
296+#linuxaudiodev linuxaudiodev.c
297+
298+
299+# George Neville-Neil's timing module:
300+
301+#timing timingmodule.c
302+
303+
304+# The _tkinter module.
305+#
306+# The command for _tkinter is long and site specific. Please
307+# uncomment and/or edit those parts as indicated. If you don't have a
308+# specific extension (e.g. Tix or BLT), leave the corresponding line
309+# commented out. (Leave the trailing backslashes in! If you
310+# experience strange errors, you may want to join all uncommented
311+# lines and remove the backslashes -- the backslash interpretation is
312+# done by the shell's "read" command and it may not be implemented on
313+# every system.
314+
315+# *** Always uncomment this (leave the leading underscore in!):
316+# _tkinter _tkinter.c tkappinit.c -DWITH_APPINIT \
317+# *** Uncomment and edit to reflect where your Tcl/Tk libraries are:
318+# -L/usr/local/lib \
319+# *** Uncomment and edit to reflect where your Tcl/Tk headers are:
320+# -I/usr/local/include \
321+# *** Uncomment and edit to reflect where your X11 header files are:
322+# -I/usr/X11R6/include \
323+# *** Or uncomment this for Solaris:
324+# -I/usr/openwin/include \
325+# *** Uncomment and edit for Tix extension only:
326+# -DWITH_TIX -ltix8.1.8.2 \
327+# *** Uncomment and edit for BLT extension only:
328+# -DWITH_BLT -I/usr/local/blt/blt8.0-unoff/include -lBLT8.0 \
329+# *** Uncomment and edit for PIL (TkImaging) extension only:
330+# (See http://www.pythonware.com/products/pil/ for more info)
331+# -DWITH_PIL -I../Extensions/Imaging/libImaging tkImaging.c \
332+# *** Uncomment and edit for TOGL extension only:
333+# -DWITH_TOGL togl.c \
334+# *** Uncomment and edit to reflect your Tcl/Tk versions:
335+# -ltk8.2 -ltcl8.2 \
336+# *** Uncomment and edit to reflect where your X11 libraries are:
337+# -L/usr/X11R6/lib \
338+# *** Or uncomment this for Solaris:
339+# -L/usr/openwin/lib \
340+# *** Uncomment these for TOGL extension only:
341+# -lGL -lGLU -lXext -lXmu \
342+# *** Uncomment for AIX:
343+# -lld \
344+# *** Always uncomment this; X11 libraries to link with:
345+# -lX11
346+
347+# Lance Ellinghaus's syslog module
348+#syslog syslogmodule.c # syslog daemon interface
349+
350+
351+# Curses support, requring the System V version of curses, often
352+# provided by the ncurses library. e.g. on Linux, link with -lncurses
353+# instead of -lcurses).
354+#
355+# First, look at Setup.config; configure may have set this for you.
356+
357+#_curses _cursesmodule.c -lcurses -ltermcap
358+# Wrapper for the panel library that's part of ncurses and SYSV curses.
359+#_curses_panel _curses_panel.c -lpanel -lncurses
360+
361+
362+# Generic (SunOS / SVR4) dynamic loading module.
363+# This is not needed for dynamic loading of Python modules --
364+# it is a highly experimental and dangerous device for calling
365+# *arbitrary* C functions in *arbitrary* shared libraries:
366+
367+#dl dlmodule.c
368+
369+
370+# Modules that provide persistent dictionary-like semantics. You will
371+# probably want to arrange for at least one of them to be available on
372+# your machine, though none are defined by default because of library
373+# dependencies. The Python module anydbm.py provides an
374+# implementation independent wrapper for these; dumbdbm.py provides
375+# similar functionality (but slower of course) implemented in Python.
376+
377+# The standard Unix dbm module has been moved to Setup.config so that
378+# it will be compiled as a shared library by default. Compiling it as
379+# a built-in module causes conflicts with the pybsddb3 module since it
380+# creates a static dependency on an out-of-date version of db.so.
381+#
382+# First, look at Setup.config; configure may have set this for you.
383+
384+#dbm dbmmodule.c # dbm(3) may require -lndbm or similar
385+
386+# Anthony Baxter's gdbm module. GNU dbm(3) will require -lgdbm:
387+#
388+# First, look at Setup.config; configure may have set this for you.
389+
390+#gdbm gdbmmodule.c -I/usr/local/include -L/usr/local/lib -lgdbm
391+
392+
393+# Sleepycat Berkeley DB interface.
394+#
395+# This requires the Sleepycat DB code, see http://www.sleepycat.com/
396+# The earliest supported version of that library is 3.0, the latest
397+# supported version is 4.0 (4.1 is specifically not supported, as that
398+# changes the semantics of transactional databases). A list of available
399+# releases can be found at
400+#
401+# http://www.sleepycat.com/update/index.html
402+#
403+# Edit the variables DB and DBLIBVERto point to the db top directory
404+# and the subdirectory of PORT where you built it.
405+#DB=/usr/local/BerkeleyDB.4.0
406+#DBLIBVER=4.0
407+#DBINC=$(DB)/include
408+#DBLIB=$(DB)/lib
409+#_bsddb _bsddb.c -I$(DBINC) -L$(DBLIB) -ldb-$(DBLIBVER)
410+
411+# Historical Berkeley DB 1.85
412+#
413+# This module is deprecated; the 1.85 version of the Berkeley DB library has
414+# bugs that can cause data corruption. If you can, use later versions of the
415+# library instead, available from <http://www.sleepycat.com/>.
416+
417+#DB=/depot/sundry/src/berkeley-db/db.1.85
418+#DBPORT=$(DB)/PORT/irix.5.3
419+#bsddb185 bsddbmodule.c -I$(DBPORT)/include -I$(DBPORT) $(DBPORT)/libdb.a
420+
421+
422+
423+# Helper module for various ascii-encoders
424+#binascii binascii.c
425+
426+# Fred Drake's interface to the Python parser
427+#parser parsermodule.c
428+
429+# cStringIO and cPickle
430+#cStringIO cStringIO.c
431+#cPickle cPickle.c
432+
433+
434+# Lee Busby's SIGFPE modules.
435+# The library to link fpectl with is platform specific.
436+# Choose *one* of the options below for fpectl:
437+
438+# For SGI IRIX (tested on 5.3):
439+#fpectl fpectlmodule.c -lfpe
440+
441+# For Solaris with SunPro compiler (tested on Solaris 2.5 with SunPro C 4.2):
442+# (Without the compiler you don't have -lsunmath.)
443+#fpectl fpectlmodule.c -R/opt/SUNWspro/lib -lsunmath -lm
444+
445+# For other systems: see instructions in fpectlmodule.c.
446+#fpectl fpectlmodule.c ...
447+
448+# Test module for fpectl. No extra libraries needed.
449+#fpetest fpetestmodule.c
450+
451+# Andrew Kuchling's zlib module.
452+# This require zlib 1.1.3 (or later).
453+# See http://www.gzip.org/zlib/
454+#zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz
455+
456+# Interface to the Expat XML parser
457+#
458+# Expat was written by James Clark and is now maintained by a group of
459+# developers on SourceForge; see www.libexpat.org for more
460+# information. The pyexpat module was written by Paul Prescod after a
461+# prototype by Jack Jansen. Source of Expat 1.95.2 is included in
462+# Modules/expat/. Usage of a system shared libexpat.so/expat.dll is
463+# not advised.
464+#
465+# More information on Expat can be found at www.libexpat.org.
466+#
467+#EXPAT_DIR=/usr/local/src/expat-1.95.2
468+#pyexpat pyexpat.c -DHAVE_EXPAT_H -I$(EXPAT_DIR)/lib -L$(EXPAT_DIR) -lexpat
469+
470+
471+# Hye-Shik Chang's CJKCodecs
472+
473+# multibytecodec is required for all the other CJK codec modules
474+#_multibytecodec cjkcodecs/multibytecodec.c
475+
476+#_codecs_cn cjkcodecs/_codecs_cn.c
477+#_codecs_hk cjkcodecs/_codecs_hk.c
478+#_codecs_iso2022 cjkcodecs/_codecs_iso2022.c
479+#_codecs_jp cjkcodecs/_codecs_jp.c
480+#_codecs_kr cjkcodecs/_codecs_kr.c
481+#_codecs_tw cjkcodecs/_codecs_tw.c
482+
483+# Example -- included for reference only:
484+# xx xxmodule.c
485+
486+# Another example -- the 'xxsubtype' module shows C-level subtyping in action
487+xxsubtype xxsubtype.c
sys/src/cmd/python/Modules/Setup.local+1−0
@@ -0,0 +1 @@
1+# Edit this file for local setup changes
sys/src/cmd/python/Modules/_bisectmodule.c+235−0
@@ -0,0 +1,235 @@
1+/* Bisection algorithms. Drop in replacement for bisect.py
2+
3+Converted to C by Dmitry Vasiliev (dima at hlabs.spb.ru).
4+*/
5+
6+#include "Python.h"
7+
8+static int
9+internal_bisect_right(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t hi)
10+{
11+ PyObject *litem;
12+ Py_ssize_t mid, res;
13+
14+ if (hi == -1) {
15+ hi = PySequence_Size(list);
16+ if (hi < 0)
17+ return -1;
18+ }
19+ while (lo < hi) {
20+ mid = (lo + hi) / 2;
21+ litem = PySequence_GetItem(list, mid);
22+ if (litem == NULL)
23+ return -1;
24+ res = PyObject_RichCompareBool(item, litem, Py_LT);
25+ Py_DECREF(litem);
26+ if (res < 0)
27+ return -1;
28+ if (res)
29+ hi = mid;
30+ else
31+ lo = mid + 1;
32+ }
33+ return lo;
34+}
35+
36+static PyObject *
37+bisect_right(PyObject *self, PyObject *args, PyObject *kw)
38+{
39+ PyObject *list, *item;
40+ int lo = 0;
41+ int hi = -1;
42+ int index;
43+ static char *keywords[] = {"a", "x", "lo", "hi", NULL};
44+
45+ if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|ii:bisect_right",
46+ keywords, &list, &item, &lo, &hi))
47+ return NULL;
48+ index = internal_bisect_right(list, item, lo, hi);
49+ if (index < 0)
50+ return NULL;
51+ return PyInt_FromLong(index);
52+}
53+
54+PyDoc_STRVAR(bisect_right_doc,
55+"bisect_right(a, x[, lo[, hi]]) -> index\n\
56+\n\
57+Return the index where to insert item x in list a, assuming a is sorted.\n\
58+\n\
59+The return value i is such that all e in a[:i] have e <= x, and all e in\n\
60+a[i:] have e > x. So if x already appears in the list, i points just\n\
61+beyond the rightmost x already there\n\
62+\n\
63+Optional args lo (default 0) and hi (default len(a)) bound the\n\
64+slice of a to be searched.\n");
65+
66+static PyObject *
67+insort_right(PyObject *self, PyObject *args, PyObject *kw)
68+{
69+ PyObject *list, *item, *result;
70+ int lo = 0;
71+ int hi = -1;
72+ int index;
73+ static char *keywords[] = {"a", "x", "lo", "hi", NULL};
74+
75+ if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|ii:insort_right",
76+ keywords, &list, &item, &lo, &hi))
77+ return NULL;
78+ index = internal_bisect_right(list, item, lo, hi);
79+ if (index < 0)
80+ return NULL;
81+ if (PyList_Check(list)) {
82+ if (PyList_Insert(list, index, item) < 0)
83+ return NULL;
84+ } else {
85+ result = PyObject_CallMethod(list, "insert", "iO",
86+ index, item);
87+ if (result == NULL)
88+ return NULL;
89+ Py_DECREF(result);
90+ }
91+
92+ Py_RETURN_NONE;
93+}
94+
95+PyDoc_STRVAR(insort_right_doc,
96+"insort_right(a, x[, lo[, hi]])\n\
97+\n\
98+Insert item x in list a, and keep it sorted assuming a is sorted.\n\
99+\n\
100+If x is already in a, insert it to the right of the rightmost x.\n\
101+\n\
102+Optional args lo (default 0) and hi (default len(a)) bound the\n\
103+slice of a to be searched.\n");
104+
105+static int
106+internal_bisect_left(PyObject *list, PyObject *item, int lo, int hi)
107+{
108+ PyObject *litem;
109+ int mid, res;
110+
111+ if (hi == -1) {
112+ hi = PySequence_Size(list);
113+ if (hi < 0)
114+ return -1;
115+ }
116+ while (lo < hi) {
117+ mid = (lo + hi) / 2;
118+ litem = PySequence_GetItem(list, mid);
119+ if (litem == NULL)
120+ return -1;
121+ res = PyObject_RichCompareBool(litem, item, Py_LT);
122+ Py_DECREF(litem);
123+ if (res < 0)
124+ return -1;
125+ if (res)
126+ lo = mid + 1;
127+ else
128+ hi = mid;
129+ }
130+ return lo;
131+}
132+
133+static PyObject *
134+bisect_left(PyObject *self, PyObject *args, PyObject *kw)
135+{
136+ PyObject *list, *item;
137+ int lo = 0;
138+ int hi = -1;
139+ int index;
140+ static char *keywords[] = {"a", "x", "lo", "hi", NULL};
141+
142+ if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|ii:bisect_left",
143+ keywords, &list, &item, &lo, &hi))
144+ return NULL;
145+ index = internal_bisect_left(list, item, lo, hi);
146+ if (index < 0)
147+ return NULL;
148+ return PyInt_FromLong(index);
149+}
150+
151+PyDoc_STRVAR(bisect_left_doc,
152+"bisect_left(a, x[, lo[, hi]]) -> index\n\
153+\n\
154+Return the index where to insert item x in list a, assuming a is sorted.\n\
155+\n\
156+The return value i is such that all e in a[:i] have e < x, and all e in\n\
157+a[i:] have e >= x. So if x already appears in the list, i points just\n\
158+before the leftmost x already there.\n\
159+\n\
160+Optional args lo (default 0) and hi (default len(a)) bound the\n\
161+slice of a to be searched.\n");
162+
163+static PyObject *
164+insort_left(PyObject *self, PyObject *args, PyObject *kw)
165+{
166+ PyObject *list, *item, *result;
167+ int lo = 0;
168+ int hi = -1;
169+ int index;
170+ static char *keywords[] = {"a", "x", "lo", "hi", NULL};
171+
172+ if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|ii:insort_left",
173+ keywords, &list, &item, &lo, &hi))
174+ return NULL;
175+ index = internal_bisect_left(list, item, lo, hi);
176+ if (index < 0)
177+ return NULL;
178+ if (PyList_Check(list)) {
179+ if (PyList_Insert(list, index, item) < 0)
180+ return NULL;
181+ } else {
182+ result = PyObject_CallMethod(list, "insert", "iO",
183+ index, item);
184+ if (result == NULL)
185+ return NULL;
186+ Py_DECREF(result);
187+ }
188+
189+ Py_RETURN_NONE;
190+}
191+
192+PyDoc_STRVAR(insort_left_doc,
193+"insort_left(a, x[, lo[, hi]])\n\
194+\n\
195+Insert item x in list a, and keep it sorted assuming a is sorted.\n\
196+\n\
197+If x is already in a, insert it to the left of the leftmost x.\n\
198+\n\
199+Optional args lo (default 0) and hi (default len(a)) bound the\n\
200+slice of a to be searched.\n");
201+
202+PyDoc_STRVAR(bisect_doc, "Alias for bisect_right().\n");
203+PyDoc_STRVAR(insort_doc, "Alias for insort_right().\n");
204+
205+static PyMethodDef bisect_methods[] = {
206+ {"bisect_right", (PyCFunction)bisect_right,
207+ METH_VARARGS|METH_KEYWORDS, bisect_right_doc},
208+ {"bisect", (PyCFunction)bisect_right,
209+ METH_VARARGS|METH_KEYWORDS, bisect_doc},
210+ {"insort_right", (PyCFunction)insort_right,
211+ METH_VARARGS|METH_KEYWORDS, insort_right_doc},
212+ {"insort", (PyCFunction)insort_right,
213+ METH_VARARGS|METH_KEYWORDS, insort_doc},
214+ {"bisect_left", (PyCFunction)bisect_left,
215+ METH_VARARGS|METH_KEYWORDS, bisect_left_doc},
216+ {"insort_left", (PyCFunction)insort_left,
217+ METH_VARARGS|METH_KEYWORDS, insort_left_doc},
218+ {NULL, NULL} /* sentinel */
219+};
220+
221+PyDoc_STRVAR(module_doc,
222+"Bisection algorithms.\n\
223+\n\
224+This module provides support for maintaining a list in sorted order without\n\
225+having to sort the list after each insertion. For long lists of items with\n\
226+expensive comparison operations, this can be an improvement over the more\n\
227+common approach.\n");
228+
229+PyMODINIT_FUNC
230+init_bisect(void)
231+{
232+ PyObject *m;
233+
234+ m = Py_InitModule3("_bisect", bisect_methods, module_doc);
235+}
sys/src/cmd/python/Modules/_bsddb.c+6047−0
@@ -0,0 +1,6047 @@
1+/*----------------------------------------------------------------------
2+ Copyright (c) 1999-2001, Digital Creations, Fredericksburg, VA, USA
3+ and Andrew Kuchling. All rights reserved.
4+
5+ Redistribution and use in source and binary forms, with or without
6+ modification, are permitted provided that the following conditions are
7+ met:
8+
9+ o Redistributions of source code must retain the above copyright
10+ notice, this list of conditions, and the disclaimer that follows.
11+
12+ o Redistributions in binary form must reproduce the above copyright
13+ notice, this list of conditions, and the following disclaimer in
14+ the documentation and/or other materials provided with the
15+ distribution.
16+
17+ o Neither the name of Digital Creations nor the names of its
18+ contributors may be used to endorse or promote products derived
19+ from this software without specific prior written permission.
20+
21+ THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
22+ IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
25+ CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28+ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
30+ TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
31+ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
32+ DAMAGE.
33+------------------------------------------------------------------------*/
34+
35+
36+/*
37+ * Handwritten code to wrap version 3.x of the Berkeley DB library,
38+ * written to replace a SWIG-generated file. It has since been updated
39+ * to compile with BerkeleyDB versions 3.2 through 4.2.
40+ *
41+ * This module was started by Andrew Kuchling to remove the dependency
42+ * on SWIG in a package by Gregory P. Smith <greg@electricrain.com> who
43+ * based his work on a similar package by Robin Dunn <robin@alldunn.com>
44+ * which wrapped Berkeley DB 2.7.x.
45+ *
46+ * Development of this module then returned full circle back to Robin Dunn
47+ * who worked on behalf of Digital Creations to complete the wrapping of
48+ * the DB 3.x API and to build a solid unit test suite. Robin has
49+ * since gone onto other projects (wxPython).
50+ *
51+ * Gregory P. Smith <greg@electricrain.com> is once again the maintainer.
52+ *
53+ * Use the pybsddb-users@lists.sf.net mailing list for all questions.
54+ * Things can change faster than the header of this file is updated. This
55+ * file is shared with the PyBSDDB project at SourceForge:
56+ *
57+ * http://pybsddb.sf.net
58+ *
59+ * This file should remain backward compatible with Python 2.1, but see PEP
60+ * 291 for the most current backward compatibility requirements:
61+ *
62+ * http://www.python.org/peps/pep-0291.html
63+ *
64+ * This module contains 6 types:
65+ *
66+ * DB (Database)
67+ * DBCursor (Database Cursor)
68+ * DBEnv (database environment)
69+ * DBTxn (An explicit database transaction)
70+ * DBLock (A lock handle)
71+ * DBSequence (Sequence)
72+ *
73+ */
74+
75+/* --------------------------------------------------------------------- */
76+
77+/*
78+ * Portions of this module, associated unit tests and build scripts are the
79+ * result of a contract with The Written Word (http://thewrittenword.com/)
80+ * Many thanks go out to them for causing me to raise the bar on quality and
81+ * functionality, resulting in a better bsddb3 package for all of us to use.
82+ *
83+ * --Robin
84+ */
85+
86+/* --------------------------------------------------------------------- */
87+
88+#include <stddef.h> /* for offsetof() */
89+#include <Python.h>
90+#include <db.h>
91+
92+/* --------------------------------------------------------------------- */
93+/* Various macro definitions */
94+
95+/* 40 = 4.0, 33 = 3.3; this will break if the second number is > 9 */
96+#define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR)
97+#if DB_VERSION_MINOR > 9
98+#error "eek! DBVER can't handle minor versions > 9"
99+#endif
100+
101+#define PY_BSDDB_VERSION "4.4.5.2"
102+static char *rcs_id = "$Id: _bsddb.c 53254 2007-01-05 02:09:06Z gregory.p.smith $";
103+
104+
105+#if (PY_VERSION_HEX < 0x02050000)
106+typedef int Py_ssize_t;
107+#endif
108+
109+#ifdef WITH_THREAD
110+
111+/* These are for when calling Python --> C */
112+#define MYDB_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS;
113+#define MYDB_END_ALLOW_THREADS Py_END_ALLOW_THREADS;
114+
115+/* For 2.3, use the PyGILState_ calls */
116+#if (PY_VERSION_HEX >= 0x02030000)
117+#define MYDB_USE_GILSTATE
118+#endif
119+
120+/* and these are for calling C --> Python */
121+#if defined(MYDB_USE_GILSTATE)
122+#define MYDB_BEGIN_BLOCK_THREADS \
123+ PyGILState_STATE __savestate = PyGILState_Ensure();
124+#define MYDB_END_BLOCK_THREADS \
125+ PyGILState_Release(__savestate);
126+#else /* MYDB_USE_GILSTATE */
127+/* Pre GILState API - do it the long old way */
128+static PyInterpreterState* _db_interpreterState = NULL;
129+#define MYDB_BEGIN_BLOCK_THREADS { \
130+ PyThreadState* prevState; \
131+ PyThreadState* newState; \
132+ PyEval_AcquireLock(); \
133+ newState = PyThreadState_New(_db_interpreterState); \
134+ prevState = PyThreadState_Swap(newState);
135+
136+#define MYDB_END_BLOCK_THREADS \
137+ newState = PyThreadState_Swap(prevState); \
138+ PyThreadState_Clear(newState); \
139+ PyEval_ReleaseLock(); \
140+ PyThreadState_Delete(newState); \
141+ }
142+#endif /* MYDB_USE_GILSTATE */
143+
144+#else
145+/* Compiled without threads - avoid all this cruft */
146+#define MYDB_BEGIN_ALLOW_THREADS
147+#define MYDB_END_ALLOW_THREADS
148+#define MYDB_BEGIN_BLOCK_THREADS
149+#define MYDB_END_BLOCK_THREADS
150+
151+#endif
152+
153+/* Should DB_INCOMPLETE be turned into a warning or an exception? */
154+#define INCOMPLETE_IS_WARNING 1
155+
156+/* --------------------------------------------------------------------- */
157+/* Exceptions */
158+
159+static PyObject* DBError; /* Base class, all others derive from this */
160+static PyObject* DBCursorClosedError; /* raised when trying to use a closed cursor object */
161+static PyObject* DBKeyEmptyError; /* DB_KEYEMPTY: also derives from KeyError */
162+static PyObject* DBKeyExistError; /* DB_KEYEXIST */
163+static PyObject* DBLockDeadlockError; /* DB_LOCK_DEADLOCK */
164+static PyObject* DBLockNotGrantedError; /* DB_LOCK_NOTGRANTED */
165+static PyObject* DBNotFoundError; /* DB_NOTFOUND: also derives from KeyError */
166+static PyObject* DBOldVersionError; /* DB_OLD_VERSION */
167+static PyObject* DBRunRecoveryError; /* DB_RUNRECOVERY */
168+static PyObject* DBVerifyBadError; /* DB_VERIFY_BAD */
169+static PyObject* DBNoServerError; /* DB_NOSERVER */
170+static PyObject* DBNoServerHomeError; /* DB_NOSERVER_HOME */
171+static PyObject* DBNoServerIDError; /* DB_NOSERVER_ID */
172+#if (DBVER >= 33)
173+static PyObject* DBPageNotFoundError; /* DB_PAGE_NOTFOUND */
174+static PyObject* DBSecondaryBadError; /* DB_SECONDARY_BAD */
175+#endif
176+
177+#if !INCOMPLETE_IS_WARNING
178+static PyObject* DBIncompleteError; /* DB_INCOMPLETE */
179+#endif
180+
181+static PyObject* DBInvalidArgError; /* EINVAL */
182+static PyObject* DBAccessError; /* EACCES */
183+static PyObject* DBNoSpaceError; /* ENOSPC */
184+static PyObject* DBNoMemoryError; /* DB_BUFFER_SMALL (ENOMEM when < 4.3) */
185+static PyObject* DBAgainError; /* EAGAIN */
186+static PyObject* DBBusyError; /* EBUSY */
187+static PyObject* DBFileExistsError; /* EEXIST */
188+static PyObject* DBNoSuchFileError; /* ENOENT */
189+static PyObject* DBPermissionsError; /* EPERM */
190+
191+#if (DBVER < 43)
192+#define DB_BUFFER_SMALL ENOMEM
193+#endif
194+
195+
196+/* --------------------------------------------------------------------- */
197+/* Structure definitions */
198+
199+#if PYTHON_API_VERSION >= 1010 /* python >= 2.1 support weak references */
200+#define HAVE_WEAKREF
201+#else
202+#undef HAVE_WEAKREF
203+#endif
204+
205+/* if Python >= 2.1 better support warnings */
206+#if PYTHON_API_VERSION >= 1010
207+#define HAVE_WARNINGS
208+#else
209+#undef HAVE_WARNINGS
210+#endif
211+
212+#if PYTHON_API_VERSION <= 1007
213+ /* 1.5 compatibility */
214+#define PyObject_New PyObject_NEW
215+#define PyObject_Del PyMem_DEL
216+#endif
217+
218+struct behaviourFlags {
219+ /* What is the default behaviour when DB->get or DBCursor->get returns a
220+ DB_NOTFOUND || DB_KEYEMPTY error? Return None or raise an exception? */
221+ unsigned int getReturnsNone : 1;
222+ /* What is the default behaviour for DBCursor.set* methods when DBCursor->get
223+ * returns a DB_NOTFOUND || DB_KEYEMPTY error? Return None or raise? */
224+ unsigned int cursorSetReturnsNone : 1;
225+};
226+
227+#define DEFAULT_GET_RETURNS_NONE 1
228+#define DEFAULT_CURSOR_SET_RETURNS_NONE 1 /* 0 in pybsddb < 4.2, python < 2.4 */
229+
230+typedef struct {
231+ PyObject_HEAD
232+ DB_ENV* db_env;
233+ u_int32_t flags; /* saved flags from open() */
234+ int closed;
235+ struct behaviourFlags moduleFlags;
236+#ifdef HAVE_WEAKREF
237+ PyObject *in_weakreflist; /* List of weak references */
238+#endif
239+} DBEnvObject;
240+
241+
242+typedef struct {
243+ PyObject_HEAD
244+ DB* db;
245+ DBEnvObject* myenvobj; /* PyObject containing the DB_ENV */
246+ u_int32_t flags; /* saved flags from open() */
247+ u_int32_t setflags; /* saved flags from set_flags() */
248+ int haveStat;
249+ struct behaviourFlags moduleFlags;
250+#if (DBVER >= 33)
251+ PyObject* associateCallback;
252+ PyObject* btCompareCallback;
253+ int primaryDBType;
254+#endif
255+#ifdef HAVE_WEAKREF
256+ PyObject *in_weakreflist; /* List of weak references */
257+#endif
258+} DBObject;
259+
260+
261+typedef struct {
262+ PyObject_HEAD
263+ DBC* dbc;
264+ DBObject* mydb;
265+#ifdef HAVE_WEAKREF
266+ PyObject *in_weakreflist; /* List of weak references */
267+#endif
268+} DBCursorObject;
269+
270+
271+typedef struct {
272+ PyObject_HEAD
273+ DB_TXN* txn;
274+ PyObject *env;
275+#ifdef HAVE_WEAKREF
276+ PyObject *in_weakreflist; /* List of weak references */
277+#endif
278+} DBTxnObject;
279+
280+
281+typedef struct {
282+ PyObject_HEAD
283+ DB_LOCK lock;
284+#ifdef HAVE_WEAKREF
285+ PyObject *in_weakreflist; /* List of weak references */
286+#endif
287+} DBLockObject;
288+
289+#if (DBVER >= 43)
290+typedef struct {
291+ PyObject_HEAD
292+ DB_SEQUENCE* sequence;
293+ DBObject* mydb;
294+#ifdef HAVE_WEAKREF
295+ PyObject *in_weakreflist; /* List of weak references */
296+#endif
297+} DBSequenceObject;
298+staticforward PyTypeObject DBSequence_Type;
299+#endif
300+
301+staticforward PyTypeObject DB_Type, DBCursor_Type, DBEnv_Type, DBTxn_Type, DBLock_Type;
302+
303+#define DBObject_Check(v) ((v)->ob_type == &DB_Type)
304+#define DBCursorObject_Check(v) ((v)->ob_type == &DBCursor_Type)
305+#define DBEnvObject_Check(v) ((v)->ob_type == &DBEnv_Type)
306+#define DBTxnObject_Check(v) ((v)->ob_type == &DBTxn_Type)
307+#define DBLockObject_Check(v) ((v)->ob_type == &DBLock_Type)
308+#if (DBVER >= 43)
309+#define DBSequenceObject_Check(v) ((v)->ob_type == &DBSequence_Type)
310+#endif
311+
312+
313+/* --------------------------------------------------------------------- */
314+/* Utility macros and functions */
315+
316+#define RETURN_IF_ERR() \
317+ if (makeDBError(err)) { \
318+ return NULL; \
319+ }
320+
321+#define RETURN_NONE() Py_INCREF(Py_None); return Py_None;
322+
323+#define _CHECK_OBJECT_NOT_CLOSED(nonNull, pyErrObj, name) \
324+ if ((nonNull) == NULL) { \
325+ PyObject *errTuple = NULL; \
326+ errTuple = Py_BuildValue("(is)", 0, #name " object has been closed"); \
327+ PyErr_SetObject((pyErrObj), errTuple); \
328+ Py_DECREF(errTuple); \
329+ return NULL; \
330+ }
331+
332+#define CHECK_DB_NOT_CLOSED(dbobj) \
333+ _CHECK_OBJECT_NOT_CLOSED(dbobj->db, DBError, DB)
334+
335+#define CHECK_ENV_NOT_CLOSED(env) \
336+ _CHECK_OBJECT_NOT_CLOSED(env->db_env, DBError, DBEnv)
337+
338+#define CHECK_CURSOR_NOT_CLOSED(curs) \
339+ _CHECK_OBJECT_NOT_CLOSED(curs->dbc, DBCursorClosedError, DBCursor)
340+
341+#if (DBVER >= 43)
342+#define CHECK_SEQUENCE_NOT_CLOSED(curs) \
343+ _CHECK_OBJECT_NOT_CLOSED(curs->sequence, DBError, DBSequence)
344+#endif
345+
346+#define CHECK_DBFLAG(mydb, flag) (((mydb)->flags & (flag)) || \
347+ (((mydb)->myenvobj != NULL) && ((mydb)->myenvobj->flags & (flag))))
348+
349+#define CLEAR_DBT(dbt) (memset(&(dbt), 0, sizeof(dbt)))
350+
351+#define FREE_DBT(dbt) if ((dbt.flags & (DB_DBT_MALLOC|DB_DBT_REALLOC)) && \
352+ dbt.data != NULL) { free(dbt.data); dbt.data = NULL; }
353+
354+
355+static int makeDBError(int err);
356+
357+
358+/* Return the access method type of the DBObject */
359+static int _DB_get_type(DBObject* self)
360+{
361+#if (DBVER >= 33)
362+ DBTYPE type;
363+ int err;
364+ err = self->db->get_type(self->db, &type);
365+ if (makeDBError(err)) {
366+ return -1;
367+ }
368+ return type;
369+#else
370+ return self->db->get_type(self->db);
371+#endif
372+}
373+
374+
375+/* Create a DBT structure (containing key and data values) from Python
376+ strings. Returns 1 on success, 0 on an error. */
377+static int make_dbt(PyObject* obj, DBT* dbt)
378+{
379+ CLEAR_DBT(*dbt);
380+ if (obj == Py_None) {
381+ /* no need to do anything, the structure has already been zeroed */
382+ }
383+ else if (!PyArg_Parse(obj, "s#", &dbt->data, &dbt->size)) {
384+ PyErr_SetString(PyExc_TypeError,
385+ "Data values must be of type string or None.");
386+ return 0;
387+ }
388+ return 1;
389+}
390+
391+
392+/* Recno and Queue DBs can have integer keys. This function figures out
393+ what's been given, verifies that it's allowed, and then makes the DBT.
394+
395+ Caller MUST call FREE_DBT(key) when done. */
396+static int
397+make_key_dbt(DBObject* self, PyObject* keyobj, DBT* key, int* pflags)
398+{
399+ db_recno_t recno;
400+ int type;
401+
402+ CLEAR_DBT(*key);
403+ if (keyobj == Py_None) {
404+ type = _DB_get_type(self);
405+ if (type == -1)
406+ return 0;
407+ if (type == DB_RECNO || type == DB_QUEUE) {
408+ PyErr_SetString(
409+ PyExc_TypeError,
410+ "None keys not allowed for Recno and Queue DB's");
411+ return 0;
412+ }
413+ /* no need to do anything, the structure has already been zeroed */
414+ }
415+
416+ else if (PyString_Check(keyobj)) {
417+ /* verify access method type */
418+ type = _DB_get_type(self);
419+ if (type == -1)
420+ return 0;
421+ if (type == DB_RECNO || type == DB_QUEUE) {
422+ PyErr_SetString(
423+ PyExc_TypeError,
424+ "String keys not allowed for Recno and Queue DB's");
425+ return 0;
426+ }
427+
428+ key->data = PyString_AS_STRING(keyobj);
429+ key->size = PyString_GET_SIZE(keyobj);
430+ }
431+
432+ else if (PyInt_Check(keyobj)) {
433+ /* verify access method type */
434+ type = _DB_get_type(self);
435+ if (type == -1)
436+ return 0;
437+ if (type == DB_BTREE && pflags != NULL) {
438+ /* if BTREE then an Integer key is allowed with the
439+ * DB_SET_RECNO flag */
440+ *pflags |= DB_SET_RECNO;
441+ }
442+ else if (type != DB_RECNO && type != DB_QUEUE) {
443+ PyErr_SetString(
444+ PyExc_TypeError,
445+ "Integer keys only allowed for Recno and Queue DB's");
446+ return 0;
447+ }
448+
449+ /* Make a key out of the requested recno, use allocated space so DB
450+ * will be able to realloc room for the real key if needed. */
451+ recno = PyInt_AS_LONG(keyobj);
452+ key->data = malloc(sizeof(db_recno_t));
453+ if (key->data == NULL) {
454+ PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
455+ return 0;
456+ }
457+ key->ulen = key->size = sizeof(db_recno_t);
458+ memcpy(key->data, &recno, sizeof(db_recno_t));
459+ key->flags = DB_DBT_REALLOC;
460+ }
461+ else {
462+ PyErr_Format(PyExc_TypeError,
463+ "String or Integer object expected for key, %s found",
464+ keyobj->ob_type->tp_name);
465+ return 0;
466+ }
467+
468+ return 1;
469+}
470+
471+
472+/* Add partial record access to an existing DBT data struct.
473+ If dlen and doff are set, then the DB_DBT_PARTIAL flag will be set
474+ and the data storage/retrieval will be done using dlen and doff. */
475+static int add_partial_dbt(DBT* d, int dlen, int doff) {
476+ /* if neither were set we do nothing (-1 is the default value) */
477+ if ((dlen == -1) && (doff == -1)) {
478+ return 1;
479+ }
480+
481+ if ((dlen < 0) || (doff < 0)) {
482+ PyErr_SetString(PyExc_TypeError, "dlen and doff must both be >= 0");
483+ return 0;
484+ }
485+
486+ d->flags = d->flags | DB_DBT_PARTIAL;
487+ d->dlen = (unsigned int) dlen;
488+ d->doff = (unsigned int) doff;
489+ return 1;
490+}
491+
492+/* a safe strcpy() without the zeroing behaviour and semantics of strncpy. */
493+/* TODO: make this use the native libc strlcpy() when available (BSD) */
494+unsigned int our_strlcpy(char* dest, const char* src, unsigned int n)
495+{
496+ unsigned int srclen, copylen;
497+
498+ srclen = strlen(src);
499+ if (n <= 0)
500+ return srclen;
501+ copylen = (srclen > n-1) ? n-1 : srclen;
502+ /* populate dest[0] thru dest[copylen-1] */
503+ memcpy(dest, src, copylen);
504+ /* guarantee null termination */
505+ dest[copylen] = 0;
506+
507+ return srclen;
508+}
509+
510+/* Callback used to save away more information about errors from the DB
511+ * library. */
512+static char _db_errmsg[1024];
513+#if (DBVER <= 42)
514+static void _db_errorCallback(const char* prefix, char* msg)
515+#else
516+static void _db_errorCallback(const DB_ENV *db_env,
517+ const char* prefix, const char* msg)
518+#endif
519+{
520+ our_strlcpy(_db_errmsg, msg, sizeof(_db_errmsg));
521+}
522+
523+
524+/* make a nice exception object to raise for errors. */
525+static int makeDBError(int err)
526+{
527+ char errTxt[2048]; /* really big, just in case... */
528+ PyObject *errObj = NULL;
529+ PyObject *errTuple = NULL;
530+ int exceptionRaised = 0;
531+ unsigned int bytes_left;
532+
533+ switch (err) {
534+ case 0: /* successful, no error */ break;
535+
536+#if (DBVER < 41)
537+ case DB_INCOMPLETE:
538+#if INCOMPLETE_IS_WARNING
539+ bytes_left = our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt));
540+ /* Ensure that bytes_left never goes negative */
541+ if (_db_errmsg[0] && bytes_left < (sizeof(errTxt) - 4)) {
542+ bytes_left = sizeof(errTxt) - bytes_left - 4 - 1;
543+ assert(bytes_left >= 0);
544+ strcat(errTxt, " -- ");
545+ strncat(errTxt, _db_errmsg, bytes_left);
546+ }
547+ _db_errmsg[0] = 0;
548+#ifdef HAVE_WARNINGS
549+ exceptionRaised = PyErr_Warn(PyExc_RuntimeWarning, errTxt);
550+#else
551+ fprintf(stderr, errTxt);
552+ fprintf(stderr, "\n");
553+#endif
554+
555+#else /* do an exception instead */
556+ errObj = DBIncompleteError;
557+#endif
558+ break;
559+#endif /* DBVER < 41 */
560+
561+ case DB_KEYEMPTY: errObj = DBKeyEmptyError; break;
562+ case DB_KEYEXIST: errObj = DBKeyExistError; break;
563+ case DB_LOCK_DEADLOCK: errObj = DBLockDeadlockError; break;
564+ case DB_LOCK_NOTGRANTED: errObj = DBLockNotGrantedError; break;
565+ case DB_NOTFOUND: errObj = DBNotFoundError; break;
566+ case DB_OLD_VERSION: errObj = DBOldVersionError; break;
567+ case DB_RUNRECOVERY: errObj = DBRunRecoveryError; break;
568+ case DB_VERIFY_BAD: errObj = DBVerifyBadError; break;
569+ case DB_NOSERVER: errObj = DBNoServerError; break;
570+ case DB_NOSERVER_HOME: errObj = DBNoServerHomeError; break;
571+ case DB_NOSERVER_ID: errObj = DBNoServerIDError; break;
572+#if (DBVER >= 33)
573+ case DB_PAGE_NOTFOUND: errObj = DBPageNotFoundError; break;
574+ case DB_SECONDARY_BAD: errObj = DBSecondaryBadError; break;
575+#endif
576+ case DB_BUFFER_SMALL: errObj = DBNoMemoryError; break;
577+
578+#if (DBVER >= 43)
579+ /* ENOMEM and DB_BUFFER_SMALL were one and the same until 4.3 */
580+ case ENOMEM: errObj = PyExc_MemoryError; break;
581+#endif
582+ case EINVAL: errObj = DBInvalidArgError; break;
583+ case EACCES: errObj = DBAccessError; break;
584+ case ENOSPC: errObj = DBNoSpaceError; break;
585+ case EAGAIN: errObj = DBAgainError; break;
586+ case EBUSY : errObj = DBBusyError; break;
587+ case EEXIST: errObj = DBFileExistsError; break;
588+ case ENOENT: errObj = DBNoSuchFileError; break;
589+ case EPERM : errObj = DBPermissionsError; break;
590+
591+ default: errObj = DBError; break;
592+ }
593+
594+ if (errObj != NULL) {
595+ bytes_left = our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt));
596+ /* Ensure that bytes_left never goes negative */
597+ if (_db_errmsg[0] && bytes_left < (sizeof(errTxt) - 4)) {
598+ bytes_left = sizeof(errTxt) - bytes_left - 4 - 1;
599+ assert(bytes_left >= 0);
600+ strcat(errTxt, " -- ");
601+ strncat(errTxt, _db_errmsg, bytes_left);
602+ }
603+ _db_errmsg[0] = 0;
604+
605+ errTuple = Py_BuildValue("(is)", err, errTxt);
606+ PyErr_SetObject(errObj, errTuple);
607+ Py_DECREF(errTuple);
608+ }
609+
610+ return ((errObj != NULL) || exceptionRaised);
611+}
612+
613+
614+
615+/* set a type exception */
616+static void makeTypeError(char* expected, PyObject* found)
617+{
618+ PyErr_Format(PyExc_TypeError, "Expected %s argument, %s found.",
619+ expected, found->ob_type->tp_name);
620+}
621+
622+
623+/* verify that an obj is either None or a DBTxn, and set the txn pointer */
624+static int checkTxnObj(PyObject* txnobj, DB_TXN** txn)
625+{
626+ if (txnobj == Py_None || txnobj == NULL) {
627+ *txn = NULL;
628+ return 1;
629+ }
630+ if (DBTxnObject_Check(txnobj)) {
631+ *txn = ((DBTxnObject*)txnobj)->txn;
632+ return 1;
633+ }
634+ else
635+ makeTypeError("DBTxn", txnobj);
636+ return 0;
637+}
638+
639+
640+/* Delete a key from a database
641+ Returns 0 on success, -1 on an error. */
642+static int _DB_delete(DBObject* self, DB_TXN *txn, DBT *key, int flags)
643+{
644+ int err;
645+
646+ MYDB_BEGIN_ALLOW_THREADS;
647+ err = self->db->del(self->db, txn, key, 0);
648+ MYDB_END_ALLOW_THREADS;
649+ if (makeDBError(err)) {
650+ return -1;
651+ }
652+ self->haveStat = 0;
653+ return 0;
654+}
655+
656+
657+/* Store a key into a database
658+ Returns 0 on success, -1 on an error. */
659+static int _DB_put(DBObject* self, DB_TXN *txn, DBT *key, DBT *data, int flags)
660+{
661+ int err;
662+
663+ MYDB_BEGIN_ALLOW_THREADS;
664+ err = self->db->put(self->db, txn, key, data, flags);
665+ MYDB_END_ALLOW_THREADS;
666+ if (makeDBError(err)) {
667+ return -1;
668+ }
669+ self->haveStat = 0;
670+ return 0;
671+}
672+
673+/* Get a key/data pair from a cursor */
674+static PyObject* _DBCursor_get(DBCursorObject* self, int extra_flags,
675+ PyObject *args, PyObject *kwargs, char *format)
676+{
677+ int err;
678+ PyObject* retval = NULL;
679+ DBT key, data;
680+ int dlen = -1;
681+ int doff = -1;
682+ int flags = 0;
683+ static char* kwnames[] = { "flags", "dlen", "doff", NULL };
684+
685+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, kwnames,
686+ &flags, &dlen, &doff))
687+ return NULL;
688+
689+ CHECK_CURSOR_NOT_CLOSED(self);
690+
691+ flags |= extra_flags;
692+ CLEAR_DBT(key);
693+ CLEAR_DBT(data);
694+ if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
695+ /* Tell BerkeleyDB to malloc the return value (thread safe) */
696+ data.flags = DB_DBT_MALLOC;
697+ key.flags = DB_DBT_MALLOC;
698+ }
699+ if (!add_partial_dbt(&data, dlen, doff))
700+ return NULL;
701+
702+ MYDB_BEGIN_ALLOW_THREADS;
703+ err = self->dbc->c_get(self->dbc, &key, &data, flags);
704+ MYDB_END_ALLOW_THREADS;
705+
706+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
707+ && self->mydb->moduleFlags.getReturnsNone) {
708+ Py_INCREF(Py_None);
709+ retval = Py_None;
710+ }
711+ else if (makeDBError(err)) {
712+ retval = NULL;
713+ }
714+ else { /* otherwise, success! */
715+
716+ /* if Recno or Queue, return the key as an Int */
717+ switch (_DB_get_type(self->mydb)) {
718+ case -1:
719+ retval = NULL;
720+ break;
721+
722+ case DB_RECNO:
723+ case DB_QUEUE:
724+ retval = Py_BuildValue("is#", *((db_recno_t*)key.data),
725+ data.data, data.size);
726+ break;
727+ case DB_HASH:
728+ case DB_BTREE:
729+ default:
730+ retval = Py_BuildValue("s#s#", key.data, key.size,
731+ data.data, data.size);
732+ break;
733+ }
734+ }
735+ if (!err) {
736+ FREE_DBT(key);
737+ FREE_DBT(data);
738+ }
739+ return retval;
740+}
741+
742+
743+/* add an integer to a dictionary using the given name as a key */
744+static void _addIntToDict(PyObject* dict, char *name, int value)
745+{
746+ PyObject* v = PyInt_FromLong((long) value);
747+ if (!v || PyDict_SetItemString(dict, name, v))
748+ PyErr_Clear();
749+
750+ Py_XDECREF(v);
751+}
752+#if (DBVER >= 43)
753+/* add an db_seq_t to a dictionary using the given name as a key */
754+static void _addDb_seq_tToDict(PyObject* dict, char *name, db_seq_t value)
755+{
756+ PyObject* v = PyLong_FromLongLong(value);
757+ if (!v || PyDict_SetItemString(dict, name, v))
758+ PyErr_Clear();
759+
760+ Py_XDECREF(v);
761+}
762+#endif
763+
764+
765+
766+/* --------------------------------------------------------------------- */
767+/* Allocators and deallocators */
768+
769+static DBObject*
770+newDBObject(DBEnvObject* arg, int flags)
771+{
772+ DBObject* self;
773+ DB_ENV* db_env = NULL;
774+ int err;
775+
776+ self = PyObject_New(DBObject, &DB_Type);
777+ if (self == NULL)
778+ return NULL;
779+
780+ self->haveStat = 0;
781+ self->flags = 0;
782+ self->setflags = 0;
783+ self->myenvobj = NULL;
784+#if (DBVER >= 33)
785+ self->associateCallback = NULL;
786+ self->btCompareCallback = NULL;
787+ self->primaryDBType = 0;
788+#endif
789+#ifdef HAVE_WEAKREF
790+ self->in_weakreflist = NULL;
791+#endif
792+
793+ /* keep a reference to our python DBEnv object */
794+ if (arg) {
795+ Py_INCREF(arg);
796+ self->myenvobj = arg;
797+ db_env = arg->db_env;
798+ }
799+
800+ if (self->myenvobj)
801+ self->moduleFlags = self->myenvobj->moduleFlags;
802+ else
803+ self->moduleFlags.getReturnsNone = DEFAULT_GET_RETURNS_NONE;
804+ self->moduleFlags.cursorSetReturnsNone = DEFAULT_CURSOR_SET_RETURNS_NONE;
805+
806+ MYDB_BEGIN_ALLOW_THREADS;
807+ err = db_create(&self->db, db_env, flags);
808+ if (self->db != NULL) {
809+ self->db->set_errcall(self->db, _db_errorCallback);
810+#if (DBVER >= 33)
811+ self->db->app_private = (void*)self;
812+#endif
813+ }
814+ MYDB_END_ALLOW_THREADS;
815+ /* TODO add a weakref(self) to the self->myenvobj->open_child_weakrefs
816+ * list so that a DBEnv can refuse to close without aborting any open
817+ * DBTxns and closing any open DBs first. */
818+ if (makeDBError(err)) {
819+ if (self->myenvobj) {
820+ Py_DECREF(self->myenvobj);
821+ self->myenvobj = NULL;
822+ }
823+ PyObject_Del(self);
824+ self = NULL;
825+ }
826+ return self;
827+}
828+
829+
830+static void
831+DB_dealloc(DBObject* self)
832+{
833+ if (self->db != NULL) {
834+ /* avoid closing a DB when its DBEnv has been closed out from under
835+ * it */
836+ if (!self->myenvobj ||
837+ (self->myenvobj && self->myenvobj->db_env))
838+ {
839+ MYDB_BEGIN_ALLOW_THREADS;
840+ self->db->close(self->db, 0);
841+ MYDB_END_ALLOW_THREADS;
842+#ifdef HAVE_WARNINGS
843+ } else {
844+ PyErr_Warn(PyExc_RuntimeWarning,
845+ "DB could not be closed in destructor: DBEnv already closed");
846+#endif
847+ }
848+ self->db = NULL;
849+ }
850+#ifdef HAVE_WEAKREF
851+ if (self->in_weakreflist != NULL) {
852+ PyObject_ClearWeakRefs((PyObject *) self);
853+ }
854+#endif
855+ if (self->myenvobj) {
856+ Py_DECREF(self->myenvobj);
857+ self->myenvobj = NULL;
858+ }
859+#if (DBVER >= 33)
860+ if (self->associateCallback != NULL) {
861+ Py_DECREF(self->associateCallback);
862+ self->associateCallback = NULL;
863+ }
864+ if (self->btCompareCallback != NULL) {
865+ Py_DECREF(self->btCompareCallback);
866+ self->btCompareCallback = NULL;
867+ }
868+#endif
869+ PyObject_Del(self);
870+}
871+
872+
873+static DBCursorObject*
874+newDBCursorObject(DBC* dbc, DBObject* db)
875+{
876+ DBCursorObject* self = PyObject_New(DBCursorObject, &DBCursor_Type);
877+ if (self == NULL)
878+ return NULL;
879+
880+ self->dbc = dbc;
881+ self->mydb = db;
882+#ifdef HAVE_WEAKREF
883+ self->in_weakreflist = NULL;
884+#endif
885+ Py_INCREF(self->mydb);
886+ return self;
887+}
888+
889+
890+static void
891+DBCursor_dealloc(DBCursorObject* self)
892+{
893+ int err;
894+
895+#ifdef HAVE_WEAKREF
896+ if (self->in_weakreflist != NULL) {
897+ PyObject_ClearWeakRefs((PyObject *) self);
898+ }
899+#endif
900+
901+ if (self->dbc != NULL) {
902+ MYDB_BEGIN_ALLOW_THREADS;
903+ /* If the underlying database has been closed, we don't
904+ need to do anything. If the environment has been closed
905+ we need to leak, as BerkeleyDB will crash trying to access
906+ the environment. There was an exception when the
907+ user closed the environment even though there still was
908+ a database open. */
909+ if (self->mydb->db && self->mydb->myenvobj &&
910+ !self->mydb->myenvobj->closed)
911+ err = self->dbc->c_close(self->dbc);
912+ self->dbc = NULL;
913+ MYDB_END_ALLOW_THREADS;
914+ }
915+ Py_XDECREF( self->mydb );
916+ PyObject_Del(self);
917+}
918+
919+
920+static DBEnvObject*
921+newDBEnvObject(int flags)
922+{
923+ int err;
924+ DBEnvObject* self = PyObject_New(DBEnvObject, &DBEnv_Type);
925+ if (self == NULL)
926+ return NULL;
927+
928+ self->closed = 1;
929+ self->flags = flags;
930+ self->moduleFlags.getReturnsNone = DEFAULT_GET_RETURNS_NONE;
931+ self->moduleFlags.cursorSetReturnsNone = DEFAULT_CURSOR_SET_RETURNS_NONE;
932+#ifdef HAVE_WEAKREF
933+ self->in_weakreflist = NULL;
934+#endif
935+
936+ MYDB_BEGIN_ALLOW_THREADS;
937+ err = db_env_create(&self->db_env, flags);
938+ MYDB_END_ALLOW_THREADS;
939+ if (makeDBError(err)) {
940+ PyObject_Del(self);
941+ self = NULL;
942+ }
943+ else {
944+ self->db_env->set_errcall(self->db_env, _db_errorCallback);
945+ }
946+ return self;
947+}
948+
949+
950+static void
951+DBEnv_dealloc(DBEnvObject* self)
952+{
953+#ifdef HAVE_WEAKREF
954+ if (self->in_weakreflist != NULL) {
955+ PyObject_ClearWeakRefs((PyObject *) self);
956+ }
957+#endif
958+
959+ if (self->db_env && !self->closed) {
960+ MYDB_BEGIN_ALLOW_THREADS;
961+ self->db_env->close(self->db_env, 0);
962+ MYDB_END_ALLOW_THREADS;
963+ }
964+ PyObject_Del(self);
965+}
966+
967+
968+static DBTxnObject*
969+newDBTxnObject(DBEnvObject* myenv, DB_TXN *parent, int flags)
970+{
971+ int err;
972+ DBTxnObject* self = PyObject_New(DBTxnObject, &DBTxn_Type);
973+ if (self == NULL)
974+ return NULL;
975+ Py_INCREF(myenv);
976+ self->env = (PyObject*)myenv;
977+#ifdef HAVE_WEAKREF
978+ self->in_weakreflist = NULL;
979+#endif
980+
981+ MYDB_BEGIN_ALLOW_THREADS;
982+#if (DBVER >= 40)
983+ err = myenv->db_env->txn_begin(myenv->db_env, parent, &(self->txn), flags);
984+#else
985+ err = txn_begin(myenv->db_env, parent, &(self->txn), flags);
986+#endif
987+ MYDB_END_ALLOW_THREADS;
988+ if (makeDBError(err)) {
989+ Py_DECREF(self->env);
990+ PyObject_Del(self);
991+ self = NULL;
992+ }
993+ return self;
994+}
995+
996+
997+static void
998+DBTxn_dealloc(DBTxnObject* self)
999+{
1000+#ifdef HAVE_WEAKREF
1001+ if (self->in_weakreflist != NULL) {
1002+ PyObject_ClearWeakRefs((PyObject *) self);
1003+ }
1004+#endif
1005+
1006+#ifdef HAVE_WARNINGS
1007+ if (self->txn) {
1008+ /* it hasn't been finalized, abort it! */
1009+ MYDB_BEGIN_ALLOW_THREADS;
1010+#if (DBVER >= 40)
1011+ self->txn->abort(self->txn);
1012+#else
1013+ txn_abort(self->txn);
1014+#endif
1015+ MYDB_END_ALLOW_THREADS;
1016+ PyErr_Warn(PyExc_RuntimeWarning,
1017+ "DBTxn aborted in destructor. No prior commit() or abort().");
1018+ }
1019+#endif
1020+
1021+ Py_DECREF(self->env);
1022+ PyObject_Del(self);
1023+}
1024+
1025+
1026+static DBLockObject*
1027+newDBLockObject(DBEnvObject* myenv, u_int32_t locker, DBT* obj,
1028+ db_lockmode_t lock_mode, int flags)
1029+{
1030+ int err;
1031+ DBLockObject* self = PyObject_New(DBLockObject, &DBLock_Type);
1032+ if (self == NULL)
1033+ return NULL;
1034+#ifdef HAVE_WEAKREF
1035+ self->in_weakreflist = NULL;
1036+#endif
1037+
1038+ MYDB_BEGIN_ALLOW_THREADS;
1039+#if (DBVER >= 40)
1040+ err = myenv->db_env->lock_get(myenv->db_env, locker, flags, obj, lock_mode,
1041+ &self->lock);
1042+#else
1043+ err = lock_get(myenv->db_env, locker, flags, obj, lock_mode, &self->lock);
1044+#endif
1045+ MYDB_END_ALLOW_THREADS;
1046+ if (makeDBError(err)) {
1047+ PyObject_Del(self);
1048+ self = NULL;
1049+ }
1050+
1051+ return self;
1052+}
1053+
1054+
1055+static void
1056+DBLock_dealloc(DBLockObject* self)
1057+{
1058+#ifdef HAVE_WEAKREF
1059+ if (self->in_weakreflist != NULL) {
1060+ PyObject_ClearWeakRefs((PyObject *) self);
1061+ }
1062+#endif
1063+ /* TODO: is this lock held? should we release it? */
1064+
1065+ PyObject_Del(self);
1066+}
1067+
1068+
1069+#if (DBVER >= 43)
1070+static DBSequenceObject*
1071+newDBSequenceObject(DBObject* mydb, int flags)
1072+{
1073+ int err;
1074+ DBSequenceObject* self = PyObject_New(DBSequenceObject, &DBSequence_Type);
1075+ if (self == NULL)
1076+ return NULL;
1077+ Py_INCREF(mydb);
1078+ self->mydb = mydb;
1079+#ifdef HAVE_WEAKREF
1080+ self->in_weakreflist = NULL;
1081+#endif
1082+
1083+
1084+ MYDB_BEGIN_ALLOW_THREADS;
1085+ err = db_sequence_create(&self->sequence, self->mydb->db, flags);
1086+ MYDB_END_ALLOW_THREADS;
1087+ if (makeDBError(err)) {
1088+ Py_DECREF(self->mydb);
1089+ PyObject_Del(self);
1090+ self = NULL;
1091+ }
1092+
1093+ return self;
1094+}
1095+
1096+
1097+static void
1098+DBSequence_dealloc(DBSequenceObject* self)
1099+{
1100+#ifdef HAVE_WEAKREF
1101+ if (self->in_weakreflist != NULL) {
1102+ PyObject_ClearWeakRefs((PyObject *) self);
1103+ }
1104+#endif
1105+
1106+ Py_DECREF(self->mydb);
1107+ PyObject_Del(self);
1108+}
1109+#endif
1110+
1111+/* --------------------------------------------------------------------- */
1112+/* DB methods */
1113+
1114+static PyObject*
1115+DB_append(DBObject* self, PyObject* args)
1116+{
1117+ PyObject* txnobj = NULL;
1118+ PyObject* dataobj;
1119+ db_recno_t recno;
1120+ DBT key, data;
1121+ DB_TXN *txn = NULL;
1122+
1123+ if (!PyArg_UnpackTuple(args, "append", 1, 2, &dataobj, &txnobj))
1124+ return NULL;
1125+
1126+ CHECK_DB_NOT_CLOSED(self);
1127+
1128+ /* make a dummy key out of a recno */
1129+ recno = 0;
1130+ CLEAR_DBT(key);
1131+ key.data = &recno;
1132+ key.size = sizeof(recno);
1133+ key.ulen = key.size;
1134+ key.flags = DB_DBT_USERMEM;
1135+
1136+ if (!make_dbt(dataobj, &data)) return NULL;
1137+ if (!checkTxnObj(txnobj, &txn)) return NULL;
1138+
1139+ if (-1 == _DB_put(self, txn, &key, &data, DB_APPEND))
1140+ return NULL;
1141+
1142+ return PyInt_FromLong(recno);
1143+}
1144+
1145+
1146+#if (DBVER >= 33)
1147+
1148+static int
1149+_db_associateCallback(DB* db, const DBT* priKey, const DBT* priData,
1150+ DBT* secKey)
1151+{
1152+ int retval = DB_DONOTINDEX;
1153+ DBObject* secondaryDB = (DBObject*)db->app_private;
1154+ PyObject* callback = secondaryDB->associateCallback;
1155+ int type = secondaryDB->primaryDBType;
1156+ PyObject* args;
1157+ PyObject* result = NULL;
1158+
1159+
1160+ if (callback != NULL) {
1161+ MYDB_BEGIN_BLOCK_THREADS;
1162+
1163+ if (type == DB_RECNO || type == DB_QUEUE)
1164+ args = Py_BuildValue("(ls#)", *((db_recno_t*)priKey->data),
1165+ priData->data, priData->size);
1166+ else
1167+ args = Py_BuildValue("(s#s#)", priKey->data, priKey->size,
1168+ priData->data, priData->size);
1169+ if (args != NULL) {
1170+ result = PyEval_CallObject(callback, args);
1171+ }
1172+ if (args == NULL || result == NULL) {
1173+ PyErr_Print();
1174+ }
1175+ else if (result == Py_None) {
1176+ retval = DB_DONOTINDEX;
1177+ }
1178+ else if (PyInt_Check(result)) {
1179+ retval = PyInt_AsLong(result);
1180+ }
1181+ else if (PyString_Check(result)) {
1182+ char* data;
1183+ Py_ssize_t size;
1184+
1185+ CLEAR_DBT(*secKey);
1186+#if PYTHON_API_VERSION <= 1007
1187+ /* 1.5 compatibility */
1188+ size = PyString_Size(result);
1189+ data = PyString_AsString(result);
1190+#else
1191+ PyString_AsStringAndSize(result, &data, &size);
1192+#endif
1193+ secKey->flags = DB_DBT_APPMALLOC; /* DB will free */
1194+ secKey->data = malloc(size); /* TODO, check this */
1195+ if (secKey->data) {
1196+ memcpy(secKey->data, data, size);
1197+ secKey->size = size;
1198+ retval = 0;
1199+ }
1200+ else {
1201+ PyErr_SetString(PyExc_MemoryError,
1202+ "malloc failed in _db_associateCallback");
1203+ PyErr_Print();
1204+ }
1205+ }
1206+ else {
1207+ PyErr_SetString(
1208+ PyExc_TypeError,
1209+ "DB associate callback should return DB_DONOTINDEX or string.");
1210+ PyErr_Print();
1211+ }
1212+
1213+ Py_XDECREF(args);
1214+ Py_XDECREF(result);
1215+
1216+ MYDB_END_BLOCK_THREADS;
1217+ }
1218+ return retval;
1219+}
1220+
1221+
1222+static PyObject*
1223+DB_associate(DBObject* self, PyObject* args, PyObject* kwargs)
1224+{
1225+ int err, flags=0;
1226+ DBObject* secondaryDB;
1227+ PyObject* callback;
1228+#if (DBVER >= 41)
1229+ PyObject *txnobj = NULL;
1230+ DB_TXN *txn = NULL;
1231+ static char* kwnames[] = {"secondaryDB", "callback", "flags", "txn",
1232+ NULL};
1233+#else
1234+ static char* kwnames[] = {"secondaryDB", "callback", "flags", NULL};
1235+#endif
1236+
1237+#if (DBVER >= 41)
1238+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iO:associate", kwnames,
1239+ &secondaryDB, &callback, &flags,
1240+ &txnobj)) {
1241+#else
1242+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i:associate", kwnames,
1243+ &secondaryDB, &callback, &flags)) {
1244+#endif
1245+ return NULL;
1246+ }
1247+
1248+#if (DBVER >= 41)
1249+ if (!checkTxnObj(txnobj, &txn)) return NULL;
1250+#endif
1251+
1252+ CHECK_DB_NOT_CLOSED(self);
1253+ if (!DBObject_Check(secondaryDB)) {
1254+ makeTypeError("DB", (PyObject*)secondaryDB);
1255+ return NULL;
1256+ }
1257+ CHECK_DB_NOT_CLOSED(secondaryDB);
1258+ if (callback == Py_None) {
1259+ callback = NULL;
1260+ }
1261+ else if (!PyCallable_Check(callback)) {
1262+ makeTypeError("Callable", callback);
1263+ return NULL;
1264+ }
1265+
1266+ /* Save a reference to the callback in the secondary DB. */
1267+ Py_XDECREF(secondaryDB->associateCallback);
1268+ Py_XINCREF(callback);
1269+ secondaryDB->associateCallback = callback;
1270+ secondaryDB->primaryDBType = _DB_get_type(self);
1271+
1272+ /* PyEval_InitThreads is called here due to a quirk in python 1.5
1273+ * - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>:
1274+ * The global interepreter lock is not initialized until the first
1275+ * thread is created using thread.start_new_thread() or fork() is
1276+ * called. that would cause the ALLOW_THREADS here to segfault due
1277+ * to a null pointer reference if no threads or child processes
1278+ * have been created. This works around that and is a no-op if
1279+ * threads have already been initialized.
1280+ * (see pybsddb-users mailing list post on 2002-08-07)
1281+ */
1282+#ifdef WITH_THREAD
1283+ PyEval_InitThreads();
1284+#endif
1285+ MYDB_BEGIN_ALLOW_THREADS;
1286+#if (DBVER >= 41)
1287+ err = self->db->associate(self->db,
1288+ txn,
1289+ secondaryDB->db,
1290+ _db_associateCallback,
1291+ flags);
1292+#else
1293+ err = self->db->associate(self->db,
1294+ secondaryDB->db,
1295+ _db_associateCallback,
1296+ flags);
1297+#endif
1298+ MYDB_END_ALLOW_THREADS;
1299+
1300+ if (err) {
1301+ Py_XDECREF(secondaryDB->associateCallback);
1302+ secondaryDB->associateCallback = NULL;
1303+ secondaryDB->primaryDBType = 0;
1304+ }
1305+
1306+ RETURN_IF_ERR();
1307+ RETURN_NONE();
1308+}
1309+
1310+
1311+#endif
1312+
1313+
1314+static PyObject*
1315+DB_close(DBObject* self, PyObject* args)
1316+{
1317+ int err, flags=0;
1318+ if (!PyArg_ParseTuple(args,"|i:close", &flags))
1319+ return NULL;
1320+ if (self->db != NULL) {
1321+ if (self->myenvobj)
1322+ CHECK_ENV_NOT_CLOSED(self->myenvobj);
1323+ err = self->db->close(self->db, flags);
1324+ self->db = NULL;
1325+ RETURN_IF_ERR();
1326+ }
1327+ RETURN_NONE();
1328+}
1329+
1330+
1331+#if (DBVER >= 32)
1332+static PyObject*
1333+_DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
1334+{
1335+ int err, flags=0, type;
1336+ PyObject* txnobj = NULL;
1337+ PyObject* retval = NULL;
1338+ DBT key, data;
1339+ DB_TXN *txn = NULL;
1340+ static char* kwnames[] = { "txn", "flags", NULL };
1341+
1342+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:consume", kwnames,
1343+ &txnobj, &flags))
1344+ return NULL;
1345+
1346+ CHECK_DB_NOT_CLOSED(self);
1347+ type = _DB_get_type(self);
1348+ if (type == -1)
1349+ return NULL;
1350+ if (type != DB_QUEUE) {
1351+ PyErr_SetString(PyExc_TypeError,
1352+ "Consume methods only allowed for Queue DB's");
1353+ return NULL;
1354+ }
1355+ if (!checkTxnObj(txnobj, &txn))
1356+ return NULL;
1357+
1358+ CLEAR_DBT(key);
1359+ CLEAR_DBT(data);
1360+ if (CHECK_DBFLAG(self, DB_THREAD)) {
1361+ /* Tell BerkeleyDB to malloc the return value (thread safe) */
1362+ data.flags = DB_DBT_MALLOC;
1363+ key.flags = DB_DBT_MALLOC;
1364+ }
1365+
1366+ MYDB_BEGIN_ALLOW_THREADS;
1367+ err = self->db->get(self->db, txn, &key, &data, flags|consume_flag);
1368+ MYDB_END_ALLOW_THREADS;
1369+
1370+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
1371+ && self->moduleFlags.getReturnsNone) {
1372+ err = 0;
1373+ Py_INCREF(Py_None);
1374+ retval = Py_None;
1375+ }
1376+ else if (!err) {
1377+ retval = Py_BuildValue("s#s#", key.data, key.size, data.data,
1378+ data.size);
1379+ FREE_DBT(key);
1380+ FREE_DBT(data);
1381+ }
1382+
1383+ RETURN_IF_ERR();
1384+ return retval;
1385+}
1386+
1387+static PyObject*
1388+DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
1389+{
1390+ return _DB_consume(self, args, kwargs, DB_CONSUME);
1391+}
1392+
1393+static PyObject*
1394+DB_consume_wait(DBObject* self, PyObject* args, PyObject* kwargs,
1395+ int consume_flag)
1396+{
1397+ return _DB_consume(self, args, kwargs, DB_CONSUME_WAIT);
1398+}
1399+#endif
1400+
1401+
1402+
1403+static PyObject*
1404+DB_cursor(DBObject* self, PyObject* args, PyObject* kwargs)
1405+{
1406+ int err, flags=0;
1407+ DBC* dbc;
1408+ PyObject* txnobj = NULL;
1409+ DB_TXN *txn = NULL;
1410+ static char* kwnames[] = { "txn", "flags", NULL };
1411+
1412+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
1413+ &txnobj, &flags))
1414+ return NULL;
1415+ CHECK_DB_NOT_CLOSED(self);
1416+ if (!checkTxnObj(txnobj, &txn))
1417+ return NULL;
1418+
1419+ MYDB_BEGIN_ALLOW_THREADS;
1420+ err = self->db->cursor(self->db, txn, &dbc, flags);
1421+ MYDB_END_ALLOW_THREADS;
1422+ RETURN_IF_ERR();
1423+ return (PyObject*) newDBCursorObject(dbc, self);
1424+}
1425+
1426+
1427+static PyObject*
1428+DB_delete(DBObject* self, PyObject* args, PyObject* kwargs)
1429+{
1430+ PyObject* txnobj = NULL;
1431+ int flags = 0;
1432+ PyObject* keyobj;
1433+ DBT key;
1434+ DB_TXN *txn = NULL;
1435+ static char* kwnames[] = { "key", "txn", "flags", NULL };
1436+
1437+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:delete", kwnames,
1438+ &keyobj, &txnobj, &flags))
1439+ return NULL;
1440+ CHECK_DB_NOT_CLOSED(self);
1441+ if (!make_key_dbt(self, keyobj, &key, NULL))
1442+ return NULL;
1443+ if (!checkTxnObj(txnobj, &txn)) {
1444+ FREE_DBT(key);
1445+ return NULL;
1446+ }
1447+
1448+ if (-1 == _DB_delete(self, txn, &key, 0)) {
1449+ FREE_DBT(key);
1450+ return NULL;
1451+ }
1452+
1453+ FREE_DBT(key);
1454+ RETURN_NONE();
1455+}
1456+
1457+
1458+static PyObject*
1459+DB_fd(DBObject* self, PyObject* args)
1460+{
1461+ int err, the_fd;
1462+
1463+ if (!PyArg_ParseTuple(args,":fd"))
1464+ return NULL;
1465+ CHECK_DB_NOT_CLOSED(self);
1466+
1467+ MYDB_BEGIN_ALLOW_THREADS;
1468+ err = self->db->fd(self->db, &the_fd);
1469+ MYDB_END_ALLOW_THREADS;
1470+ RETURN_IF_ERR();
1471+ return PyInt_FromLong(the_fd);
1472+}
1473+
1474+
1475+static PyObject*
1476+DB_get(DBObject* self, PyObject* args, PyObject* kwargs)
1477+{
1478+ int err, flags=0;
1479+ PyObject* txnobj = NULL;
1480+ PyObject* keyobj;
1481+ PyObject* dfltobj = NULL;
1482+ PyObject* retval = NULL;
1483+ int dlen = -1;
1484+ int doff = -1;
1485+ DBT key, data;
1486+ DB_TXN *txn = NULL;
1487+ static char* kwnames[] = {"key", "default", "txn", "flags", "dlen",
1488+ "doff", NULL};
1489+
1490+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:get", kwnames,
1491+ &keyobj, &dfltobj, &txnobj, &flags, &dlen,
1492+ &doff))
1493+ return NULL;
1494+
1495+ CHECK_DB_NOT_CLOSED(self);
1496+ if (!make_key_dbt(self, keyobj, &key, &flags))
1497+ return NULL;
1498+ if (!checkTxnObj(txnobj, &txn)) {
1499+ FREE_DBT(key);
1500+ return NULL;
1501+ }
1502+
1503+ CLEAR_DBT(data);
1504+ if (CHECK_DBFLAG(self, DB_THREAD)) {
1505+ /* Tell BerkeleyDB to malloc the return value (thread safe) */
1506+ data.flags = DB_DBT_MALLOC;
1507+ }
1508+ if (!add_partial_dbt(&data, dlen, doff)) {
1509+ FREE_DBT(key);
1510+ return NULL;
1511+ }
1512+
1513+ MYDB_BEGIN_ALLOW_THREADS;
1514+ err = self->db->get(self->db, txn, &key, &data, flags);
1515+ MYDB_END_ALLOW_THREADS;
1516+
1517+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && (dfltobj != NULL)) {
1518+ err = 0;
1519+ Py_INCREF(dfltobj);
1520+ retval = dfltobj;
1521+ }
1522+ else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
1523+ && self->moduleFlags.getReturnsNone) {
1524+ err = 0;
1525+ Py_INCREF(Py_None);
1526+ retval = Py_None;
1527+ }
1528+ else if (!err) {
1529+ if (flags & DB_SET_RECNO) /* return both key and data */
1530+ retval = Py_BuildValue("s#s#", key.data, key.size, data.data,
1531+ data.size);
1532+ else /* return just the data */
1533+ retval = PyString_FromStringAndSize((char*)data.data, data.size);
1534+ FREE_DBT(data);
1535+ }
1536+ FREE_DBT(key);
1537+
1538+ RETURN_IF_ERR();
1539+ return retval;
1540+}
1541+
1542+#if (DBVER >= 33)
1543+static PyObject*
1544+DB_pget(DBObject* self, PyObject* args, PyObject* kwargs)
1545+{
1546+ int err, flags=0;
1547+ PyObject* txnobj = NULL;
1548+ PyObject* keyobj;
1549+ PyObject* dfltobj = NULL;
1550+ PyObject* retval = NULL;
1551+ int dlen = -1;
1552+ int doff = -1;
1553+ DBT key, pkey, data;
1554+ DB_TXN *txn = NULL;
1555+ static char* kwnames[] = {"key", "default", "txn", "flags", "dlen",
1556+ "doff", NULL};
1557+
1558+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:pget", kwnames,
1559+ &keyobj, &dfltobj, &txnobj, &flags, &dlen,
1560+ &doff))
1561+ return NULL;
1562+
1563+ CHECK_DB_NOT_CLOSED(self);
1564+ if (!make_key_dbt(self, keyobj, &key, &flags))
1565+ return NULL;
1566+ if (!checkTxnObj(txnobj, &txn)) {
1567+ FREE_DBT(key);
1568+ return NULL;
1569+ }
1570+
1571+ CLEAR_DBT(data);
1572+ if (CHECK_DBFLAG(self, DB_THREAD)) {
1573+ /* Tell BerkeleyDB to malloc the return value (thread safe) */
1574+ data.flags = DB_DBT_MALLOC;
1575+ }
1576+ if (!add_partial_dbt(&data, dlen, doff)) {
1577+ FREE_DBT(key);
1578+ return NULL;
1579+ }
1580+
1581+ CLEAR_DBT(pkey);
1582+ pkey.flags = DB_DBT_MALLOC;
1583+
1584+ MYDB_BEGIN_ALLOW_THREADS;
1585+ err = self->db->pget(self->db, txn, &key, &pkey, &data, flags);
1586+ MYDB_END_ALLOW_THREADS;
1587+
1588+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && (dfltobj != NULL)) {
1589+ err = 0;
1590+ Py_INCREF(dfltobj);
1591+ retval = dfltobj;
1592+ }
1593+ else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
1594+ && self->moduleFlags.getReturnsNone) {
1595+ err = 0;
1596+ Py_INCREF(Py_None);
1597+ retval = Py_None;
1598+ }
1599+ else if (!err) {
1600+ PyObject *pkeyObj;
1601+ PyObject *dataObj;
1602+ dataObj = PyString_FromStringAndSize(data.data, data.size);
1603+
1604+ if (self->primaryDBType == DB_RECNO ||
1605+ self->primaryDBType == DB_QUEUE)
1606+ pkeyObj = PyInt_FromLong(*(int *)pkey.data);
1607+ else
1608+ pkeyObj = PyString_FromStringAndSize(pkey.data, pkey.size);
1609+
1610+ if (flags & DB_SET_RECNO) /* return key , pkey and data */
1611+ {
1612+ PyObject *keyObj;
1613+ int type = _DB_get_type(self);
1614+ if (type == DB_RECNO || type == DB_QUEUE)
1615+ keyObj = PyInt_FromLong(*(int *)key.data);
1616+ else
1617+ keyObj = PyString_FromStringAndSize(key.data, key.size);
1618+#if (PY_VERSION_HEX >= 0x02040000)
1619+ retval = PyTuple_Pack(3, keyObj, pkeyObj, dataObj);
1620+#else
1621+ retval = Py_BuildValue("OOO", keyObj, pkeyObj, dataObj);
1622+#endif
1623+ Py_DECREF(keyObj);
1624+ }
1625+ else /* return just the pkey and data */
1626+ {
1627+#if (PY_VERSION_HEX >= 0x02040000)
1628+ retval = PyTuple_Pack(2, pkeyObj, dataObj);
1629+#else
1630+ retval = Py_BuildValue("OO", pkeyObj, dataObj);
1631+#endif
1632+ }
1633+ Py_DECREF(dataObj);
1634+ Py_DECREF(pkeyObj);
1635+ FREE_DBT(pkey);
1636+ FREE_DBT(data);
1637+ }
1638+ FREE_DBT(key);
1639+
1640+ RETURN_IF_ERR();
1641+ return retval;
1642+}
1643+#endif
1644+
1645+
1646+/* Return size of entry */
1647+static PyObject*
1648+DB_get_size(DBObject* self, PyObject* args, PyObject* kwargs)
1649+{
1650+ int err, flags=0;
1651+ PyObject* txnobj = NULL;
1652+ PyObject* keyobj;
1653+ PyObject* retval = NULL;
1654+ DBT key, data;
1655+ DB_TXN *txn = NULL;
1656+ static char* kwnames[] = { "key", "txn", NULL };
1657+
1658+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:get_size", kwnames,
1659+ &keyobj, &txnobj))
1660+ return NULL;
1661+ CHECK_DB_NOT_CLOSED(self);
1662+ if (!make_key_dbt(self, keyobj, &key, &flags))
1663+ return NULL;
1664+ if (!checkTxnObj(txnobj, &txn)) {
1665+ FREE_DBT(key);
1666+ return NULL;
1667+ }
1668+ CLEAR_DBT(data);
1669+
1670+ /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and
1671+ thus getting the record size. */
1672+ data.flags = DB_DBT_USERMEM;
1673+ data.ulen = 0;
1674+ MYDB_BEGIN_ALLOW_THREADS;
1675+ err = self->db->get(self->db, txn, &key, &data, flags);
1676+ MYDB_END_ALLOW_THREADS;
1677+ if (err == DB_BUFFER_SMALL) {
1678+ retval = PyInt_FromLong((long)data.size);
1679+ err = 0;
1680+ }
1681+
1682+ FREE_DBT(key);
1683+ FREE_DBT(data);
1684+ RETURN_IF_ERR();
1685+ return retval;
1686+}
1687+
1688+
1689+static PyObject*
1690+DB_get_both(DBObject* self, PyObject* args, PyObject* kwargs)
1691+{
1692+ int err, flags=0;
1693+ PyObject* txnobj = NULL;
1694+ PyObject* keyobj;
1695+ PyObject* dataobj;
1696+ PyObject* retval = NULL;
1697+ DBT key, data;
1698+ DB_TXN *txn = NULL;
1699+ static char* kwnames[] = { "key", "data", "txn", "flags", NULL };
1700+
1701+
1702+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oi:get_both", kwnames,
1703+ &keyobj, &dataobj, &txnobj, &flags))
1704+ return NULL;
1705+
1706+ CHECK_DB_NOT_CLOSED(self);
1707+ if (!make_key_dbt(self, keyobj, &key, NULL))
1708+ return NULL;
1709+ if ( !make_dbt(dataobj, &data) ||
1710+ !checkTxnObj(txnobj, &txn) )
1711+ {
1712+ FREE_DBT(key);
1713+ return NULL;
1714+ }
1715+
1716+ flags |= DB_GET_BOTH;
1717+
1718+ if (CHECK_DBFLAG(self, DB_THREAD)) {
1719+ /* Tell BerkeleyDB to malloc the return value (thread safe) */
1720+ data.flags = DB_DBT_MALLOC;
1721+ /* TODO: Is this flag needed? We're passing a data object that should
1722+ match what's in the DB, so there should be no need to malloc.
1723+ We run the risk of freeing something twice! Check this. */
1724+ }
1725+
1726+ MYDB_BEGIN_ALLOW_THREADS;
1727+ err = self->db->get(self->db, txn, &key, &data, flags);
1728+ MYDB_END_ALLOW_THREADS;
1729+
1730+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
1731+ && self->moduleFlags.getReturnsNone) {
1732+ err = 0;
1733+ Py_INCREF(Py_None);
1734+ retval = Py_None;
1735+ }
1736+ else if (!err) {
1737+ retval = PyString_FromStringAndSize((char*)data.data, data.size);
1738+ FREE_DBT(data); /* Only if retrieval was successful */
1739+ }
1740+
1741+ FREE_DBT(key);
1742+ RETURN_IF_ERR();
1743+ return retval;
1744+}
1745+
1746+
1747+static PyObject*
1748+DB_get_byteswapped(DBObject* self, PyObject* args)
1749+{
1750+#if (DBVER >= 33)
1751+ int err = 0;
1752+#endif
1753+ int retval = -1;
1754+
1755+ if (!PyArg_ParseTuple(args,":get_byteswapped"))
1756+ return NULL;
1757+ CHECK_DB_NOT_CLOSED(self);
1758+
1759+#if (DBVER >= 33)
1760+ MYDB_BEGIN_ALLOW_THREADS;
1761+ err = self->db->get_byteswapped(self->db, &retval);
1762+ MYDB_END_ALLOW_THREADS;
1763+ RETURN_IF_ERR();
1764+#else
1765+ MYDB_BEGIN_ALLOW_THREADS;
1766+ retval = self->db->get_byteswapped(self->db);
1767+ MYDB_END_ALLOW_THREADS;
1768+#endif
1769+ return PyInt_FromLong(retval);
1770+}
1771+
1772+
1773+static PyObject*
1774+DB_get_type(DBObject* self, PyObject* args)
1775+{
1776+ int type;
1777+
1778+ if (!PyArg_ParseTuple(args,":get_type"))
1779+ return NULL;
1780+ CHECK_DB_NOT_CLOSED(self);
1781+
1782+ type = _DB_get_type(self);
1783+ if (type == -1)
1784+ return NULL;
1785+ return PyInt_FromLong(type);
1786+}
1787+
1788+
1789+static PyObject*
1790+DB_join(DBObject* self, PyObject* args)
1791+{
1792+ int err, flags=0;
1793+ int length, x;
1794+ PyObject* cursorsObj;
1795+ DBC** cursors;
1796+ DBC* dbc;
1797+
1798+ if (!PyArg_ParseTuple(args,"O|i:join", &cursorsObj, &flags))
1799+ return NULL;
1800+
1801+ CHECK_DB_NOT_CLOSED(self);
1802+
1803+ if (!PySequence_Check(cursorsObj)) {
1804+ PyErr_SetString(PyExc_TypeError,
1805+ "Sequence of DBCursor objects expected");
1806+ return NULL;
1807+ }
1808+
1809+ length = PyObject_Length(cursorsObj);
1810+ cursors = malloc((length+1) * sizeof(DBC*));
1811+ if (!cursors) {
1812+ PyErr_NoMemory();
1813+ return NULL;
1814+ }
1815+
1816+ cursors[length] = NULL;
1817+ for (x=0; x<length; x++) {
1818+ PyObject* item = PySequence_GetItem(cursorsObj, x);
1819+ if (item == NULL) {
1820+ free(cursors);
1821+ return NULL;
1822+ }
1823+ if (!DBCursorObject_Check(item)) {
1824+ PyErr_SetString(PyExc_TypeError,
1825+ "Sequence of DBCursor objects expected");
1826+ free(cursors);
1827+ return NULL;
1828+ }
1829+ cursors[x] = ((DBCursorObject*)item)->dbc;
1830+ Py_DECREF(item);
1831+ }
1832+
1833+ MYDB_BEGIN_ALLOW_THREADS;
1834+ err = self->db->join(self->db, cursors, &dbc, flags);
1835+ MYDB_END_ALLOW_THREADS;
1836+ free(cursors);
1837+ RETURN_IF_ERR();
1838+
1839+ /* FIXME: this is a buggy interface. The returned cursor
1840+ contains internal references to the passed in cursors
1841+ but does not hold python references to them or prevent
1842+ them from being closed prematurely. This can cause
1843+ python to crash when things are done in the wrong order. */
1844+ return (PyObject*) newDBCursorObject(dbc, self);
1845+}
1846+
1847+
1848+static PyObject*
1849+DB_key_range(DBObject* self, PyObject* args, PyObject* kwargs)
1850+{
1851+ int err, flags=0;
1852+ PyObject* txnobj = NULL;
1853+ PyObject* keyobj;
1854+ DBT key;
1855+ DB_TXN *txn = NULL;
1856+ DB_KEY_RANGE range;
1857+ static char* kwnames[] = { "key", "txn", "flags", NULL };
1858+
1859+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:key_range", kwnames,
1860+ &keyobj, &txnobj, &flags))
1861+ return NULL;
1862+ CHECK_DB_NOT_CLOSED(self);
1863+ if (!make_dbt(keyobj, &key))
1864+ /* BTree only, don't need to allow for an int key */
1865+ return NULL;
1866+ if (!checkTxnObj(txnobj, &txn))
1867+ return NULL;
1868+
1869+ MYDB_BEGIN_ALLOW_THREADS;
1870+ err = self->db->key_range(self->db, txn, &key, &range, flags);
1871+ MYDB_END_ALLOW_THREADS;
1872+
1873+ RETURN_IF_ERR();
1874+ return Py_BuildValue("ddd", range.less, range.equal, range.greater);
1875+}
1876+
1877+
1878+static PyObject*
1879+DB_open(DBObject* self, PyObject* args, PyObject* kwargs)
1880+{
1881+ int err, type = DB_UNKNOWN, flags=0, mode=0660;
1882+ char* filename = NULL;
1883+ char* dbname = NULL;
1884+#if (DBVER >= 41)
1885+ PyObject *txnobj = NULL;
1886+ DB_TXN *txn = NULL;
1887+ /* with dbname */
1888+ static char* kwnames[] = {
1889+ "filename", "dbname", "dbtype", "flags", "mode", "txn", NULL};
1890+ /* without dbname */
1891+ static char* kwnames_basic[] = {
1892+ "filename", "dbtype", "flags", "mode", "txn", NULL};
1893+#else
1894+ /* with dbname */
1895+ static char* kwnames[] = {
1896+ "filename", "dbname", "dbtype", "flags", "mode", NULL};
1897+ /* without dbname */
1898+ static char* kwnames_basic[] = {
1899+ "filename", "dbtype", "flags", "mode", NULL};
1900+#endif
1901+
1902+#if (DBVER >= 41)
1903+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|ziiiO:open", kwnames,
1904+ &filename, &dbname, &type, &flags, &mode,
1905+ &txnobj))
1906+#else
1907+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|ziii:open", kwnames,
1908+ &filename, &dbname, &type, &flags,
1909+ &mode))
1910+#endif
1911+ {
1912+ PyErr_Clear();
1913+ type = DB_UNKNOWN; flags = 0; mode = 0660;
1914+ filename = NULL; dbname = NULL;
1915+#if (DBVER >= 41)
1916+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,"z|iiiO:open",
1917+ kwnames_basic,
1918+ &filename, &type, &flags, &mode,
1919+ &txnobj))
1920+ return NULL;
1921+#else
1922+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,"z|iii:open",
1923+ kwnames_basic,
1924+ &filename, &type, &flags, &mode))
1925+ return NULL;
1926+#endif
1927+ }
1928+
1929+#if (DBVER >= 41)
1930+ if (!checkTxnObj(txnobj, &txn)) return NULL;
1931+#endif
1932+
1933+ if (NULL == self->db) {
1934+ PyObject *t = Py_BuildValue("(is)", 0,
1935+ "Cannot call open() twice for DB object");
1936+ PyErr_SetObject(DBError, t);
1937+ Py_DECREF(t);
1938+ return NULL;
1939+ }
1940+
1941+#if 0 && (DBVER >= 41)
1942+ if ((!txn) && (txnobj != Py_None) && self->myenvobj
1943+ && (self->myenvobj->flags & DB_INIT_TXN))
1944+ {
1945+ /* If no 'txn' parameter was supplied (no DbTxn object and None was not
1946+ * explicitly passed) but we are in a transaction ready environment:
1947+ * add DB_AUTO_COMMIT to allow for older pybsddb apps using transactions
1948+ * to work on BerkeleyDB 4.1 without needing to modify their
1949+ * DBEnv or DB open calls.
1950+ * TODO make this behaviour of the library configurable.
1951+ */
1952+ flags |= DB_AUTO_COMMIT;
1953+ }
1954+#endif
1955+
1956+ MYDB_BEGIN_ALLOW_THREADS;
1957+#if (DBVER >= 41)
1958+ err = self->db->open(self->db, txn, filename, dbname, type, flags, mode);
1959+#else
1960+ err = self->db->open(self->db, filename, dbname, type, flags, mode);
1961+#endif
1962+ MYDB_END_ALLOW_THREADS;
1963+ if (makeDBError(err)) {
1964+ self->db->close(self->db, 0);
1965+ self->db = NULL;
1966+ return NULL;
1967+ }
1968+
1969+ self->flags = flags;
1970+ RETURN_NONE();
1971+}
1972+
1973+
1974+static PyObject*
1975+DB_put(DBObject* self, PyObject* args, PyObject* kwargs)
1976+{
1977+ int flags=0;
1978+ PyObject* txnobj = NULL;
1979+ int dlen = -1;
1980+ int doff = -1;
1981+ PyObject* keyobj, *dataobj, *retval;
1982+ DBT key, data;
1983+ DB_TXN *txn = NULL;
1984+ static char* kwnames[] = { "key", "data", "txn", "flags", "dlen",
1985+ "doff", NULL };
1986+
1987+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oiii:put", kwnames,
1988+ &keyobj, &dataobj, &txnobj, &flags, &dlen, &doff))
1989+ return NULL;
1990+
1991+ CHECK_DB_NOT_CLOSED(self);
1992+ if (!make_key_dbt(self, keyobj, &key, NULL))
1993+ return NULL;
1994+ if ( !make_dbt(dataobj, &data) ||
1995+ !add_partial_dbt(&data, dlen, doff) ||
1996+ !checkTxnObj(txnobj, &txn) )
1997+ {
1998+ FREE_DBT(key);
1999+ return NULL;
2000+ }
2001+
2002+ if (-1 == _DB_put(self, txn, &key, &data, flags)) {
2003+ FREE_DBT(key);
2004+ return NULL;
2005+ }
2006+
2007+ if (flags & DB_APPEND)
2008+ retval = PyInt_FromLong(*((db_recno_t*)key.data));
2009+ else {
2010+ retval = Py_None;
2011+ Py_INCREF(retval);
2012+ }
2013+ FREE_DBT(key);
2014+ return retval;
2015+}
2016+
2017+
2018+
2019+static PyObject*
2020+DB_remove(DBObject* self, PyObject* args, PyObject* kwargs)
2021+{
2022+ char* filename;
2023+ char* database = NULL;
2024+ int err, flags=0;
2025+ static char* kwnames[] = { "filename", "dbname", "flags", NULL};
2026+
2027+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zi:remove", kwnames,
2028+ &filename, &database, &flags))
2029+ return NULL;
2030+ CHECK_DB_NOT_CLOSED(self);
2031+
2032+ err = self->db->remove(self->db, filename, database, flags);
2033+ self->db = NULL;
2034+ RETURN_IF_ERR();
2035+ RETURN_NONE();
2036+}
2037+
2038+
2039+
2040+static PyObject*
2041+DB_rename(DBObject* self, PyObject* args)
2042+{
2043+ char* filename;
2044+ char* database;
2045+ char* newname;
2046+ int err, flags=0;
2047+
2048+ if (!PyArg_ParseTuple(args, "sss|i:rename", &filename, &database, &newname,
2049+ &flags))
2050+ return NULL;
2051+ CHECK_DB_NOT_CLOSED(self);
2052+
2053+ MYDB_BEGIN_ALLOW_THREADS;
2054+ err = self->db->rename(self->db, filename, database, newname, flags);
2055+ MYDB_END_ALLOW_THREADS;
2056+ RETURN_IF_ERR();
2057+ RETURN_NONE();
2058+}
2059+
2060+
2061+static PyObject*
2062+DB_set_bt_minkey(DBObject* self, PyObject* args)
2063+{
2064+ int err, minkey;
2065+
2066+ if (!PyArg_ParseTuple(args,"i:set_bt_minkey", &minkey ))
2067+ return NULL;
2068+ CHECK_DB_NOT_CLOSED(self);
2069+
2070+ MYDB_BEGIN_ALLOW_THREADS;
2071+ err = self->db->set_bt_minkey(self->db, minkey);
2072+ MYDB_END_ALLOW_THREADS;
2073+ RETURN_IF_ERR();
2074+ RETURN_NONE();
2075+}
2076+
2077+#if (DBVER >= 33)
2078+static int
2079+_default_cmp(const DBT *leftKey,
2080+ const DBT *rightKey)
2081+{
2082+ int res;
2083+ int lsize = leftKey->size, rsize = rightKey->size;
2084+
2085+ res = memcmp(leftKey->data, rightKey->data,
2086+ lsize < rsize ? lsize : rsize);
2087+
2088+ if (res == 0) {
2089+ if (lsize < rsize) {
2090+ res = -1;
2091+ }
2092+ else if (lsize > rsize) {
2093+ res = 1;
2094+ }
2095+ }
2096+ return res;
2097+}
2098+
2099+static int
2100+_db_compareCallback(DB* db,
2101+ const DBT *leftKey,
2102+ const DBT *rightKey)
2103+{
2104+ int res = 0;
2105+ PyObject *args;
2106+ PyObject *result = NULL;
2107+ DBObject *self = (DBObject *)db->app_private;
2108+
2109+ if (self == NULL || self->btCompareCallback == NULL) {
2110+ MYDB_BEGIN_BLOCK_THREADS;
2111+ PyErr_SetString(PyExc_TypeError,
2112+ (self == 0
2113+ ? "DB_bt_compare db is NULL."
2114+ : "DB_bt_compare callback is NULL."));
2115+ /* we're in a callback within the DB code, we can't raise */
2116+ PyErr_Print();
2117+ res = _default_cmp(leftKey, rightKey);
2118+ MYDB_END_BLOCK_THREADS;
2119+ } else {
2120+ MYDB_BEGIN_BLOCK_THREADS;
2121+
2122+ args = Py_BuildValue("s#s#", leftKey->data, leftKey->size,
2123+ rightKey->data, rightKey->size);
2124+ if (args != NULL) {
2125+ /* XXX(twouters) I highly doubt this INCREF is correct */
2126+ Py_INCREF(self);
2127+ result = PyEval_CallObject(self->btCompareCallback, args);
2128+ }
2129+ if (args == NULL || result == NULL) {
2130+ /* we're in a callback within the DB code, we can't raise */
2131+ PyErr_Print();
2132+ res = _default_cmp(leftKey, rightKey);
2133+ } else if (PyInt_Check(result)) {
2134+ res = PyInt_AsLong(result);
2135+ } else {
2136+ PyErr_SetString(PyExc_TypeError,
2137+ "DB_bt_compare callback MUST return an int.");
2138+ /* we're in a callback within the DB code, we can't raise */
2139+ PyErr_Print();
2140+ res = _default_cmp(leftKey, rightKey);
2141+ }
2142+
2143+ Py_XDECREF(args);
2144+ Py_XDECREF(result);
2145+
2146+ MYDB_END_BLOCK_THREADS;
2147+ }
2148+ return res;
2149+}
2150+
2151+static PyObject*
2152+DB_set_bt_compare(DBObject* self, PyObject* args)
2153+{
2154+ int err;
2155+ PyObject *comparator;
2156+ PyObject *tuple, *result;
2157+
2158+ if (!PyArg_ParseTuple(args, "O:set_bt_compare", &comparator))
2159+ return NULL;
2160+
2161+ CHECK_DB_NOT_CLOSED(self);
2162+
2163+ if (!PyCallable_Check(comparator)) {
2164+ makeTypeError("Callable", comparator);
2165+ return NULL;
2166+ }
2167+
2168+ /*
2169+ * Perform a test call of the comparator function with two empty
2170+ * string objects here. verify that it returns an int (0).
2171+ * err if not.
2172+ */
2173+ tuple = Py_BuildValue("(ss)", "", "");
2174+ result = PyEval_CallObject(comparator, tuple);
2175+ Py_DECREF(tuple);
2176+ if (result == NULL)
2177+ return NULL;
2178+ if (!PyInt_Check(result)) {
2179+ PyErr_SetString(PyExc_TypeError,
2180+ "callback MUST return an int");
2181+ return NULL;
2182+ } else if (PyInt_AsLong(result) != 0) {
2183+ PyErr_SetString(PyExc_TypeError,
2184+ "callback failed to return 0 on two empty strings");
2185+ return NULL;
2186+ }
2187+ Py_DECREF(result);
2188+
2189+ /* We don't accept multiple set_bt_compare operations, in order to
2190+ * simplify the code. This would have no real use, as one cannot
2191+ * change the function once the db is opened anyway */
2192+ if (self->btCompareCallback != NULL) {
2193+ PyErr_SetString(PyExc_RuntimeError, "set_bt_compare() cannot be called more than once");
2194+ return NULL;
2195+ }
2196+
2197+ Py_INCREF(comparator);
2198+ self->btCompareCallback = comparator;
2199+
2200+ /* This is to workaround a problem with un-initialized threads (see
2201+ comment in DB_associate) */
2202+#ifdef WITH_THREAD
2203+ PyEval_InitThreads();
2204+#endif
2205+
2206+ err = self->db->set_bt_compare(self->db, _db_compareCallback);
2207+
2208+ if (err) {
2209+ /* restore the old state in case of error */
2210+ Py_DECREF(comparator);
2211+ self->btCompareCallback = NULL;
2212+ }
2213+
2214+ RETURN_IF_ERR();
2215+ RETURN_NONE();
2216+}
2217+#endif /* DBVER >= 33 */
2218+
2219+
2220+static PyObject*
2221+DB_set_cachesize(DBObject* self, PyObject* args)
2222+{
2223+ int err;
2224+ int gbytes = 0, bytes = 0, ncache = 0;
2225+
2226+ if (!PyArg_ParseTuple(args,"ii|i:set_cachesize",
2227+ &gbytes,&bytes,&ncache))
2228+ return NULL;
2229+ CHECK_DB_NOT_CLOSED(self);
2230+
2231+ MYDB_BEGIN_ALLOW_THREADS;
2232+ err = self->db->set_cachesize(self->db, gbytes, bytes, ncache);
2233+ MYDB_END_ALLOW_THREADS;
2234+ RETURN_IF_ERR();
2235+ RETURN_NONE();
2236+}
2237+
2238+
2239+static PyObject*
2240+DB_set_flags(DBObject* self, PyObject* args)
2241+{
2242+ int err, flags;
2243+
2244+ if (!PyArg_ParseTuple(args,"i:set_flags", &flags))
2245+ return NULL;
2246+ CHECK_DB_NOT_CLOSED(self);
2247+
2248+ MYDB_BEGIN_ALLOW_THREADS;
2249+ err = self->db->set_flags(self->db, flags);
2250+ MYDB_END_ALLOW_THREADS;
2251+ RETURN_IF_ERR();
2252+
2253+ self->setflags |= flags;
2254+ RETURN_NONE();
2255+}
2256+
2257+
2258+static PyObject*
2259+DB_set_h_ffactor(DBObject* self, PyObject* args)
2260+{
2261+ int err, ffactor;
2262+
2263+ if (!PyArg_ParseTuple(args,"i:set_h_ffactor", &ffactor))
2264+ return NULL;
2265+ CHECK_DB_NOT_CLOSED(self);
2266+
2267+ MYDB_BEGIN_ALLOW_THREADS;
2268+ err = self->db->set_h_ffactor(self->db, ffactor);
2269+ MYDB_END_ALLOW_THREADS;
2270+ RETURN_IF_ERR();
2271+ RETURN_NONE();
2272+}
2273+
2274+
2275+static PyObject*
2276+DB_set_h_nelem(DBObject* self, PyObject* args)
2277+{
2278+ int err, nelem;
2279+
2280+ if (!PyArg_ParseTuple(args,"i:set_h_nelem", &nelem))
2281+ return NULL;
2282+ CHECK_DB_NOT_CLOSED(self);
2283+
2284+ MYDB_BEGIN_ALLOW_THREADS;
2285+ err = self->db->set_h_nelem(self->db, nelem);
2286+ MYDB_END_ALLOW_THREADS;
2287+ RETURN_IF_ERR();
2288+ RETURN_NONE();
2289+}
2290+
2291+
2292+static PyObject*
2293+DB_set_lorder(DBObject* self, PyObject* args)
2294+{
2295+ int err, lorder;
2296+
2297+ if (!PyArg_ParseTuple(args,"i:set_lorder", &lorder))
2298+ return NULL;
2299+ CHECK_DB_NOT_CLOSED(self);
2300+
2301+ MYDB_BEGIN_ALLOW_THREADS;
2302+ err = self->db->set_lorder(self->db, lorder);
2303+ MYDB_END_ALLOW_THREADS;
2304+ RETURN_IF_ERR();
2305+ RETURN_NONE();
2306+}
2307+
2308+
2309+static PyObject*
2310+DB_set_pagesize(DBObject* self, PyObject* args)
2311+{
2312+ int err, pagesize;
2313+
2314+ if (!PyArg_ParseTuple(args,"i:set_pagesize", &pagesize))
2315+ return NULL;
2316+ CHECK_DB_NOT_CLOSED(self);
2317+
2318+ MYDB_BEGIN_ALLOW_THREADS;
2319+ err = self->db->set_pagesize(self->db, pagesize);
2320+ MYDB_END_ALLOW_THREADS;
2321+ RETURN_IF_ERR();
2322+ RETURN_NONE();
2323+}
2324+
2325+
2326+static PyObject*
2327+DB_set_re_delim(DBObject* self, PyObject* args)
2328+{
2329+ int err;
2330+ char delim;
2331+
2332+ if (!PyArg_ParseTuple(args,"b:set_re_delim", &delim)) {
2333+ PyErr_Clear();
2334+ if (!PyArg_ParseTuple(args,"c:set_re_delim", &delim))
2335+ return NULL;
2336+ }
2337+
2338+ CHECK_DB_NOT_CLOSED(self);
2339+
2340+ MYDB_BEGIN_ALLOW_THREADS;
2341+ err = self->db->set_re_delim(self->db, delim);
2342+ MYDB_END_ALLOW_THREADS;
2343+ RETURN_IF_ERR();
2344+ RETURN_NONE();
2345+}
2346+
2347+static PyObject*
2348+DB_set_re_len(DBObject* self, PyObject* args)
2349+{
2350+ int err, len;
2351+
2352+ if (!PyArg_ParseTuple(args,"i:set_re_len", &len))
2353+ return NULL;
2354+ CHECK_DB_NOT_CLOSED(self);
2355+
2356+ MYDB_BEGIN_ALLOW_THREADS;
2357+ err = self->db->set_re_len(self->db, len);
2358+ MYDB_END_ALLOW_THREADS;
2359+ RETURN_IF_ERR();
2360+ RETURN_NONE();
2361+}
2362+
2363+
2364+static PyObject*
2365+DB_set_re_pad(DBObject* self, PyObject* args)
2366+{
2367+ int err;
2368+ char pad;
2369+
2370+ if (!PyArg_ParseTuple(args,"b:set_re_pad", &pad)) {
2371+ PyErr_Clear();
2372+ if (!PyArg_ParseTuple(args,"c:set_re_pad", &pad))
2373+ return NULL;
2374+ }
2375+ CHECK_DB_NOT_CLOSED(self);
2376+
2377+ MYDB_BEGIN_ALLOW_THREADS;
2378+ err = self->db->set_re_pad(self->db, pad);
2379+ MYDB_END_ALLOW_THREADS;
2380+ RETURN_IF_ERR();
2381+ RETURN_NONE();
2382+}
2383+
2384+
2385+static PyObject*
2386+DB_set_re_source(DBObject* self, PyObject* args)
2387+{
2388+ int err;
2389+ char *re_source;
2390+
2391+ if (!PyArg_ParseTuple(args,"s:set_re_source", &re_source))
2392+ return NULL;
2393+ CHECK_DB_NOT_CLOSED(self);
2394+
2395+ MYDB_BEGIN_ALLOW_THREADS;
2396+ err = self->db->set_re_source(self->db, re_source);
2397+ MYDB_END_ALLOW_THREADS;
2398+ RETURN_IF_ERR();
2399+ RETURN_NONE();
2400+}
2401+
2402+
2403+#if (DBVER >= 32)
2404+static PyObject*
2405+DB_set_q_extentsize(DBObject* self, PyObject* args)
2406+{
2407+ int err;
2408+ int extentsize;
2409+
2410+ if (!PyArg_ParseTuple(args,"i:set_q_extentsize", &extentsize))
2411+ return NULL;
2412+ CHECK_DB_NOT_CLOSED(self);
2413+
2414+ MYDB_BEGIN_ALLOW_THREADS;
2415+ err = self->db->set_q_extentsize(self->db, extentsize);
2416+ MYDB_END_ALLOW_THREADS;
2417+ RETURN_IF_ERR();
2418+ RETURN_NONE();
2419+}
2420+#endif
2421+
2422+static PyObject*
2423+DB_stat(DBObject* self, PyObject* args, PyObject* kwargs)
2424+{
2425+ int err, flags = 0, type;
2426+ void* sp;
2427+ PyObject* d;
2428+#if (DBVER >= 43)
2429+ PyObject* txnobj = NULL;
2430+ DB_TXN *txn = NULL;
2431+ static char* kwnames[] = { "flags", "txn", NULL };
2432+#else
2433+ static char* kwnames[] = { "flags", NULL };
2434+#endif
2435+
2436+#if (DBVER >= 43)
2437+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iO:stat", kwnames,
2438+ &flags, &txnobj))
2439+ return NULL;
2440+ if (!checkTxnObj(txnobj, &txn))
2441+ return NULL;
2442+#else
2443+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat", kwnames, &flags))
2444+ return NULL;
2445+#endif
2446+ CHECK_DB_NOT_CLOSED(self);
2447+
2448+ MYDB_BEGIN_ALLOW_THREADS;
2449+#if (DBVER >= 43)
2450+ err = self->db->stat(self->db, txn, &sp, flags);
2451+#elif (DBVER >= 33)
2452+ err = self->db->stat(self->db, &sp, flags);
2453+#else
2454+ err = self->db->stat(self->db, &sp, NULL, flags);
2455+#endif
2456+ MYDB_END_ALLOW_THREADS;
2457+ RETURN_IF_ERR();
2458+
2459+ self->haveStat = 1;
2460+
2461+ /* Turn the stat structure into a dictionary */
2462+ type = _DB_get_type(self);
2463+ if ((type == -1) || ((d = PyDict_New()) == NULL)) {
2464+ free(sp);
2465+ return NULL;
2466+ }
2467+
2468+#define MAKE_HASH_ENTRY(name) _addIntToDict(d, #name, ((DB_HASH_STAT*)sp)->hash_##name)
2469+#define MAKE_BT_ENTRY(name) _addIntToDict(d, #name, ((DB_BTREE_STAT*)sp)->bt_##name)
2470+#define MAKE_QUEUE_ENTRY(name) _addIntToDict(d, #name, ((DB_QUEUE_STAT*)sp)->qs_##name)
2471+
2472+ switch (type) {
2473+ case DB_HASH:
2474+ MAKE_HASH_ENTRY(magic);
2475+ MAKE_HASH_ENTRY(version);
2476+ MAKE_HASH_ENTRY(nkeys);
2477+ MAKE_HASH_ENTRY(ndata);
2478+ MAKE_HASH_ENTRY(pagesize);
2479+#if (DBVER < 41)
2480+ MAKE_HASH_ENTRY(nelem);
2481+#endif
2482+ MAKE_HASH_ENTRY(ffactor);
2483+ MAKE_HASH_ENTRY(buckets);
2484+ MAKE_HASH_ENTRY(free);
2485+ MAKE_HASH_ENTRY(bfree);
2486+ MAKE_HASH_ENTRY(bigpages);
2487+ MAKE_HASH_ENTRY(big_bfree);
2488+ MAKE_HASH_ENTRY(overflows);
2489+ MAKE_HASH_ENTRY(ovfl_free);
2490+ MAKE_HASH_ENTRY(dup);
2491+ MAKE_HASH_ENTRY(dup_free);
2492+ break;
2493+
2494+ case DB_BTREE:
2495+ case DB_RECNO:
2496+ MAKE_BT_ENTRY(magic);
2497+ MAKE_BT_ENTRY(version);
2498+ MAKE_BT_ENTRY(nkeys);
2499+ MAKE_BT_ENTRY(ndata);
2500+ MAKE_BT_ENTRY(pagesize);
2501+ MAKE_BT_ENTRY(minkey);
2502+ MAKE_BT_ENTRY(re_len);
2503+ MAKE_BT_ENTRY(re_pad);
2504+ MAKE_BT_ENTRY(levels);
2505+ MAKE_BT_ENTRY(int_pg);
2506+ MAKE_BT_ENTRY(leaf_pg);
2507+ MAKE_BT_ENTRY(dup_pg);
2508+ MAKE_BT_ENTRY(over_pg);
2509+ MAKE_BT_ENTRY(free);
2510+ MAKE_BT_ENTRY(int_pgfree);
2511+ MAKE_BT_ENTRY(leaf_pgfree);
2512+ MAKE_BT_ENTRY(dup_pgfree);
2513+ MAKE_BT_ENTRY(over_pgfree);
2514+ break;
2515+
2516+ case DB_QUEUE:
2517+ MAKE_QUEUE_ENTRY(magic);
2518+ MAKE_QUEUE_ENTRY(version);
2519+ MAKE_QUEUE_ENTRY(nkeys);
2520+ MAKE_QUEUE_ENTRY(ndata);
2521+ MAKE_QUEUE_ENTRY(pagesize);
2522+ MAKE_QUEUE_ENTRY(pages);
2523+ MAKE_QUEUE_ENTRY(re_len);
2524+ MAKE_QUEUE_ENTRY(re_pad);
2525+ MAKE_QUEUE_ENTRY(pgfree);
2526+#if (DBVER == 31)
2527+ MAKE_QUEUE_ENTRY(start);
2528+#endif
2529+ MAKE_QUEUE_ENTRY(first_recno);
2530+ MAKE_QUEUE_ENTRY(cur_recno);
2531+ break;
2532+
2533+ default:
2534+ PyErr_SetString(PyExc_TypeError, "Unknown DB type, unable to stat");
2535+ Py_DECREF(d);
2536+ d = NULL;
2537+ }
2538+
2539+#undef MAKE_HASH_ENTRY
2540+#undef MAKE_BT_ENTRY
2541+#undef MAKE_QUEUE_ENTRY
2542+
2543+ free(sp);
2544+ return d;
2545+}
2546+
2547+static PyObject*
2548+DB_sync(DBObject* self, PyObject* args)
2549+{
2550+ int err;
2551+ int flags = 0;
2552+
2553+ if (!PyArg_ParseTuple(args,"|i:sync", &flags ))
2554+ return NULL;
2555+ CHECK_DB_NOT_CLOSED(self);
2556+
2557+ MYDB_BEGIN_ALLOW_THREADS;
2558+ err = self->db->sync(self->db, flags);
2559+ MYDB_END_ALLOW_THREADS;
2560+ RETURN_IF_ERR();
2561+ RETURN_NONE();
2562+}
2563+
2564+
2565+#if (DBVER >= 33)
2566+static PyObject*
2567+DB_truncate(DBObject* self, PyObject* args, PyObject* kwargs)
2568+{
2569+ int err, flags=0;
2570+ u_int32_t count=0;
2571+ PyObject* txnobj = NULL;
2572+ DB_TXN *txn = NULL;
2573+ static char* kwnames[] = { "txn", "flags", NULL };
2574+
2575+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
2576+ &txnobj, &flags))
2577+ return NULL;
2578+ CHECK_DB_NOT_CLOSED(self);
2579+ if (!checkTxnObj(txnobj, &txn))
2580+ return NULL;
2581+
2582+ MYDB_BEGIN_ALLOW_THREADS;
2583+ err = self->db->truncate(self->db, txn, &count, flags);
2584+ MYDB_END_ALLOW_THREADS;
2585+ RETURN_IF_ERR();
2586+ return PyInt_FromLong(count);
2587+}
2588+#endif
2589+
2590+
2591+static PyObject*
2592+DB_upgrade(DBObject* self, PyObject* args)
2593+{
2594+ int err, flags=0;
2595+ char *filename;
2596+
2597+ if (!PyArg_ParseTuple(args,"s|i:upgrade", &filename, &flags))
2598+ return NULL;
2599+ CHECK_DB_NOT_CLOSED(self);
2600+
2601+ MYDB_BEGIN_ALLOW_THREADS;
2602+ err = self->db->upgrade(self->db, filename, flags);
2603+ MYDB_END_ALLOW_THREADS;
2604+ RETURN_IF_ERR();
2605+ RETURN_NONE();
2606+}
2607+
2608+
2609+static PyObject*
2610+DB_verify(DBObject* self, PyObject* args, PyObject* kwargs)
2611+{
2612+ int err, flags=0;
2613+ char* fileName;
2614+ char* dbName=NULL;
2615+ char* outFileName=NULL;
2616+ FILE* outFile=NULL;
2617+ static char* kwnames[] = { "filename", "dbname", "outfile", "flags",
2618+ NULL };
2619+
2620+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zzi:verify", kwnames,
2621+ &fileName, &dbName, &outFileName, &flags))
2622+ return NULL;
2623+
2624+ CHECK_DB_NOT_CLOSED(self);
2625+ if (outFileName)
2626+ outFile = fopen(outFileName, "w");
2627+ /* XXX(nnorwitz): it should probably be an exception if outFile
2628+ can't be opened. */
2629+
2630+ MYDB_BEGIN_ALLOW_THREADS;
2631+ err = self->db->verify(self->db, fileName, dbName, outFile, flags);
2632+ MYDB_END_ALLOW_THREADS;
2633+ if (outFile)
2634+ fclose(outFile);
2635+
2636+ /* DB.verify acts as a DB handle destructor (like close); this was
2637+ * documented in BerkeleyDB 4.2 but had the undocumented effect
2638+ * of not being safe in prior versions while still requiring an explicit
2639+ * DB.close call afterwards. Lets call close for the user to emulate
2640+ * the safe 4.2 behaviour. */
2641+#if (DBVER <= 41)
2642+ self->db->close(self->db, 0);
2643+#endif
2644+ self->db = NULL;
2645+
2646+ RETURN_IF_ERR();
2647+ RETURN_NONE();
2648+}
2649+
2650+
2651+static PyObject*
2652+DB_set_get_returns_none(DBObject* self, PyObject* args)
2653+{
2654+ int flags=0;
2655+ int oldValue=0;
2656+
2657+ if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
2658+ return NULL;
2659+ CHECK_DB_NOT_CLOSED(self);
2660+
2661+ if (self->moduleFlags.getReturnsNone)
2662+ ++oldValue;
2663+ if (self->moduleFlags.cursorSetReturnsNone)
2664+ ++oldValue;
2665+ self->moduleFlags.getReturnsNone = (flags >= 1);
2666+ self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
2667+ return PyInt_FromLong(oldValue);
2668+}
2669+
2670+#if (DBVER >= 41)
2671+static PyObject*
2672+DB_set_encrypt(DBObject* self, PyObject* args, PyObject* kwargs)
2673+{
2674+ int err;
2675+ u_int32_t flags=0;
2676+ char *passwd = NULL;
2677+ static char* kwnames[] = { "passwd", "flags", NULL };
2678+
2679+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
2680+ &passwd, &flags)) {
2681+ return NULL;
2682+ }
2683+
2684+ MYDB_BEGIN_ALLOW_THREADS;
2685+ err = self->db->set_encrypt(self->db, passwd, flags);
2686+ MYDB_END_ALLOW_THREADS;
2687+
2688+ RETURN_IF_ERR();
2689+ RETURN_NONE();
2690+}
2691+#endif /* DBVER >= 41 */
2692+
2693+
2694+/*-------------------------------------------------------------- */
2695+/* Mapping and Dictionary-like access routines */
2696+
2697+Py_ssize_t DB_length(PyObject* _self)
2698+{
2699+ int err;
2700+ Py_ssize_t size = 0;
2701+ int flags = 0;
2702+ void* sp;
2703+ DBObject* self = (DBObject*)_self;
2704+
2705+ if (self->db == NULL) {
2706+ PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
2707+ PyErr_SetObject(DBError, t);
2708+ Py_DECREF(t);
2709+ return -1;
2710+ }
2711+
2712+ if (self->haveStat) { /* Has the stat function been called recently? If
2713+ so, we can use the cached value. */
2714+ flags = DB_FAST_STAT;
2715+ }
2716+
2717+ MYDB_BEGIN_ALLOW_THREADS;
2718+redo_stat_for_length:
2719+#if (DBVER >= 43)
2720+ err = self->db->stat(self->db, /*txnid*/ NULL, &sp, flags);
2721+#elif (DBVER >= 33)
2722+ err = self->db->stat(self->db, &sp, flags);
2723+#else
2724+ err = self->db->stat(self->db, &sp, NULL, flags);
2725+#endif
2726+
2727+ /* All the stat structures have matching fields upto the ndata field,
2728+ so we can use any of them for the type cast */
2729+ size = ((DB_BTREE_STAT*)sp)->bt_ndata;
2730+
2731+ /* A size of 0 could mean that BerkeleyDB no longer had the stat values cached.
2732+ * redo a full stat to make sure.
2733+ * Fixes SF python bug 1493322, pybsddb bug 1184012
2734+ */
2735+ if (size == 0 && (flags & DB_FAST_STAT)) {
2736+ flags = 0;
2737+ if (!err)
2738+ free(sp);
2739+ goto redo_stat_for_length;
2740+ }
2741+
2742+ MYDB_END_ALLOW_THREADS;
2743+
2744+ if (err)
2745+ return -1;
2746+
2747+ self->haveStat = 1;
2748+
2749+ free(sp);
2750+ return size;
2751+}
2752+
2753+
2754+PyObject* DB_subscript(DBObject* self, PyObject* keyobj)
2755+{
2756+ int err;
2757+ PyObject* retval;
2758+ DBT key;
2759+ DBT data;
2760+
2761+ CHECK_DB_NOT_CLOSED(self);
2762+ if (!make_key_dbt(self, keyobj, &key, NULL))
2763+ return NULL;
2764+
2765+ CLEAR_DBT(data);
2766+ if (CHECK_DBFLAG(self, DB_THREAD)) {
2767+ /* Tell BerkeleyDB to malloc the return value (thread safe) */
2768+ data.flags = DB_DBT_MALLOC;
2769+ }
2770+ MYDB_BEGIN_ALLOW_THREADS;
2771+ err = self->db->get(self->db, NULL, &key, &data, 0);
2772+ MYDB_END_ALLOW_THREADS;
2773+ if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
2774+ PyErr_SetObject(PyExc_KeyError, keyobj);
2775+ retval = NULL;
2776+ }
2777+ else if (makeDBError(err)) {
2778+ retval = NULL;
2779+ }
2780+ else {
2781+ retval = PyString_FromStringAndSize((char*)data.data, data.size);
2782+ FREE_DBT(data);
2783+ }
2784+
2785+ FREE_DBT(key);
2786+ return retval;
2787+}
2788+
2789+
2790+static int
2791+DB_ass_sub(DBObject* self, PyObject* keyobj, PyObject* dataobj)
2792+{
2793+ DBT key, data;
2794+ int retval;
2795+ int flags = 0;
2796+
2797+ if (self->db == NULL) {
2798+ PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
2799+ PyErr_SetObject(DBError, t);
2800+ Py_DECREF(t);
2801+ return -1;
2802+ }
2803+
2804+ if (!make_key_dbt(self, keyobj, &key, NULL))
2805+ return -1;
2806+
2807+ if (dataobj != NULL) {
2808+ if (!make_dbt(dataobj, &data))
2809+ retval = -1;
2810+ else {
2811+ if (self->setflags & (DB_DUP|DB_DUPSORT))
2812+ /* dictionaries shouldn't have duplicate keys */
2813+ flags = DB_NOOVERWRITE;
2814+ retval = _DB_put(self, NULL, &key, &data, flags);
2815+
2816+ if ((retval == -1) && (self->setflags & (DB_DUP|DB_DUPSORT))) {
2817+ /* try deleting any old record that matches and then PUT it
2818+ * again... */
2819+ _DB_delete(self, NULL, &key, 0);
2820+ PyErr_Clear();
2821+ retval = _DB_put(self, NULL, &key, &data, flags);
2822+ }
2823+ }
2824+ }
2825+ else {
2826+ /* dataobj == NULL, so delete the key */
2827+ retval = _DB_delete(self, NULL, &key, 0);
2828+ }
2829+ FREE_DBT(key);
2830+ return retval;
2831+}
2832+
2833+
2834+static PyObject*
2835+DB_has_key(DBObject* self, PyObject* args)
2836+{
2837+ int err;
2838+ PyObject* keyobj;
2839+ DBT key, data;
2840+ PyObject* txnobj = NULL;
2841+ DB_TXN *txn = NULL;
2842+
2843+ if (!PyArg_ParseTuple(args,"O|O:has_key", &keyobj, &txnobj))
2844+ return NULL;
2845+ CHECK_DB_NOT_CLOSED(self);
2846+ if (!make_key_dbt(self, keyobj, &key, NULL))
2847+ return NULL;
2848+ if (!checkTxnObj(txnobj, &txn)) {
2849+ FREE_DBT(key);
2850+ return NULL;
2851+ }
2852+
2853+ /* This causes DB_BUFFER_SMALL to be returned when the db has the key because
2854+ it has a record but can't allocate a buffer for the data. This saves
2855+ having to deal with data we won't be using.
2856+ */
2857+ CLEAR_DBT(data);
2858+ data.flags = DB_DBT_USERMEM;
2859+
2860+ MYDB_BEGIN_ALLOW_THREADS;
2861+ err = self->db->get(self->db, txn, &key, &data, 0);
2862+ MYDB_END_ALLOW_THREADS;
2863+ FREE_DBT(key);
2864+
2865+ if (err == DB_BUFFER_SMALL || err == 0) {
2866+ return PyInt_FromLong(1);
2867+ } else if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
2868+ return PyInt_FromLong(0);
2869+ }
2870+
2871+ makeDBError(err);
2872+ return NULL;
2873+}
2874+
2875+
2876+#define _KEYS_LIST 1
2877+#define _VALUES_LIST 2
2878+#define _ITEMS_LIST 3
2879+
2880+static PyObject*
2881+_DB_make_list(DBObject* self, DB_TXN* txn, int type)
2882+{
2883+ int err, dbtype;
2884+ DBT key;
2885+ DBT data;
2886+ DBC *cursor;
2887+ PyObject* list;
2888+ PyObject* item = NULL;
2889+
2890+ CHECK_DB_NOT_CLOSED(self);
2891+ CLEAR_DBT(key);
2892+ CLEAR_DBT(data);
2893+
2894+ dbtype = _DB_get_type(self);
2895+ if (dbtype == -1)
2896+ return NULL;
2897+
2898+ list = PyList_New(0);
2899+ if (list == NULL)
2900+ return NULL;
2901+
2902+ /* get a cursor */
2903+ MYDB_BEGIN_ALLOW_THREADS;
2904+ err = self->db->cursor(self->db, txn, &cursor, 0);
2905+ MYDB_END_ALLOW_THREADS;
2906+ if (makeDBError(err)) {
2907+ Py_DECREF(list);
2908+ return NULL;
2909+ }
2910+
2911+ if (CHECK_DBFLAG(self, DB_THREAD)) {
2912+ key.flags = DB_DBT_REALLOC;
2913+ data.flags = DB_DBT_REALLOC;
2914+ }
2915+
2916+ while (1) { /* use the cursor to traverse the DB, collecting items */
2917+ MYDB_BEGIN_ALLOW_THREADS;
2918+ err = cursor->c_get(cursor, &key, &data, DB_NEXT);
2919+ MYDB_END_ALLOW_THREADS;
2920+
2921+ if (err) {
2922+ /* for any error, break out of the loop */
2923+ break;
2924+ }
2925+
2926+ switch (type) {
2927+ case _KEYS_LIST:
2928+ switch(dbtype) {
2929+ case DB_BTREE:
2930+ case DB_HASH:
2931+ default:
2932+ item = PyString_FromStringAndSize((char*)key.data, key.size);
2933+ break;
2934+ case DB_RECNO:
2935+ case DB_QUEUE:
2936+ item = PyInt_FromLong(*((db_recno_t*)key.data));
2937+ break;
2938+ }
2939+ break;
2940+
2941+ case _VALUES_LIST:
2942+ item = PyString_FromStringAndSize((char*)data.data, data.size);
2943+ break;
2944+
2945+ case _ITEMS_LIST:
2946+ switch(dbtype) {
2947+ case DB_BTREE:
2948+ case DB_HASH:
2949+ default:
2950+ item = Py_BuildValue("s#s#", key.data, key.size, data.data,
2951+ data.size);
2952+ break;
2953+ case DB_RECNO:
2954+ case DB_QUEUE:
2955+ item = Py_BuildValue("is#", *((db_recno_t*)key.data),
2956+ data.data, data.size);
2957+ break;
2958+ }
2959+ break;
2960+ default:
2961+ PyErr_Format(PyExc_ValueError, "Unknown key type 0x%x", type);
2962+ item = NULL;
2963+ break;
2964+ }
2965+ if (item == NULL) {
2966+ Py_DECREF(list);
2967+ list = NULL;
2968+ goto done;
2969+ }
2970+ PyList_Append(list, item);
2971+ Py_DECREF(item);
2972+ }
2973+
2974+ /* DB_NOTFOUND || DB_KEYEMPTY is okay, it means we got to the end */
2975+ if (err != DB_NOTFOUND && err != DB_KEYEMPTY && makeDBError(err)) {
2976+ Py_DECREF(list);
2977+ list = NULL;
2978+ }
2979+
2980+ done:
2981+ FREE_DBT(key);
2982+ FREE_DBT(data);
2983+ MYDB_BEGIN_ALLOW_THREADS;
2984+ cursor->c_close(cursor);
2985+ MYDB_END_ALLOW_THREADS;
2986+ return list;
2987+}
2988+
2989+
2990+static PyObject*
2991+DB_keys(DBObject* self, PyObject* args)
2992+{
2993+ PyObject* txnobj = NULL;
2994+ DB_TXN *txn = NULL;
2995+
2996+ if (!PyArg_UnpackTuple(args, "keys", 0, 1, &txnobj))
2997+ return NULL;
2998+ if (!checkTxnObj(txnobj, &txn))
2999+ return NULL;
3000+ return _DB_make_list(self, txn, _KEYS_LIST);
3001+}
3002+
3003+
3004+static PyObject*
3005+DB_items(DBObject* self, PyObject* args)
3006+{
3007+ PyObject* txnobj = NULL;
3008+ DB_TXN *txn = NULL;
3009+
3010+ if (!PyArg_UnpackTuple(args, "items", 0, 1, &txnobj))
3011+ return NULL;
3012+ if (!checkTxnObj(txnobj, &txn))
3013+ return NULL;
3014+ return _DB_make_list(self, txn, _ITEMS_LIST);
3015+}
3016+
3017+
3018+static PyObject*
3019+DB_values(DBObject* self, PyObject* args)
3020+{
3021+ PyObject* txnobj = NULL;
3022+ DB_TXN *txn = NULL;
3023+
3024+ if (!PyArg_UnpackTuple(args, "values", 0, 1, &txnobj))
3025+ return NULL;
3026+ if (!checkTxnObj(txnobj, &txn))
3027+ return NULL;
3028+ return _DB_make_list(self, txn, _VALUES_LIST);
3029+}
3030+
3031+/* --------------------------------------------------------------------- */
3032+/* DBCursor methods */
3033+
3034+
3035+static PyObject*
3036+DBC_close(DBCursorObject* self, PyObject* args)
3037+{
3038+ int err = 0;
3039+
3040+ if (!PyArg_ParseTuple(args, ":close"))
3041+ return NULL;
3042+
3043+ if (self->dbc != NULL) {
3044+ MYDB_BEGIN_ALLOW_THREADS;
3045+ err = self->dbc->c_close(self->dbc);
3046+ self->dbc = NULL;
3047+ MYDB_END_ALLOW_THREADS;
3048+ }
3049+ RETURN_IF_ERR();
3050+ RETURN_NONE();
3051+}
3052+
3053+
3054+static PyObject*
3055+DBC_count(DBCursorObject* self, PyObject* args)
3056+{
3057+ int err = 0;
3058+ db_recno_t count;
3059+ int flags = 0;
3060+
3061+ if (!PyArg_ParseTuple(args, "|i:count", &flags))
3062+ return NULL;
3063+
3064+ CHECK_CURSOR_NOT_CLOSED(self);
3065+
3066+ MYDB_BEGIN_ALLOW_THREADS;
3067+ err = self->dbc->c_count(self->dbc, &count, flags);
3068+ MYDB_END_ALLOW_THREADS;
3069+ RETURN_IF_ERR();
3070+
3071+ return PyInt_FromLong(count);
3072+}
3073+
3074+
3075+static PyObject*
3076+DBC_current(DBCursorObject* self, PyObject* args, PyObject *kwargs)
3077+{
3078+ return _DBCursor_get(self,DB_CURRENT,args,kwargs,"|iii:current");
3079+}
3080+
3081+
3082+static PyObject*
3083+DBC_delete(DBCursorObject* self, PyObject* args)
3084+{
3085+ int err, flags=0;
3086+
3087+ if (!PyArg_ParseTuple(args, "|i:delete", &flags))
3088+ return NULL;
3089+
3090+ CHECK_CURSOR_NOT_CLOSED(self);
3091+
3092+ MYDB_BEGIN_ALLOW_THREADS;
3093+ err = self->dbc->c_del(self->dbc, flags);
3094+ MYDB_END_ALLOW_THREADS;
3095+ RETURN_IF_ERR();
3096+
3097+ self->mydb->haveStat = 0;
3098+ RETURN_NONE();
3099+}
3100+
3101+
3102+static PyObject*
3103+DBC_dup(DBCursorObject* self, PyObject* args)
3104+{
3105+ int err, flags =0;
3106+ DBC* dbc = NULL;
3107+
3108+ if (!PyArg_ParseTuple(args, "|i:dup", &flags))
3109+ return NULL;
3110+
3111+ CHECK_CURSOR_NOT_CLOSED(self);
3112+
3113+ MYDB_BEGIN_ALLOW_THREADS;
3114+ err = self->dbc->c_dup(self->dbc, &dbc, flags);
3115+ MYDB_END_ALLOW_THREADS;
3116+ RETURN_IF_ERR();
3117+
3118+ return (PyObject*) newDBCursorObject(dbc, self->mydb);
3119+}
3120+
3121+static PyObject*
3122+DBC_first(DBCursorObject* self, PyObject* args, PyObject* kwargs)
3123+{
3124+ return _DBCursor_get(self,DB_FIRST,args,kwargs,"|iii:first");
3125+}
3126+
3127+
3128+static PyObject*
3129+DBC_get(DBCursorObject* self, PyObject* args, PyObject *kwargs)
3130+{
3131+ int err, flags=0;
3132+ PyObject* keyobj = NULL;
3133+ PyObject* dataobj = NULL;
3134+ PyObject* retval = NULL;
3135+ int dlen = -1;
3136+ int doff = -1;
3137+ DBT key, data;
3138+ static char* kwnames[] = { "key","data", "flags", "dlen", "doff",
3139+ NULL };
3140+
3141+ CLEAR_DBT(key);
3142+ CLEAR_DBT(data);
3143+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:get", &kwnames[2],
3144+ &flags, &dlen, &doff))
3145+ {
3146+ PyErr_Clear();
3147+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:get",
3148+ &kwnames[1],
3149+ &keyobj, &flags, &dlen, &doff))
3150+ {
3151+ PyErr_Clear();
3152+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOi|ii:get",
3153+ kwnames, &keyobj, &dataobj,
3154+ &flags, &dlen, &doff))
3155+ {
3156+ return NULL;
3157+ }
3158+ }
3159+ }
3160+
3161+ CHECK_CURSOR_NOT_CLOSED(self);
3162+
3163+ if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL))
3164+ return NULL;
3165+ if ( (dataobj && !make_dbt(dataobj, &data)) ||
3166+ (!add_partial_dbt(&data, dlen, doff)) )
3167+ {
3168+ FREE_DBT(key);
3169+ return NULL;
3170+ }
3171+
3172+ if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
3173+ data.flags = DB_DBT_MALLOC;
3174+ if (!(key.flags & DB_DBT_REALLOC)) {
3175+ key.flags |= DB_DBT_MALLOC;
3176+ }
3177+ }
3178+
3179+ MYDB_BEGIN_ALLOW_THREADS;
3180+ err = self->dbc->c_get(self->dbc, &key, &data, flags);
3181+ MYDB_END_ALLOW_THREADS;
3182+
3183+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
3184+ && self->mydb->moduleFlags.getReturnsNone) {
3185+ Py_INCREF(Py_None);
3186+ retval = Py_None;
3187+ }
3188+ else if (makeDBError(err)) {
3189+ retval = NULL;
3190+ }
3191+ else {
3192+ switch (_DB_get_type(self->mydb)) {
3193+ case -1:
3194+ retval = NULL;
3195+ break;
3196+ case DB_BTREE:
3197+ case DB_HASH:
3198+ default:
3199+ retval = Py_BuildValue("s#s#", key.data, key.size,
3200+ data.data, data.size);
3201+ break;
3202+ case DB_RECNO:
3203+ case DB_QUEUE:
3204+ retval = Py_BuildValue("is#", *((db_recno_t*)key.data),
3205+ data.data, data.size);
3206+ break;
3207+ }
3208+ FREE_DBT(data);
3209+ }
3210+ FREE_DBT(key);
3211+ return retval;
3212+}
3213+
3214+#if (DBVER >= 33)
3215+static PyObject*
3216+DBC_pget(DBCursorObject* self, PyObject* args, PyObject *kwargs)
3217+{
3218+ int err, flags=0;
3219+ PyObject* keyobj = NULL;
3220+ PyObject* dataobj = NULL;
3221+ PyObject* retval = NULL;
3222+ int dlen = -1;
3223+ int doff = -1;
3224+ DBT key, pkey, data;
3225+ static char* kwnames_keyOnly[] = { "key", "flags", "dlen", "doff", NULL };
3226+ static char* kwnames[] = { "key", "data", "flags", "dlen", "doff", NULL };
3227+
3228+ CLEAR_DBT(key);
3229+ CLEAR_DBT(data);
3230+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:pget", &kwnames[2],
3231+ &flags, &dlen, &doff))
3232+ {
3233+ PyErr_Clear();
3234+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:pget",
3235+ kwnames_keyOnly,
3236+ &keyobj, &flags, &dlen, &doff))
3237+ {
3238+ PyErr_Clear();
3239+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOi|ii:pget",
3240+ kwnames, &keyobj, &dataobj,
3241+ &flags, &dlen, &doff))
3242+ {
3243+ return NULL;
3244+ }
3245+ }
3246+ }
3247+
3248+ CHECK_CURSOR_NOT_CLOSED(self);
3249+
3250+ if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL))
3251+ return NULL;
3252+ if ( (dataobj && !make_dbt(dataobj, &data)) ||
3253+ (!add_partial_dbt(&data, dlen, doff)) ) {
3254+ FREE_DBT(key);
3255+ return NULL;
3256+ }
3257+
3258+ if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
3259+ data.flags = DB_DBT_MALLOC;
3260+ if (!(key.flags & DB_DBT_REALLOC)) {
3261+ key.flags |= DB_DBT_MALLOC;
3262+ }
3263+ }
3264+
3265+ CLEAR_DBT(pkey);
3266+ pkey.flags = DB_DBT_MALLOC;
3267+
3268+ MYDB_BEGIN_ALLOW_THREADS;
3269+ err = self->dbc->c_pget(self->dbc, &key, &pkey, &data, flags);
3270+ MYDB_END_ALLOW_THREADS;
3271+
3272+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
3273+ && self->mydb->moduleFlags.getReturnsNone) {
3274+ Py_INCREF(Py_None);
3275+ retval = Py_None;
3276+ }
3277+ else if (makeDBError(err)) {
3278+ retval = NULL;
3279+ }
3280+ else {
3281+ PyObject *pkeyObj;
3282+ PyObject *dataObj;
3283+ dataObj = PyString_FromStringAndSize(data.data, data.size);
3284+
3285+ if (self->mydb->primaryDBType == DB_RECNO ||
3286+ self->mydb->primaryDBType == DB_QUEUE)
3287+ pkeyObj = PyInt_FromLong(*(int *)pkey.data);
3288+ else
3289+ pkeyObj = PyString_FromStringAndSize(pkey.data, pkey.size);
3290+
3291+ if (key.data && key.size) /* return key, pkey and data */
3292+ {
3293+ PyObject *keyObj;
3294+ int type = _DB_get_type(self->mydb);
3295+ if (type == DB_RECNO || type == DB_QUEUE)
3296+ keyObj = PyInt_FromLong(*(int *)key.data);
3297+ else
3298+ keyObj = PyString_FromStringAndSize(key.data, key.size);
3299+#if (PY_VERSION_HEX >= 0x02040000)
3300+ retval = PyTuple_Pack(3, keyObj, pkeyObj, dataObj);
3301+#else
3302+ retval = Py_BuildValue("OOO", keyObj, pkeyObj, dataObj);
3303+#endif
3304+ Py_DECREF(keyObj);
3305+ FREE_DBT(key);
3306+ }
3307+ else /* return just the pkey and data */
3308+ {
3309+#if (PY_VERSION_HEX >= 0x02040000)
3310+ retval = PyTuple_Pack(2, pkeyObj, dataObj);
3311+#else
3312+ retval = Py_BuildValue("OO", pkeyObj, dataObj);
3313+#endif
3314+ }
3315+ Py_DECREF(dataObj);
3316+ Py_DECREF(pkeyObj);
3317+ FREE_DBT(pkey);
3318+ FREE_DBT(data);
3319+ }
3320+ /* the only time REALLOC should be set is if we used an integer
3321+ * key that make_key_dbt malloc'd for us. always free these. */
3322+ if (key.flags & DB_DBT_REALLOC) {
3323+ FREE_DBT(key);
3324+ }
3325+ return retval;
3326+}
3327+#endif
3328+
3329+
3330+static PyObject*
3331+DBC_get_recno(DBCursorObject* self, PyObject* args)
3332+{
3333+ int err;
3334+ db_recno_t recno;
3335+ DBT key;
3336+ DBT data;
3337+
3338+ if (!PyArg_ParseTuple(args, ":get_recno"))
3339+ return NULL;
3340+
3341+ CHECK_CURSOR_NOT_CLOSED(self);
3342+
3343+ CLEAR_DBT(key);
3344+ CLEAR_DBT(data);
3345+ if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
3346+ /* Tell BerkeleyDB to malloc the return value (thread safe) */
3347+ data.flags = DB_DBT_MALLOC;
3348+ key.flags = DB_DBT_MALLOC;
3349+ }
3350+
3351+ MYDB_BEGIN_ALLOW_THREADS;
3352+ err = self->dbc->c_get(self->dbc, &key, &data, DB_GET_RECNO);
3353+ MYDB_END_ALLOW_THREADS;
3354+ RETURN_IF_ERR();
3355+
3356+ recno = *((db_recno_t*)data.data);
3357+ FREE_DBT(key);
3358+ FREE_DBT(data);
3359+ return PyInt_FromLong(recno);
3360+}
3361+
3362+
3363+static PyObject*
3364+DBC_last(DBCursorObject* self, PyObject* args, PyObject *kwargs)
3365+{
3366+ return _DBCursor_get(self,DB_LAST,args,kwargs,"|iii:last");
3367+}
3368+
3369+
3370+static PyObject*
3371+DBC_next(DBCursorObject* self, PyObject* args, PyObject *kwargs)
3372+{
3373+ return _DBCursor_get(self,DB_NEXT,args,kwargs,"|iii:next");
3374+}
3375+
3376+
3377+static PyObject*
3378+DBC_prev(DBCursorObject* self, PyObject* args, PyObject *kwargs)
3379+{
3380+ return _DBCursor_get(self,DB_PREV,args,kwargs,"|iii:prev");
3381+}
3382+
3383+
3384+static PyObject*
3385+DBC_put(DBCursorObject* self, PyObject* args, PyObject* kwargs)
3386+{
3387+ int err, flags = 0;
3388+ PyObject* keyobj, *dataobj;
3389+ DBT key, data;
3390+ static char* kwnames[] = { "key", "data", "flags", "dlen", "doff",
3391+ NULL };
3392+ int dlen = -1;
3393+ int doff = -1;
3394+
3395+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iii:put", kwnames,
3396+ &keyobj, &dataobj, &flags, &dlen, &doff))
3397+ return NULL;
3398+
3399+ CHECK_CURSOR_NOT_CLOSED(self);
3400+
3401+ if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
3402+ return NULL;
3403+ if (!make_dbt(dataobj, &data) ||
3404+ !add_partial_dbt(&data, dlen, doff) )
3405+ {
3406+ FREE_DBT(key);
3407+ return NULL;
3408+ }
3409+
3410+ MYDB_BEGIN_ALLOW_THREADS;
3411+ err = self->dbc->c_put(self->dbc, &key, &data, flags);
3412+ MYDB_END_ALLOW_THREADS;
3413+ FREE_DBT(key);
3414+ RETURN_IF_ERR();
3415+ self->mydb->haveStat = 0;
3416+ RETURN_NONE();
3417+}
3418+
3419+
3420+static PyObject*
3421+DBC_set(DBCursorObject* self, PyObject* args, PyObject *kwargs)
3422+{
3423+ int err, flags = 0;
3424+ DBT key, data;
3425+ PyObject* retval, *keyobj;
3426+ static char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
3427+ int dlen = -1;
3428+ int doff = -1;
3429+
3430+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iii:set", kwnames,
3431+ &keyobj, &flags, &dlen, &doff))
3432+ return NULL;
3433+
3434+ CHECK_CURSOR_NOT_CLOSED(self);
3435+
3436+ if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
3437+ return NULL;
3438+
3439+ CLEAR_DBT(data);
3440+ if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
3441+ /* Tell BerkeleyDB to malloc the return value (thread safe) */
3442+ data.flags = DB_DBT_MALLOC;
3443+ }
3444+ if (!add_partial_dbt(&data, dlen, doff)) {
3445+ FREE_DBT(key);
3446+ return NULL;
3447+ }
3448+
3449+ MYDB_BEGIN_ALLOW_THREADS;
3450+ err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_SET);
3451+ MYDB_END_ALLOW_THREADS;
3452+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
3453+ && self->mydb->moduleFlags.cursorSetReturnsNone) {
3454+ Py_INCREF(Py_None);
3455+ retval = Py_None;
3456+ }
3457+ else if (makeDBError(err)) {
3458+ retval = NULL;
3459+ }
3460+ else {
3461+ switch (_DB_get_type(self->mydb)) {
3462+ case -1:
3463+ retval = NULL;
3464+ break;
3465+ case DB_BTREE:
3466+ case DB_HASH:
3467+ default:
3468+ retval = Py_BuildValue("s#s#", key.data, key.size,
3469+ data.data, data.size);
3470+ break;
3471+ case DB_RECNO:
3472+ case DB_QUEUE:
3473+ retval = Py_BuildValue("is#", *((db_recno_t*)key.data),
3474+ data.data, data.size);
3475+ break;
3476+ }
3477+ FREE_DBT(data);
3478+ FREE_DBT(key);
3479+ }
3480+ /* the only time REALLOC should be set is if we used an integer
3481+ * key that make_key_dbt malloc'd for us. always free these. */
3482+ if (key.flags & DB_DBT_REALLOC) {
3483+ FREE_DBT(key);
3484+ }
3485+
3486+ return retval;
3487+}
3488+
3489+
3490+static PyObject*
3491+DBC_set_range(DBCursorObject* self, PyObject* args, PyObject* kwargs)
3492+{
3493+ int err, flags = 0;
3494+ DBT key, data;
3495+ PyObject* retval, *keyobj;
3496+ static char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
3497+ int dlen = -1;
3498+ int doff = -1;
3499+
3500+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iii:set_range", kwnames,
3501+ &keyobj, &flags, &dlen, &doff))
3502+ return NULL;
3503+
3504+ CHECK_CURSOR_NOT_CLOSED(self);
3505+
3506+ if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
3507+ return NULL;
3508+
3509+ CLEAR_DBT(data);
3510+ if (!add_partial_dbt(&data, dlen, doff)) {
3511+ FREE_DBT(key);
3512+ return NULL;
3513+ }
3514+ if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
3515+ /* Tell BerkeleyDB to malloc the return value (thread safe) */
3516+ data.flags |= DB_DBT_MALLOC;
3517+ /* only BTREE databases will return anything in the key */
3518+ if (!(key.flags & DB_DBT_REALLOC) && _DB_get_type(self->mydb) == DB_BTREE) {
3519+ key.flags |= DB_DBT_MALLOC;
3520+ }
3521+ }
3522+ MYDB_BEGIN_ALLOW_THREADS;
3523+ err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_SET_RANGE);
3524+ MYDB_END_ALLOW_THREADS;
3525+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
3526+ && self->mydb->moduleFlags.cursorSetReturnsNone) {
3527+ Py_INCREF(Py_None);
3528+ retval = Py_None;
3529+ }
3530+ else if (makeDBError(err)) {
3531+ retval = NULL;
3532+ }
3533+ else {
3534+ switch (_DB_get_type(self->mydb)) {
3535+ case -1:
3536+ retval = NULL;
3537+ break;
3538+ case DB_BTREE:
3539+ case DB_HASH:
3540+ default:
3541+ retval = Py_BuildValue("s#s#", key.data, key.size,
3542+ data.data, data.size);
3543+ break;
3544+ case DB_RECNO:
3545+ case DB_QUEUE:
3546+ retval = Py_BuildValue("is#", *((db_recno_t*)key.data),
3547+ data.data, data.size);
3548+ break;
3549+ }
3550+ FREE_DBT(key);
3551+ FREE_DBT(data);
3552+ }
3553+ /* the only time REALLOC should be set is if we used an integer
3554+ * key that make_key_dbt malloc'd for us. always free these. */
3555+ if (key.flags & DB_DBT_REALLOC) {
3556+ FREE_DBT(key);
3557+ }
3558+
3559+ return retval;
3560+}
3561+
3562+static PyObject*
3563+_DBC_get_set_both(DBCursorObject* self, PyObject* keyobj, PyObject* dataobj,
3564+ int flags, unsigned int returnsNone)
3565+{
3566+ int err;
3567+ DBT key, data;
3568+ PyObject* retval;
3569+
3570+ /* the caller did this: CHECK_CURSOR_NOT_CLOSED(self); */
3571+ if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
3572+ return NULL;
3573+ if (!make_dbt(dataobj, &data)) {
3574+ FREE_DBT(key);
3575+ return NULL;
3576+ }
3577+
3578+ MYDB_BEGIN_ALLOW_THREADS;
3579+ err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_GET_BOTH);
3580+ MYDB_END_ALLOW_THREADS;
3581+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && returnsNone) {
3582+ Py_INCREF(Py_None);
3583+ retval = Py_None;
3584+ }
3585+ else if (makeDBError(err)) {
3586+ retval = NULL;
3587+ }
3588+ else {
3589+ switch (_DB_get_type(self->mydb)) {
3590+ case -1:
3591+ retval = NULL;
3592+ break;
3593+ case DB_BTREE:
3594+ case DB_HASH:
3595+ default:
3596+ retval = Py_BuildValue("s#s#", key.data, key.size,
3597+ data.data, data.size);
3598+ break;
3599+ case DB_RECNO:
3600+ case DB_QUEUE:
3601+ retval = Py_BuildValue("is#", *((db_recno_t*)key.data),
3602+ data.data, data.size);
3603+ break;
3604+ }
3605+ }
3606+
3607+ FREE_DBT(key);
3608+ return retval;
3609+}
3610+
3611+static PyObject*
3612+DBC_get_both(DBCursorObject* self, PyObject* args)
3613+{
3614+ int flags=0;
3615+ PyObject *keyobj, *dataobj;
3616+
3617+ if (!PyArg_ParseTuple(args, "OO|i:get_both", &keyobj, &dataobj, &flags))
3618+ return NULL;
3619+
3620+ /* if the cursor is closed, self->mydb may be invalid */
3621+ CHECK_CURSOR_NOT_CLOSED(self);
3622+
3623+ return _DBC_get_set_both(self, keyobj, dataobj, flags,
3624+ self->mydb->moduleFlags.getReturnsNone);
3625+}
3626+
3627+/* Return size of entry */
3628+static PyObject*
3629+DBC_get_current_size(DBCursorObject* self, PyObject* args)
3630+{
3631+ int err, flags=DB_CURRENT;
3632+ PyObject* retval = NULL;
3633+ DBT key, data;
3634+
3635+ if (!PyArg_ParseTuple(args, ":get_current_size"))
3636+ return NULL;
3637+ CHECK_CURSOR_NOT_CLOSED(self);
3638+ CLEAR_DBT(key);
3639+ CLEAR_DBT(data);
3640+
3641+ /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and thus
3642+ getting the record size. */
3643+ data.flags = DB_DBT_USERMEM;
3644+ data.ulen = 0;
3645+ MYDB_BEGIN_ALLOW_THREADS;
3646+ err = self->dbc->c_get(self->dbc, &key, &data, flags);
3647+ MYDB_END_ALLOW_THREADS;
3648+ if (err == DB_BUFFER_SMALL || !err) {
3649+ /* DB_BUFFER_SMALL means positive size, !err means zero length value */
3650+ retval = PyInt_FromLong((long)data.size);
3651+ err = 0;
3652+ }
3653+
3654+ FREE_DBT(key);
3655+ FREE_DBT(data);
3656+ RETURN_IF_ERR();
3657+ return retval;
3658+}
3659+
3660+static PyObject*
3661+DBC_set_both(DBCursorObject* self, PyObject* args)
3662+{
3663+ int flags=0;
3664+ PyObject *keyobj, *dataobj;
3665+
3666+ if (!PyArg_ParseTuple(args, "OO|i:set_both", &keyobj, &dataobj, &flags))
3667+ return NULL;
3668+
3669+ /* if the cursor is closed, self->mydb may be invalid */
3670+ CHECK_CURSOR_NOT_CLOSED(self);
3671+
3672+ return _DBC_get_set_both(self, keyobj, dataobj, flags,
3673+ self->mydb->moduleFlags.cursorSetReturnsNone);
3674+}
3675+
3676+
3677+static PyObject*
3678+DBC_set_recno(DBCursorObject* self, PyObject* args, PyObject *kwargs)
3679+{
3680+ int err, irecno, flags=0;
3681+ db_recno_t recno;
3682+ DBT key, data;
3683+ PyObject* retval;
3684+ int dlen = -1;
3685+ int doff = -1;
3686+ static char* kwnames[] = { "recno","flags", "dlen", "doff", NULL };
3687+
3688+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|iii:set_recno", kwnames,
3689+ &irecno, &flags, &dlen, &doff))
3690+ return NULL;
3691+
3692+ CHECK_CURSOR_NOT_CLOSED(self);
3693+
3694+ CLEAR_DBT(key);
3695+ recno = (db_recno_t) irecno;
3696+ /* use allocated space so DB will be able to realloc room for the real
3697+ * key */
3698+ key.data = malloc(sizeof(db_recno_t));
3699+ if (key.data == NULL) {
3700+ PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
3701+ return NULL;
3702+ }
3703+ key.size = sizeof(db_recno_t);
3704+ key.ulen = key.size;
3705+ memcpy(key.data, &recno, sizeof(db_recno_t));
3706+ key.flags = DB_DBT_REALLOC;
3707+
3708+ CLEAR_DBT(data);
3709+ if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
3710+ /* Tell BerkeleyDB to malloc the return value (thread safe) */
3711+ data.flags = DB_DBT_MALLOC;
3712+ }
3713+ if (!add_partial_dbt(&data, dlen, doff)) {
3714+ FREE_DBT(key);
3715+ return NULL;
3716+ }
3717+
3718+ MYDB_BEGIN_ALLOW_THREADS;
3719+ err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_SET_RECNO);
3720+ MYDB_END_ALLOW_THREADS;
3721+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
3722+ && self->mydb->moduleFlags.cursorSetReturnsNone) {
3723+ Py_INCREF(Py_None);
3724+ retval = Py_None;
3725+ }
3726+ else if (makeDBError(err)) {
3727+ retval = NULL;
3728+ }
3729+ else { /* Can only be used for BTrees, so no need to return int key */
3730+ retval = Py_BuildValue("s#s#", key.data, key.size,
3731+ data.data, data.size);
3732+ FREE_DBT(data);
3733+ }
3734+ FREE_DBT(key);
3735+
3736+ return retval;
3737+}
3738+
3739+
3740+static PyObject*
3741+DBC_consume(DBCursorObject* self, PyObject* args, PyObject *kwargs)
3742+{
3743+ return _DBCursor_get(self,DB_CONSUME,args,kwargs,"|iii:consume");
3744+}
3745+
3746+
3747+static PyObject*
3748+DBC_next_dup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
3749+{
3750+ return _DBCursor_get(self,DB_NEXT_DUP,args,kwargs,"|iii:next_dup");
3751+}
3752+
3753+
3754+static PyObject*
3755+DBC_next_nodup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
3756+{
3757+ return _DBCursor_get(self,DB_NEXT_NODUP,args,kwargs,"|iii:next_nodup");
3758+}
3759+
3760+
3761+static PyObject*
3762+DBC_prev_nodup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
3763+{
3764+ return _DBCursor_get(self,DB_PREV_NODUP,args,kwargs,"|iii:prev_nodup");
3765+}
3766+
3767+
3768+static PyObject*
3769+DBC_join_item(DBCursorObject* self, PyObject* args)
3770+{
3771+ int err, flags=0;
3772+ DBT key, data;
3773+ PyObject* retval;
3774+
3775+ if (!PyArg_ParseTuple(args, "|i:join_item", &flags))
3776+ return NULL;
3777+
3778+ CHECK_CURSOR_NOT_CLOSED(self);
3779+
3780+ CLEAR_DBT(key);
3781+ CLEAR_DBT(data);
3782+ if (CHECK_DBFLAG(self->mydb, DB_THREAD)) {
3783+ /* Tell BerkeleyDB to malloc the return value (thread safe) */
3784+ key.flags = DB_DBT_MALLOC;
3785+ }
3786+
3787+ MYDB_BEGIN_ALLOW_THREADS;
3788+ err = self->dbc->c_get(self->dbc, &key, &data, flags | DB_JOIN_ITEM);
3789+ MYDB_END_ALLOW_THREADS;
3790+ if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
3791+ && self->mydb->moduleFlags.getReturnsNone) {
3792+ Py_INCREF(Py_None);
3793+ retval = Py_None;
3794+ }
3795+ else if (makeDBError(err)) {
3796+ retval = NULL;
3797+ }
3798+ else {
3799+ retval = Py_BuildValue("s#", key.data, key.size);
3800+ FREE_DBT(key);
3801+ }
3802+
3803+ return retval;
3804+}
3805+
3806+
3807+
3808+/* --------------------------------------------------------------------- */
3809+/* DBEnv methods */
3810+
3811+
3812+static PyObject*
3813+DBEnv_close(DBEnvObject* self, PyObject* args)
3814+{
3815+ int err, flags = 0;
3816+
3817+ if (!PyArg_ParseTuple(args, "|i:close", &flags))
3818+ return NULL;
3819+ if (!self->closed) { /* Don't close more than once */
3820+ MYDB_BEGIN_ALLOW_THREADS;
3821+ err = self->db_env->close(self->db_env, flags);
3822+ MYDB_END_ALLOW_THREADS;
3823+ /* after calling DBEnv->close, regardless of error, this DBEnv
3824+ * may not be accessed again (BerkeleyDB docs). */
3825+ self->closed = 1;
3826+ self->db_env = NULL;
3827+ RETURN_IF_ERR();
3828+ }
3829+ RETURN_NONE();
3830+}
3831+
3832+
3833+static PyObject*
3834+DBEnv_open(DBEnvObject* self, PyObject* args)
3835+{
3836+ int err, flags=0, mode=0660;
3837+ char *db_home;
3838+
3839+ if (!PyArg_ParseTuple(args, "z|ii:open", &db_home, &flags, &mode))
3840+ return NULL;
3841+
3842+ CHECK_ENV_NOT_CLOSED(self);
3843+
3844+ MYDB_BEGIN_ALLOW_THREADS;
3845+ err = self->db_env->open(self->db_env, db_home, flags, mode);
3846+ MYDB_END_ALLOW_THREADS;
3847+ RETURN_IF_ERR();
3848+ self->closed = 0;
3849+ self->flags = flags;
3850+ RETURN_NONE();
3851+}
3852+
3853+
3854+static PyObject*
3855+DBEnv_remove(DBEnvObject* self, PyObject* args)
3856+{
3857+ int err, flags=0;
3858+ char *db_home;
3859+
3860+ if (!PyArg_ParseTuple(args, "s|i:remove", &db_home, &flags))
3861+ return NULL;
3862+ CHECK_ENV_NOT_CLOSED(self);
3863+ MYDB_BEGIN_ALLOW_THREADS;
3864+ err = self->db_env->remove(self->db_env, db_home, flags);
3865+ MYDB_END_ALLOW_THREADS;
3866+ RETURN_IF_ERR();
3867+ RETURN_NONE();
3868+}
3869+
3870+#if (DBVER >= 41)
3871+static PyObject*
3872+DBEnv_dbremove(DBEnvObject* self, PyObject* args, PyObject* kwargs)
3873+{
3874+ int err;
3875+ u_int32_t flags=0;
3876+ char *file = NULL;
3877+ char *database = NULL;
3878+ PyObject *txnobj = NULL;
3879+ DB_TXN *txn = NULL;
3880+ static char* kwnames[] = { "file", "database", "txn", "flags",
3881+ NULL };
3882+
3883+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zOi:dbremove", kwnames,
3884+ &file, &database, &txnobj, &flags)) {
3885+ return NULL;
3886+ }
3887+ if (!checkTxnObj(txnobj, &txn)) {
3888+ return NULL;
3889+ }
3890+ CHECK_ENV_NOT_CLOSED(self);
3891+ MYDB_BEGIN_ALLOW_THREADS;
3892+ err = self->db_env->dbremove(self->db_env, txn, file, database, flags);
3893+ MYDB_END_ALLOW_THREADS;
3894+ RETURN_IF_ERR();
3895+ RETURN_NONE();
3896+}
3897+
3898+static PyObject*
3899+DBEnv_dbrename(DBEnvObject* self, PyObject* args, PyObject* kwargs)
3900+{
3901+ int err;
3902+ u_int32_t flags=0;
3903+ char *file = NULL;
3904+ char *database = NULL;
3905+ char *newname = NULL;
3906+ PyObject *txnobj = NULL;
3907+ DB_TXN *txn = NULL;
3908+ static char* kwnames[] = { "file", "database", "newname", "txn",
3909+ "flags", NULL };
3910+
3911+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "szs|Oi:dbrename", kwnames,
3912+ &file, &database, &newname, &txnobj, &flags)) {
3913+ return NULL;
3914+ }
3915+ if (!checkTxnObj(txnobj, &txn)) {
3916+ return NULL;
3917+ }
3918+ CHECK_ENV_NOT_CLOSED(self);
3919+ MYDB_BEGIN_ALLOW_THREADS;
3920+ err = self->db_env->dbrename(self->db_env, txn, file, database, newname,
3921+ flags);
3922+ MYDB_END_ALLOW_THREADS;
3923+ RETURN_IF_ERR();
3924+ RETURN_NONE();
3925+}
3926+
3927+static PyObject*
3928+DBEnv_set_encrypt(DBEnvObject* self, PyObject* args, PyObject* kwargs)
3929+{
3930+ int err;
3931+ u_int32_t flags=0;
3932+ char *passwd = NULL;
3933+ static char* kwnames[] = { "passwd", "flags", NULL };
3934+
3935+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
3936+ &passwd, &flags)) {
3937+ return NULL;
3938+ }
3939+
3940+ MYDB_BEGIN_ALLOW_THREADS;
3941+ err = self->db_env->set_encrypt(self->db_env, passwd, flags);
3942+ MYDB_END_ALLOW_THREADS;
3943+
3944+ RETURN_IF_ERR();
3945+ RETURN_NONE();
3946+}
3947+#endif /* DBVER >= 41 */
3948+
3949+#if (DBVER >= 40)
3950+static PyObject*
3951+DBEnv_set_timeout(DBEnvObject* self, PyObject* args, PyObject* kwargs)
3952+{
3953+ int err;
3954+ u_int32_t flags=0;
3955+ u_int32_t timeout = 0;
3956+ static char* kwnames[] = { "timeout", "flags", NULL };
3957+
3958+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:set_timeout", kwnames,
3959+ &timeout, &flags)) {
3960+ return NULL;
3961+ }
3962+
3963+ MYDB_BEGIN_ALLOW_THREADS;
3964+ err = self->db_env->set_timeout(self->db_env, (db_timeout_t)timeout, flags);
3965+ MYDB_END_ALLOW_THREADS;
3966+
3967+ RETURN_IF_ERR();
3968+ RETURN_NONE();
3969+}
3970+#endif /* DBVER >= 40 */
3971+
3972+static PyObject*
3973+DBEnv_set_shm_key(DBEnvObject* self, PyObject* args)
3974+{
3975+ int err;
3976+ long shm_key = 0;
3977+
3978+ if (!PyArg_ParseTuple(args, "l:set_shm_key", &shm_key))
3979+ return NULL;
3980+ CHECK_ENV_NOT_CLOSED(self);
3981+
3982+ err = self->db_env->set_shm_key(self->db_env, shm_key);
3983+ RETURN_IF_ERR();
3984+ RETURN_NONE();
3985+}
3986+
3987+static PyObject*
3988+DBEnv_set_cachesize(DBEnvObject* self, PyObject* args)
3989+{
3990+ int err, gbytes=0, bytes=0, ncache=0;
3991+
3992+ if (!PyArg_ParseTuple(args, "ii|i:set_cachesize",
3993+ &gbytes, &bytes, &ncache))
3994+ return NULL;
3995+ CHECK_ENV_NOT_CLOSED(self);
3996+
3997+ MYDB_BEGIN_ALLOW_THREADS;
3998+ err = self->db_env->set_cachesize(self->db_env, gbytes, bytes, ncache);
3999+ MYDB_END_ALLOW_THREADS;
4000+ RETURN_IF_ERR();
4001+ RETURN_NONE();
4002+}
4003+
4004+
4005+#if (DBVER >= 32)
4006+static PyObject*
4007+DBEnv_set_flags(DBEnvObject* self, PyObject* args)
4008+{
4009+ int err, flags=0, onoff=0;
4010+
4011+ if (!PyArg_ParseTuple(args, "ii:set_flags",
4012+ &flags, &onoff))
4013+ return NULL;
4014+ CHECK_ENV_NOT_CLOSED(self);
4015+
4016+ MYDB_BEGIN_ALLOW_THREADS;
4017+ err = self->db_env->set_flags(self->db_env, flags, onoff);
4018+ MYDB_END_ALLOW_THREADS;
4019+ RETURN_IF_ERR();
4020+ RETURN_NONE();
4021+}
4022+#endif
4023+
4024+
4025+static PyObject*
4026+DBEnv_set_data_dir(DBEnvObject* self, PyObject* args)
4027+{
4028+ int err;
4029+ char *dir;
4030+
4031+ if (!PyArg_ParseTuple(args, "s:set_data_dir", &dir))
4032+ return NULL;
4033+ CHECK_ENV_NOT_CLOSED(self);
4034+
4035+ MYDB_BEGIN_ALLOW_THREADS;
4036+ err = self->db_env->set_data_dir(self->db_env, dir);
4037+ MYDB_END_ALLOW_THREADS;
4038+ RETURN_IF_ERR();
4039+ RETURN_NONE();
4040+}
4041+
4042+
4043+static PyObject*
4044+DBEnv_set_lg_bsize(DBEnvObject* self, PyObject* args)
4045+{
4046+ int err, lg_bsize;
4047+
4048+ if (!PyArg_ParseTuple(args, "i:set_lg_bsize", &lg_bsize))
4049+ return NULL;
4050+ CHECK_ENV_NOT_CLOSED(self);
4051+
4052+ MYDB_BEGIN_ALLOW_THREADS;
4053+ err = self->db_env->set_lg_bsize(self->db_env, lg_bsize);
4054+ MYDB_END_ALLOW_THREADS;
4055+ RETURN_IF_ERR();
4056+ RETURN_NONE();
4057+}
4058+
4059+
4060+static PyObject*
4061+DBEnv_set_lg_dir(DBEnvObject* self, PyObject* args)
4062+{
4063+ int err;
4064+ char *dir;
4065+
4066+ if (!PyArg_ParseTuple(args, "s:set_lg_dir", &dir))
4067+ return NULL;
4068+ CHECK_ENV_NOT_CLOSED(self);
4069+
4070+ MYDB_BEGIN_ALLOW_THREADS;
4071+ err = self->db_env->set_lg_dir(self->db_env, dir);
4072+ MYDB_END_ALLOW_THREADS;
4073+ RETURN_IF_ERR();
4074+ RETURN_NONE();
4075+}
4076+
4077+static PyObject*
4078+DBEnv_set_lg_max(DBEnvObject* self, PyObject* args)
4079+{
4080+ int err, lg_max;
4081+
4082+ if (!PyArg_ParseTuple(args, "i:set_lg_max", &lg_max))
4083+ return NULL;
4084+ CHECK_ENV_NOT_CLOSED(self);
4085+
4086+ MYDB_BEGIN_ALLOW_THREADS;
4087+ err = self->db_env->set_lg_max(self->db_env, lg_max);
4088+ MYDB_END_ALLOW_THREADS;
4089+ RETURN_IF_ERR();
4090+ RETURN_NONE();
4091+}
4092+
4093+
4094+#if (DBVER >= 33)
4095+static PyObject*
4096+DBEnv_set_lg_regionmax(DBEnvObject* self, PyObject* args)
4097+{
4098+ int err, lg_max;
4099+
4100+ if (!PyArg_ParseTuple(args, "i:set_lg_regionmax", &lg_max))
4101+ return NULL;
4102+ CHECK_ENV_NOT_CLOSED(self);
4103+
4104+ MYDB_BEGIN_ALLOW_THREADS;
4105+ err = self->db_env->set_lg_regionmax(self->db_env, lg_max);
4106+ MYDB_END_ALLOW_THREADS;
4107+ RETURN_IF_ERR();
4108+ RETURN_NONE();
4109+}
4110+#endif
4111+
4112+
4113+static PyObject*
4114+DBEnv_set_lk_detect(DBEnvObject* self, PyObject* args)
4115+{
4116+ int err, lk_detect;
4117+
4118+ if (!PyArg_ParseTuple(args, "i:set_lk_detect", &lk_detect))
4119+ return NULL;
4120+ CHECK_ENV_NOT_CLOSED(self);
4121+
4122+ MYDB_BEGIN_ALLOW_THREADS;
4123+ err = self->db_env->set_lk_detect(self->db_env, lk_detect);
4124+ MYDB_END_ALLOW_THREADS;
4125+ RETURN_IF_ERR();
4126+ RETURN_NONE();
4127+}
4128+
4129+
4130+#if (DBVER < 45)
4131+static PyObject*
4132+DBEnv_set_lk_max(DBEnvObject* self, PyObject* args)
4133+{
4134+ int err, max;
4135+
4136+ if (!PyArg_ParseTuple(args, "i:set_lk_max", &max))
4137+ return NULL;
4138+ CHECK_ENV_NOT_CLOSED(self);
4139+
4140+ MYDB_BEGIN_ALLOW_THREADS;
4141+ err = self->db_env->set_lk_max(self->db_env, max);
4142+ MYDB_END_ALLOW_THREADS;
4143+ RETURN_IF_ERR();
4144+ RETURN_NONE();
4145+}
4146+#endif
4147+
4148+
4149+#if (DBVER >= 32)
4150+
4151+static PyObject*
4152+DBEnv_set_lk_max_locks(DBEnvObject* self, PyObject* args)
4153+{
4154+ int err, max;
4155+
4156+ if (!PyArg_ParseTuple(args, "i:set_lk_max_locks", &max))
4157+ return NULL;
4158+ CHECK_ENV_NOT_CLOSED(self);
4159+
4160+ MYDB_BEGIN_ALLOW_THREADS;
4161+ err = self->db_env->set_lk_max_locks(self->db_env, max);
4162+ MYDB_END_ALLOW_THREADS;
4163+ RETURN_IF_ERR();
4164+ RETURN_NONE();
4165+}
4166+
4167+
4168+static PyObject*
4169+DBEnv_set_lk_max_lockers(DBEnvObject* self, PyObject* args)
4170+{
4171+ int err, max;
4172+
4173+ if (!PyArg_ParseTuple(args, "i:set_lk_max_lockers", &max))
4174+ return NULL;
4175+ CHECK_ENV_NOT_CLOSED(self);
4176+
4177+ MYDB_BEGIN_ALLOW_THREADS;
4178+ err = self->db_env->set_lk_max_lockers(self->db_env, max);
4179+ MYDB_END_ALLOW_THREADS;
4180+ RETURN_IF_ERR();
4181+ RETURN_NONE();
4182+}
4183+
4184+
4185+static PyObject*
4186+DBEnv_set_lk_max_objects(DBEnvObject* self, PyObject* args)
4187+{
4188+ int err, max;
4189+
4190+ if (!PyArg_ParseTuple(args, "i:set_lk_max_objects", &max))
4191+ return NULL;
4192+ CHECK_ENV_NOT_CLOSED(self);
4193+
4194+ MYDB_BEGIN_ALLOW_THREADS;
4195+ err = self->db_env->set_lk_max_objects(self->db_env, max);
4196+ MYDB_END_ALLOW_THREADS;
4197+ RETURN_IF_ERR();
4198+ RETURN_NONE();
4199+}
4200+
4201+#endif
4202+
4203+
4204+static PyObject*
4205+DBEnv_set_mp_mmapsize(DBEnvObject* self, PyObject* args)
4206+{
4207+ int err, mp_mmapsize;
4208+
4209+ if (!PyArg_ParseTuple(args, "i:set_mp_mmapsize", &mp_mmapsize))
4210+ return NULL;
4211+ CHECK_ENV_NOT_CLOSED(self);
4212+
4213+ MYDB_BEGIN_ALLOW_THREADS;
4214+ err = self->db_env->set_mp_mmapsize(self->db_env, mp_mmapsize);
4215+ MYDB_END_ALLOW_THREADS;
4216+ RETURN_IF_ERR();
4217+ RETURN_NONE();
4218+}
4219+
4220+
4221+static PyObject*
4222+DBEnv_set_tmp_dir(DBEnvObject* self, PyObject* args)
4223+{
4224+ int err;
4225+ char *dir;
4226+
4227+ if (!PyArg_ParseTuple(args, "s:set_tmp_dir", &dir))
4228+ return NULL;
4229+ CHECK_ENV_NOT_CLOSED(self);
4230+
4231+ MYDB_BEGIN_ALLOW_THREADS;
4232+ err = self->db_env->set_tmp_dir(self->db_env, dir);
4233+ MYDB_END_ALLOW_THREADS;
4234+ RETURN_IF_ERR();
4235+ RETURN_NONE();
4236+}
4237+
4238+
4239+static PyObject*
4240+DBEnv_txn_begin(DBEnvObject* self, PyObject* args, PyObject* kwargs)
4241+{
4242+ int flags = 0;
4243+ PyObject* txnobj = NULL;
4244+ DB_TXN *txn = NULL;
4245+ static char* kwnames[] = { "parent", "flags", NULL };
4246+
4247+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:txn_begin", kwnames,
4248+ &txnobj, &flags))
4249+ return NULL;
4250+
4251+ if (!checkTxnObj(txnobj, &txn))
4252+ return NULL;
4253+ CHECK_ENV_NOT_CLOSED(self);
4254+
4255+ return (PyObject*)newDBTxnObject(self, txn, flags);
4256+}
4257+
4258+
4259+static PyObject*
4260+DBEnv_txn_checkpoint(DBEnvObject* self, PyObject* args)
4261+{
4262+ int err, kbyte=0, min=0, flags=0;
4263+
4264+ if (!PyArg_ParseTuple(args, "|iii:txn_checkpoint", &kbyte, &min, &flags))
4265+ return NULL;
4266+ CHECK_ENV_NOT_CLOSED(self);
4267+
4268+ MYDB_BEGIN_ALLOW_THREADS;
4269+#if (DBVER >= 40)
4270+ err = self->db_env->txn_checkpoint(self->db_env, kbyte, min, flags);
4271+#else
4272+ err = txn_checkpoint(self->db_env, kbyte, min, flags);
4273+#endif
4274+ MYDB_END_ALLOW_THREADS;
4275+ RETURN_IF_ERR();
4276+ RETURN_NONE();
4277+}
4278+
4279+
4280+static PyObject*
4281+DBEnv_set_tx_max(DBEnvObject* self, PyObject* args)
4282+{
4283+ int err, max;
4284+
4285+ if (!PyArg_ParseTuple(args, "i:set_tx_max", &max))
4286+ return NULL;
4287+ CHECK_ENV_NOT_CLOSED(self);
4288+
4289+ err = self->db_env->set_tx_max(self->db_env, max);
4290+ RETURN_IF_ERR();
4291+ RETURN_NONE();
4292+}
4293+
4294+
4295+static PyObject*
4296+DBEnv_set_tx_timestamp(DBEnvObject* self, PyObject* args)
4297+{
4298+ int err;
4299+ long stamp;
4300+ time_t timestamp;
4301+
4302+ if (!PyArg_ParseTuple(args, "l:set_tx_timestamp", &stamp))
4303+ return NULL;
4304+ CHECK_ENV_NOT_CLOSED(self);
4305+ timestamp = (time_t)stamp;
4306+ err = self->db_env->set_tx_timestamp(self->db_env, &timestamp);
4307+ RETURN_IF_ERR();
4308+ RETURN_NONE();
4309+}
4310+
4311+
4312+static PyObject*
4313+DBEnv_lock_detect(DBEnvObject* self, PyObject* args)
4314+{
4315+ int err, atype, flags=0;
4316+ int aborted = 0;
4317+
4318+ if (!PyArg_ParseTuple(args, "i|i:lock_detect", &atype, &flags))
4319+ return NULL;
4320+ CHECK_ENV_NOT_CLOSED(self);
4321+
4322+ MYDB_BEGIN_ALLOW_THREADS;
4323+#if (DBVER >= 40)
4324+ err = self->db_env->lock_detect(self->db_env, flags, atype, &aborted);
4325+#else
4326+ err = lock_detect(self->db_env, flags, atype, &aborted);
4327+#endif
4328+ MYDB_END_ALLOW_THREADS;
4329+ RETURN_IF_ERR();
4330+ return PyInt_FromLong(aborted);
4331+}
4332+
4333+
4334+static PyObject*
4335+DBEnv_lock_get(DBEnvObject* self, PyObject* args)
4336+{
4337+ int flags=0;
4338+ int locker, lock_mode;
4339+ DBT obj;
4340+ PyObject* objobj;
4341+
4342+ if (!PyArg_ParseTuple(args, "iOi|i:lock_get", &locker, &objobj, &lock_mode, &flags))
4343+ return NULL;
4344+
4345+
4346+ if (!make_dbt(objobj, &obj))
4347+ return NULL;
4348+
4349+ return (PyObject*)newDBLockObject(self, locker, &obj, lock_mode, flags);
4350+}
4351+
4352+
4353+static PyObject*
4354+DBEnv_lock_id(DBEnvObject* self, PyObject* args)
4355+{
4356+ int err;
4357+ u_int32_t theID;
4358+
4359+ if (!PyArg_ParseTuple(args, ":lock_id"))
4360+ return NULL;
4361+
4362+ CHECK_ENV_NOT_CLOSED(self);
4363+ MYDB_BEGIN_ALLOW_THREADS;
4364+#if (DBVER >= 40)
4365+ err = self->db_env->lock_id(self->db_env, &theID);
4366+#else
4367+ err = lock_id(self->db_env, &theID);
4368+#endif
4369+ MYDB_END_ALLOW_THREADS;
4370+ RETURN_IF_ERR();
4371+
4372+ return PyInt_FromLong((long)theID);
4373+}
4374+
4375+
4376+static PyObject*
4377+DBEnv_lock_put(DBEnvObject* self, PyObject* args)
4378+{
4379+ int err;
4380+ DBLockObject* dblockobj;
4381+
4382+ if (!PyArg_ParseTuple(args, "O!:lock_put", &DBLock_Type, &dblockobj))
4383+ return NULL;
4384+
4385+ CHECK_ENV_NOT_CLOSED(self);
4386+ MYDB_BEGIN_ALLOW_THREADS;
4387+#if (DBVER >= 40)
4388+ err = self->db_env->lock_put(self->db_env, &dblockobj->lock);
4389+#else
4390+ err = lock_put(self->db_env, &dblockobj->lock);
4391+#endif
4392+ MYDB_END_ALLOW_THREADS;
4393+ RETURN_IF_ERR();
4394+ RETURN_NONE();
4395+}
4396+
4397+#if (DBVER >= 44)
4398+static PyObject*
4399+DBEnv_lsn_reset(DBEnvObject* self, PyObject* args, PyObject* kwargs)
4400+{
4401+ int err;
4402+ char *file;
4403+ u_int32_t flags = 0;
4404+ static char* kwnames[] = { "file", "flags", NULL};
4405+
4406+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|i:lsn_reset", kwnames,
4407+ &file, &flags))
4408+ return NULL;
4409+ CHECK_ENV_NOT_CLOSED(self);
4410+
4411+ MYDB_BEGIN_ALLOW_THREADS;
4412+ err = self->db_env->lsn_reset(self->db_env, file, flags);
4413+ MYDB_END_ALLOW_THREADS;
4414+ RETURN_IF_ERR();
4415+ RETURN_NONE();
4416+}
4417+#endif /* DBVER >= 4.4 */
4418+
4419+#if (DBVER >= 40)
4420+static PyObject*
4421+DBEnv_log_stat(DBEnvObject* self, PyObject* args)
4422+{
4423+ int err;
4424+ DB_LOG_STAT* statp = NULL;
4425+ PyObject* d = NULL;
4426+ u_int32_t flags = 0;
4427+
4428+ if (!PyArg_ParseTuple(args, "|i:log_stat", &flags))
4429+ return NULL;
4430+ CHECK_ENV_NOT_CLOSED(self);
4431+
4432+ MYDB_BEGIN_ALLOW_THREADS;
4433+ err = self->db_env->log_stat(self->db_env, &statp, flags);
4434+ MYDB_END_ALLOW_THREADS;
4435+ RETURN_IF_ERR();
4436+
4437+ /* Turn the stat structure into a dictionary */
4438+ d = PyDict_New();
4439+ if (d == NULL) {
4440+ if (statp)
4441+ free(statp);
4442+ return NULL;
4443+ }
4444+
4445+#define MAKE_ENTRY(name) _addIntToDict(d, #name, statp->st_##name)
4446+
4447+ MAKE_ENTRY(magic);
4448+ MAKE_ENTRY(version);
4449+ MAKE_ENTRY(mode);
4450+ MAKE_ENTRY(lg_bsize);
4451+#if (DBVER >= 44)
4452+ MAKE_ENTRY(lg_size);
4453+ MAKE_ENTRY(record);
4454+#endif
4455+#if (DBVER <= 40)
4456+ MAKE_ENTRY(lg_max);
4457+#endif
4458+ MAKE_ENTRY(w_mbytes);
4459+ MAKE_ENTRY(w_bytes);
4460+ MAKE_ENTRY(wc_mbytes);
4461+ MAKE_ENTRY(wc_bytes);
4462+ MAKE_ENTRY(wcount);
4463+ MAKE_ENTRY(wcount_fill);
4464+#if (DBVER >= 44)
4465+ MAKE_ENTRY(rcount);
4466+#endif
4467+ MAKE_ENTRY(scount);
4468+ MAKE_ENTRY(cur_file);
4469+ MAKE_ENTRY(cur_offset);
4470+ MAKE_ENTRY(disk_file);
4471+ MAKE_ENTRY(disk_offset);
4472+ MAKE_ENTRY(maxcommitperflush);
4473+ MAKE_ENTRY(mincommitperflush);
4474+ MAKE_ENTRY(regsize);
4475+ MAKE_ENTRY(region_wait);
4476+ MAKE_ENTRY(region_nowait);
4477+
4478+#undef MAKE_ENTRY
4479+ free(statp);
4480+ return d;
4481+} /* DBEnv_log_stat */
4482+#endif /* DBVER >= 4.0 for log_stat method */
4483+
4484+
4485+static PyObject*
4486+DBEnv_lock_stat(DBEnvObject* self, PyObject* args)
4487+{
4488+ int err;
4489+ DB_LOCK_STAT* sp;
4490+ PyObject* d = NULL;
4491+ u_int32_t flags = 0;
4492+
4493+ if (!PyArg_ParseTuple(args, "|i:lock_stat", &flags))
4494+ return NULL;
4495+ CHECK_ENV_NOT_CLOSED(self);
4496+
4497+ MYDB_BEGIN_ALLOW_THREADS;
4498+#if (DBVER >= 40)
4499+ err = self->db_env->lock_stat(self->db_env, &sp, flags);
4500+#else
4501+#if (DBVER >= 33)
4502+ err = lock_stat(self->db_env, &sp);
4503+#else
4504+ err = lock_stat(self->db_env, &sp, NULL);
4505+#endif
4506+#endif
4507+ MYDB_END_ALLOW_THREADS;
4508+ RETURN_IF_ERR();
4509+
4510+ /* Turn the stat structure into a dictionary */
4511+ d = PyDict_New();
4512+ if (d == NULL) {
4513+ free(sp);
4514+ return NULL;
4515+ }
4516+
4517+#define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
4518+
4519+#if (DBVER < 41)
4520+ MAKE_ENTRY(lastid);
4521+#endif
4522+ MAKE_ENTRY(nmodes);
4523+#if (DBVER >= 32)
4524+ MAKE_ENTRY(maxlocks);
4525+ MAKE_ENTRY(maxlockers);
4526+ MAKE_ENTRY(maxobjects);
4527+ MAKE_ENTRY(nlocks);
4528+ MAKE_ENTRY(maxnlocks);
4529+#endif
4530+ MAKE_ENTRY(nlockers);
4531+ MAKE_ENTRY(maxnlockers);
4532+#if (DBVER >= 32)
4533+ MAKE_ENTRY(nobjects);
4534+ MAKE_ENTRY(maxnobjects);
4535+#endif
4536+ MAKE_ENTRY(nrequests);
4537+ MAKE_ENTRY(nreleases);
4538+#if (DBVER < 44)
4539+ MAKE_ENTRY(nnowaits); /* these were renamed in 4.4 */
4540+ MAKE_ENTRY(nconflicts);
4541+#else
4542+ MAKE_ENTRY(lock_nowait);
4543+ MAKE_ENTRY(lock_wait);
4544+#endif
4545+ MAKE_ENTRY(ndeadlocks);
4546+ MAKE_ENTRY(regsize);
4547+ MAKE_ENTRY(region_wait);
4548+ MAKE_ENTRY(region_nowait);
4549+
4550+#undef MAKE_ENTRY
4551+ free(sp);
4552+ return d;
4553+}
4554+
4555+
4556+static PyObject*
4557+DBEnv_log_archive(DBEnvObject* self, PyObject* args)
4558+{
4559+ int flags=0;
4560+ int err;
4561+ char **log_list = NULL;
4562+ PyObject* list;
4563+ PyObject* item = NULL;
4564+
4565+ if (!PyArg_ParseTuple(args, "|i:log_archive", &flags))
4566+ return NULL;
4567+
4568+ CHECK_ENV_NOT_CLOSED(self);
4569+ MYDB_BEGIN_ALLOW_THREADS;
4570+#if (DBVER >= 40)
4571+ err = self->db_env->log_archive(self->db_env, &log_list, flags);
4572+#elif (DBVER == 33)
4573+ err = log_archive(self->db_env, &log_list, flags);
4574+#else
4575+ err = log_archive(self->db_env, &log_list, flags, NULL);
4576+#endif
4577+ MYDB_END_ALLOW_THREADS;
4578+ RETURN_IF_ERR();
4579+
4580+ list = PyList_New(0);
4581+ if (list == NULL) {
4582+ if (log_list)
4583+ free(log_list);
4584+ return NULL;
4585+ }
4586+
4587+ if (log_list) {
4588+ char **log_list_start;
4589+ for (log_list_start = log_list; *log_list != NULL; ++log_list) {
4590+ item = PyString_FromString (*log_list);
4591+ if (item == NULL) {
4592+ Py_DECREF(list);
4593+ list = NULL;
4594+ break;
4595+ }
4596+ PyList_Append(list, item);
4597+ Py_DECREF(item);
4598+ }
4599+ free(log_list_start);
4600+ }
4601+ return list;
4602+}
4603+
4604+
4605+static PyObject*
4606+DBEnv_txn_stat(DBEnvObject* self, PyObject* args)
4607+{
4608+ int err;
4609+ DB_TXN_STAT* sp;
4610+ PyObject* d = NULL;
4611+ u_int32_t flags=0;
4612+
4613+ if (!PyArg_ParseTuple(args, "|i:txn_stat", &flags))
4614+ return NULL;
4615+ CHECK_ENV_NOT_CLOSED(self);
4616+
4617+ MYDB_BEGIN_ALLOW_THREADS;
4618+#if (DBVER >= 40)
4619+ err = self->db_env->txn_stat(self->db_env, &sp, flags);
4620+#elif (DBVER == 33)
4621+ err = txn_stat(self->db_env, &sp);
4622+#else
4623+ err = txn_stat(self->db_env, &sp, NULL);
4624+#endif
4625+ MYDB_END_ALLOW_THREADS;
4626+ RETURN_IF_ERR();
4627+
4628+ /* Turn the stat structure into a dictionary */
4629+ d = PyDict_New();
4630+ if (d == NULL) {
4631+ free(sp);
4632+ return NULL;
4633+ }
4634+
4635+#define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
4636+
4637+ MAKE_ENTRY(time_ckp);
4638+ MAKE_ENTRY(last_txnid);
4639+ MAKE_ENTRY(maxtxns);
4640+ MAKE_ENTRY(nactive);
4641+ MAKE_ENTRY(maxnactive);
4642+ MAKE_ENTRY(nbegins);
4643+ MAKE_ENTRY(naborts);
4644+ MAKE_ENTRY(ncommits);
4645+ MAKE_ENTRY(regsize);
4646+ MAKE_ENTRY(region_wait);
4647+ MAKE_ENTRY(region_nowait);
4648+
4649+#undef MAKE_ENTRY
4650+ free(sp);
4651+ return d;
4652+}
4653+
4654+
4655+static PyObject*
4656+DBEnv_set_get_returns_none(DBEnvObject* self, PyObject* args)
4657+{
4658+ int flags=0;
4659+ int oldValue=0;
4660+
4661+ if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
4662+ return NULL;
4663+ CHECK_ENV_NOT_CLOSED(self);
4664+
4665+ if (self->moduleFlags.getReturnsNone)
4666+ ++oldValue;
4667+ if (self->moduleFlags.cursorSetReturnsNone)
4668+ ++oldValue;
4669+ self->moduleFlags.getReturnsNone = (flags >= 1);
4670+ self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
4671+ return PyInt_FromLong(oldValue);
4672+}
4673+
4674+
4675+/* --------------------------------------------------------------------- */
4676+/* DBTxn methods */
4677+
4678+
4679+static PyObject*
4680+DBTxn_commit(DBTxnObject* self, PyObject* args)
4681+{
4682+ int flags=0, err;
4683+ DB_TXN *txn;
4684+
4685+ if (!PyArg_ParseTuple(args, "|i:commit", &flags))
4686+ return NULL;
4687+
4688+ if (!self->txn) {
4689+ PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
4690+ "after txn_commit or txn_abort");
4691+ PyErr_SetObject(DBError, t);
4692+ Py_DECREF(t);
4693+ return NULL;
4694+ }
4695+ txn = self->txn;
4696+ self->txn = NULL; /* this DB_TXN is no longer valid after this call */
4697+ MYDB_BEGIN_ALLOW_THREADS;
4698+#if (DBVER >= 40)
4699+ err = txn->commit(txn, flags);
4700+#else
4701+ err = txn_commit(txn, flags);
4702+#endif
4703+ MYDB_END_ALLOW_THREADS;
4704+ RETURN_IF_ERR();
4705+ RETURN_NONE();
4706+}
4707+
4708+static PyObject*
4709+DBTxn_prepare(DBTxnObject* self, PyObject* args)
4710+{
4711+#if (DBVER >= 33)
4712+ int err;
4713+ char* gid=NULL;
4714+ int gid_size=0;
4715+
4716+ if (!PyArg_ParseTuple(args, "s#:prepare", &gid, &gid_size))
4717+ return NULL;
4718+
4719+ if (gid_size != DB_XIDDATASIZE) {
4720+ PyErr_SetString(PyExc_TypeError,
4721+ "gid must be DB_XIDDATASIZE bytes long");
4722+ return NULL;
4723+ }
4724+
4725+ if (!self->txn) {
4726+ PyObject *t = Py_BuildValue("(is)", 0,"DBTxn must not be used "
4727+ "after txn_commit or txn_abort");
4728+ PyErr_SetObject(DBError, t);
4729+ Py_DECREF(t);
4730+ return NULL;
4731+ }
4732+ MYDB_BEGIN_ALLOW_THREADS;
4733+#if (DBVER >= 40)
4734+ err = self->txn->prepare(self->txn, (u_int8_t*)gid);
4735+#else
4736+ err = txn_prepare(self->txn, (u_int8_t*)gid);
4737+#endif
4738+ MYDB_END_ALLOW_THREADS;
4739+ RETURN_IF_ERR();
4740+ RETURN_NONE();
4741+#else
4742+ int err;
4743+
4744+ if (!PyArg_ParseTuple(args, ":prepare"))
4745+ return NULL;
4746+
4747+ if (!self->txn) {
4748+ PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
4749+ "after txn_commit or txn_abort");
4750+ PyErr_SetObject(DBError, t);
4751+ Py_DECREF(t);
4752+ return NULL;
4753+ }
4754+ MYDB_BEGIN_ALLOW_THREADS;
4755+ err = txn_prepare(self->txn);
4756+ MYDB_END_ALLOW_THREADS;
4757+ RETURN_IF_ERR();
4758+ RETURN_NONE();
4759+#endif
4760+}
4761+
4762+
4763+static PyObject*
4764+DBTxn_abort(DBTxnObject* self, PyObject* args)
4765+{
4766+ int err;
4767+ DB_TXN *txn;
4768+
4769+ if (!PyArg_ParseTuple(args, ":abort"))
4770+ return NULL;
4771+
4772+ if (!self->txn) {
4773+ PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
4774+ "after txn_commit or txn_abort");
4775+ PyErr_SetObject(DBError, t);
4776+ Py_DECREF(t);
4777+ return NULL;
4778+ }
4779+ txn = self->txn;
4780+ self->txn = NULL; /* this DB_TXN is no longer valid after this call */
4781+ MYDB_BEGIN_ALLOW_THREADS;
4782+#if (DBVER >= 40)
4783+ err = txn->abort(txn);
4784+#else
4785+ err = txn_abort(txn);
4786+#endif
4787+ MYDB_END_ALLOW_THREADS;
4788+ RETURN_IF_ERR();
4789+ RETURN_NONE();
4790+}
4791+
4792+
4793+static PyObject*
4794+DBTxn_id(DBTxnObject* self, PyObject* args)
4795+{
4796+ int id;
4797+
4798+ if (!PyArg_ParseTuple(args, ":id"))
4799+ return NULL;
4800+
4801+ if (!self->txn) {
4802+ PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
4803+ "after txn_commit or txn_abort");
4804+ PyErr_SetObject(DBError, t);
4805+ Py_DECREF(t);
4806+ return NULL;
4807+ }
4808+ MYDB_BEGIN_ALLOW_THREADS;
4809+#if (DBVER >= 40)
4810+ id = self->txn->id(self->txn);
4811+#else
4812+ id = txn_id(self->txn);
4813+#endif
4814+ MYDB_END_ALLOW_THREADS;
4815+ return PyInt_FromLong(id);
4816+}
4817+
4818+#if (DBVER >= 43)
4819+/* --------------------------------------------------------------------- */
4820+/* DBSequence methods */
4821+
4822+
4823+static PyObject*
4824+DBSequence_close(DBSequenceObject* self, PyObject* args)
4825+{
4826+ int err, flags=0;
4827+ if (!PyArg_ParseTuple(args,"|i:close", &flags))
4828+ return NULL;
4829+ CHECK_SEQUENCE_NOT_CLOSED(self)
4830+
4831+ MYDB_BEGIN_ALLOW_THREADS
4832+ err = self->sequence->close(self->sequence, flags);
4833+ self->sequence = NULL;
4834+ MYDB_END_ALLOW_THREADS
4835+
4836+ RETURN_IF_ERR();
4837+
4838+ RETURN_NONE();
4839+}
4840+
4841+static PyObject*
4842+DBSequence_get(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
4843+{
4844+ int err, flags = 0;
4845+ int delta = 1;
4846+ db_seq_t value;
4847+ PyObject *txnobj = NULL;
4848+ DB_TXN *txn = NULL;
4849+ static char* kwnames[] = {"delta", "txn", "flags", NULL };
4850+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iOi:get", kwnames, &delta, &txnobj, &flags))
4851+ return NULL;
4852+ CHECK_SEQUENCE_NOT_CLOSED(self)
4853+
4854+ if (!checkTxnObj(txnobj, &txn))
4855+ return NULL;
4856+
4857+ MYDB_BEGIN_ALLOW_THREADS
4858+ err = self->sequence->get(self->sequence, txn, delta, &value, flags);
4859+ MYDB_END_ALLOW_THREADS
4860+
4861+ RETURN_IF_ERR();
4862+ return PyLong_FromLongLong(value);
4863+
4864+}
4865+
4866+static PyObject*
4867+DBSequence_get_dbp(DBSequenceObject* self, PyObject* args)
4868+{
4869+ if (!PyArg_ParseTuple(args,":get_dbp"))
4870+ return NULL;
4871+ CHECK_SEQUENCE_NOT_CLOSED(self)
4872+ Py_INCREF(self->mydb);
4873+ return (PyObject* )self->mydb;
4874+}
4875+
4876+static PyObject*
4877+DBSequence_get_key(DBSequenceObject* self, PyObject* args)
4878+{
4879+ int err;
4880+ DBT key;
4881+ CHECK_SEQUENCE_NOT_CLOSED(self)
4882+ MYDB_BEGIN_ALLOW_THREADS
4883+ err = self->sequence->get_key(self->sequence, &key);
4884+ MYDB_END_ALLOW_THREADS
4885+
4886+ RETURN_IF_ERR();
4887+
4888+ return PyString_FromStringAndSize(key.data, key.size);
4889+}
4890+
4891+static PyObject*
4892+DBSequence_init_value(DBSequenceObject* self, PyObject* args)
4893+{
4894+ int err;
4895+ db_seq_t value;
4896+ if (!PyArg_ParseTuple(args,"L:init_value", &value))
4897+ return NULL;
4898+ CHECK_SEQUENCE_NOT_CLOSED(self)
4899+
4900+ MYDB_BEGIN_ALLOW_THREADS
4901+ err = self->sequence->initial_value(self->sequence, value);
4902+ MYDB_END_ALLOW_THREADS
4903+
4904+ RETURN_IF_ERR();
4905+
4906+ RETURN_NONE();
4907+}
4908+
4909+static PyObject*
4910+DBSequence_open(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
4911+{
4912+ int err, flags = 0;
4913+ PyObject* keyobj;
4914+ PyObject *txnobj = NULL;
4915+ DB_TXN *txn = NULL;
4916+ DBT key;
4917+
4918+ static char* kwnames[] = {"key", "txn", "flags", NULL };
4919+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:open", kwnames, &keyobj, &txnobj, &flags))
4920+ return NULL;
4921+
4922+ if (!checkTxnObj(txnobj, &txn))
4923+ return NULL;
4924+
4925+ if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4926+ return NULL;
4927+
4928+ MYDB_BEGIN_ALLOW_THREADS
4929+ err = self->sequence->open(self->sequence, txn, &key, flags);
4930+ MYDB_END_ALLOW_THREADS
4931+
4932+ CLEAR_DBT(key);
4933+ RETURN_IF_ERR();
4934+
4935+ RETURN_NONE();
4936+}
4937+
4938+static PyObject*
4939+DBSequence_remove(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
4940+{
4941+ int err, flags = 0;
4942+ PyObject *txnobj = NULL;
4943+ DB_TXN *txn = NULL;
4944+
4945+ static char* kwnames[] = {"txn", "flags", NULL };
4946+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:remove", kwnames, &txnobj, &flags))
4947+ return NULL;
4948+
4949+ if (!checkTxnObj(txnobj, &txn))
4950+ return NULL;
4951+
4952+ CHECK_SEQUENCE_NOT_CLOSED(self)
4953+
4954+ MYDB_BEGIN_ALLOW_THREADS
4955+ err = self->sequence->remove(self->sequence, txn, flags);
4956+ MYDB_END_ALLOW_THREADS
4957+
4958+ RETURN_IF_ERR();
4959+ RETURN_NONE();
4960+}
4961+
4962+static PyObject*
4963+DBSequence_set_cachesize(DBSequenceObject* self, PyObject* args)
4964+{
4965+ int err, size;
4966+ if (!PyArg_ParseTuple(args,"i:set_cachesize", &size))
4967+ return NULL;
4968+ CHECK_SEQUENCE_NOT_CLOSED(self)
4969+
4970+ MYDB_BEGIN_ALLOW_THREADS
4971+ err = self->sequence->set_cachesize(self->sequence, size);
4972+ MYDB_END_ALLOW_THREADS
4973+
4974+ RETURN_IF_ERR();
4975+ RETURN_NONE();
4976+}
4977+
4978+static PyObject*
4979+DBSequence_get_cachesize(DBSequenceObject* self, PyObject* args)
4980+{
4981+ int err, size;
4982+ if (!PyArg_ParseTuple(args,":get_cachesize"))
4983+ return NULL;
4984+ CHECK_SEQUENCE_NOT_CLOSED(self)
4985+
4986+ MYDB_BEGIN_ALLOW_THREADS
4987+ err = self->sequence->get_cachesize(self->sequence, &size);
4988+ MYDB_END_ALLOW_THREADS
4989+
4990+ RETURN_IF_ERR();
4991+ return PyInt_FromLong(size);
4992+}
4993+
4994+static PyObject*
4995+DBSequence_set_flags(DBSequenceObject* self, PyObject* args)
4996+{
4997+ int err, flags = 0;
4998+ if (!PyArg_ParseTuple(args,"i:set_flags", &flags))
4999+ return NULL;

1048 more lines aren’t shown here.

sys/src/cmd/python/Modules/_codecsmodule.c+934−0
@@ -0,0 +1,934 @@
1+/* ------------------------------------------------------------------------
2+
3+ _codecs -- Provides access to the codec registry and the builtin
4+ codecs.
5+
6+ This module should never be imported directly. The standard library
7+ module "codecs" wraps this builtin module for use within Python.
8+
9+ The codec registry is accessible via:
10+
11+ register(search_function) -> None
12+
13+ lookup(encoding) -> (encoder, decoder, stream_reader, stream_writer)
14+
15+ The builtin Unicode codecs use the following interface:
16+
17+ <encoding>_encode(Unicode_object[,errors='strict']) ->
18+ (string object, bytes consumed)
19+
20+ <encoding>_decode(char_buffer_obj[,errors='strict']) ->
21+ (Unicode object, bytes consumed)
22+
23+ <encoding>_encode() interfaces also accept non-Unicode object as
24+ input. The objects are then converted to Unicode using
25+ PyUnicode_FromObject() prior to applying the conversion.
26+
27+ These <encoding>s are available: utf_8, unicode_escape,
28+ raw_unicode_escape, unicode_internal, latin_1, ascii (7-bit),
29+ mbcs (on win32).
30+
31+
32+Written by Marc-Andre Lemburg (mal@lemburg.com).
33+
34+Copyright (c) Corporation for National Research Initiatives.
35+
36+ ------------------------------------------------------------------------ */
37+
38+#define PY_SSIZE_T_CLEAN
39+#include "Python.h"
40+
41+/* --- Registry ----------------------------------------------------------- */
42+
43+PyDoc_STRVAR(register__doc__,
44+"register(search_function)\n\
45+\n\
46+Register a codec search function. Search functions are expected to take\n\
47+one argument, the encoding name in all lower case letters, and return\n\
48+a tuple of functions (encoder, decoder, stream_reader, stream_writer).");
49+
50+static
51+PyObject *codec_register(PyObject *self, PyObject *search_function)
52+{
53+ if (PyCodec_Register(search_function))
54+ return NULL;
55+
56+ Py_RETURN_NONE;
57+}
58+
59+PyDoc_STRVAR(lookup__doc__,
60+"lookup(encoding) -> (encoder, decoder, stream_reader, stream_writer)\n\
61+\n\
62+Looks up a codec tuple in the Python codec registry and returns\n\
63+a tuple of functions.");
64+
65+static
66+PyObject *codec_lookup(PyObject *self, PyObject *args)
67+{
68+ char *encoding;
69+
70+ if (!PyArg_ParseTuple(args, "s:lookup", &encoding))
71+ return NULL;
72+
73+ return _PyCodec_Lookup(encoding);
74+}
75+
76+PyDoc_STRVAR(encode__doc__,
77+"encode(obj, [encoding[,errors]]) -> object\n\
78+\n\
79+Encodes obj using the codec registered for encoding. encoding defaults\n\
80+to the default encoding. errors may be given to set a different error\n\
81+handling scheme. Default is 'strict' meaning that encoding errors raise\n\
82+a ValueError. Other possible values are 'ignore', 'replace' and\n\
83+'xmlcharrefreplace' as well as any other name registered with\n\
84+codecs.register_error that can handle ValueErrors.");
85+
86+static PyObject *
87+codec_encode(PyObject *self, PyObject *args)
88+{
89+ const char *encoding = NULL;
90+ const char *errors = NULL;
91+ PyObject *v;
92+
93+ if (!PyArg_ParseTuple(args, "O|ss:encode", &v, &encoding, &errors))
94+ return NULL;
95+
96+#ifdef Py_USING_UNICODE
97+ if (encoding == NULL)
98+ encoding = PyUnicode_GetDefaultEncoding();
99+#else
100+ if (encoding == NULL) {
101+ PyErr_SetString(PyExc_ValueError, "no encoding specified");
102+ return NULL;
103+ }
104+#endif
105+
106+ /* Encode via the codec registry */
107+ return PyCodec_Encode(v, encoding, errors);
108+}
109+
110+PyDoc_STRVAR(decode__doc__,
111+"decode(obj, [encoding[,errors]]) -> object\n\
112+\n\
113+Decodes obj using the codec registered for encoding. encoding defaults\n\
114+to the default encoding. errors may be given to set a different error\n\
115+handling scheme. Default is 'strict' meaning that encoding errors raise\n\
116+a ValueError. Other possible values are 'ignore' and 'replace'\n\
117+as well as any other name registerd with codecs.register_error that is\n\
118+able to handle ValueErrors.");
119+
120+static PyObject *
121+codec_decode(PyObject *self, PyObject *args)
122+{
123+ const char *encoding = NULL;
124+ const char *errors = NULL;
125+ PyObject *v;
126+
127+ if (!PyArg_ParseTuple(args, "O|ss:decode", &v, &encoding, &errors))
128+ return NULL;
129+
130+#ifdef Py_USING_UNICODE
131+ if (encoding == NULL)
132+ encoding = PyUnicode_GetDefaultEncoding();
133+#else
134+ if (encoding == NULL) {
135+ PyErr_SetString(PyExc_ValueError, "no encoding specified");
136+ return NULL;
137+ }
138+#endif
139+
140+ /* Decode via the codec registry */
141+ return PyCodec_Decode(v, encoding, errors);
142+}
143+
144+/* --- Helpers ------------------------------------------------------------ */
145+
146+static
147+PyObject *codec_tuple(PyObject *unicode,
148+ Py_ssize_t len)
149+{
150+ PyObject *v;
151+ if (unicode == NULL)
152+ return NULL;
153+ v = Py_BuildValue("On", unicode, len);
154+ Py_DECREF(unicode);
155+ return v;
156+}
157+
158+/* --- String codecs ------------------------------------------------------ */
159+static PyObject *
160+escape_decode(PyObject *self,
161+ PyObject *args)
162+{
163+ const char *errors = NULL;
164+ const char *data;
165+ Py_ssize_t size;
166+
167+ if (!PyArg_ParseTuple(args, "s#|z:escape_decode",
168+ &data, &size, &errors))
169+ return NULL;
170+ return codec_tuple(PyString_DecodeEscape(data, size, errors, 0, NULL),
171+ size);
172+}
173+
174+static PyObject *
175+escape_encode(PyObject *self,
176+ PyObject *args)
177+{
178+ PyObject *str;
179+ const char *errors = NULL;
180+ char *buf;
181+ Py_ssize_t len;
182+
183+ if (!PyArg_ParseTuple(args, "O!|z:escape_encode",
184+ &PyString_Type, &str, &errors))
185+ return NULL;
186+
187+ str = PyString_Repr(str, 0);
188+ if (!str)
189+ return NULL;
190+
191+ /* The string will be quoted. Unquote, similar to unicode-escape. */
192+ buf = PyString_AS_STRING (str);
193+ len = PyString_GET_SIZE (str);
194+ memmove(buf, buf+1, len-2);
195+ if (_PyString_Resize(&str, len-2) < 0)
196+ return NULL;
197+
198+ return codec_tuple(str, PyString_Size(str));
199+}
200+
201+#ifdef Py_USING_UNICODE
202+/* --- Decoder ------------------------------------------------------------ */
203+
204+static PyObject *
205+unicode_internal_decode(PyObject *self,
206+ PyObject *args)
207+{
208+ PyObject *obj;
209+ const char *errors = NULL;
210+ const char *data;
211+ Py_ssize_t size;
212+
213+ if (!PyArg_ParseTuple(args, "O|z:unicode_internal_decode",
214+ &obj, &errors))
215+ return NULL;
216+
217+ if (PyUnicode_Check(obj)) {
218+ Py_INCREF(obj);
219+ return codec_tuple(obj, PyUnicode_GET_SIZE(obj));
220+ }
221+ else {
222+ if (PyObject_AsReadBuffer(obj, (const void **)&data, &size))
223+ return NULL;
224+
225+ return codec_tuple(_PyUnicode_DecodeUnicodeInternal(data, size, errors),
226+ size);
227+ }
228+}
229+
230+static PyObject *
231+utf_7_decode(PyObject *self,
232+ PyObject *args)
233+{
234+ const char *data;
235+ Py_ssize_t size;
236+ const char *errors = NULL;
237+
238+ if (!PyArg_ParseTuple(args, "t#|z:utf_7_decode",
239+ &data, &size, &errors))
240+ return NULL;
241+
242+ return codec_tuple(PyUnicode_DecodeUTF7(data, size, errors),
243+ size);
244+}
245+
246+static PyObject *
247+utf_8_decode(PyObject *self,
248+ PyObject *args)
249+{
250+ const char *data;
251+ Py_ssize_t size;
252+ const char *errors = NULL;
253+ int final = 0;
254+ Py_ssize_t consumed;
255+ PyObject *decoded = NULL;
256+
257+ if (!PyArg_ParseTuple(args, "t#|zi:utf_8_decode",
258+ &data, &size, &errors, &final))
259+ return NULL;
260+ if (size < 0) {
261+ PyErr_SetString(PyExc_ValueError, "negative argument");
262+ return 0;
263+ }
264+ consumed = size;
265+
266+ decoded = PyUnicode_DecodeUTF8Stateful(data, size, errors,
267+ final ? NULL : &consumed);
268+ if (decoded == NULL)
269+ return NULL;
270+ return codec_tuple(decoded, consumed);
271+}
272+
273+static PyObject *
274+utf_16_decode(PyObject *self,
275+ PyObject *args)
276+{
277+ const char *data;
278+ Py_ssize_t size;
279+ const char *errors = NULL;
280+ int byteorder = 0;
281+ int final = 0;
282+ Py_ssize_t consumed;
283+ PyObject *decoded;
284+
285+ if (!PyArg_ParseTuple(args, "t#|zi:utf_16_decode",
286+ &data, &size, &errors, &final))
287+ return NULL;
288+ if (size < 0) {
289+ PyErr_SetString(PyExc_ValueError, "negative argument");
290+ return 0;
291+ }
292+ consumed = size; /* This is overwritten unless final is true. */
293+ decoded = PyUnicode_DecodeUTF16Stateful(data, size, errors, &byteorder,
294+ final ? NULL : &consumed);
295+ if (decoded == NULL)
296+ return NULL;
297+ return codec_tuple(decoded, consumed);
298+}
299+
300+static PyObject *
301+utf_16_le_decode(PyObject *self,
302+ PyObject *args)
303+{
304+ const char *data;
305+ Py_ssize_t size;
306+ const char *errors = NULL;
307+ int byteorder = -1;
308+ int final = 0;
309+ Py_ssize_t consumed;
310+ PyObject *decoded = NULL;
311+
312+ if (!PyArg_ParseTuple(args, "t#|zi:utf_16_le_decode",
313+ &data, &size, &errors, &final))
314+ return NULL;
315+
316+ if (size < 0) {
317+ PyErr_SetString(PyExc_ValueError, "negative argument");
318+ return 0;
319+ }
320+ consumed = size; /* This is overwritten unless final is true. */
321+ decoded = PyUnicode_DecodeUTF16Stateful(data, size, errors,
322+ &byteorder, final ? NULL : &consumed);
323+ if (decoded == NULL)
324+ return NULL;
325+ return codec_tuple(decoded, consumed);
326+
327+}
328+
329+static PyObject *
330+utf_16_be_decode(PyObject *self,
331+ PyObject *args)
332+{
333+ const char *data;
334+ Py_ssize_t size;
335+ const char *errors = NULL;
336+ int byteorder = 1;
337+ int final = 0;
338+ Py_ssize_t consumed;
339+ PyObject *decoded = NULL;
340+
341+ if (!PyArg_ParseTuple(args, "t#|zi:utf_16_be_decode",
342+ &data, &size, &errors, &final))
343+ return NULL;
344+ if (size < 0) {
345+ PyErr_SetString(PyExc_ValueError, "negative argument");
346+ return 0;
347+ }
348+ consumed = size; /* This is overwritten unless final is true. */
349+ decoded = PyUnicode_DecodeUTF16Stateful(data, size, errors,
350+ &byteorder, final ? NULL : &consumed);
351+ if (decoded == NULL)
352+ return NULL;
353+ return codec_tuple(decoded, consumed);
354+}
355+
356+/* This non-standard version also provides access to the byteorder
357+ parameter of the builtin UTF-16 codec.
358+
359+ It returns a tuple (unicode, bytesread, byteorder) with byteorder
360+ being the value in effect at the end of data.
361+
362+*/
363+
364+static PyObject *
365+utf_16_ex_decode(PyObject *self,
366+ PyObject *args)
367+{
368+ const char *data;
369+ Py_ssize_t size;
370+ const char *errors = NULL;
371+ int byteorder = 0;
372+ PyObject *unicode, *tuple;
373+ int final = 0;
374+ Py_ssize_t consumed;
375+
376+ if (!PyArg_ParseTuple(args, "t#|zii:utf_16_ex_decode",
377+ &data, &size, &errors, &byteorder, &final))
378+ return NULL;
379+ if (size < 0) {
380+ PyErr_SetString(PyExc_ValueError, "negative argument");
381+ return 0;
382+ }
383+ consumed = size; /* This is overwritten unless final is true. */
384+ unicode = PyUnicode_DecodeUTF16Stateful(data, size, errors, &byteorder,
385+ final ? NULL : &consumed);
386+ if (unicode == NULL)
387+ return NULL;
388+ tuple = Py_BuildValue("Oni", unicode, consumed, byteorder);
389+ Py_DECREF(unicode);
390+ return tuple;
391+}
392+
393+static PyObject *
394+unicode_escape_decode(PyObject *self,
395+ PyObject *args)
396+{
397+ const char *data;
398+ Py_ssize_t size;
399+ const char *errors = NULL;
400+
401+ if (!PyArg_ParseTuple(args, "t#|z:unicode_escape_decode",
402+ &data, &size, &errors))
403+ return NULL;
404+
405+ return codec_tuple(PyUnicode_DecodeUnicodeEscape(data, size, errors),
406+ size);
407+}
408+
409+static PyObject *
410+raw_unicode_escape_decode(PyObject *self,
411+ PyObject *args)
412+{
413+ const char *data;
414+ Py_ssize_t size;
415+ const char *errors = NULL;
416+
417+ if (!PyArg_ParseTuple(args, "t#|z:raw_unicode_escape_decode",
418+ &data, &size, &errors))
419+ return NULL;
420+
421+ return codec_tuple(PyUnicode_DecodeRawUnicodeEscape(data, size, errors),
422+ size);
423+}
424+
425+static PyObject *
426+latin_1_decode(PyObject *self,
427+ PyObject *args)
428+{
429+ const char *data;
430+ Py_ssize_t size;
431+ const char *errors = NULL;
432+
433+ if (!PyArg_ParseTuple(args, "t#|z:latin_1_decode",
434+ &data, &size, &errors))
435+ return NULL;
436+
437+ return codec_tuple(PyUnicode_DecodeLatin1(data, size, errors),
438+ size);
439+}
440+
441+static PyObject *
442+ascii_decode(PyObject *self,
443+ PyObject *args)
444+{
445+ const char *data;
446+ Py_ssize_t size;
447+ const char *errors = NULL;
448+
449+ if (!PyArg_ParseTuple(args, "t#|z:ascii_decode",
450+ &data, &size, &errors))
451+ return NULL;
452+
453+ return codec_tuple(PyUnicode_DecodeASCII(data, size, errors),
454+ size);
455+}
456+
457+static PyObject *
458+charmap_decode(PyObject *self,
459+ PyObject *args)
460+{
461+ const char *data;
462+ Py_ssize_t size;
463+ const char *errors = NULL;
464+ PyObject *mapping = NULL;
465+
466+ if (!PyArg_ParseTuple(args, "t#|zO:charmap_decode",
467+ &data, &size, &errors, &mapping))
468+ return NULL;
469+ if (mapping == Py_None)
470+ mapping = NULL;
471+
472+ return codec_tuple(PyUnicode_DecodeCharmap(data, size, mapping, errors),
473+ size);
474+}
475+
476+#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
477+
478+static PyObject *
479+mbcs_decode(PyObject *self,
480+ PyObject *args)
481+{
482+ const char *data;
483+ Py_ssize_t size, consumed;
484+ const char *errors = NULL;
485+ int final = 0;
486+ PyObject *decoded;
487+
488+ if (!PyArg_ParseTuple(args, "t#|zi:mbcs_decode",
489+ &data, &size, &errors, &final))
490+ return NULL;
491+
492+ decoded = PyUnicode_DecodeMBCSStateful(
493+ data, size, errors, final ? NULL : &consumed);
494+ if (!decoded)
495+ return NULL;
496+ return codec_tuple(decoded, final ? size : consumed);
497+}
498+
499+#endif /* MS_WINDOWS */
500+
501+/* --- Encoder ------------------------------------------------------------ */
502+
503+static PyObject *
504+readbuffer_encode(PyObject *self,
505+ PyObject *args)
506+{
507+ const char *data;
508+ Py_ssize_t size;
509+ const char *errors = NULL;
510+
511+ if (!PyArg_ParseTuple(args, "s#|z:readbuffer_encode",
512+ &data, &size, &errors))
513+ return NULL;
514+
515+ return codec_tuple(PyString_FromStringAndSize(data, size),
516+ size);
517+}
518+
519+static PyObject *
520+charbuffer_encode(PyObject *self,
521+ PyObject *args)
522+{
523+ const char *data;
524+ Py_ssize_t size;
525+ const char *errors = NULL;
526+
527+ if (!PyArg_ParseTuple(args, "t#|z:charbuffer_encode",
528+ &data, &size, &errors))
529+ return NULL;
530+
531+ return codec_tuple(PyString_FromStringAndSize(data, size),
532+ size);
533+}
534+
535+static PyObject *
536+unicode_internal_encode(PyObject *self,
537+ PyObject *args)
538+{
539+ PyObject *obj;
540+ const char *errors = NULL;
541+ const char *data;
542+ Py_ssize_t size;
543+
544+ if (!PyArg_ParseTuple(args, "O|z:unicode_internal_encode",
545+ &obj, &errors))
546+ return NULL;
547+
548+ if (PyUnicode_Check(obj)) {
549+ data = PyUnicode_AS_DATA(obj);
550+ size = PyUnicode_GET_DATA_SIZE(obj);
551+ return codec_tuple(PyString_FromStringAndSize(data, size),
552+ size);
553+ }
554+ else {
555+ if (PyObject_AsReadBuffer(obj, (const void **)&data, &size))
556+ return NULL;
557+ return codec_tuple(PyString_FromStringAndSize(data, size),
558+ size);
559+ }
560+}
561+
562+static PyObject *
563+utf_7_encode(PyObject *self,
564+ PyObject *args)
565+{
566+ PyObject *str, *v;
567+ const char *errors = NULL;
568+
569+ if (!PyArg_ParseTuple(args, "O|z:utf_7_encode",
570+ &str, &errors))
571+ return NULL;
572+
573+ str = PyUnicode_FromObject(str);
574+ if (str == NULL)
575+ return NULL;
576+ v = codec_tuple(PyUnicode_EncodeUTF7(PyUnicode_AS_UNICODE(str),
577+ PyUnicode_GET_SIZE(str),
578+ 0,
579+ 0,
580+ errors),
581+ PyUnicode_GET_SIZE(str));
582+ Py_DECREF(str);
583+ return v;
584+}
585+
586+static PyObject *
587+utf_8_encode(PyObject *self,
588+ PyObject *args)
589+{
590+ PyObject *str, *v;
591+ const char *errors = NULL;
592+
593+ if (!PyArg_ParseTuple(args, "O|z:utf_8_encode",
594+ &str, &errors))
595+ return NULL;
596+
597+ str = PyUnicode_FromObject(str);
598+ if (str == NULL)
599+ return NULL;
600+ v = codec_tuple(PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(str),
601+ PyUnicode_GET_SIZE(str),
602+ errors),
603+ PyUnicode_GET_SIZE(str));
604+ Py_DECREF(str);
605+ return v;
606+}
607+
608+/* This version provides access to the byteorder parameter of the
609+ builtin UTF-16 codecs as optional third argument. It defaults to 0
610+ which means: use the native byte order and prepend the data with a
611+ BOM mark.
612+
613+*/
614+
615+static PyObject *
616+utf_16_encode(PyObject *self,
617+ PyObject *args)
618+{
619+ PyObject *str, *v;
620+ const char *errors = NULL;
621+ int byteorder = 0;
622+
623+ if (!PyArg_ParseTuple(args, "O|zi:utf_16_encode",
624+ &str, &errors, &byteorder))
625+ return NULL;
626+
627+ str = PyUnicode_FromObject(str);
628+ if (str == NULL)
629+ return NULL;
630+ v = codec_tuple(PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(str),
631+ PyUnicode_GET_SIZE(str),
632+ errors,
633+ byteorder),
634+ PyUnicode_GET_SIZE(str));
635+ Py_DECREF(str);
636+ return v;
637+}
638+
639+static PyObject *
640+utf_16_le_encode(PyObject *self,
641+ PyObject *args)
642+{
643+ PyObject *str, *v;
644+ const char *errors = NULL;
645+
646+ if (!PyArg_ParseTuple(args, "O|z:utf_16_le_encode",
647+ &str, &errors))
648+ return NULL;
649+
650+ str = PyUnicode_FromObject(str);
651+ if (str == NULL)
652+ return NULL;
653+ v = codec_tuple(PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(str),
654+ PyUnicode_GET_SIZE(str),
655+ errors,
656+ -1),
657+ PyUnicode_GET_SIZE(str));
658+ Py_DECREF(str);
659+ return v;
660+}
661+
662+static PyObject *
663+utf_16_be_encode(PyObject *self,
664+ PyObject *args)
665+{
666+ PyObject *str, *v;
667+ const char *errors = NULL;
668+
669+ if (!PyArg_ParseTuple(args, "O|z:utf_16_be_encode",
670+ &str, &errors))
671+ return NULL;
672+
673+ str = PyUnicode_FromObject(str);
674+ if (str == NULL)
675+ return NULL;
676+ v = codec_tuple(PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(str),
677+ PyUnicode_GET_SIZE(str),
678+ errors,
679+ +1),
680+ PyUnicode_GET_SIZE(str));
681+ Py_DECREF(str);
682+ return v;
683+}
684+
685+static PyObject *
686+unicode_escape_encode(PyObject *self,
687+ PyObject *args)
688+{
689+ PyObject *str, *v;
690+ const char *errors = NULL;
691+
692+ if (!PyArg_ParseTuple(args, "O|z:unicode_escape_encode",
693+ &str, &errors))
694+ return NULL;
695+
696+ str = PyUnicode_FromObject(str);
697+ if (str == NULL)
698+ return NULL;
699+ v = codec_tuple(PyUnicode_EncodeUnicodeEscape(PyUnicode_AS_UNICODE(str),
700+ PyUnicode_GET_SIZE(str)),
701+ PyUnicode_GET_SIZE(str));
702+ Py_DECREF(str);
703+ return v;
704+}
705+
706+static PyObject *
707+raw_unicode_escape_encode(PyObject *self,
708+ PyObject *args)
709+{
710+ PyObject *str, *v;
711+ const char *errors = NULL;
712+
713+ if (!PyArg_ParseTuple(args, "O|z:raw_unicode_escape_encode",
714+ &str, &errors))
715+ return NULL;
716+
717+ str = PyUnicode_FromObject(str);
718+ if (str == NULL)
719+ return NULL;
720+ v = codec_tuple(PyUnicode_EncodeRawUnicodeEscape(
721+ PyUnicode_AS_UNICODE(str),
722+ PyUnicode_GET_SIZE(str)),
723+ PyUnicode_GET_SIZE(str));
724+ Py_DECREF(str);
725+ return v;
726+}
727+
728+static PyObject *
729+latin_1_encode(PyObject *self,
730+ PyObject *args)
731+{
732+ PyObject *str, *v;
733+ const char *errors = NULL;
734+
735+ if (!PyArg_ParseTuple(args, "O|z:latin_1_encode",
736+ &str, &errors))
737+ return NULL;
738+
739+ str = PyUnicode_FromObject(str);
740+ if (str == NULL)
741+ return NULL;
742+ v = codec_tuple(PyUnicode_EncodeLatin1(
743+ PyUnicode_AS_UNICODE(str),
744+ PyUnicode_GET_SIZE(str),
745+ errors),
746+ PyUnicode_GET_SIZE(str));
747+ Py_DECREF(str);
748+ return v;
749+}
750+
751+static PyObject *
752+ascii_encode(PyObject *self,
753+ PyObject *args)
754+{
755+ PyObject *str, *v;
756+ const char *errors = NULL;
757+
758+ if (!PyArg_ParseTuple(args, "O|z:ascii_encode",
759+ &str, &errors))
760+ return NULL;
761+
762+ str = PyUnicode_FromObject(str);
763+ if (str == NULL)
764+ return NULL;
765+ v = codec_tuple(PyUnicode_EncodeASCII(
766+ PyUnicode_AS_UNICODE(str),
767+ PyUnicode_GET_SIZE(str),
768+ errors),
769+ PyUnicode_GET_SIZE(str));
770+ Py_DECREF(str);
771+ return v;
772+}
773+
774+static PyObject *
775+charmap_encode(PyObject *self,
776+ PyObject *args)
777+{
778+ PyObject *str, *v;
779+ const char *errors = NULL;
780+ PyObject *mapping = NULL;
781+
782+ if (!PyArg_ParseTuple(args, "O|zO:charmap_encode",
783+ &str, &errors, &mapping))
784+ return NULL;
785+ if (mapping == Py_None)
786+ mapping = NULL;
787+
788+ str = PyUnicode_FromObject(str);
789+ if (str == NULL)
790+ return NULL;
791+ v = codec_tuple(PyUnicode_EncodeCharmap(
792+ PyUnicode_AS_UNICODE(str),
793+ PyUnicode_GET_SIZE(str),
794+ mapping,
795+ errors),
796+ PyUnicode_GET_SIZE(str));
797+ Py_DECREF(str);
798+ return v;
799+}
800+
801+static PyObject*
802+charmap_build(PyObject *self, PyObject *args)
803+{
804+ PyObject *map;
805+ if (!PyArg_ParseTuple(args, "U:charmap_build", &map))
806+ return NULL;
807+ return PyUnicode_BuildEncodingMap(map);
808+}
809+
810+#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
811+
812+static PyObject *
813+mbcs_encode(PyObject *self,
814+ PyObject *args)
815+{
816+ PyObject *str, *v;
817+ const char *errors = NULL;
818+
819+ if (!PyArg_ParseTuple(args, "O|z:mbcs_encode",
820+ &str, &errors))
821+ return NULL;
822+
823+ str = PyUnicode_FromObject(str);
824+ if (str == NULL)
825+ return NULL;
826+ v = codec_tuple(PyUnicode_EncodeMBCS(
827+ PyUnicode_AS_UNICODE(str),
828+ PyUnicode_GET_SIZE(str),
829+ errors),
830+ PyUnicode_GET_SIZE(str));
831+ Py_DECREF(str);
832+ return v;
833+}
834+
835+#endif /* MS_WINDOWS */
836+#endif /* Py_USING_UNICODE */
837+
838+/* --- Error handler registry --------------------------------------------- */
839+
840+PyDoc_STRVAR(register_error__doc__,
841+"register_error(errors, handler)\n\
842+\n\
843+Register the specified error handler under the name\n\
844+errors. handler must be a callable object, that\n\
845+will be called with an exception instance containing\n\
846+information about the location of the encoding/decoding\n\
847+error and must return a (replacement, new position) tuple.");
848+
849+static PyObject *register_error(PyObject *self, PyObject *args)
850+{
851+ const char *name;
852+ PyObject *handler;
853+
854+ if (!PyArg_ParseTuple(args, "sO:register_error",
855+ &name, &handler))
856+ return NULL;
857+ if (PyCodec_RegisterError(name, handler))
858+ return NULL;
859+ Py_RETURN_NONE;
860+}
861+
862+PyDoc_STRVAR(lookup_error__doc__,
863+"lookup_error(errors) -> handler\n\
864+\n\
865+Return the error handler for the specified error handling name\n\
866+or raise a LookupError, if no handler exists under this name.");
867+
868+static PyObject *lookup_error(PyObject *self, PyObject *args)
869+{
870+ const char *name;
871+
872+ if (!PyArg_ParseTuple(args, "s:lookup_error",
873+ &name))
874+ return NULL;
875+ return PyCodec_LookupError(name);
876+}
877+
878+/* --- Module API --------------------------------------------------------- */
879+
880+static PyMethodDef _codecs_functions[] = {
881+ {"register", codec_register, METH_O,
882+ register__doc__},
883+ {"lookup", codec_lookup, METH_VARARGS,
884+ lookup__doc__},
885+ {"encode", codec_encode, METH_VARARGS,
886+ encode__doc__},
887+ {"decode", codec_decode, METH_VARARGS,
888+ decode__doc__},
889+ {"escape_encode", escape_encode, METH_VARARGS},
890+ {"escape_decode", escape_decode, METH_VARARGS},
891+#ifdef Py_USING_UNICODE
892+ {"utf_8_encode", utf_8_encode, METH_VARARGS},
893+ {"utf_8_decode", utf_8_decode, METH_VARARGS},
894+ {"utf_7_encode", utf_7_encode, METH_VARARGS},
895+ {"utf_7_decode", utf_7_decode, METH_VARARGS},
896+ {"utf_16_encode", utf_16_encode, METH_VARARGS},
897+ {"utf_16_le_encode", utf_16_le_encode, METH_VARARGS},
898+ {"utf_16_be_encode", utf_16_be_encode, METH_VARARGS},
899+ {"utf_16_decode", utf_16_decode, METH_VARARGS},
900+ {"utf_16_le_decode", utf_16_le_decode, METH_VARARGS},
901+ {"utf_16_be_decode", utf_16_be_decode, METH_VARARGS},
902+ {"utf_16_ex_decode", utf_16_ex_decode, METH_VARARGS},
903+ {"unicode_escape_encode", unicode_escape_encode, METH_VARARGS},
904+ {"unicode_escape_decode", unicode_escape_decode, METH_VARARGS},
905+ {"unicode_internal_encode", unicode_internal_encode, METH_VARARGS},
906+ {"unicode_internal_decode", unicode_internal_decode, METH_VARARGS},
907+ {"raw_unicode_escape_encode", raw_unicode_escape_encode, METH_VARARGS},
908+ {"raw_unicode_escape_decode", raw_unicode_escape_decode, METH_VARARGS},
909+ {"latin_1_encode", latin_1_encode, METH_VARARGS},
910+ {"latin_1_decode", latin_1_decode, METH_VARARGS},
911+ {"ascii_encode", ascii_encode, METH_VARARGS},
912+ {"ascii_decode", ascii_decode, METH_VARARGS},
913+ {"charmap_encode", charmap_encode, METH_VARARGS},
914+ {"charmap_decode", charmap_decode, METH_VARARGS},
915+ {"charmap_build", charmap_build, METH_VARARGS},
916+ {"readbuffer_encode", readbuffer_encode, METH_VARARGS},
917+ {"charbuffer_encode", charbuffer_encode, METH_VARARGS},
918+#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
919+ {"mbcs_encode", mbcs_encode, METH_VARARGS},
920+ {"mbcs_decode", mbcs_decode, METH_VARARGS},
921+#endif
922+#endif /* Py_USING_UNICODE */
923+ {"register_error", register_error, METH_VARARGS,
924+ register_error__doc__},
925+ {"lookup_error", lookup_error, METH_VARARGS,
926+ lookup_error__doc__},
927+ {NULL, NULL} /* sentinel */
928+};
929+
930+PyMODINIT_FUNC
931+init_codecs(void)
932+{
933+ Py_InitModule("_codecs", _codecs_functions);
934+}
sys/src/cmd/python/Modules/_csv.c+1604−0
@@ -0,0 +1,1604 @@
1+/* csv module */
2+
3+/*
4+
5+This module provides the low-level underpinnings of a CSV reading/writing
6+module. Users should not use this module directly, but import the csv.py
7+module instead.
8+
9+**** For people modifying this code, please note that as of this writing
10+**** (2003-03-23), it is intended that this code should work with Python
11+**** 2.2.
12+
13+*/
14+
15+#define MODULE_VERSION "1.0"
16+
17+#include "Python.h"
18+#include "structmember.h"
19+
20+
21+/* begin 2.2 compatibility macros */
22+#ifndef PyDoc_STRVAR
23+/* Define macros for inline documentation. */
24+#define PyDoc_VAR(name) static char name[]
25+#define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str)
26+#ifdef WITH_DOC_STRINGS
27+#define PyDoc_STR(str) str
28+#else
29+#define PyDoc_STR(str) ""
30+#endif
31+#endif /* ifndef PyDoc_STRVAR */
32+
33+#ifndef PyMODINIT_FUNC
34+# if defined(__cplusplus)
35+# define PyMODINIT_FUNC extern "C" void
36+# else /* __cplusplus */
37+# define PyMODINIT_FUNC void
38+# endif /* __cplusplus */
39+#endif
40+
41+#ifndef Py_CLEAR
42+#define Py_CLEAR(op) \
43+ do { \
44+ if (op) { \
45+ PyObject *tmp = (PyObject *)(op); \
46+ (op) = NULL; \
47+ Py_DECREF(tmp); \
48+ } \
49+ } while (0)
50+#endif
51+#ifndef Py_VISIT
52+#define Py_VISIT(op) \
53+ do { \
54+ if (op) { \
55+ int vret = visit((PyObject *)(op), arg); \
56+ if (vret) \
57+ return vret; \
58+ } \
59+ } while (0)
60+#endif
61+
62+/* end 2.2 compatibility macros */
63+
64+#define IS_BASESTRING(o) \
65+ PyObject_TypeCheck(o, &PyBaseString_Type)
66+
67+static PyObject *error_obj; /* CSV exception */
68+static PyObject *dialects; /* Dialect registry */
69+static long field_limit = 128 * 1024; /* max parsed field size */
70+
71+typedef enum {
72+ START_RECORD, START_FIELD, ESCAPED_CHAR, IN_FIELD,
73+ IN_QUOTED_FIELD, ESCAPE_IN_QUOTED_FIELD, QUOTE_IN_QUOTED_FIELD,
74+ EAT_CRNL
75+} ParserState;
76+
77+typedef enum {
78+ QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE
79+} QuoteStyle;
80+
81+typedef struct {
82+ QuoteStyle style;
83+ char *name;
84+} StyleDesc;
85+
86+static StyleDesc quote_styles[] = {
87+ { QUOTE_MINIMAL, "QUOTE_MINIMAL" },
88+ { QUOTE_ALL, "QUOTE_ALL" },
89+ { QUOTE_NONNUMERIC, "QUOTE_NONNUMERIC" },
90+ { QUOTE_NONE, "QUOTE_NONE" },
91+ { 0 }
92+};
93+
94+typedef struct {
95+ PyObject_HEAD
96+
97+ int doublequote; /* is " represented by ""? */
98+ char delimiter; /* field separator */
99+ char quotechar; /* quote character */
100+ char escapechar; /* escape character */
101+ int skipinitialspace; /* ignore spaces following delimiter? */
102+ PyObject *lineterminator; /* string to write between records */
103+ int quoting; /* style of quoting to write */
104+
105+ int strict; /* raise exception on bad CSV */
106+} DialectObj;
107+
108+staticforward PyTypeObject Dialect_Type;
109+
110+typedef struct {
111+ PyObject_HEAD
112+
113+ PyObject *input_iter; /* iterate over this for input lines */
114+
115+ DialectObj *dialect; /* parsing dialect */
116+
117+ PyObject *fields; /* field list for current record */
118+ ParserState state; /* current CSV parse state */
119+ char *field; /* build current field in here */
120+ int field_size; /* size of allocated buffer */
121+ int field_len; /* length of current field */
122+ int numeric_field; /* treat field as numeric */
123+ unsigned long line_num; /* Source-file line number */
124+} ReaderObj;
125+
126+staticforward PyTypeObject Reader_Type;
127+
128+#define ReaderObject_Check(v) ((v)->ob_type == &Reader_Type)
129+
130+typedef struct {
131+ PyObject_HEAD
132+
133+ PyObject *writeline; /* write output lines to this file */
134+
135+ DialectObj *dialect; /* parsing dialect */
136+
137+ char *rec; /* buffer for parser.join */
138+ int rec_size; /* size of allocated record */
139+ int rec_len; /* length of record */
140+ int num_fields; /* number of fields in record */
141+} WriterObj;
142+
143+staticforward PyTypeObject Writer_Type;
144+
145+/*
146+ * DIALECT class
147+ */
148+
149+static PyObject *
150+get_dialect_from_registry(PyObject * name_obj)
151+{
152+ PyObject *dialect_obj;
153+
154+ dialect_obj = PyDict_GetItem(dialects, name_obj);
155+ if (dialect_obj == NULL) {
156+ if (!PyErr_Occurred())
157+ PyErr_Format(error_obj, "unknown dialect");
158+ }
159+ else
160+ Py_INCREF(dialect_obj);
161+ return dialect_obj;
162+}
163+
164+static PyObject *
165+get_string(PyObject *str)
166+{
167+ Py_XINCREF(str);
168+ return str;
169+}
170+
171+static PyObject *
172+get_nullchar_as_None(char c)
173+{
174+ if (c == '\0') {
175+ Py_INCREF(Py_None);
176+ return Py_None;
177+ }
178+ else
179+ return PyString_FromStringAndSize((char*)&c, 1);
180+}
181+
182+static PyObject *
183+Dialect_get_lineterminator(DialectObj *self)
184+{
185+ return get_string(self->lineterminator);
186+}
187+
188+static PyObject *
189+Dialect_get_escapechar(DialectObj *self)
190+{
191+ return get_nullchar_as_None(self->escapechar);
192+}
193+
194+static PyObject *
195+Dialect_get_quotechar(DialectObj *self)
196+{
197+ return get_nullchar_as_None(self->quotechar);
198+}
199+
200+static PyObject *
201+Dialect_get_quoting(DialectObj *self)
202+{
203+ return PyInt_FromLong(self->quoting);
204+}
205+
206+static int
207+_set_bool(const char *name, int *target, PyObject *src, int dflt)
208+{
209+ if (src == NULL)
210+ *target = dflt;
211+ else
212+ *target = PyObject_IsTrue(src);
213+ return 0;
214+}
215+
216+static int
217+_set_int(const char *name, int *target, PyObject *src, int dflt)
218+{
219+ if (src == NULL)
220+ *target = dflt;
221+ else {
222+ if (!PyInt_Check(src)) {
223+ PyErr_Format(PyExc_TypeError,
224+ "\"%s\" must be an integer", name);
225+ return -1;
226+ }
227+ *target = PyInt_AsLong(src);
228+ }
229+ return 0;
230+}
231+
232+static int
233+_set_char(const char *name, char *target, PyObject *src, char dflt)
234+{
235+ if (src == NULL)
236+ *target = dflt;
237+ else {
238+ if (src == Py_None || PyString_Size(src) == 0)
239+ *target = '\0';
240+ else if (!PyString_Check(src) || PyString_Size(src) != 1) {
241+ PyErr_Format(PyExc_TypeError,
242+ "\"%s\" must be an 1-character string",
243+ name);
244+ return -1;
245+ }
246+ else {
247+ char *s = PyString_AsString(src);
248+ if (s == NULL)
249+ return -1;
250+ *target = s[0];
251+ }
252+ }
253+ return 0;
254+}
255+
256+static int
257+_set_str(const char *name, PyObject **target, PyObject *src, const char *dflt)
258+{
259+ if (src == NULL)
260+ *target = PyString_FromString(dflt);
261+ else {
262+ if (src == Py_None)
263+ *target = NULL;
264+ else if (!IS_BASESTRING(src)) {
265+ PyErr_Format(PyExc_TypeError,
266+ "\"%s\" must be an string", name);
267+ return -1;
268+ }
269+ else {
270+ Py_XDECREF(*target);
271+ Py_INCREF(src);
272+ *target = src;
273+ }
274+ }
275+ return 0;
276+}
277+
278+static int
279+dialect_check_quoting(int quoting)
280+{
281+ StyleDesc *qs = quote_styles;
282+
283+ for (qs = quote_styles; qs->name; qs++) {
284+ if (qs->style == quoting)
285+ return 0;
286+ }
287+ PyErr_Format(PyExc_TypeError, "bad \"quoting\" value");
288+ return -1;
289+}
290+
291+#define D_OFF(x) offsetof(DialectObj, x)
292+
293+static struct PyMemberDef Dialect_memberlist[] = {
294+ { "delimiter", T_CHAR, D_OFF(delimiter), READONLY },
295+ { "skipinitialspace", T_INT, D_OFF(skipinitialspace), READONLY },
296+ { "doublequote", T_INT, D_OFF(doublequote), READONLY },
297+ { "strict", T_INT, D_OFF(strict), READONLY },
298+ { NULL }
299+};
300+
301+static PyGetSetDef Dialect_getsetlist[] = {
302+ { "escapechar", (getter)Dialect_get_escapechar},
303+ { "lineterminator", (getter)Dialect_get_lineterminator},
304+ { "quotechar", (getter)Dialect_get_quotechar},
305+ { "quoting", (getter)Dialect_get_quoting},
306+ {NULL},
307+};
308+
309+static void
310+Dialect_dealloc(DialectObj *self)
311+{
312+ Py_XDECREF(self->lineterminator);
313+ self->ob_type->tp_free((PyObject *)self);
314+}
315+
316+static char *dialect_kws[] = {
317+ "dialect",
318+ "delimiter",
319+ "doublequote",
320+ "escapechar",
321+ "lineterminator",
322+ "quotechar",
323+ "quoting",
324+ "skipinitialspace",
325+ "strict",
326+ NULL
327+};
328+
329+static PyObject *
330+dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
331+{
332+ DialectObj *self;
333+ PyObject *ret = NULL;
334+ PyObject *dialect = NULL;
335+ PyObject *delimiter = NULL;
336+ PyObject *doublequote = NULL;
337+ PyObject *escapechar = NULL;
338+ PyObject *lineterminator = NULL;
339+ PyObject *quotechar = NULL;
340+ PyObject *quoting = NULL;
341+ PyObject *skipinitialspace = NULL;
342+ PyObject *strict = NULL;
343+
344+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
345+ "|OOOOOOOOO", dialect_kws,
346+ &dialect,
347+ &delimiter,
348+ &doublequote,
349+ &escapechar,
350+ &lineterminator,
351+ &quotechar,
352+ &quoting,
353+ &skipinitialspace,
354+ &strict))
355+ return NULL;
356+
357+ if (dialect != NULL) {
358+ if (IS_BASESTRING(dialect)) {
359+ dialect = get_dialect_from_registry(dialect);
360+ if (dialect == NULL)
361+ return NULL;
362+ }
363+ else
364+ Py_INCREF(dialect);
365+ /* Can we reuse this instance? */
366+ if (PyObject_TypeCheck(dialect, &Dialect_Type) &&
367+ delimiter == 0 &&
368+ doublequote == 0 &&
369+ escapechar == 0 &&
370+ lineterminator == 0 &&
371+ quotechar == 0 &&
372+ quoting == 0 &&
373+ skipinitialspace == 0 &&
374+ strict == 0)
375+ return dialect;
376+ }
377+
378+ self = (DialectObj *)type->tp_alloc(type, 0);
379+ if (self == NULL) {
380+ Py_XDECREF(dialect);
381+ return NULL;
382+ }
383+ self->lineterminator = NULL;
384+
385+ Py_XINCREF(delimiter);
386+ Py_XINCREF(doublequote);
387+ Py_XINCREF(escapechar);
388+ Py_XINCREF(lineterminator);
389+ Py_XINCREF(quotechar);
390+ Py_XINCREF(quoting);
391+ Py_XINCREF(skipinitialspace);
392+ Py_XINCREF(strict);
393+ if (dialect != NULL) {
394+#define DIALECT_GETATTR(v, n) \
395+ if (v == NULL) \
396+ v = PyObject_GetAttrString(dialect, n)
397+ DIALECT_GETATTR(delimiter, "delimiter");
398+ DIALECT_GETATTR(doublequote, "doublequote");
399+ DIALECT_GETATTR(escapechar, "escapechar");
400+ DIALECT_GETATTR(lineterminator, "lineterminator");
401+ DIALECT_GETATTR(quotechar, "quotechar");
402+ DIALECT_GETATTR(quoting, "quoting");
403+ DIALECT_GETATTR(skipinitialspace, "skipinitialspace");
404+ DIALECT_GETATTR(strict, "strict");
405+ PyErr_Clear();
406+ }
407+
408+ /* check types and convert to C values */
409+#define DIASET(meth, name, target, src, dflt) \
410+ if (meth(name, target, src, dflt)) \
411+ goto err
412+ DIASET(_set_char, "delimiter", &self->delimiter, delimiter, ',');
413+ DIASET(_set_bool, "doublequote", &self->doublequote, doublequote, 1);
414+ DIASET(_set_char, "escapechar", &self->escapechar, escapechar, 0);
415+ DIASET(_set_str, "lineterminator", &self->lineterminator, lineterminator, "\r\n");
416+ DIASET(_set_char, "quotechar", &self->quotechar, quotechar, '"');
417+ DIASET(_set_int, "quoting", &self->quoting, quoting, QUOTE_MINIMAL);
418+ DIASET(_set_bool, "skipinitialspace", &self->skipinitialspace, skipinitialspace, 0);
419+ DIASET(_set_bool, "strict", &self->strict, strict, 0);
420+
421+ /* validate options */
422+ if (dialect_check_quoting(self->quoting))
423+ goto err;
424+ if (self->delimiter == 0) {
425+ PyErr_SetString(PyExc_TypeError, "delimiter must be set");
426+ goto err;
427+ }
428+ if (quotechar == Py_None && quoting == NULL)
429+ self->quoting = QUOTE_NONE;
430+ if (self->quoting != QUOTE_NONE && self->quotechar == 0) {
431+ PyErr_SetString(PyExc_TypeError,
432+ "quotechar must be set if quoting enabled");
433+ goto err;
434+ }
435+ if (self->lineterminator == 0) {
436+ PyErr_SetString(PyExc_TypeError, "lineterminator must be set");
437+ goto err;
438+ }
439+
440+ ret = (PyObject *)self;
441+ Py_INCREF(self);
442+err:
443+ Py_XDECREF(self);
444+ Py_XDECREF(dialect);
445+ Py_XDECREF(delimiter);
446+ Py_XDECREF(doublequote);
447+ Py_XDECREF(escapechar);
448+ Py_XDECREF(lineterminator);
449+ Py_XDECREF(quotechar);
450+ Py_XDECREF(quoting);
451+ Py_XDECREF(skipinitialspace);
452+ Py_XDECREF(strict);
453+ return ret;
454+}
455+
456+
457+PyDoc_STRVAR(Dialect_Type_doc,
458+"CSV dialect\n"
459+"\n"
460+"The Dialect type records CSV parsing and generation options.\n");
461+
462+static PyTypeObject Dialect_Type = {
463+ PyObject_HEAD_INIT(NULL)
464+ 0, /* ob_size */
465+ "_csv.Dialect", /* tp_name */
466+ sizeof(DialectObj), /* tp_basicsize */
467+ 0, /* tp_itemsize */
468+ /* methods */
469+ (destructor)Dialect_dealloc, /* tp_dealloc */
470+ (printfunc)0, /* tp_print */
471+ (getattrfunc)0, /* tp_getattr */
472+ (setattrfunc)0, /* tp_setattr */
473+ (cmpfunc)0, /* tp_compare */
474+ (reprfunc)0, /* tp_repr */
475+ 0, /* tp_as_number */
476+ 0, /* tp_as_sequence */
477+ 0, /* tp_as_mapping */
478+ (hashfunc)0, /* tp_hash */
479+ (ternaryfunc)0, /* tp_call */
480+ (reprfunc)0, /* tp_str */
481+ 0, /* tp_getattro */
482+ 0, /* tp_setattro */
483+ 0, /* tp_as_buffer */
484+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
485+ Dialect_Type_doc, /* tp_doc */
486+ 0, /* tp_traverse */
487+ 0, /* tp_clear */
488+ 0, /* tp_richcompare */
489+ 0, /* tp_weaklistoffset */
490+ 0, /* tp_iter */
491+ 0, /* tp_iternext */
492+ 0, /* tp_methods */
493+ Dialect_memberlist, /* tp_members */
494+ Dialect_getsetlist, /* tp_getset */
495+ 0, /* tp_base */
496+ 0, /* tp_dict */
497+ 0, /* tp_descr_get */
498+ 0, /* tp_descr_set */
499+ 0, /* tp_dictoffset */
500+ 0, /* tp_init */
501+ 0, /* tp_alloc */
502+ dialect_new, /* tp_new */
503+ 0, /* tp_free */
504+};
505+
506+/*
507+ * Return an instance of the dialect type, given a Python instance or kwarg
508+ * description of the dialect
509+ */
510+static PyObject *
511+_call_dialect(PyObject *dialect_inst, PyObject *kwargs)
512+{
513+ PyObject *ctor_args;
514+ PyObject *dialect;
515+
516+ ctor_args = Py_BuildValue(dialect_inst ? "(O)" : "()", dialect_inst);
517+ if (ctor_args == NULL)
518+ return NULL;
519+ dialect = PyObject_Call((PyObject *)&Dialect_Type, ctor_args, kwargs);
520+ Py_DECREF(ctor_args);
521+ return dialect;
522+}
523+
524+/*
525+ * READER
526+ */
527+static int
528+parse_save_field(ReaderObj *self)
529+{
530+ PyObject *field;
531+
532+ field = PyString_FromStringAndSize(self->field, self->field_len);
533+ if (field == NULL)
534+ return -1;
535+ self->field_len = 0;
536+ if (self->numeric_field) {
537+ PyObject *tmp;
538+
539+ self->numeric_field = 0;
540+ tmp = PyNumber_Float(field);
541+ if (tmp == NULL) {
542+ Py_DECREF(field);
543+ return -1;
544+ }
545+ Py_DECREF(field);
546+ field = tmp;
547+ }
548+ PyList_Append(self->fields, field);
549+ Py_DECREF(field);
550+ return 0;
551+}
552+
553+static int
554+parse_grow_buff(ReaderObj *self)
555+{
556+ if (self->field_size == 0) {
557+ self->field_size = 4096;
558+ if (self->field != NULL)
559+ PyMem_Free(self->field);
560+ self->field = PyMem_Malloc(self->field_size);
561+ }
562+ else {
563+ self->field_size *= 2;
564+ self->field = PyMem_Realloc(self->field, self->field_size);
565+ }
566+ if (self->field == NULL) {
567+ PyErr_NoMemory();
568+ return 0;
569+ }
570+ return 1;
571+}
572+
573+static int
574+parse_add_char(ReaderObj *self, char c)
575+{
576+ if (self->field_len >= field_limit) {
577+ PyErr_Format(error_obj, "field larger than field limit (%ld)",
578+ field_limit);
579+ return -1;
580+ }
581+ if (self->field_len == self->field_size && !parse_grow_buff(self))
582+ return -1;
583+ self->field[self->field_len++] = c;
584+ return 0;
585+}
586+
587+static int
588+parse_process_char(ReaderObj *self, char c)
589+{
590+ DialectObj *dialect = self->dialect;
591+
592+ switch (self->state) {
593+ case START_RECORD:
594+ /* start of record */
595+ if (c == '\0')
596+ /* empty line - return [] */
597+ break;
598+ else if (c == '\n' || c == '\r') {
599+ self->state = EAT_CRNL;
600+ break;
601+ }
602+ /* normal character - handle as START_FIELD */
603+ self->state = START_FIELD;
604+ /* fallthru */
605+ case START_FIELD:
606+ /* expecting field */
607+ if (c == '\n' || c == '\r' || c == '\0') {
608+ /* save empty field - return [fields] */
609+ if (parse_save_field(self) < 0)
610+ return -1;
611+ self->state = (c == '\0' ? START_RECORD : EAT_CRNL);
612+ }
613+ else if (c == dialect->quotechar &&
614+ dialect->quoting != QUOTE_NONE) {
615+ /* start quoted field */
616+ self->state = IN_QUOTED_FIELD;
617+ }
618+ else if (c == dialect->escapechar) {
619+ /* possible escaped character */
620+ self->state = ESCAPED_CHAR;
621+ }
622+ else if (c == ' ' && dialect->skipinitialspace)
623+ /* ignore space at start of field */
624+ ;
625+ else if (c == dialect->delimiter) {
626+ /* save empty field */
627+ if (parse_save_field(self) < 0)
628+ return -1;
629+ }
630+ else {
631+ /* begin new unquoted field */
632+ if (dialect->quoting == QUOTE_NONNUMERIC)
633+ self->numeric_field = 1;
634+ if (parse_add_char(self, c) < 0)
635+ return -1;
636+ self->state = IN_FIELD;
637+ }
638+ break;
639+
640+ case ESCAPED_CHAR:
641+ if (c == '\0')
642+ c = '\n';
643+ if (parse_add_char(self, c) < 0)
644+ return -1;
645+ self->state = IN_FIELD;
646+ break;
647+
648+ case IN_FIELD:
649+ /* in unquoted field */
650+ if (c == '\n' || c == '\r' || c == '\0') {
651+ /* end of line - return [fields] */
652+ if (parse_save_field(self) < 0)
653+ return -1;
654+ self->state = (c == '\0' ? START_RECORD : EAT_CRNL);
655+ }
656+ else if (c == dialect->escapechar) {
657+ /* possible escaped character */
658+ self->state = ESCAPED_CHAR;
659+ }
660+ else if (c == dialect->delimiter) {
661+ /* save field - wait for new field */
662+ if (parse_save_field(self) < 0)
663+ return -1;
664+ self->state = START_FIELD;
665+ }
666+ else {
667+ /* normal character - save in field */
668+ if (parse_add_char(self, c) < 0)
669+ return -1;
670+ }
671+ break;
672+
673+ case IN_QUOTED_FIELD:
674+ /* in quoted field */
675+ if (c == '\0')
676+ ;
677+ else if (c == dialect->escapechar) {
678+ /* Possible escape character */
679+ self->state = ESCAPE_IN_QUOTED_FIELD;
680+ }
681+ else if (c == dialect->quotechar &&
682+ dialect->quoting != QUOTE_NONE) {
683+ if (dialect->doublequote) {
684+ /* doublequote; " represented by "" */
685+ self->state = QUOTE_IN_QUOTED_FIELD;
686+ }
687+ else {
688+ /* end of quote part of field */
689+ self->state = IN_FIELD;
690+ }
691+ }
692+ else {
693+ /* normal character - save in field */
694+ if (parse_add_char(self, c) < 0)
695+ return -1;
696+ }
697+ break;
698+
699+ case ESCAPE_IN_QUOTED_FIELD:
700+ if (c == '\0')
701+ c = '\n';
702+ if (parse_add_char(self, c) < 0)
703+ return -1;
704+ self->state = IN_QUOTED_FIELD;
705+ break;
706+
707+ case QUOTE_IN_QUOTED_FIELD:
708+ /* doublequote - seen a quote in an quoted field */
709+ if (dialect->quoting != QUOTE_NONE &&
710+ c == dialect->quotechar) {
711+ /* save "" as " */
712+ if (parse_add_char(self, c) < 0)
713+ return -1;
714+ self->state = IN_QUOTED_FIELD;
715+ }
716+ else if (c == dialect->delimiter) {
717+ /* save field - wait for new field */
718+ if (parse_save_field(self) < 0)
719+ return -1;
720+ self->state = START_FIELD;
721+ }
722+ else if (c == '\n' || c == '\r' || c == '\0') {
723+ /* end of line - return [fields] */
724+ if (parse_save_field(self) < 0)
725+ return -1;
726+ self->state = (c == '\0' ? START_RECORD : EAT_CRNL);
727+ }
728+ else if (!dialect->strict) {
729+ if (parse_add_char(self, c) < 0)
730+ return -1;
731+ self->state = IN_FIELD;
732+ }
733+ else {
734+ /* illegal */
735+ PyErr_Format(error_obj, "'%c' expected after '%c'",
736+ dialect->delimiter,
737+ dialect->quotechar);
738+ return -1;
739+ }
740+ break;
741+
742+ case EAT_CRNL:
743+ if (c == '\n' || c == '\r')
744+ ;
745+ else if (c == '\0')
746+ self->state = START_RECORD;
747+ else {
748+ PyErr_Format(error_obj, "new-line character seen in unquoted field - do you need to open the file in universal-newline mode?");
749+ return -1;
750+ }
751+ break;
752+
753+ }
754+ return 0;
755+}
756+
757+static int
758+parse_reset(ReaderObj *self)
759+{
760+ Py_XDECREF(self->fields);
761+ self->fields = PyList_New(0);
762+ if (self->fields == NULL)
763+ return -1;
764+ self->field_len = 0;
765+ self->state = START_RECORD;
766+ self->numeric_field = 0;
767+ return 0;
768+}
769+
770+static PyObject *
771+Reader_iternext(ReaderObj *self)
772+{
773+ PyObject *lineobj;
774+ PyObject *fields = NULL;
775+ char *line, c;
776+ int linelen;
777+
778+ if (parse_reset(self) < 0)
779+ return NULL;
780+ do {
781+ lineobj = PyIter_Next(self->input_iter);
782+ if (lineobj == NULL) {
783+ /* End of input OR exception */
784+ if (!PyErr_Occurred() && self->field_len != 0)
785+ PyErr_Format(error_obj,
786+ "newline inside string");
787+ return NULL;
788+ }
789+ ++self->line_num;
790+
791+ line = PyString_AsString(lineobj);
792+ linelen = PyString_Size(lineobj);
793+
794+ if (line == NULL || linelen < 0) {
795+ Py_DECREF(lineobj);
796+ return NULL;
797+ }
798+ while (linelen--) {
799+ c = *line++;
800+ if (c == '\0') {
801+ Py_DECREF(lineobj);
802+ PyErr_Format(error_obj,
803+ "line contains NULL byte");
804+ goto err;
805+ }
806+ if (parse_process_char(self, c) < 0) {
807+ Py_DECREF(lineobj);
808+ goto err;
809+ }
810+ }
811+ Py_DECREF(lineobj);
812+ if (parse_process_char(self, 0) < 0)
813+ goto err;
814+ } while (self->state != START_RECORD);
815+
816+ fields = self->fields;
817+ self->fields = NULL;
818+err:
819+ return fields;
820+}
821+
822+static void
823+Reader_dealloc(ReaderObj *self)
824+{
825+ PyObject_GC_UnTrack(self);
826+ Py_XDECREF(self->dialect);
827+ Py_XDECREF(self->input_iter);
828+ Py_XDECREF(self->fields);
829+ if (self->field != NULL)
830+ PyMem_Free(self->field);
831+ PyObject_GC_Del(self);
832+}
833+
834+static int
835+Reader_traverse(ReaderObj *self, visitproc visit, void *arg)
836+{
837+ Py_VISIT(self->dialect);
838+ Py_VISIT(self->input_iter);
839+ Py_VISIT(self->fields);
840+ return 0;
841+}
842+
843+static int
844+Reader_clear(ReaderObj *self)
845+{
846+ Py_CLEAR(self->dialect);
847+ Py_CLEAR(self->input_iter);
848+ Py_CLEAR(self->fields);
849+ return 0;
850+}
851+
852+PyDoc_STRVAR(Reader_Type_doc,
853+"CSV reader\n"
854+"\n"
855+"Reader objects are responsible for reading and parsing tabular data\n"
856+"in CSV format.\n"
857+);
858+
859+static struct PyMethodDef Reader_methods[] = {
860+ { NULL, NULL }
861+};
862+#define R_OFF(x) offsetof(ReaderObj, x)
863+
864+static struct PyMemberDef Reader_memberlist[] = {
865+ { "dialect", T_OBJECT, R_OFF(dialect), RO },
866+ { "line_num", T_ULONG, R_OFF(line_num), RO },
867+ { NULL }
868+};
869+
870+
871+static PyTypeObject Reader_Type = {
872+ PyObject_HEAD_INIT(NULL)
873+ 0, /*ob_size*/
874+ "_csv.reader", /*tp_name*/
875+ sizeof(ReaderObj), /*tp_basicsize*/
876+ 0, /*tp_itemsize*/
877+ /* methods */
878+ (destructor)Reader_dealloc, /*tp_dealloc*/
879+ (printfunc)0, /*tp_print*/
880+ (getattrfunc)0, /*tp_getattr*/
881+ (setattrfunc)0, /*tp_setattr*/
882+ (cmpfunc)0, /*tp_compare*/
883+ (reprfunc)0, /*tp_repr*/
884+ 0, /*tp_as_number*/
885+ 0, /*tp_as_sequence*/
886+ 0, /*tp_as_mapping*/
887+ (hashfunc)0, /*tp_hash*/
888+ (ternaryfunc)0, /*tp_call*/
889+ (reprfunc)0, /*tp_str*/
890+ 0, /*tp_getattro*/
891+ 0, /*tp_setattro*/
892+ 0, /*tp_as_buffer*/
893+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
894+ Py_TPFLAGS_HAVE_GC, /*tp_flags*/
895+ Reader_Type_doc, /*tp_doc*/
896+ (traverseproc)Reader_traverse, /*tp_traverse*/
897+ (inquiry)Reader_clear, /*tp_clear*/
898+ 0, /*tp_richcompare*/
899+ 0, /*tp_weaklistoffset*/
900+ PyObject_SelfIter, /*tp_iter*/
901+ (getiterfunc)Reader_iternext, /*tp_iternext*/
902+ Reader_methods, /*tp_methods*/
903+ Reader_memberlist, /*tp_members*/
904+ 0, /*tp_getset*/
905+
906+};
907+
908+static PyObject *
909+csv_reader(PyObject *module, PyObject *args, PyObject *keyword_args)
910+{
911+ PyObject * iterator, * dialect = NULL;
912+ ReaderObj * self = PyObject_GC_New(ReaderObj, &Reader_Type);
913+
914+ if (!self)
915+ return NULL;
916+
917+ self->dialect = NULL;
918+ self->fields = NULL;
919+ self->input_iter = NULL;
920+ self->field = NULL;
921+ self->field_size = 0;
922+ self->line_num = 0;
923+
924+ if (parse_reset(self) < 0) {
925+ Py_DECREF(self);
926+ return NULL;
927+ }
928+
929+ if (!PyArg_UnpackTuple(args, "", 1, 2, &iterator, &dialect)) {
930+ Py_DECREF(self);
931+ return NULL;
932+ }
933+ self->input_iter = PyObject_GetIter(iterator);
934+ if (self->input_iter == NULL) {
935+ PyErr_SetString(PyExc_TypeError,
936+ "argument 1 must be an iterator");
937+ Py_DECREF(self);
938+ return NULL;
939+ }
940+ self->dialect = (DialectObj *)_call_dialect(dialect, keyword_args);
941+ if (self->dialect == NULL) {
942+ Py_DECREF(self);
943+ return NULL;
944+ }
945+
946+ PyObject_GC_Track(self);
947+ return (PyObject *)self;
948+}
949+
950+/*
951+ * WRITER
952+ */
953+/* ---------------------------------------------------------------- */
954+static void
955+join_reset(WriterObj *self)
956+{
957+ self->rec_len = 0;
958+ self->num_fields = 0;
959+}
960+
961+#define MEM_INCR 32768
962+
963+/* Calculate new record length or append field to record. Return new
964+ * record length.
965+ */
966+static int
967+join_append_data(WriterObj *self, char *field, int quote_empty,
968+ int *quoted, int copy_phase)
969+{
970+ DialectObj *dialect = self->dialect;
971+ int i, rec_len;
972+ char *lineterm;
973+
974+#define ADDCH(c) \
975+ do {\
976+ if (copy_phase) \
977+ self->rec[rec_len] = c;\
978+ rec_len++;\
979+ } while(0)
980+
981+ lineterm = PyString_AsString(dialect->lineterminator);
982+ if (lineterm == NULL)
983+ return -1;
984+
985+ rec_len = self->rec_len;
986+
987+ /* If this is not the first field we need a field separator */
988+ if (self->num_fields > 0)
989+ ADDCH(dialect->delimiter);
990+
991+ /* Handle preceding quote */
992+ if (copy_phase && *quoted)
993+ ADDCH(dialect->quotechar);
994+
995+ /* Copy/count field data */
996+ for (i = 0;; i++) {
997+ char c = field[i];
998+ int want_escape = 0;
999+
1000+ if (c == '\0')
1001+ break;
1002+
1003+ if (c == dialect->delimiter ||
1004+ c == dialect->escapechar ||
1005+ c == dialect->quotechar ||
1006+ strchr(lineterm, c)) {
1007+ if (dialect->quoting == QUOTE_NONE)
1008+ want_escape = 1;
1009+ else {
1010+ if (c == dialect->quotechar) {
1011+ if (dialect->doublequote)
1012+ ADDCH(dialect->quotechar);
1013+ else
1014+ want_escape = 1;
1015+ }
1016+ if (!want_escape)
1017+ *quoted = 1;
1018+ }
1019+ if (want_escape) {
1020+ if (!dialect->escapechar) {
1021+ PyErr_Format(error_obj,
1022+ "need to escape, but no escapechar set");
1023+ return -1;
1024+ }
1025+ ADDCH(dialect->escapechar);
1026+ }
1027+ }
1028+ /* Copy field character into record buffer.
1029+ */
1030+ ADDCH(c);
1031+ }
1032+
1033+ /* If field is empty check if it needs to be quoted.
1034+ */
1035+ if (i == 0 && quote_empty) {
1036+ if (dialect->quoting == QUOTE_NONE) {
1037+ PyErr_Format(error_obj,
1038+ "single empty field record must be quoted");
1039+ return -1;
1040+ }
1041+ else
1042+ *quoted = 1;
1043+ }
1044+
1045+ if (*quoted) {
1046+ if (copy_phase)
1047+ ADDCH(dialect->quotechar);
1048+ else
1049+ rec_len += 2;
1050+ }
1051+ return rec_len;
1052+#undef ADDCH
1053+}
1054+
1055+static int
1056+join_check_rec_size(WriterObj *self, int rec_len)
1057+{
1058+ if (rec_len > self->rec_size) {
1059+ if (self->rec_size == 0) {
1060+ self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR;
1061+ if (self->rec != NULL)
1062+ PyMem_Free(self->rec);
1063+ self->rec = PyMem_Malloc(self->rec_size);
1064+ }
1065+ else {
1066+ char *old_rec = self->rec;
1067+
1068+ self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR;
1069+ self->rec = PyMem_Realloc(self->rec, self->rec_size);
1070+ if (self->rec == NULL)
1071+ PyMem_Free(old_rec);
1072+ }
1073+ if (self->rec == NULL) {
1074+ PyErr_NoMemory();
1075+ return 0;
1076+ }
1077+ }
1078+ return 1;
1079+}
1080+
1081+static int
1082+join_append(WriterObj *self, char *field, int *quoted, int quote_empty)
1083+{
1084+ int rec_len;
1085+
1086+ rec_len = join_append_data(self, field, quote_empty, quoted, 0);
1087+ if (rec_len < 0)
1088+ return 0;
1089+
1090+ /* grow record buffer if necessary */
1091+ if (!join_check_rec_size(self, rec_len))
1092+ return 0;
1093+
1094+ self->rec_len = join_append_data(self, field, quote_empty, quoted, 1);
1095+ self->num_fields++;
1096+
1097+ return 1;
1098+}
1099+
1100+static int
1101+join_append_lineterminator(WriterObj *self)
1102+{
1103+ int terminator_len;
1104+ char *terminator;
1105+
1106+ terminator_len = PyString_Size(self->dialect->lineterminator);
1107+ if (terminator_len == -1)
1108+ return 0;
1109+
1110+ /* grow record buffer if necessary */
1111+ if (!join_check_rec_size(self, self->rec_len + terminator_len))
1112+ return 0;
1113+
1114+ terminator = PyString_AsString(self->dialect->lineterminator);
1115+ if (terminator == NULL)
1116+ return 0;
1117+ memmove(self->rec + self->rec_len, terminator, terminator_len);
1118+ self->rec_len += terminator_len;
1119+
1120+ return 1;
1121+}
1122+
1123+PyDoc_STRVAR(csv_writerow_doc,
1124+"writerow(sequence)\n"
1125+"\n"
1126+"Construct and write a CSV record from a sequence of fields. Non-string\n"
1127+"elements will be converted to string.");
1128+
1129+static PyObject *
1130+csv_writerow(WriterObj *self, PyObject *seq)
1131+{
1132+ DialectObj *dialect = self->dialect;
1133+ int len, i;
1134+
1135+ if (!PySequence_Check(seq))
1136+ return PyErr_Format(error_obj, "sequence expected");
1137+
1138+ len = PySequence_Length(seq);
1139+ if (len < 0)
1140+ return NULL;
1141+
1142+ /* Join all fields in internal buffer.
1143+ */
1144+ join_reset(self);
1145+ for (i = 0; i < len; i++) {
1146+ PyObject *field;
1147+ int append_ok;
1148+ int quoted;
1149+
1150+ field = PySequence_GetItem(seq, i);
1151+ if (field == NULL)
1152+ return NULL;
1153+
1154+ switch (dialect->quoting) {
1155+ case QUOTE_NONNUMERIC:
1156+ quoted = !PyNumber_Check(field);
1157+ break;
1158+ case QUOTE_ALL:
1159+ quoted = 1;
1160+ break;
1161+ default:
1162+ quoted = 0;
1163+ break;
1164+ }
1165+
1166+ if (PyString_Check(field)) {
1167+ append_ok = join_append(self,
1168+ PyString_AS_STRING(field),
1169+ &quoted, len == 1);
1170+ Py_DECREF(field);
1171+ }
1172+ else if (field == Py_None) {
1173+ append_ok = join_append(self, "", &quoted, len == 1);
1174+ Py_DECREF(field);
1175+ }
1176+ else {
1177+ PyObject *str;
1178+
1179+ str = PyObject_Str(field);
1180+ Py_DECREF(field);
1181+ if (str == NULL)
1182+ return NULL;
1183+
1184+ append_ok = join_append(self, PyString_AS_STRING(str),
1185+ &quoted, len == 1);
1186+ Py_DECREF(str);
1187+ }
1188+ if (!append_ok)
1189+ return NULL;
1190+ }
1191+
1192+ /* Add line terminator.
1193+ */
1194+ if (!join_append_lineterminator(self))
1195+ return 0;
1196+
1197+ return PyObject_CallFunction(self->writeline,
1198+ "(s#)", self->rec, self->rec_len);
1199+}
1200+
1201+PyDoc_STRVAR(csv_writerows_doc,
1202+"writerows(sequence of sequences)\n"
1203+"\n"
1204+"Construct and write a series of sequences to a csv file. Non-string\n"
1205+"elements will be converted to string.");
1206+
1207+static PyObject *
1208+csv_writerows(WriterObj *self, PyObject *seqseq)
1209+{
1210+ PyObject *row_iter, *row_obj, *result;
1211+
1212+ row_iter = PyObject_GetIter(seqseq);
1213+ if (row_iter == NULL) {
1214+ PyErr_SetString(PyExc_TypeError,
1215+ "writerows() argument must be iterable");
1216+ return NULL;
1217+ }
1218+ while ((row_obj = PyIter_Next(row_iter))) {
1219+ result = csv_writerow(self, row_obj);
1220+ Py_DECREF(row_obj);
1221+ if (!result) {
1222+ Py_DECREF(row_iter);
1223+ return NULL;
1224+ }
1225+ else
1226+ Py_DECREF(result);
1227+ }
1228+ Py_DECREF(row_iter);
1229+ if (PyErr_Occurred())
1230+ return NULL;
1231+ Py_INCREF(Py_None);
1232+ return Py_None;
1233+}
1234+
1235+static struct PyMethodDef Writer_methods[] = {
1236+ { "writerow", (PyCFunction)csv_writerow, METH_O, csv_writerow_doc},
1237+ { "writerows", (PyCFunction)csv_writerows, METH_O, csv_writerows_doc},
1238+ { NULL, NULL }
1239+};
1240+
1241+#define W_OFF(x) offsetof(WriterObj, x)
1242+
1243+static struct PyMemberDef Writer_memberlist[] = {
1244+ { "dialect", T_OBJECT, W_OFF(dialect), RO },
1245+ { NULL }
1246+};
1247+
1248+static void
1249+Writer_dealloc(WriterObj *self)
1250+{
1251+ PyObject_GC_UnTrack(self);
1252+ Py_XDECREF(self->dialect);
1253+ Py_XDECREF(self->writeline);
1254+ if (self->rec != NULL)
1255+ PyMem_Free(self->rec);
1256+ PyObject_GC_Del(self);
1257+}
1258+
1259+static int
1260+Writer_traverse(WriterObj *self, visitproc visit, void *arg)
1261+{
1262+ Py_VISIT(self->dialect);
1263+ Py_VISIT(self->writeline);
1264+ return 0;
1265+}
1266+
1267+static int
1268+Writer_clear(WriterObj *self)
1269+{
1270+ Py_CLEAR(self->dialect);
1271+ Py_CLEAR(self->writeline);
1272+ return 0;
1273+}
1274+
1275+PyDoc_STRVAR(Writer_Type_doc,
1276+"CSV writer\n"
1277+"\n"
1278+"Writer objects are responsible for generating tabular data\n"
1279+"in CSV format from sequence input.\n"
1280+);
1281+
1282+static PyTypeObject Writer_Type = {
1283+ PyObject_HEAD_INIT(NULL)
1284+ 0, /*ob_size*/
1285+ "_csv.writer", /*tp_name*/
1286+ sizeof(WriterObj), /*tp_basicsize*/
1287+ 0, /*tp_itemsize*/
1288+ /* methods */
1289+ (destructor)Writer_dealloc, /*tp_dealloc*/
1290+ (printfunc)0, /*tp_print*/
1291+ (getattrfunc)0, /*tp_getattr*/
1292+ (setattrfunc)0, /*tp_setattr*/
1293+ (cmpfunc)0, /*tp_compare*/
1294+ (reprfunc)0, /*tp_repr*/
1295+ 0, /*tp_as_number*/
1296+ 0, /*tp_as_sequence*/
1297+ 0, /*tp_as_mapping*/
1298+ (hashfunc)0, /*tp_hash*/
1299+ (ternaryfunc)0, /*tp_call*/
1300+ (reprfunc)0, /*tp_str*/
1301+ 0, /*tp_getattro*/
1302+ 0, /*tp_setattro*/
1303+ 0, /*tp_as_buffer*/
1304+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
1305+ Py_TPFLAGS_HAVE_GC, /*tp_flags*/
1306+ Writer_Type_doc,
1307+ (traverseproc)Writer_traverse, /*tp_traverse*/
1308+ (inquiry)Writer_clear, /*tp_clear*/
1309+ 0, /*tp_richcompare*/
1310+ 0, /*tp_weaklistoffset*/
1311+ (getiterfunc)0, /*tp_iter*/
1312+ (getiterfunc)0, /*tp_iternext*/
1313+ Writer_methods, /*tp_methods*/
1314+ Writer_memberlist, /*tp_members*/
1315+ 0, /*tp_getset*/
1316+};
1317+
1318+static PyObject *
1319+csv_writer(PyObject *module, PyObject *args, PyObject *keyword_args)
1320+{
1321+ PyObject * output_file, * dialect = NULL;
1322+ WriterObj * self = PyObject_GC_New(WriterObj, &Writer_Type);
1323+
1324+ if (!self)
1325+ return NULL;
1326+
1327+ self->dialect = NULL;
1328+ self->writeline = NULL;
1329+
1330+ self->rec = NULL;
1331+ self->rec_size = 0;
1332+ self->rec_len = 0;
1333+ self->num_fields = 0;
1334+
1335+ if (!PyArg_UnpackTuple(args, "", 1, 2, &output_file, &dialect)) {
1336+ Py_DECREF(self);
1337+ return NULL;
1338+ }
1339+ self->writeline = PyObject_GetAttrString(output_file, "write");
1340+ if (self->writeline == NULL || !PyCallable_Check(self->writeline)) {
1341+ PyErr_SetString(PyExc_TypeError,
1342+ "argument 1 must have a \"write\" method");
1343+ Py_DECREF(self);
1344+ return NULL;
1345+ }
1346+ self->dialect = (DialectObj *)_call_dialect(dialect, keyword_args);
1347+ if (self->dialect == NULL) {
1348+ Py_DECREF(self);
1349+ return NULL;
1350+ }
1351+ PyObject_GC_Track(self);
1352+ return (PyObject *)self;
1353+}
1354+
1355+/*
1356+ * DIALECT REGISTRY
1357+ */
1358+static PyObject *
1359+csv_list_dialects(PyObject *module, PyObject *args)
1360+{
1361+ return PyDict_Keys(dialects);
1362+}
1363+
1364+static PyObject *
1365+csv_register_dialect(PyObject *module, PyObject *args, PyObject *kwargs)
1366+{
1367+ PyObject *name_obj, *dialect_obj = NULL;
1368+ PyObject *dialect;
1369+
1370+ if (!PyArg_UnpackTuple(args, "", 1, 2, &name_obj, &dialect_obj))
1371+ return NULL;
1372+ if (!IS_BASESTRING(name_obj)) {
1373+ PyErr_SetString(PyExc_TypeError,
1374+ "dialect name must be a string or unicode");
1375+ return NULL;
1376+ }
1377+ dialect = _call_dialect(dialect_obj, kwargs);
1378+ if (dialect == NULL)
1379+ return NULL;
1380+ if (PyDict_SetItem(dialects, name_obj, dialect) < 0) {
1381+ Py_DECREF(dialect);
1382+ return NULL;
1383+ }
1384+ Py_DECREF(dialect);
1385+ Py_INCREF(Py_None);
1386+ return Py_None;
1387+}
1388+
1389+static PyObject *
1390+csv_unregister_dialect(PyObject *module, PyObject *name_obj)
1391+{
1392+ if (PyDict_DelItem(dialects, name_obj) < 0)
1393+ return PyErr_Format(error_obj, "unknown dialect");
1394+ Py_INCREF(Py_None);
1395+ return Py_None;
1396+}
1397+
1398+static PyObject *
1399+csv_get_dialect(PyObject *module, PyObject *name_obj)
1400+{
1401+ return get_dialect_from_registry(name_obj);
1402+}
1403+
1404+static PyObject *
1405+csv_field_size_limit(PyObject *module, PyObject *args)
1406+{
1407+ PyObject *new_limit = NULL;
1408+ long old_limit = field_limit;
1409+
1410+ if (!PyArg_UnpackTuple(args, "field_size_limit", 0, 1, &new_limit))
1411+ return NULL;
1412+ if (new_limit != NULL) {
1413+ if (!PyInt_Check(new_limit)) {
1414+ PyErr_Format(PyExc_TypeError,
1415+ "limit must be an integer");
1416+ return NULL;
1417+ }
1418+ field_limit = PyInt_AsLong(new_limit);
1419+ }
1420+ return PyInt_FromLong(old_limit);
1421+}
1422+
1423+/*
1424+ * MODULE
1425+ */
1426+
1427+PyDoc_STRVAR(csv_module_doc,
1428+"CSV parsing and writing.\n"
1429+"\n"
1430+"This module provides classes that assist in the reading and writing\n"
1431+"of Comma Separated Value (CSV) files, and implements the interface\n"
1432+"described by PEP 305. Although many CSV files are simple to parse,\n"
1433+"the format is not formally defined by a stable specification and\n"
1434+"is subtle enough that parsing lines of a CSV file with something\n"
1435+"like line.split(\",\") is bound to fail. The module supports three\n"
1436+"basic APIs: reading, writing, and registration of dialects.\n"
1437+"\n"
1438+"\n"
1439+"DIALECT REGISTRATION:\n"
1440+"\n"
1441+"Readers and writers support a dialect argument, which is a convenient\n"
1442+"handle on a group of settings. When the dialect argument is a string,\n"
1443+"it identifies one of the dialects previously registered with the module.\n"
1444+"If it is a class or instance, the attributes of the argument are used as\n"
1445+"the settings for the reader or writer:\n"
1446+"\n"
1447+" class excel:\n"
1448+" delimiter = ','\n"
1449+" quotechar = '\"'\n"
1450+" escapechar = None\n"
1451+" doublequote = True\n"
1452+" skipinitialspace = False\n"
1453+" lineterminator = '\\r\\n'\n"
1454+" quoting = QUOTE_MINIMAL\n"
1455+"\n"
1456+"SETTINGS:\n"
1457+"\n"
1458+" * quotechar - specifies a one-character string to use as the \n"
1459+" quoting character. It defaults to '\"'.\n"
1460+" * delimiter - specifies a one-character string to use as the \n"
1461+" field separator. It defaults to ','.\n"
1462+" * skipinitialspace - specifies how to interpret whitespace which\n"
1463+" immediately follows a delimiter. It defaults to False, which\n"
1464+" means that whitespace immediately following a delimiter is part\n"
1465+" of the following field.\n"
1466+" * lineterminator - specifies the character sequence which should \n"
1467+" terminate rows.\n"
1468+" * quoting - controls when quotes should be generated by the writer.\n"
1469+" It can take on any of the following module constants:\n"
1470+"\n"
1471+" csv.QUOTE_MINIMAL means only when required, for example, when a\n"
1472+" field contains either the quotechar or the delimiter\n"
1473+" csv.QUOTE_ALL means that quotes are always placed around fields.\n"
1474+" csv.QUOTE_NONNUMERIC means that quotes are always placed around\n"
1475+" fields which do not parse as integers or floating point\n"
1476+" numbers.\n"
1477+" csv.QUOTE_NONE means that quotes are never placed around fields.\n"
1478+" * escapechar - specifies a one-character string used to escape \n"
1479+" the delimiter when quoting is set to QUOTE_NONE.\n"
1480+" * doublequote - controls the handling of quotes inside fields. When\n"
1481+" True, two consecutive quotes are interpreted as one during read,\n"
1482+" and when writing, each quote character embedded in the data is\n"
1483+" written as two quotes\n");
1484+
1485+PyDoc_STRVAR(csv_reader_doc,
1486+" csv_reader = reader(iterable [, dialect='excel']\n"
1487+" [optional keyword args])\n"
1488+" for row in csv_reader:\n"
1489+" process(row)\n"
1490+"\n"
1491+"The \"iterable\" argument can be any object that returns a line\n"
1492+"of input for each iteration, such as a file object or a list. The\n"
1493+"optional \"dialect\" parameter is discussed below. The function\n"
1494+"also accepts optional keyword arguments which override settings\n"
1495+"provided by the dialect.\n"
1496+"\n"
1497+"The returned object is an iterator. Each iteration returns a row\n"
1498+"of the CSV file (which can span multiple input lines):\n");
1499+
1500+PyDoc_STRVAR(csv_writer_doc,
1501+" csv_writer = csv.writer(fileobj [, dialect='excel']\n"
1502+" [optional keyword args])\n"
1503+" for row in sequence:\n"
1504+" csv_writer.writerow(row)\n"
1505+"\n"
1506+" [or]\n"
1507+"\n"
1508+" csv_writer = csv.writer(fileobj [, dialect='excel']\n"
1509+" [optional keyword args])\n"
1510+" csv_writer.writerows(rows)\n"
1511+"\n"
1512+"The \"fileobj\" argument can be any object that supports the file API.\n");
1513+
1514+PyDoc_STRVAR(csv_list_dialects_doc,
1515+"Return a list of all know dialect names.\n"
1516+" names = csv.list_dialects()");
1517+
1518+PyDoc_STRVAR(csv_get_dialect_doc,
1519+"Return the dialect instance associated with name.\n"
1520+" dialect = csv.get_dialect(name)");
1521+
1522+PyDoc_STRVAR(csv_register_dialect_doc,
1523+"Create a mapping from a string name to a dialect class.\n"
1524+" dialect = csv.register_dialect(name, dialect)");
1525+
1526+PyDoc_STRVAR(csv_unregister_dialect_doc,
1527+"Delete the name/dialect mapping associated with a string name.\n"
1528+" csv.unregister_dialect(name)");
1529+
1530+PyDoc_STRVAR(csv_field_size_limit_doc,
1531+"Sets an upper limit on parsed fields.\n"
1532+" csv.field_size_limit([limit])\n"
1533+"\n"
1534+"Returns old limit. If limit is not given, no new limit is set and\n"
1535+"the old limit is returned");
1536+
1537+static struct PyMethodDef csv_methods[] = {
1538+ { "reader", (PyCFunction)csv_reader,
1539+ METH_VARARGS | METH_KEYWORDS, csv_reader_doc},
1540+ { "writer", (PyCFunction)csv_writer,
1541+ METH_VARARGS | METH_KEYWORDS, csv_writer_doc},
1542+ { "list_dialects", (PyCFunction)csv_list_dialects,
1543+ METH_NOARGS, csv_list_dialects_doc},
1544+ { "register_dialect", (PyCFunction)csv_register_dialect,
1545+ METH_VARARGS | METH_KEYWORDS, csv_register_dialect_doc},
1546+ { "unregister_dialect", (PyCFunction)csv_unregister_dialect,
1547+ METH_O, csv_unregister_dialect_doc},
1548+ { "get_dialect", (PyCFunction)csv_get_dialect,
1549+ METH_O, csv_get_dialect_doc},
1550+ { "field_size_limit", (PyCFunction)csv_field_size_limit,
1551+ METH_VARARGS, csv_field_size_limit_doc},
1552+ { NULL, NULL }
1553+};
1554+
1555+PyMODINIT_FUNC
1556+init_csv(void)
1557+{
1558+ PyObject *module;
1559+ StyleDesc *style;
1560+
1561+ if (PyType_Ready(&Dialect_Type) < 0)
1562+ return;
1563+
1564+ if (PyType_Ready(&Reader_Type) < 0)
1565+ return;
1566+
1567+ if (PyType_Ready(&Writer_Type) < 0)
1568+ return;
1569+
1570+ /* Create the module and add the functions */
1571+ module = Py_InitModule3("_csv", csv_methods, csv_module_doc);
1572+ if (module == NULL)
1573+ return;
1574+
1575+ /* Add version to the module. */
1576+ if (PyModule_AddStringConstant(module, "__version__",
1577+ MODULE_VERSION) == -1)
1578+ return;
1579+
1580+ /* Add _dialects dictionary */
1581+ dialects = PyDict_New();
1582+ if (dialects == NULL)
1583+ return;
1584+ if (PyModule_AddObject(module, "_dialects", dialects))
1585+ return;
1586+
1587+ /* Add quote styles into dictionary */
1588+ for (style = quote_styles; style->name; style++) {
1589+ if (PyModule_AddIntConstant(module, style->name,
1590+ style->style) == -1)
1591+ return;
1592+ }
1593+
1594+ /* Add the Dialect type */
1595+ Py_INCREF(&Dialect_Type);
1596+ if (PyModule_AddObject(module, "Dialect", (PyObject *)&Dialect_Type))
1597+ return;
1598+
1599+ /* Add the CSV exception object to the module. */
1600+ error_obj = PyErr_NewException("_csv.Error", NULL, NULL);
1601+ if (error_obj == NULL)
1602+ return;
1603+ PyModule_AddObject(module, "Error", error_obj);
1604+}
sys/src/cmd/python/Modules/_ctypes/_ctypes.c+4859−0
@@ -0,0 +1,4859 @@
1+/*****************************************************************
2+ This file should be kept compatible with Python 2.3, see PEP 291.
3+ *****************************************************************/
4+
5+
6+/*
7+ ToDo:
8+
9+ Get rid of the checker (and also the converters) field in CFuncPtrObject and
10+ StgDictObject, and replace them by slot functions in StgDictObject.
11+
12+ think about a buffer-like object (memory? bytes?)
13+
14+ Should POINTER(c_char) and POINTER(c_wchar) have a .value property?
15+ What about c_char and c_wchar arrays then?
16+
17+ Add from_mmap, from_file, from_string metaclass methods.
18+
19+ Maybe we can get away with from_file (calls read) and with a from_buffer
20+ method?
21+
22+ And what about the to_mmap, to_file, to_str(?) methods? They would clobber
23+ the namespace, probably. So, functions instead? And we already have memmove...
24+*/
25+
26+/*
27+
28+Name methods, members, getsets
29+==============================================================================
30+
31+StructType_Type __new__(), from_address(), __mul__(), from_param()
32+UnionType_Type __new__(), from_address(), __mul__(), from_param()
33+PointerType_Type __new__(), from_address(), __mul__(), from_param(), set_type()
34+ArrayType_Type __new__(), from_address(), __mul__(), from_param()
35+SimpleType_Type __new__(), from_address(), __mul__(), from_param()
36+
37+CData_Type
38+ Struct_Type __new__(), __init__()
39+ Pointer_Type __new__(), __init__(), _as_parameter_, contents
40+ Array_Type __new__(), __init__(), _as_parameter_, __get/setitem__(), __len__()
41+ Simple_Type __new__(), __init__(), _as_parameter_
42+
43+CField_Type
44+StgDict_Type
45+
46+==============================================================================
47+
48+class methods
49+-------------
50+
51+It has some similarity to the byref() construct compared to pointer()
52+from_address(addr)
53+ - construct an instance from a given memory block (sharing this memory block)
54+
55+from_param(obj)
56+ - typecheck and convert a Python object into a C function call parameter
57+ the result may be an instance of the type, or an integer or tuple
58+ (typecode, value[, obj])
59+
60+instance methods/properties
61+---------------------------
62+
63+_as_parameter_
64+ - convert self into a C function call parameter
65+ This is either an integer, or a 3-tuple (typecode, value, obj)
66+
67+functions
68+---------
69+
70+sizeof(cdata)
71+ - return the number of bytes the buffer contains
72+
73+sizeof(ctype)
74+ - return the number of bytes the buffer of an instance would contain
75+
76+byref(cdata)
77+
78+addressof(cdata)
79+
80+pointer(cdata)
81+
82+POINTER(ctype)
83+
84+bytes(cdata)
85+ - return the buffer contents as a sequence of bytes (which is currently a string)
86+
87+*/
88+
89+/*
90+ * StgDict_Type
91+ * StructType_Type
92+ * UnionType_Type
93+ * PointerType_Type
94+ * ArrayType_Type
95+ * SimpleType_Type
96+ *
97+ * CData_Type
98+ * Struct_Type
99+ * Union_Type
100+ * Array_Type
101+ * Simple_Type
102+ * Pointer_Type
103+ * CField_Type
104+ *
105+ */
106+
107+#include "Python.h"
108+#include "structmember.h"
109+
110+#include <ffi.h>
111+#ifdef MS_WIN32
112+#include <windows.h>
113+#include <malloc.h>
114+#ifndef IS_INTRESOURCE
115+#define IS_INTRESOURCE(x) (((size_t)(x) >> 16) == 0)
116+#endif
117+# ifdef _WIN32_WCE
118+/* Unlike desktop Windows, WinCE has both W and A variants of
119+ GetProcAddress, but the default W version is not what we want */
120+# undef GetProcAddress
121+# define GetProcAddress GetProcAddressA
122+# endif
123+#else
124+#include "ctypes_dlfcn.h"
125+#endif
126+#include "ctypes.h"
127+
128+PyObject *PyExc_ArgError;
129+static PyTypeObject Simple_Type;
130+
131+char *conversion_mode_encoding = NULL;
132+char *conversion_mode_errors = NULL;
133+
134+
135+/******************************************************************/
136+/*
137+ StructType_Type - a meta type/class. Creating a new class using this one as
138+ __metaclass__ will call the contructor StructUnionType_new. It replaces the
139+ tp_dict member with a new instance of StgDict, and initializes the C
140+ accessible fields somehow.
141+*/
142+
143+static PyCArgObject *
144+StructUnionType_paramfunc(CDataObject *self)
145+{
146+ PyCArgObject *parg;
147+ StgDictObject *stgdict;
148+
149+ parg = new_CArgObject();
150+ if (parg == NULL)
151+ return NULL;
152+
153+ parg->tag = 'V';
154+ stgdict = PyObject_stgdict((PyObject *)self);
155+ assert(stgdict); /* Cannot be NULL for structure/union instances */
156+ parg->pffi_type = &stgdict->ffi_type_pointer;
157+ /* For structure parameters (by value), parg->value doesn't contain the structure
158+ data itself, instead parg->value.p *points* to the structure's data
159+ See also _ctypes.c, function _call_function_pointer().
160+ */
161+ parg->value.p = self->b_ptr;
162+ parg->size = self->b_size;
163+ Py_INCREF(self);
164+ parg->obj = (PyObject *)self;
165+ return parg;
166+}
167+
168+static PyObject *
169+StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isStruct)
170+{
171+ PyTypeObject *result;
172+ PyObject *fields;
173+ StgDictObject *dict;
174+
175+ /* create the new instance (which is a class,
176+ since we are a metatype!) */
177+ result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
178+ if (!result)
179+ return NULL;
180+
181+ /* keep this for bw compatibility */
182+ if (PyDict_GetItemString(result->tp_dict, "_abstract_"))
183+ return (PyObject *)result;
184+
185+ dict = (StgDictObject *)PyObject_CallObject((PyObject *)&StgDict_Type, NULL);
186+ if (!dict) {
187+ Py_DECREF(result);
188+ return NULL;
189+ }
190+ /* replace the class dict by our updated stgdict, which holds info
191+ about storage requirements of the instances */
192+ if (-1 == PyDict_Update((PyObject *)dict, result->tp_dict)) {
193+ Py_DECREF(result);
194+ Py_DECREF((PyObject *)dict);
195+ return NULL;
196+ }
197+ Py_DECREF(result->tp_dict);
198+ result->tp_dict = (PyObject *)dict;
199+
200+ dict->paramfunc = StructUnionType_paramfunc;
201+
202+ fields = PyDict_GetItemString((PyObject *)dict, "_fields_");
203+ if (!fields) {
204+ StgDictObject *basedict = PyType_stgdict((PyObject *)result->tp_base);
205+
206+ if (basedict == NULL)
207+ return (PyObject *)result;
208+ /* copy base dict */
209+ if (-1 == StgDict_clone(dict, basedict)) {
210+ Py_DECREF(result);
211+ return NULL;
212+ }
213+ dict->flags &= ~DICTFLAG_FINAL; /* clear the 'final' flag in the subclass dict */
214+ basedict->flags |= DICTFLAG_FINAL; /* set the 'final' flag in the baseclass dict */
215+ return (PyObject *)result;
216+ }
217+
218+ if (-1 == PyObject_SetAttrString((PyObject *)result, "_fields_", fields)) {
219+ Py_DECREF(result);
220+ return NULL;
221+ }
222+ return (PyObject *)result;
223+}
224+
225+static PyObject *
226+StructType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
227+{
228+ return StructUnionType_new(type, args, kwds, 1);
229+}
230+
231+static PyObject *
232+UnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
233+{
234+ return StructUnionType_new(type, args, kwds, 0);
235+}
236+
237+static char from_address_doc[] =
238+"C.from_address(integer) -> C instance\naccess a C instance at the specified address";
239+
240+static PyObject *
241+CDataType_from_address(PyObject *type, PyObject *value)
242+{
243+ void *buf;
244+ if (!PyInt_Check(value) && !PyLong_Check(value)) {
245+ PyErr_SetString(PyExc_TypeError,
246+ "integer expected");
247+ return NULL;
248+ }
249+ buf = (void *)PyLong_AsVoidPtr(value);
250+ if (PyErr_Occurred())
251+ return NULL;
252+ return CData_AtAddress(type, buf);
253+}
254+
255+static char in_dll_doc[] =
256+"C.in_dll(dll, name) -> C instance\naccess a C instance in a dll";
257+
258+static PyObject *
259+CDataType_in_dll(PyObject *type, PyObject *args)
260+{
261+ PyObject *dll;
262+ char *name;
263+ PyObject *obj;
264+ void *handle;
265+ void *address;
266+
267+ if (!PyArg_ParseTuple(args, "Os:in_dll", &dll, &name))
268+ return NULL;
269+
270+ obj = PyObject_GetAttrString(dll, "_handle");
271+ if (!obj)
272+ return NULL;
273+ if (!PyInt_Check(obj) && !PyLong_Check(obj)) {
274+ PyErr_SetString(PyExc_TypeError,
275+ "the _handle attribute of the second argument must be an integer");
276+ Py_DECREF(obj);
277+ return NULL;
278+ }
279+ handle = (void *)PyLong_AsVoidPtr(obj);
280+ Py_DECREF(obj);
281+ if (PyErr_Occurred()) {
282+ PyErr_SetString(PyExc_ValueError,
283+ "could not convert the _handle attribute to a pointer");
284+ return NULL;
285+ }
286+
287+#ifdef MS_WIN32
288+ address = (void *)GetProcAddress(handle, name);
289+ if (!address) {
290+ PyErr_Format(PyExc_ValueError,
291+ "symbol '%s' not found",
292+ name);
293+ return NULL;
294+ }
295+#else
296+ address = (void *)ctypes_dlsym(handle, name);
297+ if (!address) {
298+ PyErr_Format(PyExc_ValueError,
299+#ifdef __CYGWIN__
300+/* dlerror() isn't very helpful on cygwin */
301+ "symbol '%s' not found (%s) ",
302+ name,
303+#endif
304+ ctypes_dlerror());
305+ return NULL;
306+ }
307+#endif
308+ return CData_AtAddress(type, address);
309+}
310+
311+static char from_param_doc[] =
312+"Convert a Python object into a function call parameter.";
313+
314+static PyObject *
315+CDataType_from_param(PyObject *type, PyObject *value)
316+{
317+ PyObject *as_parameter;
318+ if (1 == PyObject_IsInstance(value, type)) {
319+ Py_INCREF(value);
320+ return value;
321+ }
322+ if (PyCArg_CheckExact(value)) {
323+ PyCArgObject *p = (PyCArgObject *)value;
324+ PyObject *ob = p->obj;
325+ const char *ob_name;
326+ StgDictObject *dict;
327+ dict = PyType_stgdict(type);
328+
329+ /* If we got a PyCArgObject, we must check if the object packed in it
330+ is an instance of the type's dict->proto */
331+ if(dict && ob
332+ && PyObject_IsInstance(ob, dict->proto)) {
333+ Py_INCREF(value);
334+ return value;
335+ }
336+ ob_name = (ob) ? ob->ob_type->tp_name : "???";
337+ PyErr_Format(PyExc_TypeError,
338+ "expected %s instance instead of pointer to %s",
339+ ((PyTypeObject *)type)->tp_name, ob_name);
340+ return NULL;
341+ }
342+
343+ as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
344+ if (as_parameter) {
345+ value = CDataType_from_param(type, as_parameter);
346+ Py_DECREF(as_parameter);
347+ return value;
348+ }
349+ PyErr_Format(PyExc_TypeError,
350+ "expected %s instance instead of %s",
351+ ((PyTypeObject *)type)->tp_name,
352+ value->ob_type->tp_name);
353+ return NULL;
354+}
355+
356+static PyMethodDef CDataType_methods[] = {
357+ { "from_param", CDataType_from_param, METH_O, from_param_doc },
358+ { "from_address", CDataType_from_address, METH_O, from_address_doc },
359+ { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc },
360+ { NULL, NULL },
361+};
362+
363+static PyObject *
364+CDataType_repeat(PyObject *self, Py_ssize_t length)
365+{
366+ if (length < 0)
367+ return PyErr_Format(PyExc_ValueError,
368+#if (PY_VERSION_HEX < 0x02050000)
369+ "Array length must be >= 0, not %d",
370+#else
371+ "Array length must be >= 0, not %zd",
372+#endif
373+ length);
374+ return CreateArrayType(self, length);
375+}
376+
377+static PySequenceMethods CDataType_as_sequence = {
378+ 0, /* inquiry sq_length; */
379+ 0, /* binaryfunc sq_concat; */
380+ CDataType_repeat, /* intargfunc sq_repeat; */
381+ 0, /* intargfunc sq_item; */
382+ 0, /* intintargfunc sq_slice; */
383+ 0, /* intobjargproc sq_ass_item; */
384+ 0, /* intintobjargproc sq_ass_slice; */
385+ 0, /* objobjproc sq_contains; */
386+
387+ 0, /* binaryfunc sq_inplace_concat; */
388+ 0, /* intargfunc sq_inplace_repeat; */
389+};
390+
391+static int
392+CDataType_clear(PyTypeObject *self)
393+{
394+ StgDictObject *dict = PyType_stgdict((PyObject *)self);
395+ if (dict)
396+ Py_CLEAR(dict->proto);
397+ return PyType_Type.tp_clear((PyObject *)self);
398+}
399+
400+static int
401+CDataType_traverse(PyTypeObject *self, visitproc visit, void *arg)
402+{
403+ StgDictObject *dict = PyType_stgdict((PyObject *)self);
404+ if (dict)
405+ Py_VISIT(dict->proto);
406+ return PyType_Type.tp_traverse((PyObject *)self, visit, arg);
407+}
408+
409+static int
410+StructType_setattro(PyObject *self, PyObject *key, PyObject *value)
411+{
412+ /* XXX Should we disallow deleting _fields_? */
413+ if (-1 == PyObject_GenericSetAttr(self, key, value))
414+ return -1;
415+
416+ if (value && PyString_Check(key) &&
417+ 0 == strcmp(PyString_AS_STRING(key), "_fields_"))
418+ return StructUnionType_update_stgdict(self, value, 1);
419+ return 0;
420+}
421+
422+
423+static int
424+UnionType_setattro(PyObject *self, PyObject *key, PyObject *value)
425+{
426+ /* XXX Should we disallow deleting _fields_? */
427+ if (-1 == PyObject_GenericSetAttr(self, key, value))
428+ return -1;
429+
430+ if (PyString_Check(key) &&
431+ 0 == strcmp(PyString_AS_STRING(key), "_fields_"))
432+ return StructUnionType_update_stgdict(self, value, 0);
433+ return 0;
434+}
435+
436+
437+PyTypeObject StructType_Type = {
438+ PyObject_HEAD_INIT(NULL)
439+ 0, /* ob_size */
440+ "_ctypes.StructType", /* tp_name */
441+ 0, /* tp_basicsize */
442+ 0, /* tp_itemsize */
443+ 0, /* tp_dealloc */
444+ 0, /* tp_print */
445+ 0, /* tp_getattr */
446+ 0, /* tp_setattr */
447+ 0, /* tp_compare */
448+ 0, /* tp_repr */
449+ 0, /* tp_as_number */
450+ &CDataType_as_sequence, /* tp_as_sequence */
451+ 0, /* tp_as_mapping */
452+ 0, /* tp_hash */
453+ 0, /* tp_call */
454+ 0, /* tp_str */
455+ 0, /* tp_getattro */
456+ StructType_setattro, /* tp_setattro */
457+ 0, /* tp_as_buffer */
458+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
459+ "metatype for the CData Objects", /* tp_doc */
460+ (traverseproc)CDataType_traverse, /* tp_traverse */
461+ (inquiry)CDataType_clear, /* tp_clear */
462+ 0, /* tp_richcompare */
463+ 0, /* tp_weaklistoffset */
464+ 0, /* tp_iter */
465+ 0, /* tp_iternext */
466+ CDataType_methods, /* tp_methods */
467+ 0, /* tp_members */
468+ 0, /* tp_getset */
469+ 0, /* tp_base */
470+ 0, /* tp_dict */
471+ 0, /* tp_descr_get */
472+ 0, /* tp_descr_set */
473+ 0, /* tp_dictoffset */
474+ 0, /* tp_init */
475+ 0, /* tp_alloc */
476+ StructType_new, /* tp_new */
477+ 0, /* tp_free */
478+};
479+
480+static PyTypeObject UnionType_Type = {
481+ PyObject_HEAD_INIT(NULL)
482+ 0, /* ob_size */
483+ "_ctypes.UnionType", /* tp_name */
484+ 0, /* tp_basicsize */
485+ 0, /* tp_itemsize */
486+ 0, /* tp_dealloc */
487+ 0, /* tp_print */
488+ 0, /* tp_getattr */
489+ 0, /* tp_setattr */
490+ 0, /* tp_compare */
491+ 0, /* tp_repr */
492+ 0, /* tp_as_number */
493+ &CDataType_as_sequence, /* tp_as_sequence */
494+ 0, /* tp_as_mapping */
495+ 0, /* tp_hash */
496+ 0, /* tp_call */
497+ 0, /* tp_str */
498+ 0, /* tp_getattro */
499+ UnionType_setattro, /* tp_setattro */
500+ 0, /* tp_as_buffer */
501+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
502+ "metatype for the CData Objects", /* tp_doc */
503+ (traverseproc)CDataType_traverse, /* tp_traverse */
504+ (inquiry)CDataType_clear, /* tp_clear */
505+ 0, /* tp_richcompare */
506+ 0, /* tp_weaklistoffset */
507+ 0, /* tp_iter */
508+ 0, /* tp_iternext */
509+ CDataType_methods, /* tp_methods */
510+ 0, /* tp_members */
511+ 0, /* tp_getset */
512+ 0, /* tp_base */
513+ 0, /* tp_dict */
514+ 0, /* tp_descr_get */
515+ 0, /* tp_descr_set */
516+ 0, /* tp_dictoffset */
517+ 0, /* tp_init */
518+ 0, /* tp_alloc */
519+ UnionType_new, /* tp_new */
520+ 0, /* tp_free */
521+};
522+
523+
524+/******************************************************************/
525+
526+/*
527+
528+The PointerType_Type metaclass must ensure that the subclass of Pointer can be
529+created. It must check for a _type_ attribute in the class. Since are no
530+runtime created properties, a CField is probably *not* needed ?
531+
532+class IntPointer(Pointer):
533+ _type_ = "i"
534+
535+The Pointer_Type provides the functionality: a contents method/property, a
536+size property/method, and the sequence protocol.
537+
538+*/
539+
540+static int
541+PointerType_SetProto(StgDictObject *stgdict, PyObject *proto)
542+{
543+ if (!proto || !PyType_Check(proto)) {
544+ PyErr_SetString(PyExc_TypeError,
545+ "_type_ must be a type");
546+ return -1;
547+ }
548+ if (!PyType_stgdict(proto)) {
549+ PyErr_SetString(PyExc_TypeError,
550+ "_type_ must have storage info");
551+ return -1;
552+ }
553+ Py_INCREF(proto);
554+ Py_XDECREF(stgdict->proto);
555+ stgdict->proto = proto;
556+ return 0;
557+}
558+
559+static PyCArgObject *
560+PointerType_paramfunc(CDataObject *self)
561+{
562+ PyCArgObject *parg;
563+
564+ parg = new_CArgObject();
565+ if (parg == NULL)
566+ return NULL;
567+
568+ parg->tag = 'P';
569+ parg->pffi_type = &ffi_type_pointer;
570+ Py_INCREF(self);
571+ parg->obj = (PyObject *)self;
572+ parg->value.p = *(void **)self->b_ptr;
573+ return parg;
574+}
575+
576+static PyObject *
577+PointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
578+{
579+ PyTypeObject *result;
580+ StgDictObject *stgdict;
581+ PyObject *proto;
582+ PyObject *typedict;
583+
584+ typedict = PyTuple_GetItem(args, 2);
585+ if (!typedict)
586+ return NULL;
587+/*
588+ stgdict items size, align, length contain info about pointers itself,
589+ stgdict->proto has info about the pointed to type!
590+*/
591+ stgdict = (StgDictObject *)PyObject_CallObject(
592+ (PyObject *)&StgDict_Type, NULL);
593+ if (!stgdict)
594+ return NULL;
595+ stgdict->size = sizeof(void *);
596+ stgdict->align = getentry("P")->pffi_type->alignment;
597+ stgdict->length = 1;
598+ stgdict->ffi_type_pointer = ffi_type_pointer;
599+ stgdict->paramfunc = PointerType_paramfunc;
600+
601+ proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */
602+ if (proto && -1 == PointerType_SetProto(stgdict, proto)) {
603+ Py_DECREF((PyObject *)stgdict);
604+ return NULL;
605+ }
606+
607+ /* create the new instance (which is a class,
608+ since we are a metatype!) */
609+ result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
610+ if (result == NULL) {
611+ Py_DECREF((PyObject *)stgdict);
612+ return NULL;
613+ }
614+
615+ /* replace the class dict by our updated spam dict */
616+ if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
617+ Py_DECREF(result);
618+ Py_DECREF((PyObject *)stgdict);
619+ return NULL;
620+ }
621+ Py_DECREF(result->tp_dict);
622+ result->tp_dict = (PyObject *)stgdict;
623+
624+ return (PyObject *)result;
625+}
626+
627+
628+static PyObject *
629+PointerType_set_type(PyTypeObject *self, PyObject *type)
630+{
631+ StgDictObject *dict;
632+
633+ dict = PyType_stgdict((PyObject *)self);
634+ assert(dict);
635+
636+ if (-1 == PointerType_SetProto(dict, type))
637+ return NULL;
638+
639+ if (-1 == PyDict_SetItemString((PyObject *)dict, "_type_", type))
640+ return NULL;
641+
642+ Py_INCREF(Py_None);
643+ return Py_None;
644+}
645+
646+staticforward PyObject *_byref(PyObject *);
647+
648+static PyObject *
649+PointerType_from_param(PyObject *type, PyObject *value)
650+{
651+ StgDictObject *typedict;
652+
653+ if (value == Py_None)
654+ return PyInt_FromLong(0); /* NULL pointer */
655+
656+ typedict = PyType_stgdict(type);
657+ assert(typedict); /* Cannot be NULL for pointer types */
658+
659+ /* If we expect POINTER(<type>), but receive a <type> instance, accept
660+ it by calling byref(<type>).
661+ */
662+ switch (PyObject_IsInstance(value, typedict->proto)) {
663+ case 1:
664+ Py_INCREF(value); /* _byref steals a refcount */
665+ return _byref(value);
666+ case -1:
667+ PyErr_Clear();
668+ break;
669+ default:
670+ break;
671+ }
672+
673+ if (PointerObject_Check(value) || ArrayObject_Check(value)) {
674+ /* Array instances are also pointers when
675+ the item types are the same.
676+ */
677+ StgDictObject *v = PyObject_stgdict(value);
678+ assert(v); /* Cannot be NULL for pointer or array objects */
679+ if (PyObject_IsSubclass(v->proto, typedict->proto)) {
680+ Py_INCREF(value);
681+ return value;
682+ }
683+ }
684+ return CDataType_from_param(type, value);
685+}
686+
687+static PyMethodDef PointerType_methods[] = {
688+ { "from_address", CDataType_from_address, METH_O, from_address_doc },
689+ { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc},
690+ { "from_param", (PyCFunction)PointerType_from_param, METH_O, from_param_doc},
691+ { "set_type", (PyCFunction)PointerType_set_type, METH_O },
692+ { NULL, NULL },
693+};
694+
695+PyTypeObject PointerType_Type = {
696+ PyObject_HEAD_INIT(NULL)
697+ 0, /* ob_size */
698+ "_ctypes.PointerType", /* tp_name */
699+ 0, /* tp_basicsize */
700+ 0, /* tp_itemsize */
701+ 0, /* tp_dealloc */
702+ 0, /* tp_print */
703+ 0, /* tp_getattr */
704+ 0, /* tp_setattr */
705+ 0, /* tp_compare */
706+ 0, /* tp_repr */
707+ 0, /* tp_as_number */
708+ &CDataType_as_sequence, /* tp_as_sequence */
709+ 0, /* tp_as_mapping */
710+ 0, /* tp_hash */
711+ 0, /* tp_call */
712+ 0, /* tp_str */
713+ 0, /* tp_getattro */
714+ 0, /* tp_setattro */
715+ 0, /* tp_as_buffer */
716+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
717+ "metatype for the Pointer Objects", /* tp_doc */
718+ (traverseproc)CDataType_traverse, /* tp_traverse */
719+ (inquiry)CDataType_clear, /* tp_clear */
720+ 0, /* tp_richcompare */
721+ 0, /* tp_weaklistoffset */
722+ 0, /* tp_iter */
723+ 0, /* tp_iternext */
724+ PointerType_methods, /* tp_methods */
725+ 0, /* tp_members */
726+ 0, /* tp_getset */
727+ 0, /* tp_base */
728+ 0, /* tp_dict */
729+ 0, /* tp_descr_get */
730+ 0, /* tp_descr_set */
731+ 0, /* tp_dictoffset */
732+ 0, /* tp_init */
733+ 0, /* tp_alloc */
734+ PointerType_new, /* tp_new */
735+ 0, /* tp_free */
736+};
737+
738+
739+/******************************************************************/
740+/*
741+ ArrayType_Type
742+*/
743+/*
744+ ArrayType_new ensures that the new Array subclass created has a _length_
745+ attribute, and a _type_ attribute.
746+*/
747+
748+static int
749+CharArray_set_raw(CDataObject *self, PyObject *value)
750+{
751+ char *ptr;
752+ Py_ssize_t size;
753+ if (PyBuffer_Check(value)) {
754+ size = value->ob_type->tp_as_buffer->bf_getreadbuffer(value, 0, (void *)&ptr);
755+ if (size < 0)
756+ return -1;
757+ } else if (-1 == PyString_AsStringAndSize(value, &ptr, &size)) {
758+ return -1;
759+ }
760+ if (size > self->b_size) {
761+ PyErr_SetString(PyExc_ValueError,
762+ "string too long");
763+ return -1;
764+ }
765+
766+ memcpy(self->b_ptr, ptr, size);
767+
768+ return 0;
769+}
770+
771+static PyObject *
772+CharArray_get_raw(CDataObject *self)
773+{
774+ return PyString_FromStringAndSize(self->b_ptr, self->b_size);
775+}
776+
777+static PyObject *
778+CharArray_get_value(CDataObject *self)
779+{
780+ int i;
781+ char *ptr = self->b_ptr;
782+ for (i = 0; i < self->b_size; ++i)
783+ if (*ptr++ == '\0')
784+ break;
785+ return PyString_FromStringAndSize(self->b_ptr, i);
786+}
787+
788+static int
789+CharArray_set_value(CDataObject *self, PyObject *value)
790+{
791+ char *ptr;
792+ int size;
793+
794+ if (PyUnicode_Check(value)) {
795+ value = PyUnicode_AsEncodedString(value,
796+ conversion_mode_encoding,
797+ conversion_mode_errors);
798+ if (!value)
799+ return -1;
800+ } else if (!PyString_Check(value)) {
801+ PyErr_Format(PyExc_TypeError,
802+ "string expected instead of %s instance",
803+ value->ob_type->tp_name);
804+ return -1;
805+ } else
806+ Py_INCREF(value);
807+ size = PyString_GET_SIZE(value);
808+ if (size > self->b_size) {
809+ PyErr_SetString(PyExc_ValueError,
810+ "string too long");
811+ Py_DECREF(value);
812+ return -1;
813+ }
814+
815+ ptr = PyString_AS_STRING(value);
816+ memcpy(self->b_ptr, ptr, size);
817+ if (size < self->b_size)
818+ self->b_ptr[size] = '\0';
819+ Py_DECREF(value);
820+
821+ return 0;
822+}
823+
824+static PyGetSetDef CharArray_getsets[] = {
825+ { "raw", (getter)CharArray_get_raw, (setter)CharArray_set_raw,
826+ "value", NULL },
827+ { "value", (getter)CharArray_get_value, (setter)CharArray_set_value,
828+ "string value"},
829+ { NULL, NULL }
830+};
831+
832+#ifdef CTYPES_UNICODE
833+static PyObject *
834+WCharArray_get_value(CDataObject *self)
835+{
836+ unsigned int i;
837+ wchar_t *ptr = (wchar_t *)self->b_ptr;
838+ for (i = 0; i < self->b_size/sizeof(wchar_t); ++i)
839+ if (*ptr++ == (wchar_t)0)
840+ break;
841+ return PyUnicode_FromWideChar((wchar_t *)self->b_ptr, i);
842+}
843+
844+static int
845+WCharArray_set_value(CDataObject *self, PyObject *value)
846+{
847+ int result = 0;
848+
849+ if (PyString_Check(value)) {
850+ value = PyUnicode_FromEncodedObject(value,
851+ conversion_mode_encoding,
852+ conversion_mode_errors);
853+ if (!value)
854+ return -1;
855+ } else if (!PyUnicode_Check(value)) {
856+ PyErr_Format(PyExc_TypeError,
857+ "unicode string expected instead of %s instance",
858+ value->ob_type->tp_name);
859+ return -1;
860+ } else
861+ Py_INCREF(value);
862+ if ((unsigned)PyUnicode_GET_SIZE(value) > self->b_size/sizeof(wchar_t)) {
863+ PyErr_SetString(PyExc_ValueError,
864+ "string too long");
865+ result = -1;
866+ goto done;
867+ }
868+ result = PyUnicode_AsWideChar((PyUnicodeObject *)value,
869+ (wchar_t *)self->b_ptr,
870+ self->b_size/sizeof(wchar_t));
871+ if (result >= 0 && (unsigned)result < self->b_size/sizeof(wchar_t))
872+ ((wchar_t *)self->b_ptr)[result] = (wchar_t)0;
873+ if (result > 0)
874+ result = 0;
875+ done:
876+ Py_DECREF(value);
877+
878+ return result;
879+}
880+
881+static PyGetSetDef WCharArray_getsets[] = {
882+ { "value", (getter)WCharArray_get_value, (setter)WCharArray_set_value,
883+ "string value"},
884+ { NULL, NULL }
885+};
886+#endif
887+
888+/*
889+ The next three functions copied from Python's typeobject.c.
890+
891+ They are used to attach methods, members, or getsets to a type *after* it
892+ has been created: Arrays of characters have additional getsets to treat them
893+ as strings.
894+ */
895+/*
896+static int
897+add_methods(PyTypeObject *type, PyMethodDef *meth)
898+{
899+ PyObject *dict = type->tp_dict;
900+ for (; meth->ml_name != NULL; meth++) {
901+ PyObject *descr;
902+ descr = PyDescr_NewMethod(type, meth);
903+ if (descr == NULL)
904+ return -1;
905+ if (PyDict_SetItemString(dict,meth->ml_name, descr) < 0)
906+ return -1;
907+ Py_DECREF(descr);
908+ }
909+ return 0;
910+}
911+
912+static int
913+add_members(PyTypeObject *type, PyMemberDef *memb)
914+{
915+ PyObject *dict = type->tp_dict;
916+ for (; memb->name != NULL; memb++) {
917+ PyObject *descr;
918+ descr = PyDescr_NewMember(type, memb);
919+ if (descr == NULL)
920+ return -1;
921+ if (PyDict_SetItemString(dict, memb->name, descr) < 0)
922+ return -1;
923+ Py_DECREF(descr);
924+ }
925+ return 0;
926+}
927+*/
928+
929+static int
930+add_getset(PyTypeObject *type, PyGetSetDef *gsp)
931+{
932+ PyObject *dict = type->tp_dict;
933+ for (; gsp->name != NULL; gsp++) {
934+ PyObject *descr;
935+ descr = PyDescr_NewGetSet(type, gsp);
936+ if (descr == NULL)
937+ return -1;
938+ if (PyDict_SetItemString(dict, gsp->name, descr) < 0)
939+ return -1;
940+ Py_DECREF(descr);
941+ }
942+ return 0;
943+}
944+
945+static PyCArgObject *
946+ArrayType_paramfunc(CDataObject *self)
947+{
948+ PyCArgObject *p = new_CArgObject();
949+ if (p == NULL)
950+ return NULL;
951+ p->tag = 'P';
952+ p->pffi_type = &ffi_type_pointer;
953+ p->value.p = (char *)self->b_ptr;
954+ Py_INCREF(self);
955+ p->obj = (PyObject *)self;
956+ return p;
957+}
958+
959+static PyObject *
960+ArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
961+{
962+ PyTypeObject *result;
963+ StgDictObject *stgdict;
964+ StgDictObject *itemdict;
965+ PyObject *proto;
966+ PyObject *typedict;
967+ int length;
968+
969+ int itemsize, itemalign;
970+
971+ typedict = PyTuple_GetItem(args, 2);
972+ if (!typedict)
973+ return NULL;
974+
975+ proto = PyDict_GetItemString(typedict, "_length_"); /* Borrowed ref */
976+ if (!proto || !PyInt_Check(proto)) {
977+ PyErr_SetString(PyExc_AttributeError,
978+ "class must define a '_length_' attribute, "
979+ "which must be a positive integer");
980+ return NULL;
981+ }
982+ length = PyInt_AS_LONG(proto);
983+
984+ proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */
985+ if (!proto) {
986+ PyErr_SetString(PyExc_AttributeError,
987+ "class must define a '_type_' attribute");
988+ return NULL;
989+ }
990+
991+ stgdict = (StgDictObject *)PyObject_CallObject(
992+ (PyObject *)&StgDict_Type, NULL);
993+ if (!stgdict)
994+ return NULL;
995+
996+ itemdict = PyType_stgdict(proto);
997+ if (!itemdict) {
998+ PyErr_SetString(PyExc_TypeError,
999+ "_type_ must have storage info");
1000+ Py_DECREF((PyObject *)stgdict);
1001+ return NULL;
1002+ }
1003+
1004+ itemsize = itemdict->size;
1005+ if (length * itemsize < 0) {
1006+ PyErr_SetString(PyExc_OverflowError,
1007+ "array too large");
1008+ return NULL;
1009+ }
1010+
1011+ itemalign = itemdict->align;
1012+
1013+ stgdict->size = itemsize * length;
1014+ stgdict->align = itemalign;
1015+ stgdict->length = length;
1016+ Py_INCREF(proto);
1017+ stgdict->proto = proto;
1018+
1019+ stgdict->paramfunc = &ArrayType_paramfunc;
1020+
1021+ /* Arrays are passed as pointers to function calls. */
1022+ stgdict->ffi_type_pointer = ffi_type_pointer;
1023+
1024+ /* create the new instance (which is a class,
1025+ since we are a metatype!) */
1026+ result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
1027+ if (result == NULL)
1028+ return NULL;
1029+
1030+ /* replace the class dict by our updated spam dict */
1031+ if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
1032+ Py_DECREF(result);
1033+ Py_DECREF((PyObject *)stgdict);
1034+ return NULL;
1035+ }
1036+ Py_DECREF(result->tp_dict);
1037+ result->tp_dict = (PyObject *)stgdict;
1038+
1039+ /* Special case for character arrays.
1040+ A permanent annoyance: char arrays are also strings!
1041+ */
1042+ if (itemdict->getfunc == getentry("c")->getfunc) {
1043+ if (-1 == add_getset(result, CharArray_getsets))
1044+ return NULL;
1045+#ifdef CTYPES_UNICODE
1046+ } else if (itemdict->getfunc == getentry("u")->getfunc) {
1047+ if (-1 == add_getset(result, WCharArray_getsets))
1048+ return NULL;
1049+#endif
1050+ }
1051+
1052+ return (PyObject *)result;
1053+}
1054+
1055+PyTypeObject ArrayType_Type = {
1056+ PyObject_HEAD_INIT(NULL)
1057+ 0, /* ob_size */
1058+ "_ctypes.ArrayType", /* tp_name */
1059+ 0, /* tp_basicsize */
1060+ 0, /* tp_itemsize */
1061+ 0, /* tp_dealloc */
1062+ 0, /* tp_print */
1063+ 0, /* tp_getattr */
1064+ 0, /* tp_setattr */
1065+ 0, /* tp_compare */
1066+ 0, /* tp_repr */
1067+ 0, /* tp_as_number */
1068+ &CDataType_as_sequence, /* tp_as_sequence */
1069+ 0, /* tp_as_mapping */
1070+ 0, /* tp_hash */
1071+ 0, /* tp_call */
1072+ 0, /* tp_str */
1073+ 0, /* tp_getattro */
1074+ 0, /* tp_setattro */
1075+ 0, /* tp_as_buffer */
1076+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
1077+ "metatype for the Array Objects", /* tp_doc */
1078+ 0, /* tp_traverse */
1079+ 0, /* tp_clear */
1080+ 0, /* tp_richcompare */
1081+ 0, /* tp_weaklistoffset */
1082+ 0, /* tp_iter */
1083+ 0, /* tp_iternext */
1084+ CDataType_methods, /* tp_methods */
1085+ 0, /* tp_members */
1086+ 0, /* tp_getset */
1087+ 0, /* tp_base */
1088+ 0, /* tp_dict */
1089+ 0, /* tp_descr_get */
1090+ 0, /* tp_descr_set */
1091+ 0, /* tp_dictoffset */
1092+ 0, /* tp_init */
1093+ 0, /* tp_alloc */
1094+ ArrayType_new, /* tp_new */
1095+ 0, /* tp_free */
1096+};
1097+
1098+
1099+/******************************************************************/
1100+/*
1101+ SimpleType_Type
1102+*/
1103+/*
1104+
1105+SimpleType_new ensures that the new Simple_Type subclass created has a valid
1106+_type_ attribute.
1107+
1108+*/
1109+
1110+static char *SIMPLE_TYPE_CHARS = "cbBhHiIlLdfuzZqQPXOv";
1111+
1112+static PyObject *
1113+c_wchar_p_from_param(PyObject *type, PyObject *value)
1114+{
1115+ PyObject *as_parameter;
1116+#if (PYTHON_API_VERSION < 1012)
1117+# error not supported
1118+#endif
1119+ if (value == Py_None) {
1120+ Py_INCREF(Py_None);
1121+ return Py_None;
1122+ }
1123+ if (PyUnicode_Check(value) || PyString_Check(value)) {
1124+ PyCArgObject *parg;
1125+ struct fielddesc *fd = getentry("Z");
1126+
1127+ parg = new_CArgObject();
1128+ if (parg == NULL)
1129+ return NULL;
1130+ parg->pffi_type = &ffi_type_pointer;
1131+ parg->tag = 'Z';
1132+ parg->obj = fd->setfunc(&parg->value, value, 0);
1133+ if (parg->obj == NULL) {
1134+ Py_DECREF(parg);
1135+ return NULL;
1136+ }
1137+ return (PyObject *)parg;
1138+ }
1139+ if (PyObject_IsInstance(value, type)) {
1140+ Py_INCREF(value);
1141+ return value;
1142+ }
1143+ if (ArrayObject_Check(value) || PointerObject_Check(value)) {
1144+ /* c_wchar array instance or pointer(c_wchar(...)) */
1145+ StgDictObject *dt = PyObject_stgdict(value);
1146+ StgDictObject *dict;
1147+ assert(dt); /* Cannot be NULL for pointer or array objects */
1148+ dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
1149+ if (dict && (dict->setfunc == getentry("u")->setfunc)) {
1150+ Py_INCREF(value);
1151+ return value;
1152+ }
1153+ }
1154+ if (PyCArg_CheckExact(value)) {
1155+ /* byref(c_char(...)) */
1156+ PyCArgObject *a = (PyCArgObject *)value;
1157+ StgDictObject *dict = PyObject_stgdict(a->obj);
1158+ if (dict && (dict->setfunc == getentry("u")->setfunc)) {
1159+ Py_INCREF(value);
1160+ return value;
1161+ }
1162+ }
1163+
1164+ as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
1165+ if (as_parameter) {
1166+ value = c_wchar_p_from_param(type, as_parameter);
1167+ Py_DECREF(as_parameter);
1168+ return value;
1169+ }
1170+ /* XXX better message */
1171+ PyErr_SetString(PyExc_TypeError,
1172+ "wrong type");
1173+ return NULL;
1174+}
1175+
1176+static PyObject *
1177+c_char_p_from_param(PyObject *type, PyObject *value)
1178+{
1179+ PyObject *as_parameter;
1180+#if (PYTHON_API_VERSION < 1012)
1181+# error not supported
1182+#endif
1183+ if (value == Py_None) {
1184+ Py_INCREF(Py_None);
1185+ return Py_None;
1186+ }
1187+ if (PyString_Check(value) || PyUnicode_Check(value)) {
1188+ PyCArgObject *parg;
1189+ struct fielddesc *fd = getentry("z");
1190+
1191+ parg = new_CArgObject();
1192+ if (parg == NULL)
1193+ return NULL;
1194+ parg->pffi_type = &ffi_type_pointer;
1195+ parg->tag = 'z';
1196+ parg->obj = fd->setfunc(&parg->value, value, 0);
1197+ if (parg->obj == NULL) {
1198+ Py_DECREF(parg);
1199+ return NULL;
1200+ }
1201+ return (PyObject *)parg;
1202+ }
1203+ if (PyObject_IsInstance(value, type)) {
1204+ Py_INCREF(value);
1205+ return value;
1206+ }
1207+ if (ArrayObject_Check(value) || PointerObject_Check(value)) {
1208+ /* c_char array instance or pointer(c_char(...)) */
1209+ StgDictObject *dt = PyObject_stgdict(value);
1210+ StgDictObject *dict;
1211+ assert(dt); /* Cannot be NULL for pointer or array objects */
1212+ dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
1213+ if (dict && (dict->setfunc == getentry("c")->setfunc)) {
1214+ Py_INCREF(value);
1215+ return value;
1216+ }
1217+ }
1218+ if (PyCArg_CheckExact(value)) {
1219+ /* byref(c_char(...)) */
1220+ PyCArgObject *a = (PyCArgObject *)value;
1221+ StgDictObject *dict = PyObject_stgdict(a->obj);
1222+ if (dict && (dict->setfunc == getentry("c")->setfunc)) {
1223+ Py_INCREF(value);
1224+ return value;
1225+ }
1226+ }
1227+
1228+ as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
1229+ if (as_parameter) {
1230+ value = c_char_p_from_param(type, as_parameter);
1231+ Py_DECREF(as_parameter);
1232+ return value;
1233+ }
1234+ /* XXX better message */
1235+ PyErr_SetString(PyExc_TypeError,
1236+ "wrong type");
1237+ return NULL;
1238+}
1239+
1240+static PyObject *
1241+c_void_p_from_param(PyObject *type, PyObject *value)
1242+{
1243+ StgDictObject *stgd;
1244+ PyObject *as_parameter;
1245+#if (PYTHON_API_VERSION < 1012)
1246+# error not supported
1247+#endif
1248+
1249+/* None */
1250+ if (value == Py_None) {
1251+ Py_INCREF(Py_None);
1252+ return Py_None;
1253+ }
1254+ /* Should probably allow buffer interface as well */
1255+/* int, long */
1256+ if (PyInt_Check(value) || PyLong_Check(value)) {
1257+ PyCArgObject *parg;
1258+ struct fielddesc *fd = getentry("P");
1259+
1260+ parg = new_CArgObject();
1261+ if (parg == NULL)
1262+ return NULL;
1263+ parg->pffi_type = &ffi_type_pointer;
1264+ parg->tag = 'P';
1265+ parg->obj = fd->setfunc(&parg->value, value, 0);
1266+ if (parg->obj == NULL) {
1267+ Py_DECREF(parg);
1268+ return NULL;
1269+ }
1270+ return (PyObject *)parg;
1271+ }
1272+/* string */
1273+ if (PyString_Check(value)) {
1274+ PyCArgObject *parg;
1275+ struct fielddesc *fd = getentry("z");
1276+
1277+ parg = new_CArgObject();
1278+ if (parg == NULL)
1279+ return NULL;
1280+ parg->pffi_type = &ffi_type_pointer;
1281+ parg->tag = 'z';
1282+ parg->obj = fd->setfunc(&parg->value, value, 0);
1283+ if (parg->obj == NULL) {
1284+ Py_DECREF(parg);
1285+ return NULL;
1286+ }
1287+ return (PyObject *)parg;
1288+ }
1289+/* unicode */
1290+ if (PyUnicode_Check(value)) {
1291+ PyCArgObject *parg;
1292+ struct fielddesc *fd = getentry("Z");
1293+
1294+ parg = new_CArgObject();
1295+ if (parg == NULL)
1296+ return NULL;
1297+ parg->pffi_type = &ffi_type_pointer;
1298+ parg->tag = 'Z';
1299+ parg->obj = fd->setfunc(&parg->value, value, 0);
1300+ if (parg->obj == NULL) {
1301+ Py_DECREF(parg);
1302+ return NULL;
1303+ }
1304+ return (PyObject *)parg;
1305+ }
1306+/* c_void_p instance (or subclass) */
1307+ if (PyObject_IsInstance(value, type)) {
1308+ /* c_void_p instances */
1309+ Py_INCREF(value);
1310+ return value;
1311+ }
1312+/* ctypes array or pointer instance */
1313+ if (ArrayObject_Check(value) || PointerObject_Check(value)) {
1314+ /* Any array or pointer is accepted */
1315+ Py_INCREF(value);
1316+ return value;
1317+ }
1318+/* byref(...) */
1319+ if (PyCArg_CheckExact(value)) {
1320+ /* byref(c_xxx()) */
1321+ PyCArgObject *a = (PyCArgObject *)value;
1322+ if (a->tag == 'P') {
1323+ Py_INCREF(value);
1324+ return value;
1325+ }
1326+ }
1327+/* function pointer */
1328+ if (CFuncPtrObject_Check(value)) {
1329+ PyCArgObject *parg;
1330+ CFuncPtrObject *func;
1331+ func = (CFuncPtrObject *)value;
1332+ parg = new_CArgObject();
1333+ if (parg == NULL)
1334+ return NULL;
1335+ parg->pffi_type = &ffi_type_pointer;
1336+ parg->tag = 'P';
1337+ Py_INCREF(value);
1338+ parg->value.p = *(void **)func->b_ptr;
1339+ parg->obj = value;
1340+ return (PyObject *)parg;
1341+ }
1342+/* c_char_p, c_wchar_p */
1343+ stgd = PyObject_stgdict(value);
1344+ if (stgd && CDataObject_Check(value) && stgd->proto && PyString_Check(stgd->proto)) {
1345+ PyCArgObject *parg;
1346+
1347+ switch (PyString_AS_STRING(stgd->proto)[0]) {
1348+ case 'z': /* c_char_p */
1349+ case 'Z': /* c_wchar_p */
1350+ parg = new_CArgObject();
1351+ if (parg == NULL)
1352+ return NULL;
1353+ parg->pffi_type = &ffi_type_pointer;
1354+ parg->tag = 'Z';
1355+ Py_INCREF(value);
1356+ parg->obj = value;
1357+ /* Remember: b_ptr points to where the pointer is stored! */
1358+ parg->value.p = *(void **)(((CDataObject *)value)->b_ptr);
1359+ return (PyObject *)parg;
1360+ }
1361+ }
1362+
1363+ as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
1364+ if (as_parameter) {
1365+ value = c_void_p_from_param(type, as_parameter);
1366+ Py_DECREF(as_parameter);
1367+ return value;
1368+ }
1369+ /* XXX better message */
1370+ PyErr_SetString(PyExc_TypeError,
1371+ "wrong type");
1372+ return NULL;
1373+}
1374+#if (PYTHON_API_VERSION >= 1012)
1375+
1376+static PyMethodDef c_void_p_method = { "from_param", c_void_p_from_param, METH_O };
1377+static PyMethodDef c_char_p_method = { "from_param", c_char_p_from_param, METH_O };
1378+static PyMethodDef c_wchar_p_method = { "from_param", c_wchar_p_from_param, METH_O };
1379+
1380+#else
1381+#error
1382+static PyMethodDef c_void_p_method = { "from_param", c_void_p_from_param, METH_VARARGS };
1383+static PyMethodDef c_char_p_method = { "from_param", c_char_p_from_param, METH_VARARGS };
1384+static PyMethodDef c_wchar_p_method = { "from_param", c_wchar_p_from_param, METH_VARARGS };
1385+
1386+#endif
1387+
1388+static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject *kwds,
1389+ PyObject *proto, struct fielddesc *fmt)
1390+{
1391+ PyTypeObject *result;
1392+ StgDictObject *stgdict;
1393+ PyObject *name = PyTuple_GET_ITEM(args, 0);
1394+ PyObject *swapped_args;
1395+ static PyObject *suffix;
1396+ Py_ssize_t i;
1397+
1398+ swapped_args = PyTuple_New(PyTuple_GET_SIZE(args));
1399+ if (!swapped_args)
1400+ return NULL;
1401+
1402+ if (suffix == NULL)
1403+#ifdef WORDS_BIGENDIAN
1404+ suffix = PyString_FromString("_le");
1405+#else
1406+ suffix = PyString_FromString("_be");
1407+#endif
1408+
1409+ Py_INCREF(name);
1410+ PyString_Concat(&name, suffix);
1411+ if (name == NULL)
1412+ return NULL;
1413+
1414+ PyTuple_SET_ITEM(swapped_args, 0, name);
1415+ for (i=1; i<PyTuple_GET_SIZE(args); ++i) {
1416+ PyObject *v = PyTuple_GET_ITEM(args, i);
1417+ Py_INCREF(v);
1418+ PyTuple_SET_ITEM(swapped_args, i, v);
1419+ }
1420+
1421+ /* create the new instance (which is a class,
1422+ since we are a metatype!) */
1423+ result = (PyTypeObject *)PyType_Type.tp_new(type, swapped_args, kwds);
1424+ Py_DECREF(swapped_args);
1425+ if (result == NULL)
1426+ return NULL;
1427+
1428+ stgdict = (StgDictObject *)PyObject_CallObject(
1429+ (PyObject *)&StgDict_Type, NULL);
1430+ if (!stgdict) /* XXX leaks result! */
1431+ return NULL;
1432+
1433+ stgdict->ffi_type_pointer = *fmt->pffi_type;
1434+ stgdict->align = fmt->pffi_type->alignment;
1435+ stgdict->length = 0;
1436+ stgdict->size = fmt->pffi_type->size;
1437+ stgdict->setfunc = fmt->setfunc_swapped;
1438+ stgdict->getfunc = fmt->getfunc_swapped;
1439+
1440+ Py_INCREF(proto);
1441+ stgdict->proto = proto;
1442+
1443+ /* replace the class dict by our updated spam dict */
1444+ if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
1445+ Py_DECREF(result);
1446+ Py_DECREF((PyObject *)stgdict);
1447+ return NULL;
1448+ }
1449+ Py_DECREF(result->tp_dict);
1450+ result->tp_dict = (PyObject *)stgdict;
1451+
1452+ return (PyObject *)result;
1453+}
1454+
1455+static PyCArgObject *
1456+SimpleType_paramfunc(CDataObject *self)
1457+{
1458+ StgDictObject *dict;
1459+ char *fmt;
1460+ PyCArgObject *parg;
1461+ struct fielddesc *fd;
1462+
1463+ dict = PyObject_stgdict((PyObject *)self);
1464+ assert(dict); /* Cannot be NULL for CDataObject instances */
1465+ fmt = PyString_AsString(dict->proto);
1466+ assert(fmt);
1467+
1468+ fd = getentry(fmt);
1469+ assert(fd);
1470+
1471+ parg = new_CArgObject();
1472+ if (parg == NULL)
1473+ return NULL;
1474+
1475+ parg->tag = fmt[0];
1476+ parg->pffi_type = fd->pffi_type;
1477+ Py_INCREF(self);
1478+ parg->obj = (PyObject *)self;
1479+ memcpy(&parg->value, self->b_ptr, self->b_size);
1480+ return parg;
1481+}
1482+
1483+static PyObject *
1484+SimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1485+{
1486+ PyTypeObject *result;
1487+ StgDictObject *stgdict;
1488+ PyObject *proto;
1489+ PyMethodDef *ml;
1490+ struct fielddesc *fmt;
1491+
1492+ /* create the new instance (which is a class,
1493+ since we are a metatype!) */
1494+ result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
1495+ if (result == NULL)
1496+ return NULL;
1497+
1498+ proto = PyObject_GetAttrString((PyObject *)result, "_type_"); /* new ref */
1499+ if (!proto
1500+ || !PyString_Check(proto)
1501+ || 1 != strlen(PyString_AS_STRING(proto))
1502+ || !strchr(SIMPLE_TYPE_CHARS, PyString_AS_STRING(proto)[0])) {
1503+ PyErr_Format(PyExc_AttributeError,
1504+ "class must define a '_type_' attribute which must be\n"
1505+ "a single character string containing one of '%s'.",
1506+ SIMPLE_TYPE_CHARS);
1507+ Py_XDECREF(proto);
1508+ Py_DECREF(result);
1509+ return NULL;
1510+ }
1511+ fmt = getentry(PyString_AS_STRING(proto));
1512+ if (fmt == NULL) {
1513+ Py_DECREF(result);
1514+ PyErr_Format(PyExc_ValueError,
1515+ "_type_ '%s' not supported",
1516+ PyString_AS_STRING(proto));
1517+ return NULL;
1518+ }
1519+
1520+ stgdict = (StgDictObject *)PyObject_CallObject(
1521+ (PyObject *)&StgDict_Type, NULL);
1522+ if (!stgdict)
1523+ return NULL;
1524+
1525+ stgdict->ffi_type_pointer = *fmt->pffi_type;
1526+ stgdict->align = fmt->pffi_type->alignment;
1527+ stgdict->length = 0;
1528+ stgdict->size = fmt->pffi_type->size;
1529+ stgdict->setfunc = fmt->setfunc;
1530+ stgdict->getfunc = fmt->getfunc;
1531+
1532+ stgdict->paramfunc = SimpleType_paramfunc;
1533+/*
1534+ if (result->tp_base != &Simple_Type) {
1535+ stgdict->setfunc = NULL;
1536+ stgdict->getfunc = NULL;
1537+ }
1538+*/
1539+
1540+ /* This consumes the refcount on proto which we have */
1541+ stgdict->proto = proto;
1542+
1543+ /* replace the class dict by our updated spam dict */
1544+ if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
1545+ Py_DECREF(result);
1546+ Py_DECREF((PyObject *)stgdict);
1547+ return NULL;
1548+ }
1549+ Py_DECREF(result->tp_dict);
1550+ result->tp_dict = (PyObject *)stgdict;
1551+
1552+ /* Install from_param class methods in ctypes base classes.
1553+ Overrides the SimpleType_from_param generic method.
1554+ */
1555+ if (result->tp_base == &Simple_Type) {
1556+ switch (PyString_AS_STRING(proto)[0]) {
1557+ case 'z': /* c_char_p */
1558+ ml = &c_char_p_method;
1559+ break;
1560+ case 'Z': /* c_wchar_p */
1561+ ml = &c_wchar_p_method;
1562+ break;
1563+ case 'P': /* c_void_p */
1564+ ml = &c_void_p_method;
1565+ break;
1566+ default:
1567+ ml = NULL;
1568+ break;
1569+ }
1570+
1571+ if (ml) {
1572+#if (PYTHON_API_VERSION >= 1012)
1573+ PyObject *meth;
1574+ int x;
1575+ meth = PyDescr_NewClassMethod(result, ml);
1576+ if (!meth)
1577+ return NULL;
1578+#else
1579+#error
1580+ PyObject *meth, *func;
1581+ int x;
1582+ func = PyCFunction_New(ml, NULL);
1583+ if (!func)
1584+ return NULL;
1585+ meth = PyObject_CallFunctionObjArgs(
1586+ (PyObject *)&PyClassMethod_Type,
1587+ func, NULL);
1588+ Py_DECREF(func);
1589+ if (!meth) {
1590+ return NULL;
1591+ }
1592+#endif
1593+ x = PyDict_SetItemString(result->tp_dict,
1594+ ml->ml_name,
1595+ meth);
1596+ Py_DECREF(meth);
1597+ if (x == -1) {
1598+ Py_DECREF(result);
1599+ return NULL;
1600+ }
1601+ }
1602+ }
1603+
1604+ if (type == &SimpleType_Type && fmt->setfunc_swapped && fmt->getfunc_swapped) {
1605+ PyObject *swapped = CreateSwappedType(type, args, kwds,
1606+ proto, fmt);
1607+ if (swapped == NULL) {
1608+ Py_DECREF(result);
1609+ return NULL;
1610+ }
1611+#ifdef WORDS_BIGENDIAN
1612+ PyObject_SetAttrString((PyObject *)result, "__ctype_le__", swapped);
1613+ PyObject_SetAttrString((PyObject *)result, "__ctype_be__", (PyObject *)result);
1614+ PyObject_SetAttrString(swapped, "__ctype_be__", (PyObject *)result);
1615+ PyObject_SetAttrString(swapped, "__ctype_le__", swapped);
1616+#else
1617+ PyObject_SetAttrString((PyObject *)result, "__ctype_be__", swapped);
1618+ PyObject_SetAttrString((PyObject *)result, "__ctype_le__", (PyObject *)result);
1619+ PyObject_SetAttrString(swapped, "__ctype_le__", (PyObject *)result);
1620+ PyObject_SetAttrString(swapped, "__ctype_be__", swapped);
1621+#endif
1622+ Py_DECREF(swapped);
1623+ };
1624+
1625+ return (PyObject *)result;
1626+}
1627+
1628+/*
1629+ * This is a *class method*.
1630+ * Convert a parameter into something that ConvParam can handle.
1631+ */
1632+static PyObject *
1633+SimpleType_from_param(PyObject *type, PyObject *value)
1634+{
1635+ StgDictObject *dict;
1636+ char *fmt;
1637+ PyCArgObject *parg;
1638+ struct fielddesc *fd;
1639+ PyObject *as_parameter;
1640+
1641+ /* If the value is already an instance of the requested type,
1642+ we can use it as is */
1643+ if (1 == PyObject_IsInstance(value, type)) {
1644+ Py_INCREF(value);
1645+ return value;
1646+ }
1647+
1648+ dict = PyType_stgdict(type);
1649+ assert(dict);
1650+
1651+ /* I think we can rely on this being a one-character string */
1652+ fmt = PyString_AsString(dict->proto);
1653+ assert(fmt);
1654+
1655+ fd = getentry(fmt);
1656+ assert(fd);
1657+
1658+ parg = new_CArgObject();
1659+ if (parg == NULL)
1660+ return NULL;
1661+
1662+ parg->tag = fmt[0];
1663+ parg->pffi_type = fd->pffi_type;
1664+ parg->obj = fd->setfunc(&parg->value, value, 0);
1665+ if (parg->obj)
1666+ return (PyObject *)parg;
1667+ PyErr_Clear();
1668+ Py_DECREF(parg);
1669+
1670+ as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
1671+ if (as_parameter) {
1672+ value = SimpleType_from_param(type, as_parameter);
1673+ Py_DECREF(as_parameter);
1674+ return value;
1675+ }
1676+ PyErr_SetString(PyExc_TypeError,
1677+ "wrong type");
1678+ return NULL;
1679+}
1680+
1681+static PyMethodDef SimpleType_methods[] = {
1682+ { "from_param", SimpleType_from_param, METH_O, from_param_doc },
1683+ { "from_address", CDataType_from_address, METH_O, from_address_doc },
1684+ { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc},
1685+ { NULL, NULL },
1686+};
1687+
1688+PyTypeObject SimpleType_Type = {
1689+ PyObject_HEAD_INIT(NULL)
1690+ 0, /* ob_size */
1691+ "_ctypes.SimpleType", /* tp_name */
1692+ 0, /* tp_basicsize */
1693+ 0, /* tp_itemsize */
1694+ 0, /* tp_dealloc */
1695+ 0, /* tp_print */
1696+ 0, /* tp_getattr */
1697+ 0, /* tp_setattr */
1698+ 0, /* tp_compare */
1699+ 0, /* tp_repr */
1700+ 0, /* tp_as_number */
1701+ &CDataType_as_sequence, /* tp_as_sequence */
1702+ 0, /* tp_as_mapping */
1703+ 0, /* tp_hash */
1704+ 0, /* tp_call */
1705+ 0, /* tp_str */
1706+ 0, /* tp_getattro */
1707+ 0, /* tp_setattro */
1708+ 0, /* tp_as_buffer */
1709+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
1710+ "metatype for the SimpleType Objects", /* tp_doc */
1711+ 0, /* tp_traverse */
1712+ 0, /* tp_clear */
1713+ 0, /* tp_richcompare */
1714+ 0, /* tp_weaklistoffset */
1715+ 0, /* tp_iter */
1716+ 0, /* tp_iternext */
1717+ SimpleType_methods, /* tp_methods */
1718+ 0, /* tp_members */
1719+ 0, /* tp_getset */
1720+ 0, /* tp_base */
1721+ 0, /* tp_dict */
1722+ 0, /* tp_descr_get */
1723+ 0, /* tp_descr_set */
1724+ 0, /* tp_dictoffset */
1725+ 0, /* tp_init */
1726+ 0, /* tp_alloc */
1727+ SimpleType_new, /* tp_new */
1728+ 0, /* tp_free */
1729+};
1730+
1731+/******************************************************************/
1732+/*
1733+ CFuncPtrType_Type
1734+ */
1735+
1736+static PyObject *
1737+converters_from_argtypes(PyObject *ob)
1738+{
1739+ PyObject *converters;
1740+ int i;
1741+ int nArgs;
1742+
1743+ ob = PySequence_Tuple(ob); /* new reference */
1744+ if (!ob) {
1745+ PyErr_SetString(PyExc_TypeError,
1746+ "_argtypes_ must be a sequence of types");
1747+ return NULL;
1748+ }
1749+
1750+ nArgs = PyTuple_GET_SIZE(ob);
1751+ converters = PyTuple_New(nArgs);
1752+ if (!converters)
1753+ return NULL;
1754+
1755+ /* I have to check if this is correct. Using c_char, which has a size
1756+ of 1, will be assumed to be pushed as only one byte!
1757+ Aren't these promoted to integers by the C compiler and pushed as 4 bytes?
1758+ */
1759+
1760+ for (i = 0; i < nArgs; ++i) {
1761+ PyObject *tp = PyTuple_GET_ITEM(ob, i);
1762+ PyObject *cnv = PyObject_GetAttrString(tp, "from_param");
1763+ if (!cnv)
1764+ goto argtypes_error_1;
1765+ PyTuple_SET_ITEM(converters, i, cnv);
1766+ }
1767+ Py_DECREF(ob);
1768+ return converters;
1769+
1770+ argtypes_error_1:
1771+ Py_XDECREF(converters);
1772+ Py_DECREF(ob);
1773+ PyErr_Format(PyExc_TypeError,
1774+ "item %d in _argtypes_ has no from_param method", i+1);
1775+ return NULL;
1776+}
1777+
1778+static int
1779+make_funcptrtype_dict(StgDictObject *stgdict)
1780+{
1781+ PyObject *ob;
1782+ PyObject *converters = NULL;
1783+
1784+ stgdict->align = getentry("P")->pffi_type->alignment;
1785+ stgdict->length = 1;
1786+ stgdict->size = sizeof(void *);
1787+ stgdict->setfunc = NULL;
1788+ stgdict->getfunc = NULL;
1789+ stgdict->ffi_type_pointer = ffi_type_pointer;
1790+
1791+ ob = PyDict_GetItemString((PyObject *)stgdict, "_flags_");
1792+ if (!ob || !PyInt_Check(ob)) {
1793+ PyErr_SetString(PyExc_TypeError,
1794+ "class must define _flags_ which must be an integer");
1795+ return -1;
1796+ }
1797+ stgdict->flags = PyInt_AS_LONG(ob);
1798+
1799+ /* _argtypes_ is optional... */
1800+ ob = PyDict_GetItemString((PyObject *)stgdict, "_argtypes_");
1801+ if (ob) {
1802+ converters = converters_from_argtypes(ob);
1803+ if (!converters)
1804+ goto error;
1805+ Py_INCREF(ob);
1806+ stgdict->argtypes = ob;
1807+ stgdict->converters = converters;
1808+ }
1809+
1810+ ob = PyDict_GetItemString((PyObject *)stgdict, "_restype_");
1811+ if (ob) {
1812+ if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
1813+ PyErr_SetString(PyExc_TypeError,
1814+ "_restype_ must be a type, a callable, or None");
1815+ return -1;
1816+ }
1817+ Py_INCREF(ob);
1818+ stgdict->restype = ob;
1819+ stgdict->checker = PyObject_GetAttrString(ob, "_check_retval_");
1820+ if (stgdict->checker == NULL)
1821+ PyErr_Clear();
1822+ }
1823+/* XXX later, maybe.
1824+ ob = PyDict_GetItemString((PyObject *)stgdict, "_errcheck_");
1825+ if (ob) {
1826+ if (!PyCallable_Check(ob)) {
1827+ PyErr_SetString(PyExc_TypeError,
1828+ "_errcheck_ must be callable");
1829+ return -1;
1830+ }
1831+ Py_INCREF(ob);
1832+ stgdict->errcheck = ob;
1833+ }
1834+*/
1835+ return 0;
1836+
1837+ error:
1838+ Py_XDECREF(converters);
1839+ return -1;
1840+
1841+}
1842+
1843+static PyCArgObject *
1844+CFuncPtrType_paramfunc(CDataObject *self)
1845+{
1846+ PyCArgObject *parg;
1847+
1848+ parg = new_CArgObject();
1849+ if (parg == NULL)
1850+ return NULL;
1851+
1852+ parg->tag = 'P';
1853+ parg->pffi_type = &ffi_type_pointer;
1854+ Py_INCREF(self);
1855+ parg->obj = (PyObject *)self;
1856+ parg->value.p = *(void **)self->b_ptr;
1857+ return parg;
1858+}
1859+
1860+static PyObject *
1861+CFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1862+{
1863+ PyTypeObject *result;
1864+ StgDictObject *stgdict;
1865+
1866+ stgdict = (StgDictObject *)PyObject_CallObject(
1867+ (PyObject *)&StgDict_Type, NULL);
1868+ if (!stgdict)
1869+ return NULL;
1870+
1871+ stgdict->paramfunc = CFuncPtrType_paramfunc;
1872+
1873+ /* create the new instance (which is a class,
1874+ since we are a metatype!) */
1875+ result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
1876+ if (result == NULL) {
1877+ Py_DECREF((PyObject *)stgdict);
1878+ return NULL;
1879+ }
1880+
1881+ /* replace the class dict by our updated storage dict */
1882+ if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
1883+ Py_DECREF(result);
1884+ Py_DECREF((PyObject *)stgdict);
1885+ return NULL;
1886+ }
1887+ Py_DECREF(result->tp_dict);
1888+ result->tp_dict = (PyObject *)stgdict;
1889+
1890+ if (-1 == make_funcptrtype_dict(stgdict)) {
1891+ Py_DECREF(result);
1892+ return NULL;
1893+ }
1894+
1895+ return (PyObject *)result;
1896+}
1897+
1898+PyTypeObject CFuncPtrType_Type = {
1899+ PyObject_HEAD_INIT(NULL)
1900+ 0, /* ob_size */
1901+ "_ctypes.CFuncPtrType", /* tp_name */
1902+ 0, /* tp_basicsize */
1903+ 0, /* tp_itemsize */
1904+ 0, /* tp_dealloc */
1905+ 0, /* tp_print */
1906+ 0, /* tp_getattr */
1907+ 0, /* tp_setattr */
1908+ 0, /* tp_compare */
1909+ 0, /* tp_repr */
1910+ 0, /* tp_as_number */
1911+ &CDataType_as_sequence, /* tp_as_sequence */
1912+ 0, /* tp_as_mapping */
1913+ 0, /* tp_hash */
1914+ 0, /* tp_call */
1915+ 0, /* tp_str */
1916+ 0, /* tp_getattro */
1917+ 0, /* tp_setattro */
1918+ 0, /* tp_as_buffer */
1919+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1920+ "metatype for C function pointers", /* tp_doc */
1921+ (traverseproc)CDataType_traverse, /* tp_traverse */
1922+ (inquiry)CDataType_clear, /* tp_clear */
1923+ 0, /* tp_richcompare */
1924+ 0, /* tp_weaklistoffset */
1925+ 0, /* tp_iter */
1926+ 0, /* tp_iternext */
1927+ CDataType_methods, /* tp_methods */
1928+ 0, /* tp_members */
1929+ 0, /* tp_getset */
1930+ 0, /* tp_base */
1931+ 0, /* tp_dict */
1932+ 0, /* tp_descr_get */
1933+ 0, /* tp_descr_set */
1934+ 0, /* tp_dictoffset */
1935+ 0, /* tp_init */
1936+ 0, /* tp_alloc */
1937+ CFuncPtrType_new, /* tp_new */
1938+ 0, /* tp_free */
1939+};
1940+
1941+
1942+/*****************************************************************
1943+ * Code to keep needed objects alive
1944+ */
1945+
1946+static CDataObject *
1947+CData_GetContainer(CDataObject *self)
1948+{
1949+ while (self->b_base)
1950+ self = self->b_base;
1951+ if (self->b_objects == NULL) {
1952+ if (self->b_length) {
1953+ self->b_objects = PyDict_New();
1954+ } else {
1955+ Py_INCREF(Py_None);
1956+ self->b_objects = Py_None;
1957+ }
1958+ }
1959+ return self;
1960+}
1961+
1962+static PyObject *
1963+GetKeepedObjects(CDataObject *target)
1964+{
1965+ return CData_GetContainer(target)->b_objects;
1966+}
1967+
1968+static PyObject *
1969+unique_key(CDataObject *target, Py_ssize_t index)
1970+{
1971+ char string[256];
1972+ char *cp = string;
1973+ size_t bytes_left;
1974+
1975+ assert(sizeof(string) - 1 > sizeof(Py_ssize_t) * 2);
1976+#if (PY_VERSION_HEX < 0x02050000)
1977+ cp += sprintf(cp, "%x", index);
1978+#else
1979+ cp += sprintf(cp, "%x", Py_SAFE_DOWNCAST(index, Py_ssize_t, int));
1980+#endif
1981+ while (target->b_base) {
1982+ bytes_left = sizeof(string) - (cp - string) - 1;
1983+ /* Hex format needs 2 characters per byte */
1984+ if (bytes_left < sizeof(Py_ssize_t) * 2) {
1985+ PyErr_SetString(PyExc_ValueError,
1986+ "ctypes object structure too deep");
1987+ return NULL;
1988+ }
1989+#if (PY_VERSION_HEX < 0x02050000)
1990+ cp += sprintf(cp, ":%x", (int)target->b_index);
1991+#else
1992+ cp += sprintf(cp, ":%x", Py_SAFE_DOWNCAST(target->b_index, Py_ssize_t, int));
1993+#endif
1994+ target = target->b_base;
1995+ }
1996+ return PyString_FromStringAndSize(string, cp-string);
1997+}
1998+
1999+/*
2000+ * Keep a reference to 'keep' in the 'target', at index 'index'.
2001+ *
2002+ * If 'keep' is None, do nothing.
2003+ *
2004+ * Otherwise create a dictionary (if it does not yet exist) id the root
2005+ * objects 'b_objects' item, which will store the 'keep' object under a unique
2006+ * key.
2007+ *
2008+ * The unique_key helper travels the target's b_base pointer down to the root,
2009+ * building a string containing hex-formatted indexes found during traversal,
2010+ * separated by colons.
2011+ *
2012+ * The index tuple is used as a key into the root object's b_objects dict.
2013+ *
2014+ * Note: This function steals a refcount of the third argument, even if it
2015+ * fails!
2016+ */
2017+static int
2018+KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep)
2019+{
2020+ int result;
2021+ CDataObject *ob;
2022+ PyObject *key;
2023+
2024+/* Optimization: no need to store None */
2025+ if (keep == Py_None) {
2026+ Py_DECREF(Py_None);
2027+ return 0;
2028+ }
2029+ ob = CData_GetContainer(target);
2030+ if (ob->b_objects == NULL || !PyDict_Check(ob->b_objects)) {
2031+ Py_XDECREF(ob->b_objects);
2032+ ob->b_objects = keep; /* refcount consumed */
2033+ return 0;
2034+ }
2035+ key = unique_key(target, index);
2036+ if (key == NULL) {
2037+ Py_DECREF(keep);
2038+ return -1;
2039+ }
2040+ result = PyDict_SetItem(ob->b_objects, key, keep);
2041+ Py_DECREF(key);
2042+ Py_DECREF(keep);
2043+ return result;
2044+}
2045+
2046+/******************************************************************/
2047+/*
2048+ CData_Type
2049+ */
2050+static int
2051+CData_traverse(CDataObject *self, visitproc visit, void *arg)
2052+{
2053+ Py_VISIT(self->b_objects);
2054+ Py_VISIT((PyObject *)self->b_base);
2055+ return 0;
2056+}
2057+
2058+static int
2059+CData_clear(CDataObject *self)
2060+{
2061+ StgDictObject *dict = PyObject_stgdict((PyObject *)self);
2062+ assert(dict); /* Cannot be NULL for CDataObject instances */
2063+ Py_CLEAR(self->b_objects);
2064+ if ((self->b_needsfree)
2065+ && ((size_t)dict->size > sizeof(self->b_value)))
2066+ PyMem_Free(self->b_ptr);
2067+ self->b_ptr = NULL;
2068+ Py_CLEAR(self->b_base);
2069+ return 0;
2070+}
2071+
2072+static void
2073+CData_dealloc(PyObject *self)
2074+{
2075+ CData_clear((CDataObject *)self);
2076+ self->ob_type->tp_free(self);
2077+}
2078+
2079+static PyMemberDef CData_members[] = {
2080+ { "_b_base_", T_OBJECT,
2081+ offsetof(CDataObject, b_base), READONLY,
2082+ "the base object" },
2083+ { "_b_needsfree_", T_INT,
2084+ offsetof(CDataObject, b_needsfree), READONLY,
2085+ "whether the object owns the memory or not" },
2086+ { "_objects", T_OBJECT,
2087+ offsetof(CDataObject, b_objects), READONLY,
2088+ "internal objects tree (NEVER CHANGE THIS OBJECT!)"},
2089+ { NULL },
2090+};
2091+
2092+static Py_ssize_t CData_GetBuffer(PyObject *_self, Py_ssize_t seg, void **pptr)
2093+{
2094+ CDataObject *self = (CDataObject *)_self;
2095+ if (seg != 0) {
2096+ /* Hm. Must this set an exception? */
2097+ return -1;
2098+ }
2099+ *pptr = self->b_ptr;
2100+ return self->b_size;
2101+}
2102+
2103+static Py_ssize_t CData_GetSegcount(PyObject *_self, Py_ssize_t *lenp)
2104+{
2105+ if (lenp)
2106+ *lenp = 1;
2107+ return 1;
2108+}
2109+
2110+static PyBufferProcs CData_as_buffer = {
2111+ CData_GetBuffer,
2112+ CData_GetBuffer,
2113+ CData_GetSegcount,
2114+ NULL,
2115+};
2116+
2117+/*
2118+ * CData objects are mutable, so they cannot be hashable!
2119+ */
2120+static long
2121+CData_nohash(PyObject *self)
2122+{
2123+ PyErr_SetString(PyExc_TypeError, "unhashable type");
2124+ return -1;
2125+}
2126+
2127+/*
2128+ * default __ctypes_from_outparam__ method returns self.
2129+ */
2130+static PyObject *
2131+CData_from_outparam(PyObject *self, PyObject *args)
2132+{
2133+ Py_INCREF(self);
2134+ return self;
2135+}
2136+
2137+static PyMethodDef CData_methods[] = {
2138+ { "__ctypes_from_outparam__", CData_from_outparam, METH_NOARGS, },
2139+ { NULL, NULL },
2140+};
2141+
2142+PyTypeObject CData_Type = {
2143+ PyObject_HEAD_INIT(NULL)
2144+ 0,
2145+ "_ctypes._CData",
2146+ sizeof(CDataObject), /* tp_basicsize */
2147+ 0, /* tp_itemsize */
2148+ CData_dealloc, /* tp_dealloc */
2149+ 0, /* tp_print */
2150+ 0, /* tp_getattr */
2151+ 0, /* tp_setattr */
2152+ 0, /* tp_compare */
2153+ 0, /* tp_repr */
2154+ 0, /* tp_as_number */
2155+ 0, /* tp_as_sequence */
2156+ 0, /* tp_as_mapping */
2157+ CData_nohash, /* tp_hash */
2158+ 0, /* tp_call */
2159+ 0, /* tp_str */
2160+ 0, /* tp_getattro */
2161+ 0, /* tp_setattro */
2162+ &CData_as_buffer, /* tp_as_buffer */
2163+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2164+ "XXX to be provided", /* tp_doc */
2165+ (traverseproc)CData_traverse, /* tp_traverse */
2166+ (inquiry)CData_clear, /* tp_clear */
2167+ 0, /* tp_richcompare */
2168+ 0, /* tp_weaklistoffset */
2169+ 0, /* tp_iter */
2170+ 0, /* tp_iternext */
2171+ CData_methods, /* tp_methods */
2172+ CData_members, /* tp_members */
2173+ 0, /* tp_getset */
2174+ 0, /* tp_base */
2175+ 0, /* tp_dict */
2176+ 0, /* tp_descr_get */
2177+ 0, /* tp_descr_set */
2178+ 0, /* tp_dictoffset */
2179+ 0, /* tp_init */
2180+ 0, /* tp_alloc */
2181+ 0, /* tp_new */
2182+ 0, /* tp_free */
2183+};
2184+
2185+static int CData_MallocBuffer(CDataObject *obj, StgDictObject *dict)
2186+{
2187+ if ((size_t)dict->size <= sizeof(obj->b_value)) {
2188+ /* No need to call malloc, can use the default buffer */
2189+ obj->b_ptr = (char *)&obj->b_value;
2190+ /* The b_needsfree flag does not mean that we actually did
2191+ call PyMem_Malloc to allocate the memory block; instead it
2192+ means we are the *owner* of the memory and are responsible
2193+ for freeing resources associated with the memory. This is
2194+ also the reason that b_needsfree is exposed to Python.
2195+ */
2196+ obj->b_needsfree = 1;
2197+ } else {
2198+ /* In python 2.4, and ctypes 0.9.6, the malloc call took about
2199+ 33% of the creation time for c_int().
2200+ */
2201+ obj->b_ptr = (char *)PyMem_Malloc(dict->size);
2202+ if (obj->b_ptr == NULL) {
2203+ PyErr_NoMemory();
2204+ return -1;
2205+ }
2206+ obj->b_needsfree = 1;
2207+ memset(obj->b_ptr, 0, dict->size);
2208+ }
2209+ obj->b_size = dict->size;
2210+ return 0;
2211+}
2212+
2213+PyObject *
2214+CData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr)
2215+{
2216+ CDataObject *cmem;
2217+ StgDictObject *dict;
2218+
2219+ assert(PyType_Check(type));
2220+ dict = PyType_stgdict(type);
2221+ if (!dict) {
2222+ PyErr_SetString(PyExc_TypeError,
2223+ "abstract class");
2224+ return NULL;
2225+ }
2226+ dict->flags |= DICTFLAG_FINAL;
2227+ cmem = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
2228+ if (cmem == NULL)
2229+ return NULL;
2230+ assert(CDataObject_Check(cmem));
2231+
2232+ cmem->b_length = dict->length;
2233+ cmem->b_size = dict->size;
2234+ if (base) { /* use base's buffer */
2235+ assert(CDataObject_Check(base));
2236+ cmem->b_ptr = adr;
2237+ cmem->b_needsfree = 0;
2238+ Py_INCREF(base);
2239+ cmem->b_base = (CDataObject *)base;
2240+ cmem->b_index = index;
2241+ } else { /* copy contents of adr */
2242+ if (-1 == CData_MallocBuffer(cmem, dict)) {
2243+ return NULL;
2244+ Py_DECREF(cmem);
2245+ }
2246+ memcpy(cmem->b_ptr, adr, dict->size);
2247+ cmem->b_index = index;
2248+ }
2249+ return (PyObject *)cmem;
2250+}
2251+
2252+/*
2253+ Box a memory block into a CData instance.
2254+*/
2255+PyObject *
2256+CData_AtAddress(PyObject *type, void *buf)
2257+{
2258+ CDataObject *pd;
2259+ StgDictObject *dict;
2260+
2261+ assert(PyType_Check(type));
2262+ dict = PyType_stgdict(type);
2263+ if (!dict) {
2264+ PyErr_SetString(PyExc_TypeError,
2265+ "abstract class");
2266+ return NULL;
2267+ }
2268+ dict->flags |= DICTFLAG_FINAL;
2269+
2270+ pd = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
2271+ if (!pd)
2272+ return NULL;
2273+ assert(CDataObject_Check(pd));
2274+ pd->b_ptr = (char *)buf;
2275+ pd->b_length = dict->length;
2276+ pd->b_size = dict->size;
2277+ return (PyObject *)pd;
2278+}
2279+
2280+/*
2281+ This function returns TRUE for c_int, c_void_p, and these kind of
2282+ classes. FALSE otherwise FALSE also for subclasses of c_int and
2283+ such.
2284+*/
2285+int IsSimpleSubType(PyObject *obj)
2286+{
2287+ PyTypeObject *type = (PyTypeObject *)obj;
2288+
2289+ if (SimpleTypeObject_Check(type))
2290+ return type->tp_base != &Simple_Type;
2291+ return 0;
2292+}
2293+
2294+PyObject *
2295+CData_get(PyObject *type, GETFUNC getfunc, PyObject *src,
2296+ Py_ssize_t index, Py_ssize_t size, char *adr)
2297+{
2298+ StgDictObject *dict;
2299+ if (getfunc)
2300+ return getfunc(adr, size);
2301+ assert(type);
2302+ dict = PyType_stgdict(type);
2303+ if (dict && dict->getfunc && !IsSimpleSubType(type))
2304+ return dict->getfunc(adr, size);
2305+ return CData_FromBaseObj(type, src, index, adr);
2306+}
2307+
2308+/*
2309+ Helper function for CData_set below.
2310+*/
2311+static PyObject *
2312+_CData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
2313+ Py_ssize_t size, char *ptr)
2314+{
2315+ CDataObject *src;
2316+
2317+ if (setfunc)
2318+ return setfunc(ptr, value, size);
2319+
2320+ if (!CDataObject_Check(value)) {
2321+ StgDictObject *dict = PyType_stgdict(type);
2322+ if (dict && dict->setfunc)
2323+ return dict->setfunc(ptr, value, size);
2324+ /*
2325+ If value is a tuple, we try to call the type with the tuple
2326+ and use the result!
2327+ */
2328+ assert(PyType_Check(type));
2329+ if (PyTuple_Check(value)) {
2330+ PyObject *ob;
2331+ PyObject *result;
2332+ ob = PyObject_CallObject(type, value);
2333+ if (ob == NULL) {
2334+ Extend_Error_Info(PyExc_RuntimeError, "(%s) ",
2335+ ((PyTypeObject *)type)->tp_name);
2336+ return NULL;
2337+ }
2338+ result = _CData_set(dst, type, setfunc, ob,
2339+ size, ptr);
2340+ Py_DECREF(ob);
2341+ return result;
2342+ } else if (value == Py_None && PointerTypeObject_Check(type)) {
2343+ *(void **)ptr = NULL;
2344+ Py_INCREF(Py_None);
2345+ return Py_None;
2346+ } else {
2347+ PyErr_Format(PyExc_TypeError,
2348+ "expected %s instance, got %s",
2349+ ((PyTypeObject *)type)->tp_name,
2350+ value->ob_type->tp_name);
2351+ return NULL;
2352+ }
2353+ }
2354+ src = (CDataObject *)value;
2355+
2356+ if (PyObject_IsInstance(value, type)) {
2357+ memcpy(ptr,
2358+ src->b_ptr,
2359+ size);
2360+
2361+ if (PointerTypeObject_Check(type))
2362+ /* XXX */;
2363+
2364+ value = GetKeepedObjects(src);
2365+ Py_INCREF(value);
2366+ return value;
2367+ }
2368+
2369+ if (PointerTypeObject_Check(type)
2370+ && ArrayObject_Check(value)) {
2371+ StgDictObject *p1, *p2;
2372+ PyObject *keep;
2373+ p1 = PyObject_stgdict(value);
2374+ assert(p1); /* Cannot be NULL for array instances */
2375+ p2 = PyType_stgdict(type);
2376+ assert(p2); /* Cannot be NULL for pointer types */
2377+
2378+ if (p1->proto != p2->proto) {
2379+ PyErr_Format(PyExc_TypeError,
2380+ "incompatible types, %s instance instead of %s instance",
2381+ value->ob_type->tp_name,
2382+ ((PyTypeObject *)type)->tp_name);
2383+ return NULL;
2384+ }
2385+ *(void **)ptr = src->b_ptr;
2386+
2387+ keep = GetKeepedObjects(src);
2388+ /*
2389+ We are assigning an array object to a field which represents
2390+ a pointer. This has the same effect as converting an array
2391+ into a pointer. So, again, we have to keep the whole object
2392+ pointed to (which is the array in this case) alive, and not
2393+ only it's object list. So we create a tuple, containing
2394+ b_objects list PLUS the array itself, and return that!
2395+ */
2396+ return Py_BuildValue("(OO)", keep, value);
2397+ }
2398+ PyErr_Format(PyExc_TypeError,
2399+ "incompatible types, %s instance instead of %s instance",
2400+ value->ob_type->tp_name,
2401+ ((PyTypeObject *)type)->tp_name);
2402+ return NULL;
2403+}
2404+
2405+/*
2406+ * Set a slice in object 'dst', which has the type 'type',
2407+ * to the value 'value'.
2408+ */
2409+int
2410+CData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
2411+ Py_ssize_t index, Py_ssize_t size, char *ptr)
2412+{
2413+ CDataObject *mem = (CDataObject *)dst;
2414+ PyObject *result;
2415+
2416+ if (!CDataObject_Check(dst)) {
2417+ PyErr_SetString(PyExc_TypeError,
2418+ "not a ctype instance");
2419+ return -1;
2420+ }
2421+
2422+ result = _CData_set(mem, type, setfunc, value,
2423+ size, ptr);
2424+ if (result == NULL)
2425+ return -1;
2426+
2427+ /* KeepRef steals a refcount from it's last argument */
2428+ /* If KeepRef fails, we are stumped. The dst memory block has already
2429+ been changed */
2430+ return KeepRef(mem, index, result);
2431+}
2432+
2433+
2434+/******************************************************************/
2435+static PyObject *
2436+GenericCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2437+{
2438+ CDataObject *obj;
2439+ StgDictObject *dict;
2440+
2441+ dict = PyType_stgdict((PyObject *)type);
2442+ if (!dict) {
2443+ PyErr_SetString(PyExc_TypeError,
2444+ "abstract class");
2445+ return NULL;
2446+ }
2447+ dict->flags |= DICTFLAG_FINAL;
2448+
2449+ obj = (CDataObject *)type->tp_alloc(type, 0);
2450+ if (!obj)
2451+ return NULL;
2452+
2453+ obj->b_base = NULL;
2454+ obj->b_index = 0;
2455+ obj->b_objects = NULL;
2456+ obj->b_length = dict->length;
2457+
2458+ if (-1 == CData_MallocBuffer(obj, dict)) {
2459+ Py_DECREF(obj);
2460+ return NULL;
2461+ }
2462+ return (PyObject *)obj;
2463+}
2464+/*****************************************************************/
2465+/*
2466+ CFuncPtr_Type
2467+*/
2468+
2469+static int
2470+CFuncPtr_set_errcheck(CFuncPtrObject *self, PyObject *ob)
2471+{
2472+ if (ob && !PyCallable_Check(ob)) {
2473+ PyErr_SetString(PyExc_TypeError,
2474+ "the errcheck attribute must be callable");
2475+ return -1;
2476+ }
2477+ Py_XDECREF(self->errcheck);
2478+ Py_XINCREF(ob);
2479+ self->errcheck = ob;
2480+ return 0;
2481+}
2482+
2483+static PyObject *
2484+CFuncPtr_get_errcheck(CFuncPtrObject *self)
2485+{
2486+ if (self->errcheck) {
2487+ Py_INCREF(self->errcheck);
2488+ return self->errcheck;
2489+ }
2490+ Py_INCREF(Py_None);
2491+ return Py_None;
2492+}
2493+
2494+static int
2495+CFuncPtr_set_restype(CFuncPtrObject *self, PyObject *ob)
2496+{
2497+ if (ob == NULL) {
2498+ Py_XDECREF(self->restype);
2499+ self->restype = NULL;
2500+ Py_XDECREF(self->checker);
2501+ self->checker = NULL;
2502+ return 0;
2503+ }
2504+ if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
2505+ PyErr_SetString(PyExc_TypeError,
2506+ "restype must be a type, a callable, or None");
2507+ return -1;
2508+ }
2509+ Py_XDECREF(self->checker);
2510+ Py_XDECREF(self->restype);
2511+ Py_INCREF(ob);
2512+ self->restype = ob;
2513+ self->checker = PyObject_GetAttrString(ob, "_check_retval_");
2514+ if (self->checker == NULL)
2515+ PyErr_Clear();
2516+ return 0;
2517+}
2518+
2519+static PyObject *
2520+CFuncPtr_get_restype(CFuncPtrObject *self)
2521+{
2522+ StgDictObject *dict;
2523+ if (self->restype) {
2524+ Py_INCREF(self->restype);
2525+ return self->restype;
2526+ }
2527+ dict = PyObject_stgdict((PyObject *)self);
2528+ assert(dict); /* Cannot be NULL for CFuncPtrObject instances */
2529+ if (dict->restype) {
2530+ Py_INCREF(dict->restype);
2531+ return dict->restype;
2532+ } else {
2533+ Py_INCREF(Py_None);
2534+ return Py_None;
2535+ }
2536+}
2537+
2538+static int
2539+CFuncPtr_set_argtypes(CFuncPtrObject *self, PyObject *ob)
2540+{
2541+ PyObject *converters;
2542+
2543+ if (ob == NULL || ob == Py_None) {
2544+ Py_XDECREF(self->converters);
2545+ self->converters = NULL;
2546+ Py_XDECREF(self->argtypes);
2547+ self->argtypes = NULL;
2548+ } else {
2549+ converters = converters_from_argtypes(ob);
2550+ if (!converters)
2551+ return -1;
2552+ Py_XDECREF(self->converters);
2553+ self->converters = converters;
2554+ Py_XDECREF(self->argtypes);
2555+ Py_INCREF(ob);
2556+ self->argtypes = ob;
2557+ }
2558+ return 0;
2559+}
2560+
2561+static PyObject *
2562+CFuncPtr_get_argtypes(CFuncPtrObject *self)
2563+{
2564+ StgDictObject *dict;
2565+ if (self->argtypes) {
2566+ Py_INCREF(self->argtypes);
2567+ return self->argtypes;
2568+ }
2569+ dict = PyObject_stgdict((PyObject *)self);
2570+ assert(dict); /* Cannot be NULL for CFuncPtrObject instances */
2571+ if (dict->argtypes) {
2572+ Py_INCREF(dict->argtypes);
2573+ return dict->argtypes;
2574+ } else {
2575+ Py_INCREF(Py_None);
2576+ return Py_None;
2577+ }
2578+}
2579+
2580+static PyGetSetDef CFuncPtr_getsets[] = {
2581+ { "errcheck", (getter)CFuncPtr_get_errcheck, (setter)CFuncPtr_set_errcheck,
2582+ "a function to check for errors", NULL },
2583+ { "restype", (getter)CFuncPtr_get_restype, (setter)CFuncPtr_set_restype,
2584+ "specify the result type", NULL },
2585+ { "argtypes", (getter)CFuncPtr_get_argtypes,
2586+ (setter)CFuncPtr_set_argtypes,
2587+ "specify the argument types", NULL },
2588+ { NULL, NULL }
2589+};
2590+
2591+#ifdef MS_WIN32
2592+static PPROC FindAddress(void *handle, char *name, PyObject *type)
2593+{
2594+ PPROC address;
2595+ char *mangled_name;
2596+ int i;
2597+ StgDictObject *dict = PyType_stgdict((PyObject *)type);
2598+
2599+ address = (PPROC)GetProcAddress(handle, name);
2600+ if (address)
2601+ return address;
2602+
2603+ if (((size_t)name & ~0xFFFF) == 0) {
2604+ return NULL;
2605+ }
2606+
2607+ /* It should not happen that dict is NULL, but better be safe */
2608+ if (dict==NULL || dict->flags & FUNCFLAG_CDECL)
2609+ return address;
2610+
2611+ /* for stdcall, try mangled names:
2612+ funcname -> _funcname@<n>
2613+ where n is 0, 4, 8, 12, ..., 128
2614+ */
2615+ mangled_name = alloca(strlen(name) + 1 + 1 + 1 + 3); /* \0 _ @ %d */
2616+ if (!mangled_name)
2617+ return NULL;
2618+ for (i = 0; i < 32; ++i) {
2619+ sprintf(mangled_name, "_%s@%d", name, i*4);
2620+ address = (PPROC)GetProcAddress(handle, mangled_name);
2621+ if (address)
2622+ return address;
2623+ }
2624+ return NULL;
2625+}
2626+#endif
2627+
2628+/* Return 1 if usable, 0 else and exception set. */
2629+static int
2630+_check_outarg_type(PyObject *arg, int index)
2631+{
2632+ StgDictObject *dict;
2633+
2634+ if (PointerTypeObject_Check(arg))
2635+ return 1;
2636+
2637+ if (ArrayTypeObject_Check(arg))
2638+ return 1;
2639+
2640+ dict = PyType_stgdict(arg);
2641+ if (dict
2642+ /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
2643+ && PyString_Check(dict->proto)
2644+/* We only allow c_void_p, c_char_p and c_wchar_p as a simple output parameter type */
2645+ && (strchr("PzZ", PyString_AS_STRING(dict->proto)[0]))) {
2646+ return 1;
2647+ }
2648+
2649+ PyErr_Format(PyExc_TypeError,
2650+ "'out' parameter %d must be a pointer type, not %s",
2651+ index,
2652+ PyType_Check(arg) ?
2653+ ((PyTypeObject *)arg)->tp_name :
2654+ arg->ob_type->tp_name);
2655+ return 0;
2656+}
2657+
2658+/* Returns 1 on success, 0 on error */
2659+static int
2660+_validate_paramflags(PyTypeObject *type, PyObject *paramflags)
2661+{
2662+ int i, len;
2663+ StgDictObject *dict;
2664+ PyObject *argtypes;
2665+
2666+ dict = PyType_stgdict((PyObject *)type);
2667+ assert(dict); /* Cannot be NULL. 'type' is a CFuncPtr type. */
2668+ argtypes = dict->argtypes;
2669+
2670+ if (paramflags == NULL || dict->argtypes == NULL)
2671+ return 1;
2672+
2673+ if (!PyTuple_Check(paramflags)) {
2674+ PyErr_SetString(PyExc_TypeError,
2675+ "paramflags must be a tuple or None");
2676+ return 0;
2677+ }
2678+
2679+ len = PyTuple_GET_SIZE(paramflags);
2680+ if (len != PyTuple_GET_SIZE(dict->argtypes)) {
2681+ PyErr_SetString(PyExc_ValueError,
2682+ "paramflags must have the same length as argtypes");
2683+ return 0;
2684+ }
2685+
2686+ for (i = 0; i < len; ++i) {
2687+ PyObject *item = PyTuple_GET_ITEM(paramflags, i);
2688+ int flag;
2689+ char *name;
2690+ PyObject *defval;
2691+ PyObject *typ;
2692+ if (!PyArg_ParseTuple(item, "i|zO", &flag, &name, &defval)) {
2693+ PyErr_SetString(PyExc_TypeError,
2694+ "paramflags must be a sequence of (int [,string [,value]]) tuples");
2695+ return 0;
2696+ }
2697+ typ = PyTuple_GET_ITEM(argtypes, i);
2698+ switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
2699+ case 0:
2700+ case PARAMFLAG_FIN:
2701+ case PARAMFLAG_FIN | PARAMFLAG_FLCID:
2702+ case PARAMFLAG_FIN | PARAMFLAG_FOUT:
2703+ break;
2704+ case PARAMFLAG_FOUT:
2705+ if (!_check_outarg_type(typ, i+1))
2706+ return 0;
2707+ break;
2708+ default:
2709+ PyErr_Format(PyExc_TypeError,
2710+ "paramflag value %d not supported",
2711+ flag);
2712+ return 0;
2713+ }
2714+ }
2715+ return 1;
2716+}
2717+
2718+static int
2719+_get_name(PyObject *obj, char **pname)
2720+{
2721+#ifdef MS_WIN32
2722+ if (PyInt_Check(obj) || PyLong_Check(obj)) {
2723+ /* We have to use MAKEINTRESOURCEA for Windows CE.
2724+ Works on Windows as well, of course.
2725+ */
2726+ *pname = MAKEINTRESOURCEA(PyInt_AsUnsignedLongMask(obj) & 0xFFFF);
2727+ return 1;
2728+ }
2729+#endif
2730+ if (PyString_Check(obj) || PyUnicode_Check(obj)) {
2731+ *pname = PyString_AsString(obj);
2732+ return *pname ? 1 : 0;
2733+ }
2734+ PyErr_SetString(PyExc_TypeError,
2735+ "function name must be string or integer");
2736+ return 0;
2737+}
2738+
2739+
2740+static PyObject *
2741+CFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
2742+{
2743+ char *name;
2744+ int (* address)(void);
2745+ PyObject *dll;
2746+ PyObject *obj;
2747+ CFuncPtrObject *self;
2748+ void *handle;
2749+ PyObject *paramflags = NULL;
2750+
2751+ if (!PyArg_ParseTuple(args, "(O&O)|O", _get_name, &name, &dll, &paramflags))
2752+ return NULL;
2753+ if (paramflags == Py_None)
2754+ paramflags = NULL;
2755+
2756+ obj = PyObject_GetAttrString(dll, "_handle");
2757+ if (!obj)
2758+ return NULL;
2759+ if (!PyInt_Check(obj) && !PyLong_Check(obj)) {
2760+ PyErr_SetString(PyExc_TypeError,
2761+ "the _handle attribute of the second argument must be an integer");
2762+ Py_DECREF(obj);
2763+ return NULL;
2764+ }
2765+ handle = (void *)PyLong_AsVoidPtr(obj);
2766+ Py_DECREF(obj);
2767+ if (PyErr_Occurred()) {
2768+ PyErr_SetString(PyExc_ValueError,
2769+ "could not convert the _handle attribute to a pointer");
2770+ return NULL;
2771+ }
2772+
2773+#ifdef MS_WIN32
2774+ address = FindAddress(handle, name, (PyObject *)type);
2775+ if (!address) {
2776+ if (!IS_INTRESOURCE(name))
2777+ PyErr_Format(PyExc_AttributeError,
2778+ "function '%s' not found",
2779+ name);
2780+ else
2781+ PyErr_Format(PyExc_AttributeError,
2782+ "function ordinal %d not found",
2783+ (WORD)(size_t)name);
2784+ return NULL;
2785+ }
2786+#else
2787+ address = (PPROC)ctypes_dlsym(handle, name);
2788+ if (!address) {
2789+ PyErr_Format(PyExc_AttributeError,
2790+#ifdef __CYGWIN__
2791+/* dlerror() isn't very helpful on cygwin */
2792+ "function '%s' not found (%s) ",
2793+ name,
2794+#endif
2795+ ctypes_dlerror());
2796+ return NULL;
2797+ }
2798+#endif
2799+ if (!_validate_paramflags(type, paramflags))
2800+ return NULL;
2801+
2802+ self = (CFuncPtrObject *)GenericCData_new(type, args, kwds);
2803+ if (!self)
2804+ return NULL;
2805+
2806+ Py_XINCREF(paramflags);
2807+ self->paramflags = paramflags;
2808+
2809+ *(void **)self->b_ptr = address;
2810+
2811+ Py_INCREF((PyObject *)dll); /* for KeepRef */
2812+ if (-1 == KeepRef((CDataObject *)self, 0, dll)) {
2813+ Py_DECREF((PyObject *)self);
2814+ return NULL;
2815+ }
2816+
2817+ Py_INCREF(self);
2818+ self->callable = (PyObject *)self;
2819+ return (PyObject *)self;
2820+}
2821+
2822+#ifdef MS_WIN32
2823+static PyObject *
2824+CFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds)
2825+{
2826+ CFuncPtrObject *self;
2827+ int index;
2828+ char *name = NULL;
2829+ PyObject *paramflags = NULL;
2830+ GUID *iid = NULL;
2831+ int iid_len = 0;
2832+
2833+ if (!PyArg_ParseTuple(args, "is|Oz#", &index, &name, &paramflags, &iid, &iid_len))
2834+ return NULL;
2835+ if (paramflags == Py_None)
2836+ paramflags = NULL;
2837+
2838+ if (!_validate_paramflags(type, paramflags))
2839+ return NULL;
2840+
2841+ self = (CFuncPtrObject *)GenericCData_new(type, args, kwds);
2842+ self->index = index + 0x1000;
2843+ Py_XINCREF(paramflags);
2844+ self->paramflags = paramflags;
2845+ if (iid_len == sizeof(GUID))
2846+ self->iid = iid;
2847+ return (PyObject *)self;
2848+}
2849+#endif
2850+
2851+/*
2852+ CFuncPtr_new accepts different argument lists in addition to the standard
2853+ _basespec_ keyword arg:
2854+
2855+ one argument form
2856+ "i" - function address
2857+ "O" - must be a callable, creates a C callable function
2858+
2859+ two or more argument forms (the third argument is a paramflags tuple)
2860+ "(sO)|..." - (function name, dll object (with an integer handle)), paramflags
2861+ "(iO)|..." - (function ordinal, dll object (with an integer handle)), paramflags
2862+ "is|..." - vtable index, method name, creates callable calling COM vtbl
2863+*/
2864+static PyObject *
2865+CFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2866+{
2867+ CFuncPtrObject *self;
2868+ PyObject *callable;
2869+ StgDictObject *dict;
2870+ ffi_info *thunk;
2871+
2872+ if (PyTuple_GET_SIZE(args) == 0)
2873+ return GenericCData_new(type, args, kwds);
2874+
2875+ if (1 <= PyTuple_GET_SIZE(args) && PyTuple_Check(PyTuple_GET_ITEM(args, 0)))
2876+ return CFuncPtr_FromDll(type, args, kwds);
2877+
2878+#ifdef MS_WIN32
2879+ if (2 <= PyTuple_GET_SIZE(args) && PyInt_Check(PyTuple_GET_ITEM(args, 0)))
2880+ return CFuncPtr_FromVtblIndex(type, args, kwds);
2881+#endif
2882+
2883+ if (1 == PyTuple_GET_SIZE(args)
2884+ && (PyInt_Check(PyTuple_GET_ITEM(args, 0))
2885+ || PyLong_Check(PyTuple_GET_ITEM(args, 0)))) {
2886+ CDataObject *ob;
2887+ void *ptr = PyLong_AsVoidPtr(PyTuple_GET_ITEM(args, 0));
2888+ if (ptr == NULL)
2889+ return NULL;
2890+ ob = (CDataObject *)GenericCData_new(type, args, kwds);
2891+ if (ob == NULL)
2892+ return NULL;
2893+ *(void **)ob->b_ptr = ptr;
2894+ return (PyObject *)ob;
2895+ }
2896+
2897+ if (!PyArg_ParseTuple(args, "O", &callable))
2898+ return NULL;
2899+ if (!PyCallable_Check(callable)) {
2900+ PyErr_SetString(PyExc_TypeError,
2901+ "argument must be callable or integer function address");
2902+ return NULL;
2903+ }
2904+
2905+ /* XXX XXX This would allow to pass additional options. For COM
2906+ method *implementations*, we would probably want different
2907+ behaviour than in 'normal' callback functions: return a HRESULT if
2908+ an exception occurrs in the callback, and print the traceback not
2909+ only on the console, but also to OutputDebugString() or something
2910+ like that.
2911+ */
2912+/*
2913+ if (kwds && PyDict_GetItemString(kwds, "options")) {
2914+ ...
2915+ }
2916+*/
2917+
2918+ dict = PyType_stgdict((PyObject *)type);
2919+ /* XXXX Fails if we do: 'CFuncPtr(lambda x: x)' */
2920+ if (!dict || !dict->argtypes) {
2921+ PyErr_SetString(PyExc_TypeError,
2922+ "cannot construct instance of this class:"
2923+ " no argtypes");
2924+ return NULL;
2925+ }
2926+
2927+ /*****************************************************************/
2928+ /* The thunk keeps unowned references to callable and dict->argtypes
2929+ so we have to keep them alive somewhere else: callable is kept in self,
2930+ dict->argtypes is in the type's stgdict.
2931+ */
2932+ thunk = AllocFunctionCallback(callable,
2933+ dict->argtypes,
2934+ dict->restype,
2935+ dict->flags & FUNCFLAG_CDECL);
2936+ if (!thunk)
2937+ return NULL;
2938+
2939+ self = (CFuncPtrObject *)GenericCData_new(type, args, kwds);
2940+ if (self == NULL)
2941+ return NULL;
2942+
2943+ Py_INCREF(callable);
2944+ self->callable = callable;
2945+
2946+ self->thunk = thunk;
2947+ *(void **)self->b_ptr = *(void **)thunk;
2948+
2949+ /* We store ourself in self->b_objects[0], because the whole instance
2950+ must be kept alive if stored in a structure field, for example.
2951+ Cycle GC to the rescue! And we have a unittest proving that this works
2952+ correctly...
2953+ */
2954+
2955+ Py_INCREF((PyObject *)self); /* for KeepRef */
2956+ if (-1 == KeepRef((CDataObject *)self, 0, (PyObject *)self)) {
2957+ Py_DECREF((PyObject *)self);
2958+ return NULL;
2959+ }
2960+
2961+ return (PyObject *)self;
2962+}
2963+
2964+
2965+/*
2966+ _byref consumes a refcount to its argument
2967+*/
2968+static PyObject *
2969+_byref(PyObject *obj)
2970+{
2971+ PyCArgObject *parg;
2972+ if (!CDataObject_Check(obj)) {
2973+ PyErr_SetString(PyExc_TypeError,
2974+ "expected CData instance");
2975+ return NULL;
2976+ }
2977+
2978+ parg = new_CArgObject();
2979+ if (parg == NULL) {
2980+ Py_DECREF(obj);
2981+ return NULL;
2982+ }
2983+
2984+ parg->tag = 'P';
2985+ parg->pffi_type = &ffi_type_pointer;
2986+ parg->obj = obj;
2987+ parg->value.p = ((CDataObject *)obj)->b_ptr;
2988+ return (PyObject *)parg;
2989+}
2990+
2991+static PyObject *
2992+_get_arg(int *pindex, char *name, PyObject *defval, PyObject *inargs, PyObject *kwds)
2993+{
2994+ PyObject *v;
2995+
2996+ if (*pindex < PyTuple_GET_SIZE(inargs)) {
2997+ v = PyTuple_GET_ITEM(inargs, *pindex);
2998+ ++*pindex;
2999+ Py_INCREF(v);
3000+ return v;
3001+ }
3002+ if (kwds && (v = PyDict_GetItemString(kwds, name))) {
3003+ ++*pindex;
3004+ Py_INCREF(v);
3005+ return v;
3006+ }
3007+ if (defval) {
3008+ Py_INCREF(defval);
3009+ return defval;
3010+ }
3011+ /* we can't currently emit a better error message */
3012+ if (name)
3013+ PyErr_Format(PyExc_TypeError,
3014+ "required argument '%s' missing", name);
3015+ else
3016+ PyErr_Format(PyExc_TypeError,
3017+ "not enough arguments");
3018+ return NULL;
3019+}
3020+
3021+/*
3022+ This function implements higher level functionality plus the ability to call
3023+ functions with keyword arguments by looking at parameter flags. parameter
3024+ flags is a tuple of 1, 2 or 3-tuples. The first entry in each is an integer
3025+ specifying the direction of the data transfer for this parameter - 'in',
3026+ 'out' or 'inout' (zero means the same as 'in'). The second entry is the
3027+ parameter name, and the third is the default value if the parameter is
3028+ missing in the function call.
3029+
3030+ This function builds and returns a new tuple 'callargs' which contains the
3031+ parameters to use in the call. Items on this tuple are copied from the
3032+ 'inargs' tuple for 'in' and 'in, out' parameters, and constructed from the
3033+ 'argtypes' tuple for 'out' parameters. It also calculates numretvals which
3034+ is the number of return values for the function, outmask/inoutmask are
3035+ bitmasks containing indexes into the callargs tuple specifying which
3036+ parameters have to be returned. _build_result builds the return value of the
3037+ function.
3038+*/
3039+static PyObject *
3040+_build_callargs(CFuncPtrObject *self, PyObject *argtypes,
3041+ PyObject *inargs, PyObject *kwds,
3042+ int *poutmask, int *pinoutmask, unsigned int *pnumretvals)
3043+{
3044+ PyObject *paramflags = self->paramflags;
3045+ PyObject *callargs;
3046+ StgDictObject *dict;
3047+ int i, len;
3048+ int inargs_index = 0;
3049+ /* It's a little bit difficult to determine how many arguments the
3050+ function call requires/accepts. For simplicity, we count the consumed
3051+ args and compare this to the number of supplied args. */
3052+ int actual_args;
3053+
3054+ *poutmask = 0;
3055+ *pinoutmask = 0;
3056+ *pnumretvals = 0;
3057+
3058+ /* Trivial cases, where we either return inargs itself, or a slice of it. */
3059+ if (argtypes == NULL || paramflags == NULL || PyTuple_GET_SIZE(argtypes) == 0) {
3060+#ifdef MS_WIN32
3061+ if (self->index)
3062+ return PyTuple_GetSlice(inargs, 1, PyTuple_GET_SIZE(inargs));
3063+#endif
3064+ Py_INCREF(inargs);
3065+ return inargs;
3066+ }
3067+
3068+ len = PyTuple_GET_SIZE(argtypes);
3069+ callargs = PyTuple_New(len); /* the argument tuple we build */
3070+ if (callargs == NULL)
3071+ return NULL;
3072+
3073+#ifdef MS_WIN32
3074+ /* For a COM method, skip the first arg */
3075+ if (self->index) {
3076+ inargs_index = 1;
3077+ }
3078+#endif
3079+ for (i = 0; i < len; ++i) {
3080+ PyObject *item = PyTuple_GET_ITEM(paramflags, i);
3081+ PyObject *ob;
3082+ int flag;
3083+ char *name = NULL;
3084+ PyObject *defval = NULL;
3085+
3086+ /* This way seems to be ~2 us faster than the PyArg_ParseTuple
3087+ calls below. */
3088+ /* We HAVE already checked that the tuple can be parsed with "i|zO", so... */
3089+ int tsize = PyTuple_GET_SIZE(item);
3090+ flag = PyInt_AS_LONG(PyTuple_GET_ITEM(item, 0));
3091+ name = tsize > 1 ? PyString_AS_STRING(PyTuple_GET_ITEM(item, 1)) : NULL;
3092+ defval = tsize > 2 ? PyTuple_GET_ITEM(item, 2) : NULL;
3093+
3094+ switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
3095+ case PARAMFLAG_FIN | PARAMFLAG_FLCID:
3096+ /* ['in', 'lcid'] parameter. Always taken from defval,
3097+ if given, else the integer 0. */
3098+ if (defval == NULL) {
3099+ defval = PyInt_FromLong(0);
3100+ if (defval == NULL)
3101+ goto error;
3102+ } else
3103+ Py_INCREF(defval);
3104+ PyTuple_SET_ITEM(callargs, i, defval);
3105+ break;
3106+ case (PARAMFLAG_FIN | PARAMFLAG_FOUT):
3107+ *pinoutmask |= (1 << i); /* mark as inout arg */
3108+ (*pnumretvals)++;
3109+ /* fall through to PARAMFLAG_FIN... */
3110+ case 0:
3111+ case PARAMFLAG_FIN:
3112+ /* 'in' parameter. Copy it from inargs. */
3113+ ob =_get_arg(&inargs_index, name, defval, inargs, kwds);
3114+ if (ob == NULL)
3115+ goto error;
3116+ PyTuple_SET_ITEM(callargs, i, ob);
3117+ break;
3118+ case PARAMFLAG_FOUT:
3119+ /* XXX Refactor this code into a separate function. */
3120+ /* 'out' parameter.
3121+ argtypes[i] must be a POINTER to a c type.
3122+
3123+ Cannot by supplied in inargs, but a defval will be used
3124+ if available. XXX Should we support getting it from kwds?
3125+ */
3126+ if (defval) {
3127+ /* XXX Using mutable objects as defval will
3128+ make the function non-threadsafe, unless we
3129+ copy the object in each invocation */
3130+ Py_INCREF(defval);
3131+ PyTuple_SET_ITEM(callargs, i, defval);
3132+ *poutmask |= (1 << i); /* mark as out arg */
3133+ (*pnumretvals)++;
3134+ break;
3135+ }
3136+ ob = PyTuple_GET_ITEM(argtypes, i);
3137+ dict = PyType_stgdict(ob);
3138+ if (dict == NULL) {
3139+ /* Cannot happen: _validate_paramflags()
3140+ would not accept such an object */
3141+ PyErr_Format(PyExc_RuntimeError,
3142+ "NULL stgdict unexpected");
3143+ goto error;
3144+ }
3145+ if (PyString_Check(dict->proto)) {
3146+ PyErr_Format(
3147+ PyExc_TypeError,
3148+ "%s 'out' parameter must be passed as default value",
3149+ ((PyTypeObject *)ob)->tp_name);
3150+ goto error;
3151+ }
3152+ if (ArrayTypeObject_Check(ob))
3153+ ob = PyObject_CallObject(ob, NULL);
3154+ else
3155+ /* Create an instance of the pointed-to type */
3156+ ob = PyObject_CallObject(dict->proto, NULL);
3157+ /*
3158+ XXX Is the following correct any longer?
3159+ We must not pass a byref() to the array then but
3160+ the array instance itself. Then, we cannot retrive
3161+ the result from the PyCArgObject.
3162+ */
3163+ if (ob == NULL)
3164+ goto error;
3165+ /* The .from_param call that will ocurr later will pass this
3166+ as a byref parameter. */
3167+ PyTuple_SET_ITEM(callargs, i, ob);
3168+ *poutmask |= (1 << i); /* mark as out arg */
3169+ (*pnumretvals)++;
3170+ break;
3171+ default:
3172+ PyErr_Format(PyExc_ValueError,
3173+ "paramflag %d not yet implemented", flag);
3174+ goto error;
3175+ break;
3176+ }
3177+ }
3178+
3179+ /* We have counted the arguments we have consumed in 'inargs_index'. This
3180+ must be the same as len(inargs) + len(kwds), otherwise we have
3181+ either too much or not enough arguments. */
3182+
3183+ actual_args = PyTuple_GET_SIZE(inargs) + (kwds ? PyDict_Size(kwds) : 0);
3184+ if (actual_args != inargs_index) {
3185+ /* When we have default values or named parameters, this error
3186+ message is misleading. See unittests/test_paramflags.py
3187+ */
3188+ PyErr_Format(PyExc_TypeError,
3189+ "call takes exactly %d arguments (%d given)",
3190+ inargs_index, actual_args);
3191+ goto error;
3192+ }
3193+
3194+ /* outmask is a bitmask containing indexes into callargs. Items at
3195+ these indexes contain values to return.
3196+ */
3197+ return callargs;
3198+ error:
3199+ Py_DECREF(callargs);
3200+ return NULL;
3201+}
3202+
3203+/* See also:
3204+ http://msdn.microsoft.com/library/en-us/com/html/769127a1-1a14-4ed4-9d38-7cf3e571b661.asp
3205+*/
3206+/*
3207+ Build return value of a function.
3208+
3209+ Consumes the refcount on result and callargs.
3210+*/
3211+static PyObject *
3212+_build_result(PyObject *result, PyObject *callargs,
3213+ int outmask, int inoutmask, unsigned int numretvals)
3214+{
3215+ unsigned int i, index;
3216+ int bit;
3217+ PyObject *tup = NULL;
3218+
3219+ if (callargs == NULL)
3220+ return result;
3221+ if (result == NULL || numretvals == 0) {
3222+ Py_DECREF(callargs);
3223+ return result;
3224+ }
3225+ Py_DECREF(result);
3226+
3227+ /* tup will not be allocated if numretvals == 1 */
3228+ /* allocate tuple to hold the result */
3229+ if (numretvals > 1) {
3230+ tup = PyTuple_New(numretvals);
3231+ if (tup == NULL) {
3232+ Py_DECREF(callargs);
3233+ return NULL;
3234+ }
3235+ }
3236+
3237+ index = 0;
3238+ for (bit = 1, i = 0; i < 32; ++i, bit <<= 1) {
3239+ PyObject *v;
3240+ if (bit & inoutmask) {
3241+ v = PyTuple_GET_ITEM(callargs, i);
3242+ Py_INCREF(v);
3243+ if (numretvals == 1) {
3244+ Py_DECREF(callargs);
3245+ return v;
3246+ }
3247+ PyTuple_SET_ITEM(tup, index, v);
3248+ index++;
3249+ } else if (bit & outmask) {
3250+ v = PyTuple_GET_ITEM(callargs, i);
3251+ v = PyObject_CallMethod(v, "__ctypes_from_outparam__", NULL);
3252+ if (v == NULL || numretvals == 1) {
3253+ Py_DECREF(callargs);
3254+ return v;
3255+ }
3256+ PyTuple_SET_ITEM(tup, index, v);
3257+ index++;
3258+ }
3259+ if (index == numretvals)
3260+ break;
3261+ }
3262+
3263+ Py_DECREF(callargs);
3264+ return tup;
3265+}
3266+
3267+static PyObject *
3268+CFuncPtr_call(CFuncPtrObject *self, PyObject *inargs, PyObject *kwds)
3269+{
3270+ PyObject *restype;
3271+ PyObject *converters;
3272+ PyObject *checker;
3273+ PyObject *argtypes;
3274+ StgDictObject *dict = PyObject_stgdict((PyObject *)self);
3275+ PyObject *result;
3276+ PyObject *callargs;
3277+ PyObject *errcheck;
3278+#ifdef MS_WIN32
3279+ IUnknown *piunk = NULL;
3280+#endif
3281+ void *pProc = NULL;
3282+
3283+ int inoutmask;
3284+ int outmask;
3285+ unsigned int numretvals;
3286+
3287+ assert(dict); /* Cannot be NULL for CFuncPtrObject instances */
3288+ restype = self->restype ? self->restype : dict->restype;
3289+ converters = self->converters ? self->converters : dict->converters;
3290+ checker = self->checker ? self->checker : dict->checker;
3291+ argtypes = self->argtypes ? self->argtypes : dict->argtypes;
3292+/* later, we probably want to have an errcheck field in stgdict */
3293+ errcheck = self->errcheck /* ? self->errcheck : dict->errcheck */;
3294+
3295+
3296+ pProc = *(void **)self->b_ptr;
3297+#ifdef MS_WIN32
3298+ if (self->index) {
3299+ /* It's a COM method */
3300+ CDataObject *this;
3301+ this = (CDataObject *)PyTuple_GetItem(inargs, 0); /* borrowed ref! */
3302+ if (!this) {
3303+ PyErr_SetString(PyExc_ValueError,
3304+ "native com method call without 'this' parameter");
3305+ return NULL;
3306+ }
3307+ if (!CDataObject_Check(this)) {
3308+ PyErr_SetString(PyExc_TypeError,
3309+ "Expected a COM this pointer as first argument");
3310+ return NULL;
3311+ }
3312+ /* there should be more checks? No, in Python */
3313+ /* First arg is an pointer to an interface instance */
3314+ if (!this->b_ptr || *(void **)this->b_ptr == NULL) {
3315+ PyErr_SetString(PyExc_ValueError,
3316+ "NULL COM pointer access");
3317+ return NULL;
3318+ }
3319+ piunk = *(IUnknown **)this->b_ptr;
3320+ if (NULL == piunk->lpVtbl) {
3321+ PyErr_SetString(PyExc_ValueError,
3322+ "COM method call without VTable");
3323+ return NULL;
3324+ }
3325+ pProc = ((void **)piunk->lpVtbl)[self->index - 0x1000];
3326+ }
3327+#endif
3328+ callargs = _build_callargs(self, argtypes,
3329+ inargs, kwds,
3330+ &outmask, &inoutmask, &numretvals);
3331+ if (callargs == NULL)
3332+ return NULL;
3333+
3334+ if (converters) {
3335+ int required = PyTuple_GET_SIZE(converters);
3336+ int actual = PyTuple_GET_SIZE(callargs);
3337+
3338+ if ((dict->flags & FUNCFLAG_CDECL) == FUNCFLAG_CDECL) {
3339+ /* For cdecl functions, we allow more actual arguments
3340+ than the length of the argtypes tuple.
3341+ */
3342+ if (required > actual) {
3343+ Py_DECREF(callargs);
3344+ PyErr_Format(PyExc_TypeError,
3345+ "this function takes at least %d argument%s (%d given)",
3346+ required,
3347+ required == 1 ? "" : "s",
3348+ actual);
3349+ return NULL;
3350+ }
3351+ } else if (required != actual) {
3352+ Py_DECREF(callargs);
3353+ PyErr_Format(PyExc_TypeError,
3354+ "this function takes %d argument%s (%d given)",
3355+ required,
3356+ required == 1 ? "" : "s",
3357+ actual);
3358+ return NULL;
3359+ }
3360+ }
3361+
3362+ result = _CallProc(pProc,
3363+ callargs,
3364+#ifdef MS_WIN32
3365+ piunk,
3366+ self->iid,
3367+#endif
3368+ dict->flags,
3369+ converters,
3370+ restype,
3371+ checker);
3372+/* The 'errcheck' protocol */
3373+ if (result != NULL && errcheck) {
3374+ PyObject *v = PyObject_CallFunctionObjArgs(errcheck,
3375+ result,
3376+ self,
3377+ callargs,
3378+ NULL);
3379+ /* If the errcheck funtion failed, return NULL.
3380+ If the errcheck function returned callargs unchanged,
3381+ continue normal processing.
3382+ If the errcheck function returned something else,
3383+ use that as result.
3384+ */
3385+ if (v == NULL || v != callargs) {
3386+ Py_DECREF(result);
3387+ Py_DECREF(callargs);
3388+ return v;
3389+ }
3390+ Py_DECREF(v);
3391+ }
3392+
3393+ return _build_result(result, callargs,
3394+ outmask, inoutmask, numretvals);
3395+}
3396+
3397+static int
3398+CFuncPtr_traverse(CFuncPtrObject *self, visitproc visit, void *arg)
3399+{
3400+ Py_VISIT(self->callable);
3401+ Py_VISIT(self->restype);
3402+ Py_VISIT(self->checker);
3403+ Py_VISIT(self->errcheck);
3404+ Py_VISIT(self->argtypes);
3405+ Py_VISIT(self->converters);
3406+ Py_VISIT(self->paramflags);
3407+ return CData_traverse((CDataObject *)self, visit, arg);
3408+}
3409+
3410+static int
3411+CFuncPtr_clear(CFuncPtrObject *self)
3412+{
3413+ Py_CLEAR(self->callable);
3414+ Py_CLEAR(self->restype);
3415+ Py_CLEAR(self->checker);
3416+ Py_CLEAR(self->errcheck);
3417+ Py_CLEAR(self->argtypes);
3418+ Py_CLEAR(self->converters);
3419+ Py_CLEAR(self->paramflags);
3420+
3421+ if (self->thunk) {
3422+ FreeClosure(self->thunk->pcl);
3423+ PyMem_Free(self->thunk);
3424+ self->thunk = NULL;
3425+ }
3426+
3427+ return CData_clear((CDataObject *)self);
3428+}
3429+
3430+static void
3431+CFuncPtr_dealloc(CFuncPtrObject *self)
3432+{
3433+ CFuncPtr_clear(self);
3434+ self->ob_type->tp_free((PyObject *)self);
3435+}
3436+
3437+static PyObject *
3438+CFuncPtr_repr(CFuncPtrObject *self)
3439+{
3440+#ifdef MS_WIN32
3441+ if (self->index)
3442+ return PyString_FromFormat("<COM method offset %d: %s at %p>",
3443+ self->index - 0x1000,
3444+ self->ob_type->tp_name,
3445+ self);
3446+#endif
3447+ return PyString_FromFormat("<%s object at %p>",
3448+ self->ob_type->tp_name,
3449+ self);
3450+}
3451+
3452+PyTypeObject CFuncPtr_Type = {
3453+ PyObject_HEAD_INIT(NULL)
3454+ 0,
3455+ "_ctypes.CFuncPtr",
3456+ sizeof(CFuncPtrObject), /* tp_basicsize */
3457+ 0, /* tp_itemsize */
3458+ (destructor)CFuncPtr_dealloc, /* tp_dealloc */
3459+ 0, /* tp_print */
3460+ 0, /* tp_getattr */
3461+ 0, /* tp_setattr */
3462+ 0, /* tp_compare */
3463+ (reprfunc)CFuncPtr_repr, /* tp_repr */
3464+ 0, /* tp_as_number */
3465+ 0, /* tp_as_sequence */
3466+ 0, /* tp_as_mapping */
3467+ 0, /* tp_hash */
3468+ (ternaryfunc)CFuncPtr_call, /* tp_call */
3469+ 0, /* tp_str */
3470+ 0, /* tp_getattro */
3471+ 0, /* tp_setattro */
3472+ &CData_as_buffer, /* tp_as_buffer */
3473+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3474+ "Function Pointer", /* tp_doc */
3475+ (traverseproc)CFuncPtr_traverse, /* tp_traverse */
3476+ (inquiry)CFuncPtr_clear, /* tp_clear */
3477+ 0, /* tp_richcompare */
3478+ 0, /* tp_weaklistoffset */
3479+ 0, /* tp_iter */
3480+ 0, /* tp_iternext */
3481+ 0, /* tp_methods */
3482+ 0, /* tp_members */
3483+ CFuncPtr_getsets, /* tp_getset */
3484+ 0, /* tp_base */
3485+ 0, /* tp_dict */
3486+ 0, /* tp_descr_get */
3487+ 0, /* tp_descr_set */
3488+ 0, /* tp_dictoffset */
3489+ 0, /* tp_init */
3490+ 0, /* tp_alloc */
3491+ CFuncPtr_new, /* tp_new */
3492+ 0, /* tp_free */
3493+};
3494+
3495+/*****************************************************************/
3496+/*
3497+ Struct_Type
3498+*/
3499+static int
3500+IBUG(char *msg)
3501+{
3502+ PyErr_Format(PyExc_RuntimeError,
3503+ "inconsistent state in CDataObject (%s)", msg);
3504+ return -1;
3505+}
3506+
3507+static int
3508+Struct_init(PyObject *self, PyObject *args, PyObject *kwds)
3509+{
3510+ int i;
3511+ PyObject *fields;
3512+
3513+/* Optimization possible: Store the attribute names _fields_[x][0]
3514+ * in C accessible fields somewhere ?
3515+ */
3516+
3517+/* Check this code again for correctness! */
3518+
3519+ if (!PyTuple_Check(args)) {
3520+ PyErr_SetString(PyExc_TypeError,
3521+ "args not a tuple?");
3522+ return -1;
3523+ }
3524+ if (PyTuple_GET_SIZE(args)) {
3525+ fields = PyObject_GetAttrString(self, "_fields_");
3526+ if (!fields) {
3527+ PyErr_Clear();
3528+ fields = PyTuple_New(0);
3529+ if (!fields)
3530+ return -1;
3531+ }
3532+
3533+ if (PyTuple_GET_SIZE(args) > PySequence_Length(fields)) {
3534+ Py_DECREF(fields);
3535+ PyErr_SetString(PyExc_ValueError,
3536+ "too many initializers");
3537+ return -1;
3538+ }
3539+
3540+ for (i = 0; i < PyTuple_GET_SIZE(args); ++i) {
3541+ PyObject *pair = PySequence_GetItem(fields, i);
3542+ PyObject *name;
3543+ PyObject *val;
3544+ if (!pair) {
3545+ Py_DECREF(fields);
3546+ return IBUG("_fields_[i] failed");
3547+ }
3548+
3549+ name = PySequence_GetItem(pair, 0);
3550+ if (!name) {
3551+ Py_DECREF(pair);
3552+ Py_DECREF(fields);
3553+ return IBUG("_fields_[i][0] failed");
3554+ }
3555+
3556+ val = PyTuple_GET_ITEM(args, i);
3557+ if (-1 == PyObject_SetAttr(self, name, val)) {
3558+ Py_DECREF(pair);
3559+ Py_DECREF(name);
3560+ Py_DECREF(fields);
3561+ return -1;
3562+ }
3563+
3564+ Py_DECREF(name);
3565+ Py_DECREF(pair);
3566+ }
3567+ Py_DECREF(fields);
3568+ }
3569+
3570+ if (kwds) {
3571+ PyObject *key, *value;
3572+ Py_ssize_t pos = 0;
3573+ while(PyDict_Next(kwds, &pos, &key, &value)) {
3574+ if (-1 == PyObject_SetAttr(self, key, value))
3575+ return -1;
3576+ }
3577+ }
3578+ return 0;
3579+}
3580+
3581+static PyTypeObject Struct_Type = {
3582+ PyObject_HEAD_INIT(NULL)
3583+ 0,
3584+ "_ctypes.Structure",
3585+ sizeof(CDataObject), /* tp_basicsize */
3586+ 0, /* tp_itemsize */
3587+ 0, /* tp_dealloc */
3588+ 0, /* tp_print */
3589+ 0, /* tp_getattr */
3590+ 0, /* tp_setattr */
3591+ 0, /* tp_compare */
3592+ 0, /* tp_repr */
3593+ 0, /* tp_as_number */
3594+ 0, /* tp_as_sequence */
3595+ 0, /* tp_as_mapping */
3596+ 0, /* tp_hash */
3597+ 0, /* tp_call */
3598+ 0, /* tp_str */
3599+ 0, /* tp_getattro */
3600+ 0, /* tp_setattro */
3601+ &CData_as_buffer, /* tp_as_buffer */
3602+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3603+ "Structure base class", /* tp_doc */
3604+ (traverseproc)CData_traverse, /* tp_traverse */
3605+ (inquiry)CData_clear, /* tp_clear */
3606+ 0, /* tp_richcompare */
3607+ 0, /* tp_weaklistoffset */
3608+ 0, /* tp_iter */
3609+ 0, /* tp_iternext */
3610+ 0, /* tp_methods */
3611+ 0, /* tp_members */
3612+ 0, /* tp_getset */
3613+ 0, /* tp_base */
3614+ 0, /* tp_dict */
3615+ 0, /* tp_descr_get */
3616+ 0, /* tp_descr_set */
3617+ 0, /* tp_dictoffset */
3618+ Struct_init, /* tp_init */
3619+ 0, /* tp_alloc */
3620+ GenericCData_new, /* tp_new */
3621+ 0, /* tp_free */
3622+};
3623+
3624+static PyTypeObject Union_Type = {
3625+ PyObject_HEAD_INIT(NULL)
3626+ 0,
3627+ "_ctypes.Union",
3628+ sizeof(CDataObject), /* tp_basicsize */
3629+ 0, /* tp_itemsize */
3630+ 0, /* tp_dealloc */
3631+ 0, /* tp_print */
3632+ 0, /* tp_getattr */
3633+ 0, /* tp_setattr */
3634+ 0, /* tp_compare */
3635+ 0, /* tp_repr */
3636+ 0, /* tp_as_number */
3637+ 0, /* tp_as_sequence */
3638+ 0, /* tp_as_mapping */
3639+ 0, /* tp_hash */
3640+ 0, /* tp_call */
3641+ 0, /* tp_str */
3642+ 0, /* tp_getattro */
3643+ 0, /* tp_setattro */
3644+ &CData_as_buffer, /* tp_as_buffer */
3645+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3646+ "Union base class", /* tp_doc */
3647+ (traverseproc)CData_traverse, /* tp_traverse */
3648+ (inquiry)CData_clear, /* tp_clear */
3649+ 0, /* tp_richcompare */
3650+ 0, /* tp_weaklistoffset */
3651+ 0, /* tp_iter */
3652+ 0, /* tp_iternext */
3653+ 0, /* tp_methods */
3654+ 0, /* tp_members */
3655+ 0, /* tp_getset */
3656+ 0, /* tp_base */
3657+ 0, /* tp_dict */
3658+ 0, /* tp_descr_get */
3659+ 0, /* tp_descr_set */
3660+ 0, /* tp_dictoffset */
3661+ Struct_init, /* tp_init */
3662+ 0, /* tp_alloc */
3663+ GenericCData_new, /* tp_new */
3664+ 0, /* tp_free */
3665+};
3666+
3667+
3668+/******************************************************************/
3669+/*
3670+ Array_Type
3671+*/
3672+static int
3673+Array_init(CDataObject *self, PyObject *args, PyObject *kw)
3674+{
3675+ int i;
3676+ int n;
3677+
3678+ if (!PyTuple_Check(args)) {
3679+ PyErr_SetString(PyExc_TypeError,
3680+ "args not a tuple?");
3681+ return -1;
3682+ }
3683+ n = PyTuple_GET_SIZE(args);
3684+ for (i = 0; i < n; ++i) {
3685+ PyObject *v;
3686+ v = PyTuple_GET_ITEM(args, i);
3687+ if (-1 == PySequence_SetItem((PyObject *)self, i, v))
3688+ return -1;
3689+ }
3690+ return 0;
3691+}
3692+
3693+static PyObject *
3694+Array_item(PyObject *_self, Py_ssize_t index)
3695+{
3696+ CDataObject *self = (CDataObject *)_self;
3697+ int offset, size;
3698+ StgDictObject *stgdict;
3699+
3700+
3701+ if (index < 0 || index >= self->b_length) {
3702+ PyErr_SetString(PyExc_IndexError,
3703+ "invalid index");
3704+ return NULL;
3705+ }
3706+
3707+ stgdict = PyObject_stgdict((PyObject *)self);
3708+ assert(stgdict); /* Cannot be NULL for array instances */
3709+ /* Would it be clearer if we got the item size from
3710+ stgdict->proto's stgdict?
3711+ */
3712+ size = stgdict->size / stgdict->length;
3713+ offset = index * size;
3714+
3715+ return CData_get(stgdict->proto, stgdict->getfunc, (PyObject *)self,
3716+ index, size, self->b_ptr + offset);
3717+}
3718+
3719+static PyObject *
3720+Array_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh)
3721+{
3722+ CDataObject *self = (CDataObject *)_self;
3723+ StgDictObject *stgdict, *itemdict;
3724+ PyObject *proto;
3725+ PyListObject *np;
3726+ Py_ssize_t i, len;
3727+
3728+ if (ilow < 0)
3729+ ilow = 0;
3730+ else if (ilow > self->b_length)
3731+ ilow = self->b_length;
3732+ if (ihigh < ilow)
3733+ ihigh = ilow;
3734+ else if (ihigh > self->b_length)
3735+ ihigh = self->b_length;
3736+ len = ihigh - ilow;
3737+
3738+ stgdict = PyObject_stgdict((PyObject *)self);
3739+ assert(stgdict); /* Cannot be NULL for array object instances */
3740+ proto = stgdict->proto;
3741+ itemdict = PyType_stgdict(proto);
3742+ assert(itemdict); /* proto is the item type of the array, a ctypes
3743+ type, so this cannot be NULL */
3744+ if (itemdict->getfunc == getentry("c")->getfunc) {
3745+ char *ptr = (char *)self->b_ptr;
3746+ return PyString_FromStringAndSize(ptr + ilow, len);
3747+#ifdef CTYPES_UNICODE
3748+ } else if (itemdict->getfunc == getentry("u")->getfunc) {
3749+ wchar_t *ptr = (wchar_t *)self->b_ptr;
3750+ return PyUnicode_FromWideChar(ptr + ilow, len);
3751+#endif
3752+ }
3753+
3754+ np = (PyListObject *) PyList_New(len);
3755+ if (np == NULL)
3756+ return NULL;
3757+
3758+ for (i = 0; i < len; i++) {
3759+ PyObject *v = Array_item(_self, i+ilow);
3760+ PyList_SET_ITEM(np, i, v);
3761+ }
3762+ return (PyObject *)np;
3763+}
3764+
3765+static int
3766+Array_ass_item(PyObject *_self, Py_ssize_t index, PyObject *value)
3767+{
3768+ CDataObject *self = (CDataObject *)_self;
3769+ int size, offset;
3770+ StgDictObject *stgdict;
3771+ char *ptr;
3772+
3773+ if (value == NULL) {
3774+ PyErr_SetString(PyExc_TypeError,
3775+ "Array does not support item deletion");
3776+ return -1;
3777+ }
3778+
3779+ stgdict = PyObject_stgdict((PyObject *)self);
3780+ assert(stgdict); /* Cannot be NULL for array object instances */
3781+ if (index < 0 || index >= stgdict->length) {
3782+ PyErr_SetString(PyExc_IndexError,
3783+ "invalid index");
3784+ return -1;
3785+ }
3786+ size = stgdict->size / stgdict->length;
3787+ offset = index * size;
3788+ ptr = self->b_ptr + offset;
3789+
3790+ return CData_set((PyObject *)self, stgdict->proto, stgdict->setfunc, value,
3791+ index, size, ptr);
3792+}
3793+
3794+static int
3795+Array_ass_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *value)
3796+{
3797+ CDataObject *self = (CDataObject *)_self;
3798+ int i, len;
3799+
3800+ if (value == NULL) {
3801+ PyErr_SetString(PyExc_TypeError,
3802+ "Array does not support item deletion");
3803+ return -1;
3804+ }
3805+
3806+ if (ilow < 0)
3807+ ilow = 0;
3808+ else if (ilow > self->b_length)
3809+ ilow = self->b_length;
3810+ if (ihigh < 0)
3811+ ihigh = 0;
3812+ if (ihigh < ilow)
3813+ ihigh = ilow;
3814+ else if (ihigh > self->b_length)
3815+ ihigh = self->b_length;
3816+
3817+ len = PySequence_Length(value);
3818+ if (len != ihigh - ilow) {
3819+ PyErr_SetString(PyExc_ValueError,
3820+ "Can only assign sequence of same size");
3821+ return -1;
3822+ }
3823+ for (i = 0; i < len; i++) {
3824+ PyObject *item = PySequence_GetItem(value, i);
3825+ int result;
3826+ if (item == NULL)
3827+ return -1;
3828+ result = Array_ass_item(_self, i+ilow, item);
3829+ Py_DECREF(item);
3830+ if (result == -1)
3831+ return -1;
3832+ }
3833+ return 0;
3834+}
3835+
3836+static Py_ssize_t
3837+Array_length(PyObject *_self)
3838+{
3839+ CDataObject *self = (CDataObject *)_self;
3840+ return self->b_length;
3841+}
3842+
3843+static PySequenceMethods Array_as_sequence = {
3844+ Array_length, /* sq_length; */
3845+ 0, /* sq_concat; */
3846+ 0, /* sq_repeat; */
3847+ Array_item, /* sq_item; */
3848+ Array_slice, /* sq_slice; */
3849+ Array_ass_item, /* sq_ass_item; */
3850+ Array_ass_slice, /* sq_ass_slice; */
3851+ 0, /* sq_contains; */
3852+
3853+ 0, /* sq_inplace_concat; */
3854+ 0, /* sq_inplace_repeat; */
3855+};
3856+
3857+PyTypeObject Array_Type = {
3858+ PyObject_HEAD_INIT(NULL)
3859+ 0,
3860+ "_ctypes.Array",
3861+ sizeof(CDataObject), /* tp_basicsize */
3862+ 0, /* tp_itemsize */
3863+ 0, /* tp_dealloc */
3864+ 0, /* tp_print */
3865+ 0, /* tp_getattr */
3866+ 0, /* tp_setattr */
3867+ 0, /* tp_compare */
3868+ 0, /* tp_repr */
3869+ 0, /* tp_as_number */
3870+ &Array_as_sequence, /* tp_as_sequence */
3871+ 0, /* tp_as_mapping */
3872+ 0, /* tp_hash */
3873+ 0, /* tp_call */
3874+ 0, /* tp_str */
3875+ 0, /* tp_getattro */
3876+ 0, /* tp_setattro */
3877+ &CData_as_buffer, /* tp_as_buffer */
3878+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3879+ "XXX to be provided", /* tp_doc */
3880+ (traverseproc)CData_traverse, /* tp_traverse */
3881+ (inquiry)CData_clear, /* tp_clear */
3882+ 0, /* tp_richcompare */
3883+ 0, /* tp_weaklistoffset */
3884+ 0, /* tp_iter */
3885+ 0, /* tp_iternext */
3886+ 0, /* tp_methods */
3887+ 0, /* tp_members */
3888+ 0, /* tp_getset */
3889+ 0, /* tp_base */
3890+ 0, /* tp_dict */
3891+ 0, /* tp_descr_get */
3892+ 0, /* tp_descr_set */
3893+ 0, /* tp_dictoffset */
3894+ (initproc)Array_init, /* tp_init */
3895+ 0, /* tp_alloc */
3896+ GenericCData_new, /* tp_new */
3897+ 0, /* tp_free */
3898+};
3899+
3900+PyObject *
3901+CreateArrayType(PyObject *itemtype, Py_ssize_t length)
3902+{
3903+ static PyObject *cache;
3904+ PyObject *key;
3905+ PyObject *result;
3906+ char name[256];
3907+
3908+ if (cache == NULL) {
3909+ cache = PyDict_New();
3910+ if (cache == NULL)
3911+ return NULL;
3912+ }
3913+#if (PY_VERSION_HEX < 0x02050000)
3914+ key = Py_BuildValue("(Oi)", itemtype, length);
3915+#else
3916+ key = Py_BuildValue("(On)", itemtype, length);
3917+#endif
3918+ if (!key)
3919+ return NULL;
3920+ result = PyDict_GetItem(cache, key);
3921+ if (result) {
3922+ Py_INCREF(result);
3923+ Py_DECREF(key);
3924+ return result;
3925+ }
3926+
3927+ if (!PyType_Check(itemtype)) {
3928+ PyErr_SetString(PyExc_TypeError,
3929+ "Expected a type object");
3930+ return NULL;
3931+ }
3932+#ifdef MS_WIN64
3933+ sprintf(name, "%.200s_Array_%Id",
3934+ ((PyTypeObject *)itemtype)->tp_name, length);
3935+#else
3936+ sprintf(name, "%.200s_Array_%ld",
3937+ ((PyTypeObject *)itemtype)->tp_name, (long)length);
3938+#endif
3939+
3940+ result = PyObject_CallFunction((PyObject *)&ArrayType_Type,
3941+#if (PY_VERSION_HEX < 0x02050000)
3942+ "s(O){s:i,s:O}",
3943+#else
3944+ "s(O){s:n,s:O}",
3945+#endif
3946+ name,
3947+ &Array_Type,
3948+ "_length_",
3949+ length,
3950+ "_type_",
3951+ itemtype
3952+ );
3953+ if (!result)
3954+ return NULL;
3955+ PyDict_SetItem(cache, key, result);
3956+ Py_DECREF(key);
3957+ return result;
3958+}
3959+
3960+
3961+/******************************************************************/
3962+/*
3963+ Simple_Type
3964+*/
3965+
3966+static int
3967+Simple_set_value(CDataObject *self, PyObject *value)
3968+{
3969+ PyObject *result;
3970+ StgDictObject *dict = PyObject_stgdict((PyObject *)self);
3971+
3972+ assert(dict); /* Cannot be NULL for CDataObject instances */
3973+ assert(dict->setfunc);
3974+ result = dict->setfunc(self->b_ptr, value, dict->size);
3975+ if (!result)
3976+ return -1;
3977+
3978+ /* consumes the refcount the setfunc returns */
3979+ return KeepRef(self, 0, result);
3980+}
3981+
3982+static int
3983+Simple_init(CDataObject *self, PyObject *args, PyObject *kw)
3984+{
3985+ PyObject *value = NULL;
3986+ if (!PyArg_UnpackTuple(args, "__init__", 0, 1, &value))
3987+ return -1;
3988+ if (value)
3989+ return Simple_set_value(self, value);
3990+ return 0;
3991+}
3992+
3993+static PyObject *
3994+Simple_get_value(CDataObject *self)
3995+{
3996+ StgDictObject *dict;
3997+ dict = PyObject_stgdict((PyObject *)self);
3998+ assert(dict); /* Cannot be NULL for CDataObject instances */
3999+ assert(dict->getfunc);
4000+ return dict->getfunc(self->b_ptr, self->b_size);
4001+}
4002+
4003+static PyGetSetDef Simple_getsets[] = {
4004+ { "value", (getter)Simple_get_value, (setter)Simple_set_value,
4005+ "current value", NULL },
4006+ { NULL, NULL }
4007+};
4008+
4009+static PyObject *
4010+Simple_from_outparm(PyObject *self, PyObject *args)
4011+{
4012+ if (IsSimpleSubType((PyObject *)self->ob_type)) {
4013+ Py_INCREF(self);
4014+ return self;
4015+ }
4016+ /* call stgdict->getfunc */
4017+ return Simple_get_value((CDataObject *)self);
4018+}
4019+
4020+static PyMethodDef Simple_methods[] = {
4021+ { "__ctypes_from_outparam__", Simple_from_outparm, METH_NOARGS, },
4022+ { NULL, NULL },
4023+};
4024+
4025+static int Simple_nonzero(CDataObject *self)
4026+{
4027+ return memcmp(self->b_ptr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", self->b_size);
4028+}
4029+
4030+static PyNumberMethods Simple_as_number = {
4031+ 0, /* nb_add */
4032+ 0, /* nb_subtract */
4033+ 0, /* nb_multiply */
4034+ 0, /* nb_divide */
4035+ 0, /* nb_remainder */
4036+ 0, /* nb_divmod */
4037+ 0, /* nb_power */
4038+ 0, /* nb_negative */
4039+ 0, /* nb_positive */
4040+ 0, /* nb_absolute */
4041+ (inquiry)Simple_nonzero, /* nb_nonzero */
4042+};
4043+
4044+#if (PY_VERSION_HEX < 0x02040000)
4045+/* Only in Python 2.4 and up */
4046+static PyObject *
4047+PyTuple_Pack(int n, ...)
4048+{
4049+ int i;
4050+ PyObject *o;
4051+ PyObject *result;
4052+ PyObject **items;
4053+ va_list vargs;
4054+
4055+ va_start(vargs, n);
4056+ result = PyTuple_New(n);
4057+ if (result == NULL)
4058+ return NULL;
4059+ items = ((PyTupleObject *)result)->ob_item;
4060+ for (i = 0; i < n; i++) {
4061+ o = va_arg(vargs, PyObject *);
4062+ Py_INCREF(o);
4063+ items[i] = o;
4064+ }
4065+ va_end(vargs);
4066+ return result;
4067+}
4068+#endif
4069+
4070+/* "%s(%s)" % (self.__class__.__name__, self.value) */
4071+static PyObject *
4072+Simple_repr(CDataObject *self)
4073+{
4074+ PyObject *val, *name, *args, *result;
4075+ static PyObject *format;
4076+
4077+ if (self->ob_type->tp_base != &Simple_Type) {
4078+ return PyString_FromFormat("<%s object at %p>",
4079+ self->ob_type->tp_name, self);
4080+ }
4081+
4082+ if (format == NULL) {
4083+ format = PyString_FromString("%s(%r)");
4084+ if (format == NULL)
4085+ return NULL;
4086+ }
4087+
4088+ val = Simple_get_value(self);
4089+ if (val == NULL)
4090+ return NULL;
4091+
4092+ name = PyString_FromString(self->ob_type->tp_name);
4093+ if (name == NULL) {
4094+ Py_DECREF(val);
4095+ return NULL;
4096+ }
4097+
4098+ args = PyTuple_Pack(2, name, val);
4099+ Py_DECREF(name);
4100+ Py_DECREF(val);
4101+ if (args == NULL)
4102+ return NULL;
4103+
4104+ result = PyString_Format(format, args);
4105+ Py_DECREF(args);
4106+ return result;
4107+}
4108+
4109+static PyTypeObject Simple_Type = {
4110+ PyObject_HEAD_INIT(NULL)
4111+ 0,
4112+ "_ctypes._SimpleCData",
4113+ sizeof(CDataObject), /* tp_basicsize */
4114+ 0, /* tp_itemsize */
4115+ 0, /* tp_dealloc */
4116+ 0, /* tp_print */
4117+ 0, /* tp_getattr */
4118+ 0, /* tp_setattr */
4119+ 0, /* tp_compare */
4120+ (reprfunc)&Simple_repr, /* tp_repr */
4121+ &Simple_as_number, /* tp_as_number */
4122+ 0, /* tp_as_sequence */
4123+ 0, /* tp_as_mapping */
4124+ 0, /* tp_hash */
4125+ 0, /* tp_call */
4126+ 0, /* tp_str */
4127+ 0, /* tp_getattro */
4128+ 0, /* tp_setattro */
4129+ &CData_as_buffer, /* tp_as_buffer */
4130+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4131+ "XXX to be provided", /* tp_doc */
4132+ (traverseproc)CData_traverse, /* tp_traverse */
4133+ (inquiry)CData_clear, /* tp_clear */
4134+ 0, /* tp_richcompare */
4135+ 0, /* tp_weaklistoffset */
4136+ 0, /* tp_iter */
4137+ 0, /* tp_iternext */
4138+ Simple_methods, /* tp_methods */
4139+ 0, /* tp_members */
4140+ Simple_getsets, /* tp_getset */
4141+ 0, /* tp_base */
4142+ 0, /* tp_dict */
4143+ 0, /* tp_descr_get */
4144+ 0, /* tp_descr_set */
4145+ 0, /* tp_dictoffset */
4146+ (initproc)Simple_init, /* tp_init */
4147+ 0, /* tp_alloc */
4148+ GenericCData_new, /* tp_new */
4149+ 0, /* tp_free */
4150+};
4151+
4152+/******************************************************************/
4153+/*
4154+ Pointer_Type
4155+*/
4156+static PyObject *
4157+Pointer_item(PyObject *_self, Py_ssize_t index)
4158+{
4159+ CDataObject *self = (CDataObject *)_self;
4160+ int size;
4161+ Py_ssize_t offset;
4162+ StgDictObject *stgdict, *itemdict;
4163+ PyObject *proto;
4164+
4165+ if (*(void **)self->b_ptr == NULL) {
4166+ PyErr_SetString(PyExc_ValueError,
4167+ "NULL pointer access");
4168+ return NULL;
4169+ }
4170+
4171+ stgdict = PyObject_stgdict((PyObject *)self);
4172+ assert(stgdict); /* Cannot be NULL for pointer object instances */
4173+
4174+ proto = stgdict->proto;
4175+ assert(proto);
4176+ itemdict = PyType_stgdict(proto);
4177+ assert(itemdict); /* proto is the item type of the pointer, a ctypes
4178+ type, so this cannot be NULL */
4179+
4180+ size = itemdict->size;
4181+ offset = index * itemdict->size;
4182+
4183+ return CData_get(proto, stgdict->getfunc, (PyObject *)self,
4184+ index, size, (*(char **)self->b_ptr) + offset);
4185+}
4186+
4187+static int
4188+Pointer_ass_item(PyObject *_self, Py_ssize_t index, PyObject *value)
4189+{
4190+ CDataObject *self = (CDataObject *)_self;
4191+ int size;
4192+ Py_ssize_t offset;
4193+ StgDictObject *stgdict, *itemdict;
4194+ PyObject *proto;
4195+
4196+ if (value == NULL) {
4197+ PyErr_SetString(PyExc_TypeError,
4198+ "Pointer does not support item deletion");
4199+ return -1;
4200+ }
4201+
4202+ if (*(void **)self->b_ptr == NULL) {
4203+ PyErr_SetString(PyExc_ValueError,
4204+ "NULL pointer access");
4205+ return -1;
4206+ }
4207+
4208+ stgdict = PyObject_stgdict((PyObject *)self);
4209+ assert(stgdict); /* Cannot be NULL fr pointer instances */
4210+
4211+ proto = stgdict->proto;
4212+ assert(proto);
4213+
4214+ itemdict = PyType_stgdict(proto);
4215+ assert(itemdict); /* Cannot be NULL because the itemtype of a pointer
4216+ is always a ctypes type */
4217+
4218+ size = itemdict->size;
4219+ offset = index * itemdict->size;
4220+
4221+ return CData_set((PyObject *)self, proto, stgdict->setfunc, value,
4222+ index, size, (*(char **)self->b_ptr) + offset);
4223+}
4224+
4225+static PyObject *
4226+Pointer_get_contents(CDataObject *self, void *closure)
4227+{
4228+ StgDictObject *stgdict;
4229+
4230+ if (*(void **)self->b_ptr == NULL) {
4231+ PyErr_SetString(PyExc_ValueError,
4232+ "NULL pointer access");
4233+ return NULL;
4234+ }
4235+
4236+ stgdict = PyObject_stgdict((PyObject *)self);
4237+ assert(stgdict); /* Cannot be NULL fr pointer instances */
4238+ return CData_FromBaseObj(stgdict->proto,
4239+ (PyObject *)self, 0,
4240+ *(void **)self->b_ptr);
4241+}
4242+
4243+static int
4244+Pointer_set_contents(CDataObject *self, PyObject *value, void *closure)
4245+{
4246+ StgDictObject *stgdict;
4247+ CDataObject *dst;
4248+ PyObject *keep;
4249+
4250+ if (value == NULL) {
4251+ PyErr_SetString(PyExc_TypeError,
4252+ "Pointer does not support item deletion");
4253+ return -1;
4254+ }
4255+ stgdict = PyObject_stgdict((PyObject *)self);
4256+ assert(stgdict); /* Cannot be NULL fr pointer instances */
4257+ assert(stgdict->proto);
4258+ if (!CDataObject_Check(value)
4259+ || 0 == PyObject_IsInstance(value, stgdict->proto)) {
4260+ /* XXX PyObject_IsInstance could return -1! */
4261+ PyErr_Format(PyExc_TypeError,
4262+ "expected %s instead of %s",
4263+ ((PyTypeObject *)(stgdict->proto))->tp_name,
4264+ value->ob_type->tp_name);
4265+ return -1;
4266+ }
4267+
4268+ dst = (CDataObject *)value;
4269+ *(void **)self->b_ptr = dst->b_ptr;
4270+
4271+ /*
4272+ A Pointer instance must keep a the value it points to alive. So, a
4273+ pointer instance has b_length set to 2 instead of 1, and we set
4274+ 'value' itself as the second item of the b_objects list, additionally.
4275+ */
4276+ Py_INCREF(value);
4277+ if (-1 == KeepRef(self, 1, value))
4278+ return -1;
4279+
4280+ keep = GetKeepedObjects(dst);
4281+ Py_INCREF(keep);
4282+ return KeepRef(self, 0, keep);
4283+}
4284+
4285+static PyGetSetDef Pointer_getsets[] = {
4286+ { "contents", (getter)Pointer_get_contents,
4287+ (setter)Pointer_set_contents,
4288+ "the object this pointer points to (read-write)", NULL },
4289+ { NULL, NULL }
4290+};
4291+
4292+static int
4293+Pointer_init(CDataObject *self, PyObject *args, PyObject *kw)
4294+{
4295+ PyObject *value = NULL;
4296+
4297+ if (!PyArg_ParseTuple(args, "|O:POINTER", &value))
4298+ return -1;
4299+ if (value == NULL)
4300+ return 0;
4301+ return Pointer_set_contents(self, value, NULL);
4302+}
4303+
4304+static PyObject *
4305+Pointer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
4306+{
4307+ StgDictObject *dict = PyType_stgdict((PyObject *)type);
4308+ if (!dict || !dict->proto) {
4309+ PyErr_SetString(PyExc_TypeError,
4310+ "Cannot create instance: has no _type_");
4311+ return NULL;
4312+ }
4313+ return GenericCData_new(type, args, kw);
4314+}
4315+
4316+static PyObject *
4317+Pointer_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh)
4318+{
4319+ CDataObject *self = (CDataObject *)_self;
4320+ PyListObject *np;
4321+ StgDictObject *stgdict, *itemdict;
4322+ PyObject *proto;
4323+ Py_ssize_t i, len;
4324+
4325+ if (ilow < 0)
4326+ ilow = 0;
4327+ if (ihigh < ilow)
4328+ ihigh = ilow;
4329+ len = ihigh - ilow;
4330+
4331+ stgdict = PyObject_stgdict((PyObject *)self);
4332+ assert(stgdict); /* Cannot be NULL fr pointer instances */
4333+ proto = stgdict->proto;
4334+ assert(proto);
4335+ itemdict = PyType_stgdict(proto);
4336+ assert(itemdict);
4337+ if (itemdict->getfunc == getentry("c")->getfunc) {
4338+ char *ptr = *(char **)self->b_ptr;
4339+ return PyString_FromStringAndSize(ptr + ilow, len);
4340+#ifdef CTYPES_UNICODE
4341+ } else if (itemdict->getfunc == getentry("u")->getfunc) {
4342+ wchar_t *ptr = *(wchar_t **)self->b_ptr;
4343+ return PyUnicode_FromWideChar(ptr + ilow, len);
4344+#endif
4345+ }
4346+
4347+ np = (PyListObject *) PyList_New(len);
4348+ if (np == NULL)
4349+ return NULL;
4350+
4351+ for (i = 0; i < len; i++) {
4352+ PyObject *v = Pointer_item(_self, i+ilow);
4353+ PyList_SET_ITEM(np, i, v);
4354+ }
4355+ return (PyObject *)np;
4356+}
4357+
4358+static PySequenceMethods Pointer_as_sequence = {
4359+ 0, /* inquiry sq_length; */
4360+ 0, /* binaryfunc sq_concat; */
4361+ 0, /* intargfunc sq_repeat; */
4362+ Pointer_item, /* intargfunc sq_item; */
4363+ Pointer_slice, /* intintargfunc sq_slice; */
4364+ Pointer_ass_item, /* intobjargproc sq_ass_item; */
4365+ 0, /* intintobjargproc sq_ass_slice; */
4366+ 0, /* objobjproc sq_contains; */
4367+ /* Added in release 2.0 */
4368+ 0, /* binaryfunc sq_inplace_concat; */
4369+ 0, /* intargfunc sq_inplace_repeat; */
4370+};
4371+
4372+static int
4373+Pointer_nonzero(CDataObject *self)
4374+{
4375+ return *(void **)self->b_ptr != NULL;
4376+}
4377+
4378+static PyNumberMethods Pointer_as_number = {
4379+ 0, /* nb_add */
4380+ 0, /* nb_subtract */
4381+ 0, /* nb_multiply */
4382+ 0, /* nb_divide */
4383+ 0, /* nb_remainder */
4384+ 0, /* nb_divmod */
4385+ 0, /* nb_power */
4386+ 0, /* nb_negative */
4387+ 0, /* nb_positive */
4388+ 0, /* nb_absolute */
4389+ (inquiry)Pointer_nonzero, /* nb_nonzero */
4390+};
4391+
4392+PyTypeObject Pointer_Type = {
4393+ PyObject_HEAD_INIT(NULL)
4394+ 0,
4395+ "_ctypes._Pointer",
4396+ sizeof(CDataObject), /* tp_basicsize */
4397+ 0, /* tp_itemsize */
4398+ 0, /* tp_dealloc */
4399+ 0, /* tp_print */
4400+ 0, /* tp_getattr */
4401+ 0, /* tp_setattr */
4402+ 0, /* tp_compare */
4403+ 0, /* tp_repr */
4404+ &Pointer_as_number, /* tp_as_number */
4405+ &Pointer_as_sequence, /* tp_as_sequence */
4406+ 0, /* tp_as_mapping */
4407+ 0, /* tp_hash */
4408+ 0, /* tp_call */
4409+ 0, /* tp_str */
4410+ 0, /* tp_getattro */
4411+ 0, /* tp_setattro */
4412+ &CData_as_buffer, /* tp_as_buffer */
4413+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4414+ "XXX to be provided", /* tp_doc */
4415+ (traverseproc)CData_traverse, /* tp_traverse */
4416+ (inquiry)CData_clear, /* tp_clear */
4417+ 0, /* tp_richcompare */
4418+ 0, /* tp_weaklistoffset */
4419+ 0, /* tp_iter */
4420+ 0, /* tp_iternext */
4421+ 0, /* tp_methods */
4422+ 0, /* tp_members */
4423+ Pointer_getsets, /* tp_getset */
4424+ 0, /* tp_base */
4425+ 0, /* tp_dict */
4426+ 0, /* tp_descr_get */
4427+ 0, /* tp_descr_set */
4428+ 0, /* tp_dictoffset */
4429+ (initproc)Pointer_init, /* tp_init */
4430+ 0, /* tp_alloc */
4431+ Pointer_new, /* tp_new */
4432+ 0, /* tp_free */
4433+};
4434+
4435+
4436+/******************************************************************/
4437+/*
4438+ * Module initialization.
4439+ */
4440+
4441+static char *module_docs =
4442+"Create and manipulate C compatible data types in Python.";
4443+
4444+#ifdef MS_WIN32
4445+
4446+static char comerror_doc[] = "Raised when a COM method call failed.";
4447+
4448+static PyObject *
4449+comerror_str(PyObject *ignored, PyObject *self)
4450+{
4451+ PyObject *args = PyObject_GetAttrString(self, "args");
4452+ PyObject *result;
4453+ if (args == NULL)
4454+ return NULL;
4455+ result = PyObject_Str(args);
4456+ Py_DECREF(args);
4457+ return result;
4458+}
4459+
4460+static PyObject *
4461+comerror_init(PyObject *self, PyObject *args)
4462+{
4463+ PyObject *hresult, *text, *details;
4464+ PyObject *a;
4465+ int status;
4466+
4467+ if (!PyArg_ParseTuple(args, "OOOO:COMError", &self, &hresult, &text, &details))
4468+ return NULL;
4469+
4470+ a = PySequence_GetSlice(args, 1, PySequence_Size(args));
4471+ if (!a)
4472+ return NULL;
4473+ status = PyObject_SetAttrString(self, "args", a);
4474+ Py_DECREF(a);
4475+ if (status < 0)
4476+ return NULL;
4477+
4478+ if (PyObject_SetAttrString(self, "hresult", hresult) < 0)
4479+ return NULL;
4480+
4481+ if (PyObject_SetAttrString(self, "text", text) < 0)
4482+ return NULL;
4483+
4484+ if (PyObject_SetAttrString(self, "details", details) < 0)
4485+ return NULL;
4486+
4487+ Py_INCREF(Py_None);
4488+ return Py_None;
4489+}
4490+
4491+static PyMethodDef comerror_methods[] = {
4492+ { "__str__", comerror_str, METH_O },
4493+ { "__init__", comerror_init, METH_VARARGS },
4494+ { NULL, NULL },
4495+};
4496+
4497+PyObject *COMError;
4498+
4499+static int
4500+create_comerror(void)
4501+{
4502+ PyObject *dict = PyDict_New();
4503+ PyMethodDef *methods = comerror_methods;
4504+ PyObject *s;
4505+ int status;
4506+
4507+ ComError = PyErr_NewException("_ctypes.COMError",
4508+ NULL,
4509+ dict);
4510+ if (ComError == NULL)
4511+ return -1;
4512+ while (methods->ml_name) {
4513+ /* get a wrapper for the built-in function */
4514+ PyObject *func = PyCFunction_New(methods, NULL);
4515+ PyObject *meth;
4516+ if (func == NULL)
4517+ return -1;
4518+ meth = PyMethod_New(func, NULL, ComError);
4519+ Py_DECREF(func);
4520+ if (meth == NULL)
4521+ return -1;
4522+ PyDict_SetItemString(dict, methods->ml_name, meth);
4523+ Py_DECREF(meth);
4524+ ++methods;
4525+ }
4526+ Py_INCREF(ComError);
4527+ s = PyString_FromString(comerror_doc);
4528+ if (s == NULL)
4529+ return -1;
4530+ status = PyDict_SetItemString(dict, "__doc__", s);
4531+ Py_DECREF(s);
4532+ return status;
4533+}
4534+
4535+#endif
4536+
4537+static PyObject *
4538+string_at(const char *ptr, int size)
4539+{
4540+ if (size == -1)
4541+ return PyString_FromString(ptr);
4542+ return PyString_FromStringAndSize(ptr, size);
4543+}
4544+
4545+static int
4546+cast_check_pointertype(PyObject *arg)
4547+{
4548+ StgDictObject *dict;
4549+
4550+ if (PointerTypeObject_Check(arg))
4551+ return 1;
4552+ if (CFuncPtrTypeObject_Check(arg))
4553+ return 1;
4554+ dict = PyType_stgdict(arg);
4555+ if (dict) {
4556+ if (PyString_Check(dict->proto)
4557+ && (strchr("sPzUZXO", PyString_AS_STRING(dict->proto)[0]))) {
4558+ /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
4559+ return 1;
4560+ }
4561+ }
4562+ PyErr_Format(PyExc_TypeError,
4563+ "cast() argument 2 must be a pointer type, not %s",
4564+ PyType_Check(arg)
4565+ ? ((PyTypeObject *)arg)->tp_name
4566+ : arg->ob_type->tp_name);
4567+ return 0;
4568+}
4569+
4570+static PyObject *
4571+cast(void *ptr, PyObject *src, PyObject *ctype)
4572+{
4573+ CDataObject *result;
4574+ if (0 == cast_check_pointertype(ctype))
4575+ return NULL;
4576+ result = (CDataObject *)PyObject_CallFunctionObjArgs(ctype, NULL);
4577+ if (result == NULL)
4578+ return NULL;
4579+
4580+ /*
4581+ The casted objects '_objects' member:
4582+
4583+ It must certainly contain the source objects one.
4584+ It must contain the source object itself.
4585+ */
4586+ if (CDataObject_Check(src)) {
4587+ CDataObject *obj = (CDataObject *)src;
4588+ /* CData_GetContainer will initialize src.b_objects, we need
4589+ this so it can be shared */
4590+ CData_GetContainer(obj);
4591+ /* But we need a dictionary! */
4592+ if (obj->b_objects == Py_None) {
4593+ Py_DECREF(Py_None);
4594+ obj->b_objects = PyDict_New();
4595+ if (obj->b_objects == NULL)
4596+ goto failed;
4597+ }
4598+ Py_XINCREF(obj->b_objects);
4599+ result->b_objects = obj->b_objects;
4600+ if (result->b_objects && PyDict_Check(result->b_objects)) {
4601+ PyObject *index;
4602+ int rc;
4603+ index = PyLong_FromVoidPtr((void *)src);
4604+ if (index == NULL)
4605+ goto failed;
4606+ rc = PyDict_SetItem(result->b_objects, index, src);
4607+ Py_DECREF(index);
4608+ if (rc == -1)
4609+ goto failed;
4610+ }
4611+ }
4612+ /* Should we assert that result is a pointer type? */
4613+ memcpy(result->b_ptr, &ptr, sizeof(void *));
4614+ return (PyObject *)result;
4615+
4616+ failed:
4617+ Py_DECREF(result);
4618+ return NULL;
4619+}
4620+
4621+#ifdef CTYPES_UNICODE
4622+static PyObject *
4623+wstring_at(const wchar_t *ptr, int size)
4624+{
4625+ if (size == -1)
4626+ size = wcslen(ptr);
4627+ return PyUnicode_FromWideChar(ptr, size);
4628+}
4629+#endif
4630+
4631+PyMODINIT_FUNC
4632+init_ctypes(void)
4633+{
4634+ PyObject *m;
4635+
4636+/* Note:
4637+ ob_type is the metatype (the 'type'), defaults to PyType_Type,
4638+ tp_base is the base type, defaults to 'object' aka PyBaseObject_Type.
4639+*/
4640+#ifdef WITH_THREAD
4641+ PyEval_InitThreads();
4642+#endif
4643+ m = Py_InitModule3("_ctypes", module_methods, module_docs);
4644+ if (!m)
4645+ return;
4646+
4647+ if (PyType_Ready(&PyCArg_Type) < 0)
4648+ return;
4649+
4650+ /* StgDict is derived from PyDict_Type */
4651+ StgDict_Type.tp_base = &PyDict_Type;
4652+ if (PyType_Ready(&StgDict_Type) < 0)
4653+ return;
4654+
4655+ /*************************************************
4656+ *
4657+ * Metaclasses
4658+ */
4659+
4660+ StructType_Type.tp_base = &PyType_Type;
4661+ if (PyType_Ready(&StructType_Type) < 0)
4662+ return;
4663+
4664+ UnionType_Type.tp_base = &PyType_Type;
4665+ if (PyType_Ready(&UnionType_Type) < 0)
4666+ return;
4667+
4668+ PointerType_Type.tp_base = &PyType_Type;
4669+ if (PyType_Ready(&PointerType_Type) < 0)
4670+ return;
4671+
4672+ ArrayType_Type.tp_base = &PyType_Type;
4673+ if (PyType_Ready(&ArrayType_Type) < 0)
4674+ return;
4675+
4676+ SimpleType_Type.tp_base = &PyType_Type;
4677+ if (PyType_Ready(&SimpleType_Type) < 0)
4678+ return;
4679+
4680+ CFuncPtrType_Type.tp_base = &PyType_Type;
4681+ if (PyType_Ready(&CFuncPtrType_Type) < 0)
4682+ return;
4683+
4684+ /*************************************************
4685+ *
4686+ * Classes using a custom metaclass
4687+ */
4688+
4689+ if (PyType_Ready(&CData_Type) < 0)
4690+ return;
4691+
4692+ Struct_Type.ob_type = &StructType_Type;
4693+ Struct_Type.tp_base = &CData_Type;
4694+ if (PyType_Ready(&Struct_Type) < 0)
4695+ return;
4696+ PyModule_AddObject(m, "Structure", (PyObject *)&Struct_Type);
4697+
4698+ Union_Type.ob_type = &UnionType_Type;
4699+ Union_Type.tp_base = &CData_Type;
4700+ if (PyType_Ready(&Union_Type) < 0)
4701+ return;
4702+ PyModule_AddObject(m, "Union", (PyObject *)&Union_Type);
4703+
4704+ Pointer_Type.ob_type = &PointerType_Type;
4705+ Pointer_Type.tp_base = &CData_Type;
4706+ if (PyType_Ready(&Pointer_Type) < 0)
4707+ return;
4708+ PyModule_AddObject(m, "_Pointer", (PyObject *)&Pointer_Type);
4709+
4710+ Array_Type.ob_type = &ArrayType_Type;
4711+ Array_Type.tp_base = &CData_Type;
4712+ if (PyType_Ready(&Array_Type) < 0)
4713+ return;
4714+ PyModule_AddObject(m, "Array", (PyObject *)&Array_Type);
4715+
4716+ Simple_Type.ob_type = &SimpleType_Type;
4717+ Simple_Type.tp_base = &CData_Type;
4718+ if (PyType_Ready(&Simple_Type) < 0)
4719+ return;
4720+ PyModule_AddObject(m, "_SimpleCData", (PyObject *)&Simple_Type);
4721+
4722+ CFuncPtr_Type.ob_type = &CFuncPtrType_Type;
4723+ CFuncPtr_Type.tp_base = &CData_Type;
4724+ if (PyType_Ready(&CFuncPtr_Type) < 0)
4725+ return;
4726+ PyModule_AddObject(m, "CFuncPtr", (PyObject *)&CFuncPtr_Type);
4727+
4728+ /*************************************************
4729+ *
4730+ * Simple classes
4731+ */
4732+
4733+ /* CField_Type is derived from PyBaseObject_Type */
4734+ if (PyType_Ready(&CField_Type) < 0)
4735+ return;
4736+
4737+ /*************************************************
4738+ *
4739+ * Other stuff
4740+ */
4741+
4742+#ifdef MS_WIN32
4743+ if (create_comerror() < 0)
4744+ return;
4745+ PyModule_AddObject(m, "COMError", ComError);
4746+
4747+ PyModule_AddObject(m, "FUNCFLAG_HRESULT", PyInt_FromLong(FUNCFLAG_HRESULT));
4748+ PyModule_AddObject(m, "FUNCFLAG_STDCALL", PyInt_FromLong(FUNCFLAG_STDCALL));
4749+#endif
4750+ PyModule_AddObject(m, "FUNCFLAG_CDECL", PyInt_FromLong(FUNCFLAG_CDECL));
4751+ PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyInt_FromLong(FUNCFLAG_PYTHONAPI));
4752+ PyModule_AddStringConstant(m, "__version__", "1.0.2");
4753+
4754+ PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove));
4755+ PyModule_AddObject(m, "_memset_addr", PyLong_FromVoidPtr(memset));
4756+ PyModule_AddObject(m, "_string_at_addr", PyLong_FromVoidPtr(string_at));
4757+ PyModule_AddObject(m, "_cast_addr", PyLong_FromVoidPtr(cast));
4758+#ifdef CTYPES_UNICODE
4759+ PyModule_AddObject(m, "_wstring_at_addr", PyLong_FromVoidPtr(wstring_at));
4760+#endif
4761+
4762+/* If RTLD_LOCAL is not defined (Windows!), set it to zero. */
4763+#ifndef RTLD_LOCAL
4764+#define RTLD_LOCAL 0
4765+#endif
4766+
4767+/* If RTLD_GLOBAL is not defined (cygwin), set it to the same value as
4768+ RTLD_LOCAL.
4769+*/
4770+#ifndef RTLD_GLOBAL
4771+#define RTLD_GLOBAL RTLD_LOCAL
4772+#endif
4773+
4774+ PyModule_AddObject(m, "RTLD_LOCAL", PyInt_FromLong(RTLD_LOCAL));
4775+ PyModule_AddObject(m, "RTLD_GLOBAL", PyInt_FromLong(RTLD_GLOBAL));
4776+
4777+ PyExc_ArgError = PyErr_NewException("ctypes.ArgumentError", NULL, NULL);
4778+ if (PyExc_ArgError) {
4779+ Py_INCREF(PyExc_ArgError);
4780+ PyModule_AddObject(m, "ArgumentError", PyExc_ArgError);
4781+ }
4782+ /*************************************************
4783+ *
4784+ * Others...
4785+ */
4786+ init_callbacks_in_module(m);
4787+}
4788+
4789+/*****************************************************************
4790+ * replacements for broken Python api functions (in Python 2.3).
4791+ * See #1047269 Buffer overwrite in PyUnicode_AsWideChar
4792+ */
4793+
4794+#ifdef HAVE_WCHAR_H
4795+
4796+PyObject *My_PyUnicode_FromWideChar(register const wchar_t *w,
4797+ Py_ssize_t size)
4798+{
4799+ PyUnicodeObject *unicode;
4800+
4801+ if (w == NULL) {
4802+ PyErr_BadInternalCall();
4803+ return NULL;
4804+ }
4805+
4806+ unicode = (PyUnicodeObject *)PyUnicode_FromUnicode(NULL, size);
4807+ if (!unicode)
4808+ return NULL;
4809+
4810+ /* Copy the wchar_t data into the new object */
4811+#ifdef HAVE_USABLE_WCHAR_T
4812+ memcpy(unicode->str, w, size * sizeof(wchar_t));
4813+#else
4814+ {
4815+ register Py_UNICODE *u;
4816+ register int i;
4817+ u = PyUnicode_AS_UNICODE(unicode);
4818+ /* In Python, the following line has a one-off error */
4819+ for (i = size; i > 0; i--)
4820+ *u++ = *w++;
4821+ }
4822+#endif
4823+
4824+ return (PyObject *)unicode;
4825+}
4826+
4827+int My_PyUnicode_AsWideChar(PyUnicodeObject *unicode,
4828+ register wchar_t *w,
4829+ Py_ssize_t size)
4830+{
4831+ if (unicode == NULL) {
4832+ PyErr_BadInternalCall();
4833+ return -1;
4834+ }
4835+ if (size > PyUnicode_GET_SIZE(unicode))
4836+ size = PyUnicode_GET_SIZE(unicode);
4837+#ifdef HAVE_USABLE_WCHAR_T
4838+ memcpy(w, unicode->str, size * sizeof(wchar_t));
4839+#else
4840+ {
4841+ register Py_UNICODE *u;
4842+ register int i;
4843+ u = PyUnicode_AS_UNICODE(unicode);
4844+ /* In Python, the following line has a one-off error */
4845+ for (i = size; i > 0; i--)
4846+ *w++ = *u++;
4847+ }
4848+#endif
4849+
4850+ return size;
4851+}
4852+
4853+#endif
4854+
4855+/*
4856+ Local Variables:
4857+ compile-command: "cd .. && python setup.py -q build -g && python setup.py -q build install --home ~"
4858+ End:
4859+*/
sys/src/cmd/python/Modules/_ctypes/_ctypes_test.c+548−0
@@ -0,0 +1,548 @@
1+/*****************************************************************
2+ This file should be kept compatible with Python 2.3, see PEP 291.
3+ *****************************************************************/
4+
5+
6+#include <Python.h>
7+
8+/*
9+ Backwards compatibility:
10+ Python2.2 used LONG_LONG instead of PY_LONG_LONG
11+*/
12+#if defined(HAVE_LONG_LONG) && !defined(PY_LONG_LONG)
13+#define PY_LONG_LONG LONG_LONG
14+#endif
15+
16+#ifdef MS_WIN32
17+#include <windows.h>
18+#endif
19+
20+#if defined(MS_WIN32) || defined(__CYGWIN__)
21+#define EXPORT(x) __declspec(dllexport) x
22+#else
23+#define EXPORT(x) x
24+#endif
25+
26+/* some functions handy for testing */
27+
28+EXPORT(char *)my_strtok(char *token, const char *delim)
29+{
30+ return strtok(token, delim);
31+}
32+
33+EXPORT(char *)my_strchr(const char *s, int c)
34+{
35+ return strchr(s, c);
36+}
37+
38+
39+EXPORT(double) my_sqrt(double a)
40+{
41+ return sqrt(a);
42+}
43+
44+EXPORT(void) my_qsort(void *base, size_t num, size_t width, int(*compare)(const void*, const void*))
45+{
46+ qsort(base, num, width, compare);
47+}
48+
49+EXPORT(int *) _testfunc_ai8(int a[8])
50+{
51+ return a;
52+}
53+
54+EXPORT(void) _testfunc_v(int a, int b, int *presult)
55+{
56+ *presult = a + b;
57+}
58+
59+EXPORT(int) _testfunc_i_bhilfd(signed char b, short h, int i, long l, float f, double d)
60+{
61+/* printf("_testfunc_i_bhilfd got %d %d %d %ld %f %f\n",
62+ b, h, i, l, f, d);
63+*/
64+ return (int)(b + h + i + l + f + d);
65+}
66+
67+EXPORT(float) _testfunc_f_bhilfd(signed char b, short h, int i, long l, float f, double d)
68+{
69+/* printf("_testfunc_f_bhilfd got %d %d %d %ld %f %f\n",
70+ b, h, i, l, f, d);
71+*/
72+ return (float)(b + h + i + l + f + d);
73+}
74+
75+EXPORT(double) _testfunc_d_bhilfd(signed char b, short h, int i, long l, float f, double d)
76+{
77+/* printf("_testfunc_d_bhilfd got %d %d %d %ld %f %f\n",
78+ b, h, i, l, f, d);
79+*/
80+ return (double)(b + h + i + l + f + d);
81+}
82+
83+EXPORT(char *) _testfunc_p_p(void *s)
84+{
85+ return (char *)s;
86+}
87+
88+EXPORT(void *) _testfunc_c_p_p(int *argcp, char **argv)
89+{
90+ return argv[(*argcp)-1];
91+}
92+
93+EXPORT(void *) get_strchr(void)
94+{
95+ return (void *)strchr;
96+}
97+
98+EXPORT(char *) my_strdup(char *src)
99+{
100+ char *dst = (char *)malloc(strlen(src)+1);
101+ if (!dst)
102+ return NULL;
103+ strcpy(dst, src);
104+ return dst;
105+}
106+
107+EXPORT(void)my_free(void *ptr)
108+{
109+ free(ptr);
110+}
111+
112+#ifdef HAVE_WCHAR_H
113+EXPORT(wchar_t *) my_wcsdup(wchar_t *src)
114+{
115+ size_t len = wcslen(src);
116+ wchar_t *ptr = (wchar_t *)malloc((len + 1) * sizeof(wchar_t));
117+ if (ptr == NULL)
118+ return NULL;
119+ memcpy(ptr, src, (len+1) * sizeof(wchar_t));
120+ return ptr;
121+}
122+
123+EXPORT(size_t) my_wcslen(wchar_t *src)
124+{
125+ return wcslen(src);
126+}
127+#endif
128+
129+#ifndef MS_WIN32
130+# ifndef __stdcall
131+# define __stdcall /* */
132+# endif
133+#endif
134+
135+typedef struct {
136+ int (*c)(int, int);
137+ int (__stdcall *s)(int, int);
138+} FUNCS;
139+
140+EXPORT(int) _testfunc_callfuncp(FUNCS *fp)
141+{
142+ fp->c(1, 2);
143+ fp->s(3, 4);
144+ return 0;
145+}
146+
147+EXPORT(int) _testfunc_deref_pointer(int *pi)
148+{
149+ return *pi;
150+}
151+
152+#ifdef MS_WIN32
153+EXPORT(int) _testfunc_piunk(IUnknown FAR *piunk)
154+{
155+ piunk->lpVtbl->AddRef(piunk);
156+ return piunk->lpVtbl->Release(piunk);
157+}
158+#endif
159+
160+EXPORT(int) _testfunc_callback_with_pointer(int (*func)(int *))
161+{
162+ int table[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
163+
164+ return (*func)(table);
165+}
166+
167+#ifdef HAVE_LONG_LONG
168+EXPORT(PY_LONG_LONG) _testfunc_q_bhilfdq(signed char b, short h, int i, long l, float f,
169+ double d, PY_LONG_LONG q)
170+{
171+ return (PY_LONG_LONG)(b + h + i + l + f + d + q);
172+}
173+
174+EXPORT(PY_LONG_LONG) _testfunc_q_bhilfd(signed char b, short h, int i, long l, float f, double d)
175+{
176+ return (PY_LONG_LONG)(b + h + i + l + f + d);
177+}
178+
179+EXPORT(int) _testfunc_callback_i_if(int value, int (*func)(int))
180+{
181+ int sum = 0;
182+ while (value != 0) {
183+ sum += func(value);
184+ value /= 2;
185+ }
186+ return sum;
187+}
188+
189+EXPORT(PY_LONG_LONG) _testfunc_callback_q_qf(PY_LONG_LONG value,
190+ PY_LONG_LONG (*func)(PY_LONG_LONG))
191+{
192+ PY_LONG_LONG sum = 0;
193+
194+ while (value != 0) {
195+ sum += func(value);
196+ value /= 2;
197+ }
198+ return sum;
199+}
200+
201+#endif
202+
203+typedef struct {
204+ char *name;
205+ char *value;
206+} SPAM;
207+
208+typedef struct {
209+ char *name;
210+ int num_spams;
211+ SPAM *spams;
212+} EGG;
213+
214+SPAM my_spams[2] = {
215+ { "name1", "value1" },
216+ { "name2", "value2" },
217+};
218+
219+EGG my_eggs[1] = {
220+ { "first egg", 1, my_spams }
221+};
222+
223+EXPORT(int) getSPAMANDEGGS(EGG **eggs)
224+{
225+ *eggs = my_eggs;
226+ return 1;
227+}
228+
229+typedef struct tagpoint {
230+ int x;
231+ int y;
232+} point;
233+
234+EXPORT(int) _testfunc_byval(point in, point *pout)
235+{
236+ if (pout) {
237+ pout->x = in.x;
238+ pout->y = in.y;
239+ }
240+ return in.x + in.y;
241+}
242+
243+EXPORT (int) an_integer = 42;
244+
245+EXPORT(int) get_an_integer(void)
246+{
247+ return an_integer;
248+}
249+
250+EXPORT(double)
251+integrate(double a, double b, double (*f)(double), long nstep)
252+{
253+ double x, sum=0.0, dx=(b-a)/(double)nstep;
254+ for(x=a+0.5*dx; (b-x)*(x-a)>0.0; x+=dx)
255+ sum += f(x);
256+ return sum/(double)nstep;
257+}
258+
259+typedef struct {
260+ void (*initialize)(void *(*)(int), void(*)(void *));
261+} xxx_library;
262+
263+static void _xxx_init(void *(*Xalloc)(int), void (*Xfree)(void *))
264+{
265+ void *ptr;
266+
267+ printf("_xxx_init got %p %p\n", Xalloc, Xfree);
268+ printf("calling\n");
269+ ptr = Xalloc(32);
270+ Xfree(ptr);
271+ printf("calls done, ptr was %p\n", ptr);
272+}
273+
274+xxx_library _xxx_lib = {
275+ _xxx_init
276+};
277+
278+EXPORT(xxx_library) *library_get(void)
279+{
280+ return &_xxx_lib;
281+}
282+
283+#ifdef MS_WIN32
284+/* See Don Box (german), pp 79ff. */
285+EXPORT(void) GetString(BSTR *pbstr)
286+{
287+ *pbstr = SysAllocString(L"Goodbye!");
288+}
289+#endif
290+
291+/*
292+ * Some do-nothing functions, for speed tests
293+ */
294+PyObject *py_func_si(PyObject *self, PyObject *args)
295+{
296+ char *name;
297+ int i;
298+ if (!PyArg_ParseTuple(args, "si", &name, &i))
299+ return NULL;
300+ Py_INCREF(Py_None);
301+ return Py_None;
302+}
303+
304+EXPORT(void) _py_func_si(char *s, int i)
305+{
306+}
307+
308+PyObject *py_func(PyObject *self, PyObject *args)
309+{
310+ Py_INCREF(Py_None);
311+ return Py_None;
312+}
313+
314+EXPORT(void) _py_func(void)
315+{
316+}
317+
318+EXPORT(PY_LONG_LONG) last_tf_arg_s;
319+EXPORT(unsigned PY_LONG_LONG) last_tf_arg_u;
320+
321+struct BITS {
322+ int A: 1, B:2, C:3, D:4, E: 5, F: 6, G: 7, H: 8, I: 9;
323+ short M: 1, N: 2, O: 3, P: 4, Q: 5, R: 6, S: 7;
324+};
325+
326+DL_EXPORT(void) set_bitfields(struct BITS *bits, char name, int value)
327+{
328+ switch (name) {
329+ case 'A': bits->A = value; break;
330+ case 'B': bits->B = value; break;
331+ case 'C': bits->C = value; break;
332+ case 'D': bits->D = value; break;
333+ case 'E': bits->E = value; break;
334+ case 'F': bits->F = value; break;
335+ case 'G': bits->G = value; break;
336+ case 'H': bits->H = value; break;
337+ case 'I': bits->I = value; break;
338+
339+ case 'M': bits->M = value; break;
340+ case 'N': bits->N = value; break;
341+ case 'O': bits->O = value; break;
342+ case 'P': bits->P = value; break;
343+ case 'Q': bits->Q = value; break;
344+ case 'R': bits->R = value; break;
345+ case 'S': bits->S = value; break;
346+ }
347+}
348+
349+DL_EXPORT(int) unpack_bitfields(struct BITS *bits, char name)
350+{
351+ switch (name) {
352+ case 'A': return bits->A;
353+ case 'B': return bits->B;
354+ case 'C': return bits->C;
355+ case 'D': return bits->D;
356+ case 'E': return bits->E;
357+ case 'F': return bits->F;
358+ case 'G': return bits->G;
359+ case 'H': return bits->H;
360+ case 'I': return bits->I;
361+
362+ case 'M': return bits->M;
363+ case 'N': return bits->N;
364+ case 'O': return bits->O;
365+ case 'P': return bits->P;
366+ case 'Q': return bits->Q;
367+ case 'R': return bits->R;
368+ case 'S': return bits->S;
369+ }
370+ return 0;
371+}
372+
373+PyMethodDef module_methods[] = {
374+/* {"get_last_tf_arg_s", get_last_tf_arg_s, METH_NOARGS},
375+ {"get_last_tf_arg_u", get_last_tf_arg_u, METH_NOARGS},
376+*/
377+ {"func_si", py_func_si, METH_VARARGS},
378+ {"func", py_func, METH_NOARGS},
379+ { NULL, NULL, 0, NULL},
380+};
381+
382+#define S last_tf_arg_s = (PY_LONG_LONG)c
383+#define U last_tf_arg_u = (unsigned PY_LONG_LONG)c
384+
385+EXPORT(signed char) tf_b(signed char c) { S; return c/3; }
386+EXPORT(unsigned char) tf_B(unsigned char c) { U; return c/3; }
387+EXPORT(short) tf_h(short c) { S; return c/3; }
388+EXPORT(unsigned short) tf_H(unsigned short c) { U; return c/3; }
389+EXPORT(int) tf_i(int c) { S; return c/3; }
390+EXPORT(unsigned int) tf_I(unsigned int c) { U; return c/3; }
391+EXPORT(long) tf_l(long c) { S; return c/3; }
392+EXPORT(unsigned long) tf_L(unsigned long c) { U; return c/3; }
393+EXPORT(PY_LONG_LONG) tf_q(PY_LONG_LONG c) { S; return c/3; }
394+EXPORT(unsigned PY_LONG_LONG) tf_Q(unsigned PY_LONG_LONG c) { U; return c/3; }
395+EXPORT(float) tf_f(float c) { S; return c/3; }
396+EXPORT(double) tf_d(double c) { S; return c/3; }
397+
398+#ifdef MS_WIN32
399+EXPORT(signed char) __stdcall s_tf_b(signed char c) { S; return c/3; }
400+EXPORT(unsigned char) __stdcall s_tf_B(unsigned char c) { U; return c/3; }
401+EXPORT(short) __stdcall s_tf_h(short c) { S; return c/3; }
402+EXPORT(unsigned short) __stdcall s_tf_H(unsigned short c) { U; return c/3; }
403+EXPORT(int) __stdcall s_tf_i(int c) { S; return c/3; }
404+EXPORT(unsigned int) __stdcall s_tf_I(unsigned int c) { U; return c/3; }
405+EXPORT(long) __stdcall s_tf_l(long c) { S; return c/3; }
406+EXPORT(unsigned long) __stdcall s_tf_L(unsigned long c) { U; return c/3; }
407+EXPORT(PY_LONG_LONG) __stdcall s_tf_q(PY_LONG_LONG c) { S; return c/3; }
408+EXPORT(unsigned PY_LONG_LONG) __stdcall s_tf_Q(unsigned PY_LONG_LONG c) { U; return c/3; }
409+EXPORT(float) __stdcall s_tf_f(float c) { S; return c/3; }
410+EXPORT(double) __stdcall s_tf_d(double c) { S; return c/3; }
411+#endif
412+/*******/
413+
414+EXPORT(signed char) tf_bb(signed char x, signed char c) { S; return c/3; }
415+EXPORT(unsigned char) tf_bB(signed char x, unsigned char c) { U; return c/3; }
416+EXPORT(short) tf_bh(signed char x, short c) { S; return c/3; }
417+EXPORT(unsigned short) tf_bH(signed char x, unsigned short c) { U; return c/3; }
418+EXPORT(int) tf_bi(signed char x, int c) { S; return c/3; }
419+EXPORT(unsigned int) tf_bI(signed char x, unsigned int c) { U; return c/3; }
420+EXPORT(long) tf_bl(signed char x, long c) { S; return c/3; }
421+EXPORT(unsigned long) tf_bL(signed char x, unsigned long c) { U; return c/3; }
422+EXPORT(PY_LONG_LONG) tf_bq(signed char x, PY_LONG_LONG c) { S; return c/3; }
423+EXPORT(unsigned PY_LONG_LONG) tf_bQ(signed char x, unsigned PY_LONG_LONG c) { U; return c/3; }
424+EXPORT(float) tf_bf(signed char x, float c) { S; return c/3; }
425+EXPORT(double) tf_bd(signed char x, double c) { S; return c/3; }
426+EXPORT(void) tv_i(int c) { S; return; }
427+
428+#ifdef MS_WIN32
429+EXPORT(signed char) __stdcall s_tf_bb(signed char x, signed char c) { S; return c/3; }
430+EXPORT(unsigned char) __stdcall s_tf_bB(signed char x, unsigned char c) { U; return c/3; }
431+EXPORT(short) __stdcall s_tf_bh(signed char x, short c) { S; return c/3; }
432+EXPORT(unsigned short) __stdcall s_tf_bH(signed char x, unsigned short c) { U; return c/3; }
433+EXPORT(int) __stdcall s_tf_bi(signed char x, int c) { S; return c/3; }
434+EXPORT(unsigned int) __stdcall s_tf_bI(signed char x, unsigned int c) { U; return c/3; }
435+EXPORT(long) __stdcall s_tf_bl(signed char x, long c) { S; return c/3; }
436+EXPORT(unsigned long) __stdcall s_tf_bL(signed char x, unsigned long c) { U; return c/3; }
437+EXPORT(PY_LONG_LONG) __stdcall s_tf_bq(signed char x, PY_LONG_LONG c) { S; return c/3; }
438+EXPORT(unsigned PY_LONG_LONG) __stdcall s_tf_bQ(signed char x, unsigned PY_LONG_LONG c) { U; return c/3; }
439+EXPORT(float) __stdcall s_tf_bf(signed char x, float c) { S; return c/3; }
440+EXPORT(double) __stdcall s_tf_bd(signed char x, double c) { S; return c/3; }
441+EXPORT(void) __stdcall s_tv_i(int c) { S; return; }
442+#endif
443+
444+/********/
445+
446+#ifndef MS_WIN32
447+
448+typedef struct {
449+ long x;
450+ long y;
451+} POINT;
452+
453+typedef struct {
454+ long left;
455+ long top;
456+ long right;
457+ long bottom;
458+} RECT;
459+
460+#endif
461+
462+EXPORT(int) PointInRect(RECT *prc, POINT pt)
463+{
464+ if (pt.x < prc->left)
465+ return 0;
466+ if (pt.x > prc->right)
467+ return 0;
468+ if (pt.y < prc->top)
469+ return 0;
470+ if (pt.y > prc->bottom)
471+ return 0;
472+ return 1;
473+}
474+
475+typedef struct {
476+ short x;
477+ short y;
478+} S2H;
479+
480+EXPORT(S2H) ret_2h_func(S2H inp)
481+{
482+ inp.x *= 2;
483+ inp.y *= 3;
484+ return inp;
485+}
486+
487+typedef struct {
488+ int a, b, c, d, e, f, g, h;
489+} S8I;
490+
491+EXPORT(S8I) ret_8i_func(S8I inp)
492+{
493+ inp.a *= 2;
494+ inp.b *= 3;
495+ inp.c *= 4;
496+ inp.d *= 5;
497+ inp.e *= 6;
498+ inp.f *= 7;
499+ inp.g *= 8;
500+ inp.h *= 9;
501+ return inp;
502+}
503+
504+EXPORT(int) GetRectangle(int flag, RECT *prect)
505+{
506+ if (flag == 0)
507+ return 0;
508+ prect->left = (int)flag;
509+ prect->top = (int)flag + 1;
510+ prect->right = (int)flag + 2;
511+ prect->bottom = (int)flag + 3;
512+ return 1;
513+}
514+
515+EXPORT(void) TwoOutArgs(int a, int *pi, int b, int *pj)
516+{
517+ *pi += a;
518+ *pj += b;
519+}
520+
521+#ifdef MS_WIN32
522+EXPORT(S2H) __stdcall s_ret_2h_func(S2H inp) { return ret_2h_func(inp); }
523+EXPORT(S8I) __stdcall s_ret_8i_func(S8I inp) { return ret_8i_func(inp); }
524+#endif
525+
526+#ifdef MS_WIN32
527+/* Should port this */
528+#include <stdlib.h>
529+#include <search.h>
530+
531+EXPORT (HRESULT) KeepObject(IUnknown *punk)
532+{
533+ static IUnknown *pobj;
534+ if (punk)
535+ punk->lpVtbl->AddRef(punk);
536+ if (pobj)
537+ pobj->lpVtbl->Release(pobj);
538+ pobj = punk;
539+ return S_OK;
540+}
541+
542+#endif
543+
544+DL_EXPORT(void)
545+init_ctypes_test(void)
546+{
547+ Py_InitModule("_ctypes_test", module_methods);
548+}
sys/src/cmd/python/Modules/_ctypes/_ctypes_test.h+1−0
@@ -0,0 +1 @@
1+extern int _testfunc_i_bhilfd(char b, short h, int i, long l, float f, double d);
sys/src/cmd/python/Modules/_ctypes/callbacks.c+499−0
@@ -0,0 +1,499 @@
1+/*****************************************************************
2+ This file should be kept compatible with Python 2.3, see PEP 291.
3+ *****************************************************************/
4+
5+#include "Python.h"
6+#include "compile.h" /* required only for 2.3, as it seems */
7+#include "frameobject.h"
8+
9+#include <ffi.h>
10+#ifdef MS_WIN32
11+#include <windows.h>
12+#endif
13+#include "ctypes.h"
14+
15+static void
16+PrintError(char *msg, ...)
17+{
18+ char buf[512];
19+ PyObject *f = PySys_GetObject("stderr");
20+ va_list marker;
21+
22+ va_start(marker, msg);
23+ vsnprintf(buf, sizeof(buf), msg, marker);
24+ va_end(marker);
25+ if (f)
26+ PyFile_WriteString(buf, f);
27+ PyErr_Print();
28+}
29+
30+
31+/* after code that pyrex generates */
32+void _AddTraceback(char *funcname, char *filename, int lineno)
33+{
34+ PyObject *py_srcfile = 0;
35+ PyObject *py_funcname = 0;
36+ PyObject *py_globals = 0;
37+ PyObject *empty_tuple = 0;
38+ PyObject *empty_string = 0;
39+ PyCodeObject *py_code = 0;
40+ PyFrameObject *py_frame = 0;
41+
42+ py_srcfile = PyString_FromString(filename);
43+ if (!py_srcfile) goto bad;
44+ py_funcname = PyString_FromString(funcname);
45+ if (!py_funcname) goto bad;
46+ py_globals = PyDict_New();
47+ if (!py_globals) goto bad;
48+ empty_tuple = PyTuple_New(0);
49+ if (!empty_tuple) goto bad;
50+ empty_string = PyString_FromString("");
51+ if (!empty_string) goto bad;
52+ py_code = PyCode_New(
53+ 0, /*int argcount,*/
54+ 0, /*int nlocals,*/
55+ 0, /*int stacksize,*/
56+ 0, /*int flags,*/
57+ empty_string, /*PyObject *code,*/
58+ empty_tuple, /*PyObject *consts,*/
59+ empty_tuple, /*PyObject *names,*/
60+ empty_tuple, /*PyObject *varnames,*/
61+ empty_tuple, /*PyObject *freevars,*/
62+ empty_tuple, /*PyObject *cellvars,*/
63+ py_srcfile, /*PyObject *filename,*/
64+ py_funcname, /*PyObject *name,*/
65+ lineno, /*int firstlineno,*/
66+ empty_string /*PyObject *lnotab*/
67+ );
68+ if (!py_code) goto bad;
69+ py_frame = PyFrame_New(
70+ PyThreadState_Get(), /*PyThreadState *tstate,*/
71+ py_code, /*PyCodeObject *code,*/
72+ py_globals, /*PyObject *globals,*/
73+ 0 /*PyObject *locals*/
74+ );
75+ if (!py_frame) goto bad;
76+ py_frame->f_lineno = lineno;
77+ PyTraceBack_Here(py_frame);
78+ bad:
79+ Py_XDECREF(py_globals);
80+ Py_XDECREF(py_srcfile);
81+ Py_XDECREF(py_funcname);
82+ Py_XDECREF(empty_tuple);
83+ Py_XDECREF(empty_string);
84+ Py_XDECREF(py_code);
85+ Py_XDECREF(py_frame);
86+}
87+
88+#ifdef MS_WIN32
89+/*
90+ * We must call AddRef() on non-NULL COM pointers we receive as arguments
91+ * to callback functions - these functions are COM method implementations.
92+ * The Python instances we create have a __del__ method which calls Release().
93+ *
94+ * The presence of a class attribute named '_needs_com_addref_' triggers this
95+ * behaviour. It would also be possible to call the AddRef() Python method,
96+ * after checking for PyObject_IsTrue(), but this would probably be somewhat
97+ * slower.
98+ */
99+static void
100+TryAddRef(StgDictObject *dict, CDataObject *obj)
101+{
102+ IUnknown *punk;
103+
104+ if (NULL == PyDict_GetItemString((PyObject *)dict, "_needs_com_addref_"))
105+ return;
106+
107+ punk = *(IUnknown **)obj->b_ptr;
108+ if (punk)
109+ punk->lpVtbl->AddRef(punk);
110+ return;
111+}
112+#endif
113+
114+/******************************************************************************
115+ *
116+ * Call the python object with all arguments
117+ *
118+ */
119+static void _CallPythonObject(void *mem,
120+ ffi_type *restype,
121+ SETFUNC setfunc,
122+ PyObject *callable,
123+ PyObject *converters,
124+ void **pArgs)
125+{
126+ int i;
127+ PyObject *result;
128+ PyObject *arglist = NULL;
129+ int nArgs;
130+#ifdef WITH_THREAD
131+ PyGILState_STATE state = PyGILState_Ensure();
132+#endif
133+
134+ nArgs = PySequence_Length(converters);
135+ /* Hm. What to return in case of error?
136+ For COM, 0xFFFFFFFF seems better than 0.
137+ */
138+ if (nArgs < 0) {
139+ PrintError("BUG: PySequence_Length");
140+ goto Done;
141+ }
142+
143+ arglist = PyTuple_New(nArgs);
144+ if (!arglist) {
145+ PrintError("PyTuple_New()");
146+ goto Done;
147+ }
148+ for (i = 0; i < nArgs; ++i) {
149+ /* Note: new reference! */
150+ PyObject *cnv = PySequence_GetItem(converters, i);
151+ StgDictObject *dict;
152+ if (cnv)
153+ dict = PyType_stgdict(cnv);
154+ else {
155+ PrintError("Getting argument converter %d\n", i);
156+ goto Done;
157+ }
158+
159+ if (dict && dict->getfunc && !IsSimpleSubType(cnv)) {
160+ PyObject *v = dict->getfunc(*pArgs, dict->size);
161+ if (!v) {
162+ PrintError("create argument %d:\n", i);
163+ Py_DECREF(cnv);
164+ goto Done;
165+ }
166+ PyTuple_SET_ITEM(arglist, i, v);
167+ /* XXX XXX XX
168+ We have the problem that c_byte or c_short have dict->size of
169+ 1 resp. 4, but these parameters are pushed as sizeof(int) bytes.
170+ BTW, the same problem occurrs when they are pushed as parameters
171+ */
172+ } else if (dict) {
173+ /* Hm, shouldn't we use CData_AtAddress() or something like that instead? */
174+ CDataObject *obj = (CDataObject *)PyObject_CallFunctionObjArgs(cnv, NULL);
175+ if (!obj) {
176+ PrintError("create argument %d:\n", i);
177+ Py_DECREF(cnv);
178+ goto Done;
179+ }
180+ if (!CDataObject_Check(obj)) {
181+ Py_DECREF(obj);
182+ Py_DECREF(cnv);
183+ PrintError("unexpected result of create argument %d:\n", i);
184+ goto Done;
185+ }
186+ memcpy(obj->b_ptr, *pArgs, dict->size);
187+ PyTuple_SET_ITEM(arglist, i, (PyObject *)obj);
188+#ifdef MS_WIN32
189+ TryAddRef(dict, obj);
190+#endif
191+ } else {
192+ PyErr_SetString(PyExc_TypeError,
193+ "cannot build parameter");
194+ PrintError("Parsing argument %d\n", i);
195+ Py_DECREF(cnv);
196+ goto Done;
197+ }
198+ Py_DECREF(cnv);
199+ /* XXX error handling! */
200+ pArgs++;
201+ }
202+
203+#define CHECK(what, x) \
204+if (x == NULL) _AddTraceback(what, __FILE__, __LINE__ - 1), PyErr_Print()
205+
206+ result = PyObject_CallObject(callable, arglist);
207+ CHECK("'calling callback function'", result);
208+ if ((restype != &ffi_type_void) && result) {
209+ PyObject *keep;
210+ assert(setfunc);
211+#ifdef WORDS_BIGENDIAN
212+ /* See the corresponding code in callproc.c, around line 961 */
213+ if (restype->type != FFI_TYPE_FLOAT && restype->size < sizeof(ffi_arg))
214+ mem = (char *)mem + sizeof(ffi_arg) - restype->size;
215+#endif
216+ keep = setfunc(mem, result, 0);
217+ CHECK("'converting callback result'", keep);
218+ /* keep is an object we have to keep alive so that the result
219+ stays valid. If there is no such object, the setfunc will
220+ have returned Py_None.
221+
222+ If there is such an object, we have no choice than to keep
223+ it alive forever - but a refcount and/or memory leak will
224+ be the result. EXCEPT when restype is py_object - Python
225+ itself knows how to manage the refcount of these objects.
226+ */
227+ if (keep == NULL) /* Could not convert callback result. */
228+ PyErr_WriteUnraisable(callable);
229+ else if (keep == Py_None) /* Nothing to keep */
230+ Py_DECREF(keep);
231+ else if (setfunc != getentry("O")->setfunc) {
232+ if (-1 == PyErr_Warn(PyExc_RuntimeWarning,
233+ "memory leak in callback function."))
234+ PyErr_WriteUnraisable(callable);
235+ }
236+ }
237+ Py_XDECREF(result);
238+ Done:
239+ Py_XDECREF(arglist);
240+#ifdef WITH_THREAD
241+ PyGILState_Release(state);
242+#endif
243+}
244+
245+static void closure_fcn(ffi_cif *cif,
246+ void *resp,
247+ void **args,
248+ void *userdata)
249+{
250+ ffi_info *p = userdata;
251+
252+ _CallPythonObject(resp,
253+ p->restype,
254+ p->setfunc,
255+ p->callable,
256+ p->converters,
257+ args);
258+}
259+
260+ffi_info *AllocFunctionCallback(PyObject *callable,
261+ PyObject *converters,
262+ PyObject *restype,
263+ int is_cdecl)
264+{
265+ int result;
266+ ffi_info *p;
267+ int nArgs, i;
268+ ffi_abi cc;
269+
270+ nArgs = PySequence_Size(converters);
271+ p = (ffi_info *)PyMem_Malloc(sizeof(ffi_info) + sizeof(ffi_type) * (nArgs + 1));
272+ if (p == NULL) {
273+ PyErr_NoMemory();
274+ return NULL;
275+ }
276+ p->pcl = MallocClosure();
277+ if (p->pcl == NULL) {
278+ PyErr_NoMemory();
279+ goto error;
280+ }
281+
282+ for (i = 0; i < nArgs; ++i) {
283+ PyObject *cnv = PySequence_GetItem(converters, i);
284+ if (cnv == NULL)
285+ goto error;
286+ p->atypes[i] = GetType(cnv);
287+ Py_DECREF(cnv);
288+ }
289+ p->atypes[i] = NULL;
290+
291+ if (restype == Py_None) {
292+ p->setfunc = NULL;
293+ p->restype = &ffi_type_void;
294+ } else {
295+ StgDictObject *dict = PyType_stgdict(restype);
296+ if (dict == NULL || dict->setfunc == NULL) {
297+ PyErr_SetString(PyExc_TypeError,
298+ "invalid result type for callback function");
299+ goto error;
300+ }
301+ p->setfunc = dict->setfunc;
302+ p->restype = &dict->ffi_type_pointer;
303+ }
304+
305+ cc = FFI_DEFAULT_ABI;
306+#if defined(MS_WIN32) && !defined(_WIN32_WCE)
307+ if (is_cdecl == 0)
308+ cc = FFI_STDCALL;
309+#endif
310+ result = ffi_prep_cif(&p->cif, cc, nArgs,
311+ GetType(restype),
312+ &p->atypes[0]);
313+ if (result != FFI_OK) {
314+ PyErr_Format(PyExc_RuntimeError,
315+ "ffi_prep_cif failed with %d", result);
316+ goto error;
317+ }
318+ result = ffi_prep_closure(p->pcl, &p->cif, closure_fcn, p);
319+ if (result != FFI_OK) {
320+ PyErr_Format(PyExc_RuntimeError,
321+ "ffi_prep_closure failed with %d", result);
322+ goto error;
323+ }
324+
325+ p->converters = converters;
326+ p->callable = callable;
327+ return p;
328+
329+ error:
330+ if (p) {
331+ if (p->pcl)
332+ FreeClosure(p->pcl);
333+ PyMem_Free(p);
334+ }
335+ return NULL;
336+}
337+
338+/****************************************************************************
339+ *
340+ * callback objects: initialization
341+ */
342+
343+void init_callbacks_in_module(PyObject *m)
344+{
345+ if (PyType_Ready((PyTypeObject *)&PyType_Type) < 0)
346+ return;
347+}
348+
349+#ifdef MS_WIN32
350+
351+static void LoadPython(void)
352+{
353+ if (!Py_IsInitialized()) {
354+#ifdef WITH_THREAD
355+ PyEval_InitThreads();
356+#endif
357+ Py_Initialize();
358+ }
359+}
360+
361+/******************************************************************/
362+
363+long Call_GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
364+{
365+ PyObject *mod, *func, *result;
366+ long retval;
367+ static PyObject *context;
368+
369+ if (context == NULL)
370+ context = PyString_FromString("_ctypes.DllGetClassObject");
371+
372+ mod = PyImport_ImportModule("ctypes");
373+ if (!mod) {
374+ PyErr_WriteUnraisable(context ? context : Py_None);
375+ /* There has been a warning before about this already */
376+ return E_FAIL;
377+ }
378+
379+ func = PyObject_GetAttrString(mod, "DllGetClassObject");
380+ Py_DECREF(mod);
381+ if (!func) {
382+ PyErr_WriteUnraisable(context ? context : Py_None);
383+ return E_FAIL;
384+ }
385+
386+ result = PyObject_CallFunction(func,
387+ "iii", rclsid, riid, ppv);
388+ Py_DECREF(func);
389+ if (!result) {
390+ PyErr_WriteUnraisable(context ? context : Py_None);
391+ return E_FAIL;
392+ }
393+
394+ retval = PyInt_AsLong(result);
395+ if (PyErr_Occurred()) {
396+ PyErr_WriteUnraisable(context ? context : Py_None);
397+ retval = E_FAIL;
398+ }
399+ Py_DECREF(result);
400+ return retval;
401+}
402+
403+STDAPI DllGetClassObject(REFCLSID rclsid,
404+ REFIID riid,
405+ LPVOID *ppv)
406+{
407+ long result;
408+#ifdef WITH_THREAD
409+ PyGILState_STATE state;
410+#endif
411+
412+ LoadPython();
413+#ifdef WITH_THREAD
414+ state = PyGILState_Ensure();
415+#endif
416+ result = Call_GetClassObject(rclsid, riid, ppv);
417+#ifdef WITH_THREAD
418+ PyGILState_Release(state);
419+#endif
420+ return result;
421+}
422+
423+long Call_CanUnloadNow(void)
424+{
425+ PyObject *mod, *func, *result;
426+ long retval;
427+ static PyObject *context;
428+
429+ if (context == NULL)
430+ context = PyString_FromString("_ctypes.DllCanUnloadNow");
431+
432+ mod = PyImport_ImportModule("ctypes");
433+ if (!mod) {
434+/* OutputDebugString("Could not import ctypes"); */
435+ /* We assume that this error can only occur when shutting
436+ down, so we silently ignore it */
437+ PyErr_Clear();
438+ return E_FAIL;
439+ }
440+ /* Other errors cannot be raised, but are printed to stderr */
441+ func = PyObject_GetAttrString(mod, "DllCanUnloadNow");
442+ Py_DECREF(mod);
443+ if (!func) {
444+ PyErr_WriteUnraisable(context ? context : Py_None);
445+ return E_FAIL;
446+ }
447+
448+ result = PyObject_CallFunction(func, NULL);
449+ Py_DECREF(func);
450+ if (!result) {
451+ PyErr_WriteUnraisable(context ? context : Py_None);
452+ return E_FAIL;
453+ }
454+
455+ retval = PyInt_AsLong(result);
456+ if (PyErr_Occurred()) {
457+ PyErr_WriteUnraisable(context ? context : Py_None);
458+ retval = E_FAIL;
459+ }
460+ Py_DECREF(result);
461+ return retval;
462+}
463+
464+/*
465+ DllRegisterServer and DllUnregisterServer still missing
466+*/
467+
468+STDAPI DllCanUnloadNow(void)
469+{
470+ long result;
471+#ifdef WITH_THREAD
472+ PyGILState_STATE state = PyGILState_Ensure();
473+#endif
474+ result = Call_CanUnloadNow();
475+#ifdef WITH_THREAD
476+ PyGILState_Release(state);
477+#endif
478+ return result;
479+}
480+
481+#ifndef Py_NO_ENABLE_SHARED
482+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvRes)
483+{
484+ switch(fdwReason) {
485+ case DLL_PROCESS_ATTACH:
486+ DisableThreadLibraryCalls(hinstDLL);
487+ break;
488+ }
489+ return TRUE;
490+}
491+#endif
492+
493+#endif
494+
495+/*
496+ Local Variables:
497+ compile-command: "cd .. && python setup.py -q build_ext"
498+ End:
499+*/
sys/src/cmd/python/Modules/_ctypes/callproc.c+1581−0
@@ -0,0 +1,1581 @@
1+/*****************************************************************
2+ This file should be kept compatible with Python 2.3, see PEP 291.
3+ *****************************************************************/
4+
5+
6+/*
7+ * History: First version dated from 3/97, derived from my SCMLIB version
8+ * for win16.
9+ */
10+/*
11+ * Related Work:
12+ * - calldll http://www.nightmare.com/software.html
13+ * - libffi http://sourceware.cygnus.com/libffi/
14+ * - ffcall http://clisp.cons.org/~haible/packages-ffcall.html
15+ * and, of course, Don Beaudry's MESS package, but this is more ctypes
16+ * related.
17+ */
18+
19+
20+/*
21+ How are functions called, and how are parameters converted to C ?
22+
23+ 1. _ctypes.c::CFuncPtr_call receives an argument tuple 'inargs' and a
24+ keyword dictionary 'kwds'.
25+
26+ 2. After several checks, _build_callargs() is called which returns another
27+ tuple 'callargs'. This may be the same tuple as 'inargs', a slice of
28+ 'inargs', or a completely fresh tuple, depending on several things (is is a
29+ COM method, are 'paramflags' available).
30+
31+ 3. _build_callargs also calculates bitarrays containing indexes into
32+ the callargs tuple, specifying how to build the return value(s) of
33+ the function.
34+
35+ 4. _CallProc is then called with the 'callargs' tuple. _CallProc first
36+ allocates two arrays. The first is an array of 'struct argument' items, the
37+ second array has 'void *' entried.
38+
39+ 5. If 'converters' are present (converters is a sequence of argtypes'
40+ from_param methods), for each item in 'callargs' converter is called and the
41+ result passed to ConvParam. If 'converters' are not present, each argument
42+ is directly passed to ConvParm.
43+
44+ 6. For each arg, ConvParam stores the contained C data (or a pointer to it,
45+ for structures) into the 'struct argument' array.
46+
47+ 7. Finally, a loop fills the 'void *' array so that each item points to the
48+ data contained in or pointed to by the 'struct argument' array.
49+
50+ 8. The 'void *' argument array is what _call_function_pointer
51+ expects. _call_function_pointer then has very little to do - only some
52+ libffi specific stuff, then it calls ffi_call.
53+
54+ So, there are 4 data structures holding processed arguments:
55+ - the inargs tuple (in CFuncPtr_call)
56+ - the callargs tuple (in CFuncPtr_call)
57+ - the 'struct argguments' array
58+ - the 'void *' array
59+
60+ */
61+
62+#include "Python.h"
63+#include "structmember.h"
64+
65+#ifdef MS_WIN32
66+#include <windows.h>
67+#else
68+#include "ctypes_dlfcn.h"
69+#endif
70+
71+#ifdef MS_WIN32
72+#include <malloc.h>
73+#endif
74+
75+#include <ffi.h>
76+#include "ctypes.h"
77+
78+#if defined(_DEBUG) || defined(__MINGW32__)
79+/* Don't use structured exception handling on Windows if this is defined.
80+ MingW, AFAIK, doesn't support it.
81+*/
82+#define DONT_USE_SEH
83+#endif
84+
85+#ifdef MS_WIN32
86+PyObject *ComError;
87+
88+static TCHAR *FormatError(DWORD code)
89+{
90+ TCHAR *lpMsgBuf;
91+ DWORD n;
92+ n = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
93+ NULL,
94+ code,
95+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
96+ (LPTSTR) &lpMsgBuf,
97+ 0,
98+ NULL);
99+ if (n) {
100+ while (isspace(lpMsgBuf[n-1]))
101+ --n;
102+ lpMsgBuf[n] = '\0'; /* rstrip() */
103+ }
104+ return lpMsgBuf;
105+}
106+
107+#ifndef DONT_USE_SEH
108+void SetException(DWORD code, EXCEPTION_RECORD *pr)
109+{
110+ TCHAR *lpMsgBuf;
111+ lpMsgBuf = FormatError(code);
112+ if(lpMsgBuf) {
113+ PyErr_SetFromWindowsErr(code);
114+ LocalFree(lpMsgBuf);
115+ } else {
116+ switch (code) {
117+ case EXCEPTION_ACCESS_VIOLATION:
118+ /* The thread attempted to read from or write
119+ to a virtual address for which it does not
120+ have the appropriate access. */
121+ if (pr->ExceptionInformation[0] == 0)
122+ PyErr_Format(PyExc_WindowsError,
123+ "exception: access violation reading %p",
124+ pr->ExceptionInformation[1]);
125+ else
126+ PyErr_Format(PyExc_WindowsError,
127+ "exception: access violation writing %p",
128+ pr->ExceptionInformation[1]);
129+ break;
130+ case EXCEPTION_BREAKPOINT:
131+ /* A breakpoint was encountered. */
132+ PyErr_SetString(PyExc_WindowsError,
133+ "exception: breakpoint encountered");
134+ break;
135+
136+ case EXCEPTION_DATATYPE_MISALIGNMENT:
137+ /* The thread attempted to read or write data that is
138+ misaligned on hardware that does not provide
139+ alignment. For example, 16-bit values must be
140+ aligned on 2-byte boundaries, 32-bit values on
141+ 4-byte boundaries, and so on. */
142+ PyErr_SetString(PyExc_WindowsError,
143+ "exception: datatype misalignment");
144+ break;
145+
146+ case EXCEPTION_SINGLE_STEP:
147+ /* A trace trap or other single-instruction mechanism
148+ signaled that one instruction has been executed. */
149+ PyErr_SetString(PyExc_WindowsError,
150+ "exception: single step");
151+ break;
152+
153+ case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
154+ /* The thread attempted to access an array element
155+ that is out of bounds, and the underlying hardware
156+ supports bounds checking. */
157+ PyErr_SetString(PyExc_WindowsError,
158+ "exception: array bounds exceeded");
159+ break;
160+
161+ case EXCEPTION_FLT_DENORMAL_OPERAND:
162+ /* One of the operands in a floating-point operation
163+ is denormal. A denormal value is one that is too
164+ small to represent as a standard floating-point
165+ value. */
166+ PyErr_SetString(PyExc_WindowsError,
167+ "exception: floating-point operand denormal");
168+ break;
169+
170+ case EXCEPTION_FLT_DIVIDE_BY_ZERO:
171+ /* The thread attempted to divide a floating-point
172+ value by a floating-point divisor of zero. */
173+ PyErr_SetString(PyExc_WindowsError,
174+ "exception: float divide by zero");
175+ break;
176+
177+ case EXCEPTION_FLT_INEXACT_RESULT:
178+ /* The result of a floating-point operation cannot be
179+ represented exactly as a decimal fraction. */
180+ PyErr_SetString(PyExc_WindowsError,
181+ "exception: float inexact");
182+ break;
183+
184+ case EXCEPTION_FLT_INVALID_OPERATION:
185+ /* This exception represents any floating-point
186+ exception not included in this list. */
187+ PyErr_SetString(PyExc_WindowsError,
188+ "exception: float invalid operation");
189+ break;
190+
191+ case EXCEPTION_FLT_OVERFLOW:
192+ /* The exponent of a floating-point operation is
193+ greater than the magnitude allowed by the
194+ corresponding type. */
195+ PyErr_SetString(PyExc_WindowsError,
196+ "exception: float overflow");
197+ break;
198+
199+ case EXCEPTION_FLT_STACK_CHECK:
200+ /* The stack overflowed or underflowed as the result
201+ of a floating-point operation. */
202+ PyErr_SetString(PyExc_WindowsError,
203+ "exception: stack over/underflow");
204+ break;
205+
206+ case EXCEPTION_STACK_OVERFLOW:
207+ /* The stack overflowed or underflowed as the result
208+ of a floating-point operation. */
209+ PyErr_SetString(PyExc_WindowsError,
210+ "exception: stack overflow");
211+ break;
212+
213+ case EXCEPTION_FLT_UNDERFLOW:
214+ /* The exponent of a floating-point operation is less
215+ than the magnitude allowed by the corresponding
216+ type. */
217+ PyErr_SetString(PyExc_WindowsError,
218+ "exception: float underflow");
219+ break;
220+
221+ case EXCEPTION_INT_DIVIDE_BY_ZERO:
222+ /* The thread attempted to divide an integer value by
223+ an integer divisor of zero. */
224+ PyErr_SetString(PyExc_WindowsError,
225+ "exception: integer divide by zero");
226+ break;
227+
228+ case EXCEPTION_INT_OVERFLOW:
229+ /* The result of an integer operation caused a carry
230+ out of the most significant bit of the result. */
231+ PyErr_SetString(PyExc_WindowsError,
232+ "exception: integer overflow");
233+ break;
234+
235+ case EXCEPTION_PRIV_INSTRUCTION:
236+ /* The thread attempted to execute an instruction
237+ whose operation is not allowed in the current
238+ machine mode. */
239+ PyErr_SetString(PyExc_WindowsError,
240+ "exception: priviledged instruction");
241+ break;
242+
243+ case EXCEPTION_NONCONTINUABLE_EXCEPTION:
244+ /* The thread attempted to continue execution after a
245+ noncontinuable exception occurred. */
246+ PyErr_SetString(PyExc_WindowsError,
247+ "exception: nocontinuable");
248+ break;
249+ default:
250+ printf("error %d\n", code);
251+ PyErr_Format(PyExc_WindowsError,
252+ "exception code 0x%08x",
253+ code);
254+ break;
255+ }
256+ }
257+}
258+
259+static DWORD HandleException(EXCEPTION_POINTERS *ptrs,
260+ DWORD *pdw, EXCEPTION_RECORD *record)
261+{
262+ *pdw = ptrs->ExceptionRecord->ExceptionCode;
263+ *record = *ptrs->ExceptionRecord;
264+ return EXCEPTION_EXECUTE_HANDLER;
265+}
266+#endif
267+
268+static PyObject *
269+check_hresult(PyObject *self, PyObject *args)
270+{
271+ HRESULT hr;
272+ if (!PyArg_ParseTuple(args, "i", &hr))
273+ return NULL;
274+ if (FAILED(hr))
275+ return PyErr_SetFromWindowsErr(hr);
276+ return PyInt_FromLong(hr);
277+}
278+
279+#endif
280+
281+/**************************************************************/
282+
283+PyCArgObject *
284+new_CArgObject(void)
285+{
286+ PyCArgObject *p;
287+ p = PyObject_New(PyCArgObject, &PyCArg_Type);
288+ if (p == NULL)
289+ return NULL;
290+ p->pffi_type = NULL;
291+ p->tag = '\0';
292+ p->obj = NULL;
293+ memset(&p->value, 0, sizeof(p->value));
294+ return p;
295+}
296+
297+static void
298+PyCArg_dealloc(PyCArgObject *self)
299+{
300+ Py_XDECREF(self->obj);
301+ PyObject_Del(self);
302+}
303+
304+static PyObject *
305+PyCArg_repr(PyCArgObject *self)
306+{
307+ char buffer[256];
308+ switch(self->tag) {
309+ case 'b':
310+ case 'B':
311+ sprintf(buffer, "<cparam '%c' (%d)>",
312+ self->tag, self->value.b);
313+ break;
314+ case 'h':
315+ case 'H':
316+ sprintf(buffer, "<cparam '%c' (%d)>",
317+ self->tag, self->value.h);
318+ break;
319+ case 'i':
320+ case 'I':
321+ sprintf(buffer, "<cparam '%c' (%d)>",
322+ self->tag, self->value.i);
323+ break;
324+ case 'l':
325+ case 'L':
326+ sprintf(buffer, "<cparam '%c' (%ld)>",
327+ self->tag, self->value.l);
328+ break;
329+
330+#ifdef HAVE_LONG_LONG
331+ case 'q':
332+ case 'Q':
333+ sprintf(buffer,
334+#ifdef MS_WIN32
335+ "<cparam '%c' (%I64d)>",
336+#else
337+ "<cparam '%c' (%qd)>",
338+#endif
339+ self->tag, self->value.q);
340+ break;
341+#endif
342+ case 'd':
343+ sprintf(buffer, "<cparam '%c' (%f)>",
344+ self->tag, self->value.d);
345+ break;
346+ case 'f':
347+ sprintf(buffer, "<cparam '%c' (%f)>",
348+ self->tag, self->value.f);
349+ break;
350+
351+ case 'c':
352+ sprintf(buffer, "<cparam '%c' (%c)>",
353+ self->tag, self->value.c);
354+ break;
355+
356+/* Hm, are these 'z' and 'Z' codes useful at all?
357+ Shouldn't they be replaced by the functionality of c_string
358+ and c_wstring ?
359+*/
360+ case 'z':
361+ case 'Z':
362+ case 'P':
363+ sprintf(buffer, "<cparam '%c' (%08lx)>",
364+ self->tag, (long)self->value.p);
365+ break;
366+
367+ default:
368+ sprintf(buffer, "<cparam '%c' at %08lx>",
369+ self->tag, (long)self);
370+ break;
371+ }
372+ return PyString_FromString(buffer);
373+}
374+
375+static PyMemberDef PyCArgType_members[] = {
376+ { "_obj", T_OBJECT,
377+ offsetof(PyCArgObject, obj), READONLY,
378+ "the wrapped object" },
379+ { NULL },
380+};
381+
382+PyTypeObject PyCArg_Type = {
383+ PyObject_HEAD_INIT(NULL)
384+ 0,
385+ "CArgObject",
386+ sizeof(PyCArgObject),
387+ 0,
388+ (destructor)PyCArg_dealloc, /* tp_dealloc */
389+ 0, /* tp_print */
390+ 0, /* tp_getattr */
391+ 0, /* tp_setattr */
392+ 0, /* tp_compare */
393+ (reprfunc)PyCArg_repr, /* tp_repr */
394+ 0, /* tp_as_number */
395+ 0, /* tp_as_sequence */
396+ 0, /* tp_as_mapping */
397+ 0, /* tp_hash */
398+ 0, /* tp_call */
399+ 0, /* tp_str */
400+ 0, /* tp_getattro */
401+ 0, /* tp_setattro */
402+ 0, /* tp_as_buffer */
403+ Py_TPFLAGS_DEFAULT, /* tp_flags */
404+ 0, /* tp_doc */
405+ 0, /* tp_traverse */
406+ 0, /* tp_clear */
407+ 0, /* tp_richcompare */
408+ 0, /* tp_weaklistoffset */
409+ 0, /* tp_iter */
410+ 0, /* tp_iternext */
411+ 0, /* tp_methods */
412+ PyCArgType_members, /* tp_members */
413+};
414+
415+/****************************************************************/
416+/*
417+ * Convert a PyObject * into a parameter suitable to pass to an
418+ * C function call.
419+ *
420+ * 1. Python integers are converted to C int and passed by value.
421+ *
422+ * 2. 3-tuples are expected to have a format character in the first
423+ * item, which must be 'i', 'f', 'd', 'q', or 'P'.
424+ * The second item will have to be an integer, float, double, long long
425+ * or integer (denoting an address void *), will be converted to the
426+ * corresponding C data type and passed by value.
427+ *
428+ * 3. Other Python objects are tested for an '_as_parameter_' attribute.
429+ * The value of this attribute must be an integer which will be passed
430+ * by value, or a 2-tuple or 3-tuple which will be used according
431+ * to point 2 above. The third item (if any), is ignored. It is normally
432+ * used to keep the object alive where this parameter refers to.
433+ * XXX This convention is dangerous - you can construct arbitrary tuples
434+ * in Python and pass them. Would it be safer to use a custom container
435+ * datatype instead of a tuple?
436+ *
437+ * 4. Other Python objects cannot be passed as parameters - an exception is raised.
438+ *
439+ * 5. ConvParam will store the converted result in a struct containing format
440+ * and value.
441+ */
442+
443+union result {
444+ char c;
445+ char b;
446+ short h;
447+ int i;
448+ long l;
449+#ifdef HAVE_LONG_LONG
450+ PY_LONG_LONG q;
451+#endif
452+ double d;
453+ float f;
454+ void *p;
455+};
456+
457+struct argument {
458+ ffi_type *ffi_type;
459+ PyObject *keep;
460+ union result value;
461+};
462+
463+/*
464+ * Convert a single Python object into a PyCArgObject and return it.
465+ */
466+static int ConvParam(PyObject *obj, int index, struct argument *pa)
467+{
468+ StgDictObject *dict;
469+ pa->keep = NULL; /* so we cannot forget it later */
470+
471+ dict = PyObject_stgdict(obj);
472+ if (dict) {
473+ PyCArgObject *carg;
474+ assert(dict->paramfunc);
475+ /* If it has an stgdict, it is a CDataObject */
476+ carg = dict->paramfunc((CDataObject *)obj);
477+ pa->ffi_type = carg->pffi_type;
478+ memcpy(&pa->value, &carg->value, sizeof(pa->value));
479+ pa->keep = (PyObject *)carg;
480+ return 0;
481+ }
482+
483+ if (PyCArg_CheckExact(obj)) {
484+ PyCArgObject *carg = (PyCArgObject *)obj;
485+ pa->ffi_type = carg->pffi_type;
486+ Py_INCREF(obj);
487+ pa->keep = obj;
488+ memcpy(&pa->value, &carg->value, sizeof(pa->value));
489+ return 0;
490+ }
491+
492+ /* check for None, integer, string or unicode and use directly if successful */
493+ if (obj == Py_None) {
494+ pa->ffi_type = &ffi_type_pointer;
495+ pa->value.p = NULL;
496+ return 0;
497+ }
498+
499+ if (PyInt_Check(obj)) {
500+ pa->ffi_type = &ffi_type_sint;
501+ pa->value.i = PyInt_AS_LONG(obj);
502+ return 0;
503+ }
504+
505+ if (PyLong_Check(obj)) {
506+ pa->ffi_type = &ffi_type_sint;
507+ pa->value.i = (long)PyLong_AsUnsignedLong(obj);
508+ if (pa->value.i == -1 && PyErr_Occurred()) {
509+ PyErr_Clear();
510+ pa->value.i = PyLong_AsLong(obj);
511+ if (pa->value.i == -1 && PyErr_Occurred()) {
512+ PyErr_SetString(PyExc_OverflowError,
513+ "long int too long to convert");
514+ return -1;
515+ }
516+ }
517+ return 0;
518+ }
519+
520+ if (PyString_Check(obj)) {
521+ pa->ffi_type = &ffi_type_pointer;
522+ pa->value.p = PyString_AS_STRING(obj);
523+ Py_INCREF(obj);
524+ pa->keep = obj;
525+ return 0;
526+ }
527+
528+#ifdef CTYPES_UNICODE
529+ if (PyUnicode_Check(obj)) {
530+#ifdef HAVE_USABLE_WCHAR_T
531+ pa->ffi_type = &ffi_type_pointer;
532+ pa->value.p = PyUnicode_AS_UNICODE(obj);
533+ Py_INCREF(obj);
534+ pa->keep = obj;
535+ return 0;
536+#else
537+ int size = PyUnicode_GET_SIZE(obj);
538+ size += 1; /* terminating NUL */
539+ size *= sizeof(wchar_t);
540+ pa->value.p = PyMem_Malloc(size);
541+ if (!pa->value.p)
542+ return -1;
543+ memset(pa->value.p, 0, size);
544+ pa->keep = PyCObject_FromVoidPtr(pa->value.p, PyMem_Free);
545+ if (!pa->keep) {
546+ PyMem_Free(pa->value.p);
547+ return -1;
548+ }
549+ if (-1 == PyUnicode_AsWideChar((PyUnicodeObject *)obj,
550+ pa->value.p, PyUnicode_GET_SIZE(obj)))
551+ return -1;
552+ return 0;
553+#endif
554+ }
555+#endif
556+
557+ {
558+ PyObject *arg;
559+ arg = PyObject_GetAttrString(obj, "_as_parameter_");
560+ /* Which types should we exactly allow here?
561+ integers are required for using Python classes
562+ as parameters (they have to expose the '_as_parameter_'
563+ attribute)
564+ */
565+ if (arg) {
566+ int result;
567+ result = ConvParam(arg, index, pa);
568+ Py_DECREF(arg);
569+ return result;
570+ }
571+ PyErr_Format(PyExc_TypeError,
572+ "Don't know how to convert parameter %d", index);
573+ return -1;
574+ }
575+}
576+
577+
578+ffi_type *GetType(PyObject *obj)
579+{
580+ StgDictObject *dict;
581+ if (obj == NULL)
582+ return &ffi_type_sint;
583+ dict = PyType_stgdict(obj);
584+ if (dict == NULL)
585+ return &ffi_type_sint;
586+#if defined(MS_WIN32) && !defined(_WIN32_WCE)
587+ /* This little trick works correctly with MSVC.
588+ It returns small structures in registers
589+ */
590+ if (dict->ffi_type_pointer.type == FFI_TYPE_STRUCT) {
591+ if (dict->ffi_type_pointer.size <= 4)
592+ return &ffi_type_sint32;
593+ else if (dict->ffi_type_pointer.size <= 8)
594+ return &ffi_type_sint64;
595+ }
596+#endif
597+ return &dict->ffi_type_pointer;
598+}
599+
600+
601+/*
602+ * libffi uses:
603+ *
604+ * ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi,
605+ * unsigned int nargs,
606+ * ffi_type *rtype,
607+ * ffi_type **atypes);
608+ *
609+ * and then
610+ *
611+ * void ffi_call(ffi_cif *cif, void *fn, void *rvalue, void **avalues);
612+ */
613+static int _call_function_pointer(int flags,
614+ PPROC pProc,
615+ void **avalues,
616+ ffi_type **atypes,
617+ ffi_type *restype,
618+ void *resmem,
619+ int argcount)
620+{
621+#ifdef WITH_THREAD
622+ PyThreadState *_save = NULL; /* For Py_BLOCK_THREADS and Py_UNBLOCK_THREADS */
623+#endif
624+ ffi_cif cif;
625+ int cc;
626+#ifdef MS_WIN32
627+ int delta;
628+#ifndef DONT_USE_SEH
629+ DWORD dwExceptionCode = 0;
630+ EXCEPTION_RECORD record;
631+#endif
632+#endif
633+ /* XXX check before here */
634+ if (restype == NULL) {
635+ PyErr_SetString(PyExc_RuntimeError,
636+ "No ffi_type for result");
637+ return -1;
638+ }
639+
640+ cc = FFI_DEFAULT_ABI;
641+#if defined(MS_WIN32) && !defined(_WIN32_WCE)
642+ if ((flags & FUNCFLAG_CDECL) == 0)
643+ cc = FFI_STDCALL;
644+#endif
645+ if (FFI_OK != ffi_prep_cif(&cif,
646+ cc,
647+ argcount,
648+ restype,
649+ atypes)) {
650+ PyErr_SetString(PyExc_RuntimeError,
651+ "ffi_prep_cif failed");
652+ return -1;
653+ }
654+
655+#ifdef WITH_THREAD
656+ if ((flags & FUNCFLAG_PYTHONAPI) == 0)
657+ Py_UNBLOCK_THREADS
658+#endif
659+#ifdef MS_WIN32
660+#ifndef DONT_USE_SEH
661+ __try {
662+#endif
663+ delta =
664+#endif
665+ ffi_call(&cif, (void *)pProc, resmem, avalues);
666+#ifdef MS_WIN32
667+#ifndef DONT_USE_SEH
668+ }
669+ __except (HandleException(GetExceptionInformation(),
670+ &dwExceptionCode, &record)) {
671+ ;
672+ }
673+#endif
674+#endif
675+#ifdef WITH_THREAD
676+ if ((flags & FUNCFLAG_PYTHONAPI) == 0)
677+ Py_BLOCK_THREADS
678+#endif
679+#ifdef MS_WIN32
680+#ifndef DONT_USE_SEH
681+ if (dwExceptionCode) {
682+ SetException(dwExceptionCode, &record);
683+ return -1;
684+ }
685+#endif
686+ if (delta < 0) {
687+ if (flags & FUNCFLAG_CDECL)
688+ PyErr_Format(PyExc_ValueError,
689+ "Procedure called with not enough "
690+ "arguments (%d bytes missing) "
691+ "or wrong calling convention",
692+ -delta);
693+ else
694+ PyErr_Format(PyExc_ValueError,
695+ "Procedure probably called with not enough "
696+ "arguments (%d bytes missing)",
697+ -delta);
698+ return -1;
699+ } else if (delta > 0) {
700+ PyErr_Format(PyExc_ValueError,
701+ "Procedure probably called with too many "
702+ "arguments (%d bytes in excess)",
703+ delta);
704+ return -1;
705+ }
706+#endif
707+ if ((flags & FUNCFLAG_PYTHONAPI) && PyErr_Occurred())
708+ return -1;
709+ return 0;
710+}
711+
712+/*
713+ * Convert the C value in result into a Python object, depending on restype.
714+ *
715+ * - If restype is NULL, return a Python integer.
716+ * - If restype is None, return None.
717+ * - If restype is a simple ctypes type (c_int, c_void_p), call the type's getfunc,
718+ * pass the result to checker and return the result.
719+ * - If restype is another ctypes type, return an instance of that.
720+ * - Otherwise, call restype and return the result.
721+ */
722+static PyObject *GetResult(PyObject *restype, void *result, PyObject *checker)
723+{
724+ StgDictObject *dict;
725+ PyObject *retval, *v;
726+
727+ if (restype == NULL)
728+ return PyInt_FromLong(*(int *)result);
729+
730+ if (restype == Py_None) {
731+ Py_INCREF(Py_None);
732+ return Py_None;
733+ }
734+
735+ dict = PyType_stgdict(restype);
736+ if (dict == NULL)
737+ return PyObject_CallFunction(restype, "i", *(int *)result);
738+
739+ if (dict->getfunc && !IsSimpleSubType(restype)) {
740+ retval = dict->getfunc(result, dict->size);
741+ /* If restype is py_object (detected by comparing getfunc with
742+ O_get), we have to call Py_DECREF because O_get has already
743+ called Py_INCREF.
744+ */
745+ if (dict->getfunc == getentry("O")->getfunc) {
746+ Py_DECREF(retval);
747+ }
748+ } else
749+ retval = CData_FromBaseObj(restype, NULL, 0, result);
750+
751+ if (!checker || !retval)
752+ return retval;
753+
754+ v = PyObject_CallFunctionObjArgs(checker, retval, NULL);
755+ if (v == NULL)
756+ _AddTraceback("GetResult", __FILE__, __LINE__-2);
757+ Py_DECREF(retval);
758+ return v;
759+}
760+
761+/*
762+ * Raise a new exception 'exc_class', adding additional text to the original
763+ * exception string.
764+ */
765+void Extend_Error_Info(PyObject *exc_class, char *fmt, ...)
766+{
767+ va_list vargs;
768+ PyObject *tp, *v, *tb, *s, *cls_str, *msg_str;
769+
770+ va_start(vargs, fmt);
771+ s = PyString_FromFormatV(fmt, vargs);
772+ va_end(vargs);
773+ if (!s)
774+ return;
775+
776+ PyErr_Fetch(&tp, &v, &tb);
777+ PyErr_NormalizeException(&tp, &v, &tb);
778+ cls_str = PyObject_Str(tp);
779+ if (cls_str) {
780+ PyString_ConcatAndDel(&s, cls_str);
781+ PyString_ConcatAndDel(&s, PyString_FromString(": "));
782+ if (s == NULL)
783+ goto error;
784+ } else
785+ PyErr_Clear();
786+ msg_str = PyObject_Str(v);
787+ if (msg_str)
788+ PyString_ConcatAndDel(&s, msg_str);
789+ else {
790+ PyErr_Clear();
791+ PyString_ConcatAndDel(&s, PyString_FromString("???"));
792+ if (s == NULL)
793+ goto error;
794+ }
795+ PyErr_SetObject(exc_class, s);
796+error:
797+ Py_XDECREF(tp);
798+ Py_XDECREF(v);
799+ Py_XDECREF(tb);
800+ Py_XDECREF(s);
801+}
802+
803+
804+#ifdef MS_WIN32
805+
806+static PyObject *
807+GetComError(HRESULT errcode, GUID *riid, IUnknown *pIunk)
808+{
809+ HRESULT hr;
810+ ISupportErrorInfo *psei = NULL;
811+ IErrorInfo *pei = NULL;
812+ BSTR descr=NULL, helpfile=NULL, source=NULL;
813+ GUID guid;
814+ DWORD helpcontext=0;
815+ LPOLESTR progid;
816+ PyObject *obj;
817+ TCHAR *text;
818+
819+ /* We absolutely have to release the GIL during COM method calls,
820+ otherwise we may get a deadlock!
821+ */
822+#ifdef WITH_THREAD
823+ Py_BEGIN_ALLOW_THREADS
824+#endif
825+
826+ hr = pIunk->lpVtbl->QueryInterface(pIunk, &IID_ISupportErrorInfo, (void **)&psei);
827+ if (FAILED(hr))
828+ goto failed;
829+
830+ hr = psei->lpVtbl->InterfaceSupportsErrorInfo(psei, riid);
831+ psei->lpVtbl->Release(psei);
832+ if (FAILED(hr))
833+ goto failed;
834+
835+ hr = GetErrorInfo(0, &pei);
836+ if (hr != S_OK)
837+ goto failed;
838+
839+ pei->lpVtbl->GetDescription(pei, &descr);
840+ pei->lpVtbl->GetGUID(pei, &guid);
841+ pei->lpVtbl->GetHelpContext(pei, &helpcontext);
842+ pei->lpVtbl->GetHelpFile(pei, &helpfile);
843+ pei->lpVtbl->GetSource(pei, &source);
844+
845+ pei->lpVtbl->Release(pei);
846+
847+ failed:
848+#ifdef WITH_THREAD
849+ Py_END_ALLOW_THREADS
850+#endif
851+
852+ progid = NULL;
853+ ProgIDFromCLSID(&guid, &progid);
854+
855+ text = FormatError(errcode);
856+ obj = Py_BuildValue(
857+#ifdef _UNICODE
858+ "iu(uuuiu)",
859+#else
860+ "is(uuuiu)",
861+#endif
862+ errcode,
863+ text,
864+ descr, source, helpfile, helpcontext,
865+ progid);
866+ if (obj) {
867+ PyErr_SetObject(ComError, obj);
868+ Py_DECREF(obj);
869+ }
870+ LocalFree(text);
871+
872+ if (descr)
873+ SysFreeString(descr);
874+ if (helpfile)
875+ SysFreeString(helpfile);
876+ if (source)
877+ SysFreeString(source);
878+
879+ return NULL;
880+}
881+#endif
882+
883+/*
884+ * Requirements, must be ensured by the caller:
885+ * - argtuple is tuple of arguments
886+ * - argtypes is either NULL, or a tuple of the same size as argtuple
887+ *
888+ * - XXX various requirements for restype, not yet collected
889+ */
890+PyObject *_CallProc(PPROC pProc,
891+ PyObject *argtuple,
892+#ifdef MS_WIN32
893+ IUnknown *pIunk,
894+ GUID *iid,
895+#endif
896+ int flags,
897+ PyObject *argtypes, /* misleading name: This is a tuple of
898+ methods, not types: the .from_param
899+ class methods of the types */
900+ PyObject *restype,
901+ PyObject *checker)
902+{
903+ int i, n, argcount, argtype_count;
904+ void *resbuf;
905+ struct argument *args, *pa;
906+ ffi_type **atypes;
907+ ffi_type *rtype;
908+ void **avalues;
909+ PyObject *retval = NULL;
910+
911+ n = argcount = PyTuple_GET_SIZE(argtuple);
912+#ifdef MS_WIN32
913+ /* an optional COM object this pointer */
914+ if (pIunk)
915+ ++argcount;
916+#endif
917+
918+ args = (struct argument *)alloca(sizeof(struct argument) * argcount);
919+ if (!args) {
920+ PyErr_NoMemory();
921+ return NULL;
922+ }
923+ memset(args, 0, sizeof(struct argument) * argcount);
924+ argtype_count = argtypes ? PyTuple_GET_SIZE(argtypes) : 0;
925+#ifdef MS_WIN32
926+ if (pIunk) {
927+ args[0].ffi_type = &ffi_type_pointer;
928+ args[0].value.p = pIunk;
929+ pa = &args[1];
930+ } else
931+#endif
932+ pa = &args[0];
933+
934+ /* Convert the arguments */
935+ for (i = 0; i < n; ++i, ++pa) {
936+ PyObject *converter;
937+ PyObject *arg;
938+ int err;
939+
940+ arg = PyTuple_GET_ITEM(argtuple, i); /* borrowed ref */
941+ /* For cdecl functions, we allow more actual arguments
942+ than the length of the argtypes tuple.
943+ This is checked in _ctypes::CFuncPtr_Call
944+ */
945+ if (argtypes && argtype_count > i) {
946+ PyObject *v;
947+ converter = PyTuple_GET_ITEM(argtypes, i);
948+ v = PyObject_CallFunctionObjArgs(converter,
949+ arg,
950+ NULL);
951+ if (v == NULL) {
952+ Extend_Error_Info(PyExc_ArgError, "argument %d: ", i+1);
953+ goto cleanup;
954+ }
955+
956+ err = ConvParam(v, i+1, pa);
957+ Py_DECREF(v);
958+ if (-1 == err) {
959+ Extend_Error_Info(PyExc_ArgError, "argument %d: ", i+1);
960+ goto cleanup;
961+ }
962+ } else {
963+ err = ConvParam(arg, i+1, pa);
964+ if (-1 == err) {
965+ Extend_Error_Info(PyExc_ArgError, "argument %d: ", i+1);
966+ goto cleanup; /* leaking ? */
967+ }
968+ }
969+ }
970+
971+ rtype = GetType(restype);
972+ resbuf = alloca(max(rtype->size, sizeof(ffi_arg)));
973+
974+ avalues = (void **)alloca(sizeof(void *) * argcount);
975+ atypes = (ffi_type **)alloca(sizeof(ffi_type *) * argcount);
976+ if (!resbuf || !avalues || !atypes) {
977+ PyErr_NoMemory();
978+ goto cleanup;
979+ }
980+ for (i = 0; i < argcount; ++i) {
981+ atypes[i] = args[i].ffi_type;
982+ if (atypes[i]->type == FFI_TYPE_STRUCT)
983+ avalues[i] = (void *)args[i].value.p;
984+ else
985+ avalues[i] = (void *)&args[i].value;
986+ }
987+
988+ if (-1 == _call_function_pointer(flags, pProc, avalues, atypes,
989+ rtype, resbuf, argcount))
990+ goto cleanup;
991+
992+#ifdef WORDS_BIGENDIAN
993+ /* libffi returns the result in a buffer with sizeof(ffi_arg). This
994+ causes problems on big endian machines, since the result buffer
995+ address cannot simply be used as result pointer, instead we must
996+ adjust the pointer value:
997+ */
998+ /*
999+ XXX I should find out and clarify why this is needed at all,
1000+ especially why adjusting for ffi_type_float must be avoided on
1001+ 64-bit platforms.
1002+ */
1003+ if (rtype->type != FFI_TYPE_FLOAT
1004+ && rtype->type != FFI_TYPE_STRUCT
1005+ && rtype->size < sizeof(ffi_arg))
1006+ resbuf = (char *)resbuf + sizeof(ffi_arg) - rtype->size;
1007+#endif
1008+
1009+#ifdef MS_WIN32
1010+ if (iid && pIunk) {
1011+ if (*(int *)resbuf & 0x80000000)
1012+ retval = GetComError(*(HRESULT *)resbuf, iid, pIunk);
1013+ else
1014+ retval = PyInt_FromLong(*(int *)resbuf);
1015+ } else if (flags & FUNCFLAG_HRESULT) {
1016+ if (*(int *)resbuf & 0x80000000)
1017+ retval = PyErr_SetFromWindowsErr(*(int *)resbuf);
1018+ else
1019+ retval = PyInt_FromLong(*(int *)resbuf);
1020+ } else
1021+#endif
1022+ retval = GetResult(restype, resbuf, checker);
1023+ cleanup:
1024+ for (i = 0; i < argcount; ++i)
1025+ Py_XDECREF(args[i].keep);
1026+ return retval;
1027+}
1028+
1029+#ifdef MS_WIN32
1030+
1031+#ifdef _UNICODE
1032+# define PYBUILD_TSTR "u"
1033+#else
1034+# define PYBUILD_TSTR "s"
1035+# ifndef _T
1036+# define _T(text) text
1037+# endif
1038+#endif
1039+
1040+static char format_error_doc[] =
1041+"FormatError([integer]) -> string\n\
1042+\n\
1043+Convert a win32 error code into a string. If the error code is not\n\
1044+given, the return value of a call to GetLastError() is used.\n";
1045+static PyObject *format_error(PyObject *self, PyObject *args)
1046+{
1047+ PyObject *result;
1048+ TCHAR *lpMsgBuf;
1049+ DWORD code = 0;
1050+ if (!PyArg_ParseTuple(args, "|i:FormatError", &code))
1051+ return NULL;
1052+ if (code == 0)
1053+ code = GetLastError();
1054+ lpMsgBuf = FormatError(code);
1055+ if (lpMsgBuf) {
1056+ result = Py_BuildValue(PYBUILD_TSTR, lpMsgBuf);
1057+ LocalFree(lpMsgBuf);
1058+ } else {
1059+ result = Py_BuildValue("s", "<no description>");
1060+ }
1061+ return result;
1062+}
1063+
1064+static char load_library_doc[] =
1065+"LoadLibrary(name) -> handle\n\
1066+\n\
1067+Load an executable (usually a DLL), and return a handle to it.\n\
1068+The handle may be used to locate exported functions in this\n\
1069+module.\n";
1070+static PyObject *load_library(PyObject *self, PyObject *args)
1071+{
1072+ TCHAR *name;
1073+ PyObject *nameobj;
1074+ PyObject *ignored;
1075+ HMODULE hMod;
1076+ if (!PyArg_ParseTuple(args, "O|O:LoadLibrary", &nameobj, &ignored))
1077+ return NULL;
1078+#ifdef _UNICODE
1079+ name = alloca((PyString_Size(nameobj) + 1) * sizeof(WCHAR));
1080+ if (!name) {
1081+ PyErr_NoMemory();
1082+ return NULL;
1083+ }
1084+
1085+ {
1086+ int r;
1087+ char *aname = PyString_AsString(nameobj);
1088+ if(!aname)
1089+ return NULL;
1090+ r = MultiByteToWideChar(CP_ACP, 0, aname, -1, name, PyString_Size(nameobj) + 1);
1091+ name[r] = 0;
1092+ }
1093+#else
1094+ name = PyString_AsString(nameobj);
1095+ if(!name)
1096+ return NULL;
1097+#endif
1098+
1099+ hMod = LoadLibrary(name);
1100+ if (!hMod)
1101+ return PyErr_SetFromWindowsErr(GetLastError());
1102+ return Py_BuildValue("i", hMod);
1103+}
1104+
1105+static char free_library_doc[] =
1106+"FreeLibrary(handle) -> void\n\
1107+\n\
1108+Free the handle of an executable previously loaded by LoadLibrary.\n";
1109+static PyObject *free_library(PyObject *self, PyObject *args)
1110+{
1111+ HMODULE hMod;
1112+ if (!PyArg_ParseTuple(args, "i:FreeLibrary", &hMod))
1113+ return NULL;
1114+ if (!FreeLibrary(hMod))
1115+ return PyErr_SetFromWindowsErr(GetLastError());
1116+ Py_INCREF(Py_None);
1117+ return Py_None;
1118+}
1119+
1120+/* obsolete, should be removed */
1121+/* Only used by sample code (in samples\Windows\COM.py) */
1122+static PyObject *
1123+call_commethod(PyObject *self, PyObject *args)
1124+{
1125+ IUnknown *pIunk;
1126+ int index;
1127+ PyObject *arguments;
1128+ PPROC *lpVtbl;
1129+ PyObject *result;
1130+ CDataObject *pcom;
1131+ PyObject *argtypes = NULL;
1132+
1133+ if (!PyArg_ParseTuple(args,
1134+ "OiO!|O!",
1135+ &pcom, &index,
1136+ &PyTuple_Type, &arguments,
1137+ &PyTuple_Type, &argtypes))
1138+ return NULL;
1139+
1140+ if (argtypes && (PyTuple_GET_SIZE(arguments) != PyTuple_GET_SIZE(argtypes))) {
1141+ PyErr_Format(PyExc_TypeError,
1142+ "Method takes %d arguments (%d given)",
1143+ PyTuple_GET_SIZE(argtypes), PyTuple_GET_SIZE(arguments));
1144+ return NULL;
1145+ }
1146+
1147+ if (!CDataObject_Check(pcom) || (pcom->b_size != sizeof(void *))) {
1148+ PyErr_Format(PyExc_TypeError,
1149+ "COM Pointer expected instead of %s instance",
1150+ pcom->ob_type->tp_name);
1151+ return NULL;
1152+ }
1153+
1154+ if ((*(void **)(pcom->b_ptr)) == NULL) {
1155+ PyErr_SetString(PyExc_ValueError,
1156+ "The COM 'this' pointer is NULL");
1157+ return NULL;
1158+ }
1159+
1160+ pIunk = (IUnknown *)(*(void **)(pcom->b_ptr));
1161+ lpVtbl = (PPROC *)(pIunk->lpVtbl);
1162+
1163+ result = _CallProc(lpVtbl[index],
1164+ arguments,
1165+#ifdef MS_WIN32
1166+ pIunk,
1167+ NULL,
1168+#endif
1169+ FUNCFLAG_HRESULT, /* flags */
1170+ argtypes, /* self->argtypes */
1171+ NULL, /* self->restype */
1172+ NULL); /* checker */
1173+ return result;
1174+}
1175+
1176+static char copy_com_pointer_doc[] =
1177+"CopyComPointer(src, dst) -> HRESULT value\n";
1178+
1179+static PyObject *
1180+copy_com_pointer(PyObject *self, PyObject *args)
1181+{
1182+ PyObject *p1, *p2, *r = NULL;
1183+ struct argument a, b;
1184+ IUnknown *src, **pdst;
1185+ if (!PyArg_ParseTuple(args, "OO:CopyComPointer", &p1, &p2))
1186+ return NULL;
1187+ a.keep = b.keep = NULL;
1188+
1189+ if (-1 == ConvParam(p1, 0, &a) || -1 == ConvParam(p2, 1, &b))
1190+ goto done;
1191+ src = (IUnknown *)a.value.p;
1192+ pdst = (IUnknown **)b.value.p;
1193+
1194+ if (pdst == NULL)
1195+ r = PyInt_FromLong(E_POINTER);
1196+ else {
1197+ if (src)
1198+ src->lpVtbl->AddRef(src);
1199+ *pdst = src;
1200+ r = PyInt_FromLong(S_OK);
1201+ }
1202+ done:
1203+ Py_XDECREF(a.keep);
1204+ Py_XDECREF(b.keep);
1205+ return r;
1206+}
1207+#else
1208+
1209+static PyObject *py_dl_open(PyObject *self, PyObject *args)
1210+{
1211+ char *name;
1212+ void * handle;
1213+#ifdef RTLD_LOCAL
1214+ int mode = RTLD_NOW | RTLD_LOCAL;
1215+#else
1216+ /* cygwin doesn't define RTLD_LOCAL */
1217+ int mode = RTLD_NOW;
1218+#endif
1219+ if (!PyArg_ParseTuple(args, "z|i:dlopen", &name, &mode))
1220+ return NULL;
1221+ mode |= RTLD_NOW;
1222+ handle = ctypes_dlopen(name, mode);
1223+ if (!handle) {
1224+ PyErr_SetString(PyExc_OSError,
1225+ ctypes_dlerror());
1226+ return NULL;
1227+ }
1228+ return PyLong_FromVoidPtr(handle);
1229+}
1230+
1231+static PyObject *py_dl_close(PyObject *self, PyObject *args)
1232+{
1233+ void * handle;
1234+
1235+ if (!PyArg_ParseTuple(args, "i:dlclose", &handle))
1236+ return NULL;
1237+ if (dlclose(handle)) {
1238+ PyErr_SetString(PyExc_OSError,
1239+ ctypes_dlerror());
1240+ return NULL;
1241+ }
1242+ Py_INCREF(Py_None);
1243+ return Py_None;
1244+}
1245+
1246+static PyObject *py_dl_sym(PyObject *self, PyObject *args)
1247+{
1248+ char *name;
1249+ void *handle;
1250+ void *ptr;
1251+
1252+ if (!PyArg_ParseTuple(args, "is:dlsym", &handle, &name))
1253+ return NULL;
1254+ ptr = ctypes_dlsym(handle, name);
1255+ if (!ptr) {
1256+ PyErr_SetString(PyExc_OSError,
1257+ ctypes_dlerror());
1258+ return NULL;
1259+ }
1260+ return Py_BuildValue("i", ptr);
1261+}
1262+#endif
1263+
1264+/*
1265+ * Only for debugging so far: So that we can call CFunction instances
1266+ *
1267+ * XXX Needs to accept more arguments: flags, argtypes, restype
1268+ */
1269+static PyObject *
1270+call_function(PyObject *self, PyObject *args)
1271+{
1272+ PPROC func;
1273+ PyObject *arguments;
1274+ PyObject *result;
1275+
1276+ if (!PyArg_ParseTuple(args,
1277+ "iO!",
1278+ &func,
1279+ &PyTuple_Type, &arguments))
1280+ return NULL;
1281+
1282+ result = _CallProc(func,
1283+ arguments,
1284+#ifdef MS_WIN32
1285+ NULL,
1286+ NULL,
1287+#endif
1288+ 0, /* flags */
1289+ NULL, /* self->argtypes */
1290+ NULL, /* self->restype */
1291+ NULL); /* checker */
1292+ return result;
1293+}
1294+
1295+/*
1296+ * Only for debugging so far: So that we can call CFunction instances
1297+ *
1298+ * XXX Needs to accept more arguments: flags, argtypes, restype
1299+ */
1300+static PyObject *
1301+call_cdeclfunction(PyObject *self, PyObject *args)
1302+{
1303+ PPROC func;
1304+ PyObject *arguments;
1305+ PyObject *result;
1306+
1307+ if (!PyArg_ParseTuple(args,
1308+ "iO!",
1309+ &func,
1310+ &PyTuple_Type, &arguments))
1311+ return NULL;
1312+
1313+ result = _CallProc(func,
1314+ arguments,
1315+#ifdef MS_WIN32
1316+ NULL,
1317+ NULL,
1318+#endif
1319+ FUNCFLAG_CDECL, /* flags */
1320+ NULL, /* self->argtypes */
1321+ NULL, /* self->restype */
1322+ NULL); /* checker */
1323+ return result;
1324+}
1325+
1326+/*****************************************************************
1327+ * functions
1328+ */
1329+static char sizeof_doc[] =
1330+"sizeof(C type) -> integer\n"
1331+"sizeof(C instance) -> integer\n"
1332+"Return the size in bytes of a C instance";
1333+
1334+static PyObject *
1335+sizeof_func(PyObject *self, PyObject *obj)
1336+{
1337+ StgDictObject *dict;
1338+
1339+ dict = PyType_stgdict(obj);
1340+ if (dict)
1341+ return PyInt_FromLong(dict->size);
1342+
1343+ if (CDataObject_Check(obj))
1344+ return PyInt_FromLong(((CDataObject *)obj)->b_size);
1345+ PyErr_SetString(PyExc_TypeError,
1346+ "this type has no size");
1347+ return NULL;
1348+}
1349+
1350+static char alignment_doc[] =
1351+"alignment(C type) -> integer\n"
1352+"alignment(C instance) -> integer\n"
1353+"Return the alignment requirements of a C instance";
1354+
1355+static PyObject *
1356+align_func(PyObject *self, PyObject *obj)
1357+{
1358+ StgDictObject *dict;
1359+
1360+ dict = PyType_stgdict(obj);
1361+ if (dict)
1362+ return PyInt_FromLong(dict->align);
1363+
1364+ dict = PyObject_stgdict(obj);
1365+ if (dict)
1366+ return PyInt_FromLong(dict->align);
1367+
1368+ PyErr_SetString(PyExc_TypeError,
1369+ "no alignment info");
1370+ return NULL;
1371+}
1372+
1373+static char byref_doc[] =
1374+"byref(C instance) -> byref-object\n"
1375+"Return a pointer lookalike to a C instance, only usable\n"
1376+"as function argument";
1377+
1378+/*
1379+ * We must return something which can be converted to a parameter,
1380+ * but still has a reference to self.
1381+ */
1382+static PyObject *
1383+byref(PyObject *self, PyObject *obj)
1384+{
1385+ PyCArgObject *parg;
1386+ if (!CDataObject_Check(obj)) {
1387+ PyErr_Format(PyExc_TypeError,
1388+ "byref() argument must be a ctypes instance, not '%s'",
1389+ obj->ob_type->tp_name);
1390+ return NULL;
1391+ }
1392+
1393+ parg = new_CArgObject();
1394+ if (parg == NULL)
1395+ return NULL;
1396+
1397+ parg->tag = 'P';
1398+ parg->pffi_type = &ffi_type_pointer;
1399+ Py_INCREF(obj);
1400+ parg->obj = obj;
1401+ parg->value.p = ((CDataObject *)obj)->b_ptr;
1402+ return (PyObject *)parg;
1403+}
1404+
1405+static char addressof_doc[] =
1406+"addressof(C instance) -> integer\n"
1407+"Return the address of the C instance internal buffer";
1408+
1409+static PyObject *
1410+addressof(PyObject *self, PyObject *obj)
1411+{
1412+ if (CDataObject_Check(obj))
1413+ return PyLong_FromVoidPtr(((CDataObject *)obj)->b_ptr);
1414+ PyErr_SetString(PyExc_TypeError,
1415+ "invalid type");
1416+ return NULL;
1417+}
1418+
1419+static int
1420+converter(PyObject *obj, void **address)
1421+{
1422+ *address = PyLong_AsVoidPtr(obj);
1423+ return *address != NULL;
1424+}
1425+
1426+static PyObject *
1427+My_PyObj_FromPtr(PyObject *self, PyObject *args)
1428+{
1429+ PyObject *ob;
1430+ if (!PyArg_ParseTuple(args, "O&:PyObj_FromPtr", converter, &ob))
1431+ return NULL;
1432+ Py_INCREF(ob);
1433+ return ob;
1434+}
1435+
1436+static PyObject *
1437+My_Py_INCREF(PyObject *self, PyObject *arg)
1438+{
1439+ Py_INCREF(arg); /* that's what this function is for */
1440+ Py_INCREF(arg); /* that for returning it */
1441+ return arg;
1442+}
1443+
1444+static PyObject *
1445+My_Py_DECREF(PyObject *self, PyObject *arg)
1446+{
1447+ Py_DECREF(arg); /* that's what this function is for */
1448+ Py_INCREF(arg); /* that's for returning it */
1449+ return arg;
1450+}
1451+
1452+#ifdef CTYPES_UNICODE
1453+
1454+static char set_conversion_mode_doc[] =
1455+"set_conversion_mode(encoding, errors) -> (previous-encoding, previous-errors)\n\
1456+\n\
1457+Set the encoding and error handling ctypes uses when converting\n\
1458+between unicode and strings. Returns the previous values.\n";
1459+
1460+static PyObject *
1461+set_conversion_mode(PyObject *self, PyObject *args)
1462+{
1463+ char *coding, *mode;
1464+ PyObject *result;
1465+
1466+ if (!PyArg_ParseTuple(args, "zs:set_conversion_mode", &coding, &mode))
1467+ return NULL;
1468+ result = Py_BuildValue("(zz)", conversion_mode_encoding, conversion_mode_errors);
1469+ if (coding) {
1470+ PyMem_Free(conversion_mode_encoding);
1471+ conversion_mode_encoding = PyMem_Malloc(strlen(coding) + 1);
1472+ strcpy(conversion_mode_encoding, coding);
1473+ } else {
1474+ conversion_mode_encoding = NULL;
1475+ }
1476+ PyMem_Free(conversion_mode_errors);
1477+ conversion_mode_errors = PyMem_Malloc(strlen(mode) + 1);
1478+ strcpy(conversion_mode_errors, mode);
1479+ return result;
1480+}
1481+#endif
1482+
1483+static PyObject *
1484+resize(PyObject *self, PyObject *args)
1485+{
1486+ CDataObject *obj;
1487+ StgDictObject *dict;
1488+ Py_ssize_t size;
1489+
1490+ if (!PyArg_ParseTuple(args,
1491+#if (PY_VERSION_HEX < 0x02050000)
1492+ "Oi:resize",
1493+#else
1494+ "On:resize",
1495+#endif
1496+ (PyObject *)&obj, &size))
1497+ return NULL;
1498+
1499+ dict = PyObject_stgdict((PyObject *)obj);
1500+ if (dict == NULL) {
1501+ PyErr_SetString(PyExc_TypeError,
1502+ "excepted ctypes instance");
1503+ return NULL;
1504+ }
1505+ if (size < dict->size) {
1506+ PyErr_Format(PyExc_ValueError,
1507+#if PY_VERSION_HEX < 0x02050000
1508+ "minimum size is %d",
1509+#else
1510+ "minimum size is %zd",
1511+#endif
1512+ dict->size);
1513+ return NULL;
1514+ }
1515+ if (obj->b_needsfree == 0) {
1516+ PyErr_Format(PyExc_ValueError,
1517+ "Memory cannot be resized because this object doesn't own it");
1518+ return NULL;
1519+ }
1520+ if (size <= sizeof(obj->b_value)) {
1521+ /* internal default buffer is large enough */
1522+ obj->b_size = size;
1523+ goto done;
1524+ }
1525+ if (obj->b_size <= sizeof(obj->b_value)) {
1526+ /* We are currently using the objects default buffer, but it
1527+ isn't large enough any more. */
1528+ void *ptr = PyMem_Malloc(size);
1529+ if (ptr == NULL)
1530+ return PyErr_NoMemory();
1531+ memset(ptr, 0, size);
1532+ memmove(ptr, obj->b_ptr, obj->b_size);
1533+ obj->b_ptr = ptr;
1534+ obj->b_size = size;
1535+ } else {
1536+ void * ptr = PyMem_Realloc(obj->b_ptr, size);
1537+ if (ptr == NULL)
1538+ return PyErr_NoMemory();
1539+ obj->b_ptr = ptr;
1540+ obj->b_size = size;
1541+ }
1542+ done:
1543+ Py_INCREF(Py_None);
1544+ return Py_None;
1545+}
1546+
1547+PyMethodDef module_methods[] = {
1548+ {"resize", resize, METH_VARARGS, "Resize the memory buffer of a ctypes instance"},
1549+#ifdef CTYPES_UNICODE
1550+ {"set_conversion_mode", set_conversion_mode, METH_VARARGS, set_conversion_mode_doc},
1551+#endif
1552+#ifdef MS_WIN32
1553+ {"CopyComPointer", copy_com_pointer, METH_VARARGS, copy_com_pointer_doc},
1554+ {"FormatError", format_error, METH_VARARGS, format_error_doc},
1555+ {"LoadLibrary", load_library, METH_VARARGS, load_library_doc},
1556+ {"FreeLibrary", free_library, METH_VARARGS, free_library_doc},
1557+ {"call_commethod", call_commethod, METH_VARARGS },
1558+ {"_check_HRESULT", check_hresult, METH_VARARGS},
1559+#else
1560+ {"dlopen", py_dl_open, METH_VARARGS,
1561+ "dlopen(name, flag={RTLD_GLOBAL|RTLD_LOCAL}) open a shared library"},
1562+ {"dlclose", py_dl_close, METH_VARARGS, "dlclose a library"},
1563+ {"dlsym", py_dl_sym, METH_VARARGS, "find symbol in shared library"},
1564+#endif
1565+ {"alignment", align_func, METH_O, alignment_doc},
1566+ {"sizeof", sizeof_func, METH_O, sizeof_doc},
1567+ {"byref", byref, METH_O, byref_doc},
1568+ {"addressof", addressof, METH_O, addressof_doc},
1569+ {"call_function", call_function, METH_VARARGS },
1570+ {"call_cdeclfunction", call_cdeclfunction, METH_VARARGS },
1571+ {"PyObj_FromPtr", My_PyObj_FromPtr, METH_VARARGS },
1572+ {"Py_INCREF", My_Py_INCREF, METH_O },
1573+ {"Py_DECREF", My_Py_DECREF, METH_O },
1574+ {NULL, NULL} /* Sentinel */
1575+};
1576+
1577+/*
1578+ Local Variables:
1579+ compile-command: "cd .. && python setup.py -q build -g && python setup.py -q build install --home ~"
1580+ End:
1581+*/
sys/src/cmd/python/Modules/_ctypes/cfield.c+1668−0
@@ -0,0 +1,1668 @@
1+/*****************************************************************
2+ This file should be kept compatible with Python 2.3, see PEP 291.
3+ *****************************************************************/
4+
5+#include "Python.h"
6+
7+#include <ffi.h>
8+#ifdef MS_WIN32
9+#include <windows.h>
10+#endif
11+#include "ctypes.h"
12+
13+/******************************************************************/
14+/*
15+ CField_Type
16+*/
17+static PyObject *
18+CField_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
19+{
20+ CFieldObject *obj;
21+ obj = (CFieldObject *)type->tp_alloc(type, 0);
22+ return (PyObject *)obj;
23+}
24+
25+/*
26+ * Expects the size, index and offset for the current field in *psize and
27+ * *poffset, stores the total size so far in *psize, the offset for the next
28+ * field in *poffset, the alignment requirements for the current field in
29+ * *palign, and returns a field desriptor for this field.
30+ */
31+/*
32+ * bitfields extension:
33+ * bitsize != 0: this is a bit field.
34+ * pbitofs points to the current bit offset, this will be updated.
35+ * prev_desc points to the type of the previous bitfield, if any.
36+ */
37+PyObject *
38+CField_FromDesc(PyObject *desc, int index,
39+ int *pfield_size, int bitsize, int *pbitofs,
40+ int *psize, int *poffset, int *palign,
41+ int pack, int big_endian)
42+{
43+ CFieldObject *self;
44+ PyObject *proto;
45+ int size, align, length;
46+ SETFUNC setfunc = NULL;
47+ GETFUNC getfunc = NULL;
48+ StgDictObject *dict;
49+ int fieldtype;
50+#define NO_BITFIELD 0
51+#define NEW_BITFIELD 1
52+#define CONT_BITFIELD 2
53+#define EXPAND_BITFIELD 3
54+
55+ self = (CFieldObject *)PyObject_CallObject((PyObject *)&CField_Type,
56+ NULL);
57+ if (self == NULL)
58+ return NULL;
59+ dict = PyType_stgdict(desc);
60+ if (!dict) {
61+ PyErr_SetString(PyExc_TypeError,
62+ "has no _stginfo_");
63+ Py_DECREF(self);
64+ return NULL;
65+ }
66+ if (bitsize /* this is a bitfield request */
67+ && *pfield_size /* we have a bitfield open */
68+#if defined(MS_WIN32) && !defined(__MINGW32__)
69+ && dict->size * 8 == *pfield_size /* MSVC */
70+#else
71+ && dict->size * 8 <= *pfield_size /* GCC, MINGW */
72+#endif
73+ && (*pbitofs + bitsize) <= *pfield_size) {
74+ /* continue bit field */
75+ fieldtype = CONT_BITFIELD;
76+#ifndef MS_WIN32
77+ } else if (bitsize /* this is a bitfield request */
78+ && *pfield_size /* we have a bitfield open */
79+ && dict->size * 8 >= *pfield_size
80+ && (*pbitofs + bitsize) <= dict->size * 8) {
81+ /* expand bit field */
82+ fieldtype = EXPAND_BITFIELD;
83+#endif
84+ } else if (bitsize) {
85+ /* start new bitfield */
86+ fieldtype = NEW_BITFIELD;
87+ *pbitofs = 0;
88+ *pfield_size = dict->size * 8;
89+ } else {
90+ /* not a bit field */
91+ fieldtype = NO_BITFIELD;
92+ *pbitofs = 0;
93+ *pfield_size = 0;
94+ }
95+
96+ size = dict->size;
97+ length = dict->length;
98+ proto = desc;
99+
100+ /* Field descriptors for 'c_char * n' are be scpecial cased to
101+ return a Python string instead of an Array object instance...
102+ */
103+ if (ArrayTypeObject_Check(proto)) {
104+ StgDictObject *adict = PyType_stgdict(proto);
105+ StgDictObject *idict;
106+ if (adict && adict->proto) {
107+ idict = PyType_stgdict(adict->proto);
108+ if (!idict) {
109+ PyErr_SetString(PyExc_TypeError,
110+ "has no _stginfo_");
111+ Py_DECREF(self);
112+ return NULL;
113+ }
114+ if (idict->getfunc == getentry("c")->getfunc) {
115+ struct fielddesc *fd = getentry("s");
116+ getfunc = fd->getfunc;
117+ setfunc = fd->setfunc;
118+ }
119+#ifdef CTYPES_UNICODE
120+ if (idict->getfunc == getentry("u")->getfunc) {
121+ struct fielddesc *fd = getentry("U");
122+ getfunc = fd->getfunc;
123+ setfunc = fd->setfunc;
124+ }
125+#endif
126+ }
127+ }
128+
129+ self->setfunc = setfunc;
130+ self->getfunc = getfunc;
131+ self->index = index;
132+
133+ Py_INCREF(proto);
134+ self->proto = proto;
135+
136+ switch (fieldtype) {
137+ case NEW_BITFIELD:
138+ if (big_endian)
139+ self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize;
140+ else
141+ self->size = (bitsize << 16) + *pbitofs;
142+ *pbitofs = bitsize;
143+ /* fall through */
144+ case NO_BITFIELD:
145+ if (pack)
146+ align = min(pack, dict->align);
147+ else
148+ align = dict->align;
149+ if (align && *poffset % align) {
150+ int delta = align - (*poffset % align);
151+ *psize += delta;
152+ *poffset += delta;
153+ }
154+
155+ if (bitsize == 0)
156+ self->size = size;
157+ *psize += size;
158+
159+ self->offset = *poffset;
160+ *poffset += size;
161+
162+ *palign = align;
163+ break;
164+
165+ case EXPAND_BITFIELD:
166+ /* XXX needs more */
167+ *psize += dict->size - *pfield_size/8;
168+
169+ *pfield_size = dict->size * 8;
170+
171+ if (big_endian)
172+ self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize;
173+ else
174+ self->size = (bitsize << 16) + *pbitofs;
175+
176+ self->offset = *poffset - size; /* poffset is already updated for the NEXT field */
177+ *pbitofs += bitsize;
178+ break;
179+
180+ case CONT_BITFIELD:
181+ if (big_endian)
182+ self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize;
183+ else
184+ self->size = (bitsize << 16) + *pbitofs;
185+
186+ self->offset = *poffset - size; /* poffset is already updated for the NEXT field */
187+ *pbitofs += bitsize;
188+ break;
189+ }
190+
191+ return (PyObject *)self;
192+}
193+
194+static int
195+CField_set(CFieldObject *self, PyObject *inst, PyObject *value)
196+{
197+ CDataObject *dst;
198+ char *ptr;
199+ assert(CDataObject_Check(inst));
200+ dst = (CDataObject *)inst;
201+ ptr = dst->b_ptr + self->offset;
202+ return CData_set(inst, self->proto, self->setfunc, value,
203+ self->index, self->size, ptr);
204+}
205+
206+static PyObject *
207+CField_get(CFieldObject *self, PyObject *inst, PyTypeObject *type)
208+{
209+ CDataObject *src;
210+ if (inst == NULL) {
211+ Py_INCREF(self);
212+ return (PyObject *)self;
213+ }
214+ assert(CDataObject_Check(inst));
215+ src = (CDataObject *)inst;
216+ return CData_get(self->proto, self->getfunc, inst,
217+ self->index, self->size, src->b_ptr + self->offset);
218+}
219+
220+static PyObject *
221+CField_get_offset(PyObject *self, void *data)
222+{
223+#if (PY_VERSION_HEX < 0x02050000)
224+ return PyInt_FromLong(((CFieldObject *)self)->offset);
225+#else
226+ return PyInt_FromSsize_t(((CFieldObject *)self)->offset);
227+#endif
228+}
229+
230+static PyObject *
231+CField_get_size(PyObject *self, void *data)
232+{
233+#if (PY_VERSION_HEX < 0x02050000)
234+ return PyInt_FromLong(((CFieldObject *)self)->size);
235+#else
236+ return PyInt_FromSsize_t(((CFieldObject *)self)->size);
237+#endif
238+}
239+
240+static PyGetSetDef CField_getset[] = {
241+ { "offset", CField_get_offset, NULL, "offset in bytes of this field" },
242+ { "size", CField_get_size, NULL, "size in bytes of this field" },
243+ { NULL, NULL, NULL, NULL },
244+};
245+
246+static int
247+CField_traverse(CFieldObject *self, visitproc visit, void *arg)
248+{
249+ Py_VISIT(self->proto);
250+ return 0;
251+}
252+
253+static int
254+CField_clear(CFieldObject *self)
255+{
256+ Py_CLEAR(self->proto);
257+ return 0;
258+}
259+
260+static void
261+CField_dealloc(PyObject *self)
262+{
263+ CField_clear((CFieldObject *)self);
264+ self->ob_type->tp_free((PyObject *)self);
265+}
266+
267+static PyObject *
268+CField_repr(CFieldObject *self)
269+{
270+ PyObject *result;
271+ int bits = self->size >> 16;
272+ int size = self->size & 0xFFFF;
273+ const char *name;
274+
275+ name = ((PyTypeObject *)self->proto)->tp_name;
276+
277+ if (bits)
278+ result = PyString_FromFormat(
279+#if (PY_VERSION_HEX < 0x02050000)
280+ "<Field type=%s, ofs=%d:%d, bits=%d>",
281+#else
282+ "<Field type=%s, ofs=%zd:%d, bits=%d>",
283+#endif
284+ name, self->offset, size, bits);
285+ else
286+ result = PyString_FromFormat(
287+#if (PY_VERSION_HEX < 0x02050000)
288+ "<Field type=%s, ofs=%d, size=%d>",
289+#else
290+ "<Field type=%s, ofs=%zd, size=%d>",
291+#endif
292+ name, self->offset, size);
293+ return result;
294+}
295+
296+PyTypeObject CField_Type = {
297+ PyObject_HEAD_INIT(NULL)
298+ 0, /* ob_size */
299+ "_ctypes.CField", /* tp_name */
300+ sizeof(CFieldObject), /* tp_basicsize */
301+ 0, /* tp_itemsize */
302+ CField_dealloc, /* tp_dealloc */
303+ 0, /* tp_print */
304+ 0, /* tp_getattr */
305+ 0, /* tp_setattr */
306+ 0, /* tp_compare */
307+ (reprfunc)CField_repr, /* tp_repr */
308+ 0, /* tp_as_number */
309+ 0, /* tp_as_sequence */
310+ 0, /* tp_as_mapping */
311+ 0, /* tp_hash */
312+ 0, /* tp_call */
313+ 0, /* tp_str */
314+ 0, /* tp_getattro */
315+ 0, /* tp_setattro */
316+ 0, /* tp_as_buffer */
317+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
318+ "Structure/Union member", /* tp_doc */
319+ (traverseproc)CField_traverse, /* tp_traverse */
320+ (inquiry)CField_clear, /* tp_clear */
321+ 0, /* tp_richcompare */
322+ 0, /* tp_weaklistoffset */
323+ 0, /* tp_iter */
324+ 0, /* tp_iternext */
325+ 0, /* tp_methods */
326+ 0, /* tp_members */
327+ CField_getset, /* tp_getset */
328+ 0, /* tp_base */
329+ 0, /* tp_dict */
330+ (descrgetfunc)CField_get, /* tp_descr_get */
331+ (descrsetfunc)CField_set, /* tp_descr_set */
332+ 0, /* tp_dictoffset */
333+ 0, /* tp_init */
334+ 0, /* tp_alloc */
335+ CField_new, /* tp_new */
336+ 0, /* tp_free */
337+};
338+
339+
340+/******************************************************************/
341+/*
342+ Accessor functions
343+*/
344+
345+/* Derived from Modules/structmodule.c:
346+ Helper routine to get a Python integer and raise the appropriate error
347+ if it isn't one */
348+
349+static int
350+get_long(PyObject *v, long *p)
351+{
352+ long x;
353+ if (!PyInt_Check(v) && !PyLong_Check(v)) {
354+ PyErr_Format(PyExc_TypeError,
355+ "int expected instead of %s instance",
356+ v->ob_type->tp_name);
357+ return -1;
358+ }
359+ x = PyInt_AsUnsignedLongMask(v);
360+ if (x == -1 && PyErr_Occurred())
361+ return -1;
362+ *p = x;
363+ return 0;
364+}
365+
366+/* Same, but handling unsigned long */
367+
368+static int
369+get_ulong(PyObject *v, unsigned long *p)
370+{
371+ unsigned long x;
372+ if (!PyInt_Check(v) && !PyLong_Check(v)) {
373+ PyErr_Format(PyExc_TypeError,
374+ "int expected instead of %s instance",
375+ v->ob_type->tp_name);
376+ return -1;
377+ }
378+ x = PyInt_AsUnsignedLongMask(v);
379+ if (x == -1 && PyErr_Occurred())
380+ return -1;
381+ *p = x;
382+ return 0;
383+}
384+
385+#ifdef HAVE_LONG_LONG
386+
387+/* Same, but handling native long long. */
388+
389+static int
390+get_longlong(PyObject *v, PY_LONG_LONG *p)
391+{
392+ PY_LONG_LONG x;
393+ if (!PyInt_Check(v) && !PyLong_Check(v)) {
394+ PyErr_Format(PyExc_TypeError,
395+ "int expected instead of %s instance",
396+ v->ob_type->tp_name);
397+ return -1;
398+ }
399+ x = PyInt_AsUnsignedLongLongMask(v);
400+ if (x == -1 && PyErr_Occurred())
401+ return -1;
402+ *p = x;
403+ return 0;
404+}
405+
406+/* Same, but handling native unsigned long long. */
407+
408+static int
409+get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
410+{
411+ unsigned PY_LONG_LONG x;
412+ if (!PyInt_Check(v) && !PyLong_Check(v)) {
413+ PyErr_Format(PyExc_TypeError,
414+ "int expected instead of %s instance",
415+ v->ob_type->tp_name);
416+ return -1;
417+ }
418+ x = PyInt_AsUnsignedLongLongMask(v);
419+ if (x == -1 && PyErr_Occurred())
420+ return -1;
421+ *p = x;
422+ return 0;
423+}
424+
425+#endif
426+
427+/*****************************************************************
428+ * Integer fields, with bitfield support
429+ */
430+
431+/* how to decode the size field, for integer get/set functions */
432+#define LOW_BIT(x) ((x) & 0xFFFF)
433+#define NUM_BITS(x) ((x) >> 16)
434+
435+/* This seems nore a compiler issue than a Windows/non-Windows one */
436+#ifdef MS_WIN32
437+# define BIT_MASK(size) ((1 << NUM_BITS(size))-1)
438+#else
439+# define BIT_MASK(size) ((1LL << NUM_BITS(size))-1)
440+#endif
441+
442+/* This macro CHANGES the first parameter IN PLACE. For proper sign handling,
443+ we must first shift left, then right.
444+*/
445+#define GET_BITFIELD(v, size) \
446+ if (NUM_BITS(size)) { \
447+ v <<= (sizeof(v)*8 - LOW_BIT(size) - NUM_BITS(size)); \
448+ v >>= (sizeof(v)*8 - NUM_BITS(size)); \
449+ }
450+
451+/* This macro RETURNS the first parameter with the bit field CHANGED. */
452+#define SET(x, v, size) \
453+ (NUM_BITS(size) ? \
454+ ( ( x & ~(BIT_MASK(size) << LOW_BIT(size)) ) | ( (v & BIT_MASK(size)) << LOW_BIT(size) ) ) \
455+ : v)
456+
457+/* byte swapping macros */
458+#define SWAP_2(v) \
459+ ( ( (v >> 8) & 0x00FF) | \
460+ ( (v << 8) & 0xFF00) )
461+
462+#define SWAP_4(v) \
463+ ( ( (v & 0x000000FF) << 24 ) | \
464+ ( (v & 0x0000FF00) << 8 ) | \
465+ ( (v & 0x00FF0000) >> 8 ) | \
466+ ( ((v >> 24) & 0xFF)) )
467+
468+#ifdef _MSC_VER
469+#define SWAP_8(v) \
470+ ( ( (v & 0x00000000000000FFL) << 56 ) | \
471+ ( (v & 0x000000000000FF00L) << 40 ) | \
472+ ( (v & 0x0000000000FF0000L) << 24 ) | \
473+ ( (v & 0x00000000FF000000L) << 8 ) | \
474+ ( (v & 0x000000FF00000000L) >> 8 ) | \
475+ ( (v & 0x0000FF0000000000L) >> 24 ) | \
476+ ( (v & 0x00FF000000000000L) >> 40 ) | \
477+ ( ((v >> 56) & 0xFF)) )
478+#else
479+#define SWAP_8(v) \
480+ ( ( (v & 0x00000000000000FFLL) << 56 ) | \
481+ ( (v & 0x000000000000FF00LL) << 40 ) | \
482+ ( (v & 0x0000000000FF0000LL) << 24 ) | \
483+ ( (v & 0x00000000FF000000LL) << 8 ) | \
484+ ( (v & 0x000000FF00000000LL) >> 8 ) | \
485+ ( (v & 0x0000FF0000000000LL) >> 24 ) | \
486+ ( (v & 0x00FF000000000000LL) >> 40 ) | \
487+ ( ((v >> 56) & 0xFF)) )
488+#endif
489+
490+#define SWAP_INT SWAP_4
491+
492+#if SIZEOF_LONG == 4
493+# define SWAP_LONG SWAP_4
494+#elif SIZEOF_LONG == 8
495+# define SWAP_LONG SWAP_8
496+#endif
497+/*****************************************************************
498+ * The setter methods return an object which must be kept alive, to keep the
499+ * data valid which has been stored in the memory block. The ctypes object
500+ * instance inserts this object into its 'b_objects' list.
501+ *
502+ * For simple Python types like integers or characters, there is nothing that
503+ * has to been kept alive, so Py_None is returned in these cases. But this
504+ * makes inspecting the 'b_objects' list, which is accessible from Python for
505+ * debugging, less useful.
506+ *
507+ * So, defining the _CTYPES_DEBUG_KEEP symbol returns the original value
508+ * instead of Py_None.
509+ */
510+
511+#ifdef _CTYPES_DEBUG_KEEP
512+#define _RET(x) Py_INCREF(x); return x
513+#else
514+#define _RET(X) Py_INCREF(Py_None); return Py_None
515+#endif
516+
517+/*****************************************************************
518+ * integer accessor methods, supporting bit fields
519+ */
520+
521+static PyObject *
522+b_set(void *ptr, PyObject *value, unsigned size)
523+{
524+ long val;
525+ if (get_long(value, &val) < 0)
526+ return NULL;
527+ *(signed char *)ptr = (signed char)SET(*(signed char *)ptr, (signed char)val, size);
528+ _RET(value);
529+}
530+
531+
532+static PyObject *
533+b_get(void *ptr, unsigned size)
534+{
535+ signed char val = *(signed char *)ptr;
536+ GET_BITFIELD(val, size);
537+ return PyInt_FromLong(val);
538+}
539+
540+static PyObject *
541+B_set(void *ptr, PyObject *value, unsigned size)
542+{
543+ unsigned long val;
544+ if (get_ulong(value, &val) < 0)
545+ return NULL;
546+ *(unsigned char *)ptr = (unsigned char)SET(*(unsigned char*)ptr,
547+ (unsigned short)val, size);
548+ _RET(value);
549+}
550+
551+
552+static PyObject *
553+B_get(void *ptr, unsigned size)
554+{
555+ unsigned char val = *(unsigned char *)ptr;
556+ GET_BITFIELD(val, size);
557+ return PyInt_FromLong(val);
558+}
559+
560+static PyObject *
561+h_set(void *ptr, PyObject *value, unsigned size)
562+{
563+ long val;
564+ short x;
565+ if (get_long(value, &val) < 0)
566+ return NULL;
567+ memcpy(&x, ptr, sizeof(x));
568+ x = SET(x, (short)val, size);
569+ memcpy(ptr, &x, sizeof(x));
570+ _RET(value);
571+}
572+
573+
574+static PyObject *
575+h_set_sw(void *ptr, PyObject *value, unsigned size)
576+{
577+ long val;
578+ short field;
579+ if (get_long(value, &val) < 0)
580+ return NULL;
581+ memcpy(&field, ptr, sizeof(field));
582+ field = SWAP_2(field);
583+ field = SET(field, (short)val, size);
584+ field = SWAP_2(field);
585+ memcpy(ptr, &field, sizeof(field));
586+ _RET(value);
587+}
588+
589+static PyObject *
590+h_get(void *ptr, unsigned size)
591+{
592+ short val;
593+ memcpy(&val, ptr, sizeof(val));
594+ GET_BITFIELD(val, size);
595+ return PyInt_FromLong((long)val);
596+}
597+
598+static PyObject *
599+h_get_sw(void *ptr, unsigned size)
600+{
601+ short val;
602+ memcpy(&val, ptr, sizeof(val));
603+ val = SWAP_2(val);
604+ GET_BITFIELD(val, size);
605+ return PyInt_FromLong(val);
606+}
607+
608+static PyObject *
609+H_set(void *ptr, PyObject *value, unsigned size)
610+{
611+ unsigned long val;
612+ unsigned short x;
613+ if (get_ulong(value, &val) < 0)
614+ return NULL;
615+ memcpy(&x, ptr, sizeof(x));
616+ x = SET(x, (unsigned short)val, size);
617+ memcpy(ptr, &x, sizeof(x));
618+ _RET(value);
619+}
620+
621+static PyObject *
622+H_set_sw(void *ptr, PyObject *value, unsigned size)
623+{
624+ unsigned long val;
625+ unsigned short field;
626+ if (get_ulong(value, &val) < 0)
627+ return NULL;
628+ memcpy(&field, ptr, sizeof(field));
629+ field = SWAP_2(field);
630+ field = SET(field, (unsigned short)val, size);
631+ field = SWAP_2(field);
632+ memcpy(ptr, &field, sizeof(field));
633+ _RET(value);
634+}
635+
636+
637+static PyObject *
638+H_get(void *ptr, unsigned size)
639+{
640+ unsigned short val;
641+ memcpy(&val, ptr, sizeof(val));
642+ GET_BITFIELD(val, size);
643+ return PyInt_FromLong(val);
644+}
645+
646+static PyObject *
647+H_get_sw(void *ptr, unsigned size)
648+{
649+ unsigned short val;
650+ memcpy(&val, ptr, sizeof(val));
651+ val = SWAP_2(val);
652+ GET_BITFIELD(val, size);
653+ return PyInt_FromLong(val);
654+}
655+
656+static PyObject *
657+i_set(void *ptr, PyObject *value, unsigned size)
658+{
659+ long val;
660+ int x;
661+ if (get_long(value, &val) < 0)
662+ return NULL;
663+ memcpy(&x, ptr, sizeof(x));
664+ x = SET(x, (int)val, size);
665+ memcpy(ptr, &x, sizeof(x));
666+ _RET(value);
667+}
668+
669+static PyObject *
670+i_set_sw(void *ptr, PyObject *value, unsigned size)
671+{
672+ long val;
673+ int field;
674+ if (get_long(value, &val) < 0)
675+ return NULL;
676+ memcpy(&field, ptr, sizeof(field));
677+ field = SWAP_INT(field);
678+ field = SET(field, (int)val, size);
679+ field = SWAP_INT(field);
680+ memcpy(ptr, &field, sizeof(field));
681+ _RET(value);
682+}
683+
684+
685+static PyObject *
686+i_get(void *ptr, unsigned size)
687+{
688+ int val;
689+ memcpy(&val, ptr, sizeof(val));
690+ GET_BITFIELD(val, size);
691+ return PyInt_FromLong(val);
692+}
693+
694+static PyObject *
695+i_get_sw(void *ptr, unsigned size)
696+{
697+ int val;
698+ memcpy(&val, ptr, sizeof(val));
699+ val = SWAP_INT(val);
700+ GET_BITFIELD(val, size);
701+ return PyInt_FromLong(val);
702+}
703+
704+#ifdef MS_WIN32
705+/* short BOOL - VARIANT_BOOL */
706+static PyObject *
707+vBOOL_set(void *ptr, PyObject *value, unsigned size)
708+{
709+ switch (PyObject_IsTrue(value)) {
710+ case -1:
711+ return NULL;
712+ case 0:
713+ *(short int *)ptr = VARIANT_FALSE;
714+ _RET(value);
715+ default:
716+ *(short int *)ptr = VARIANT_TRUE;
717+ _RET(value);
718+ }
719+}
720+
721+static PyObject *
722+vBOOL_get(void *ptr, unsigned size)
723+{
724+ return PyBool_FromLong((long)*(short int *)ptr);
725+}
726+#endif
727+
728+static PyObject *
729+I_set(void *ptr, PyObject *value, unsigned size)
730+{
731+ unsigned long val;
732+ unsigned int x;
733+ if (get_ulong(value, &val) < 0)
734+ return NULL;
735+ memcpy(&x, ptr, sizeof(x));
736+ x = SET(x, (unsigned int)val, size);
737+ memcpy(ptr, &x, sizeof(x));
738+ _RET(value);
739+}
740+
741+static PyObject *
742+I_set_sw(void *ptr, PyObject *value, unsigned size)
743+{
744+ unsigned long val;
745+ unsigned int field;
746+ if (get_ulong(value, &val) < 0)
747+ return NULL;
748+ memcpy(&field, ptr, sizeof(field));
749+ field = (unsigned int)SET(field, (unsigned int)val, size);
750+ field = SWAP_INT(field);
751+ memcpy(ptr, &field, sizeof(field));
752+ _RET(value);
753+}
754+
755+
756+static PyObject *
757+I_get(void *ptr, unsigned size)
758+{
759+ unsigned int val;
760+ memcpy(&val, ptr, sizeof(val));
761+ GET_BITFIELD(val, size);
762+ return PyLong_FromUnsignedLong(val);
763+}
764+
765+static PyObject *
766+I_get_sw(void *ptr, unsigned size)
767+{
768+ unsigned int val;
769+ memcpy(&val, ptr, sizeof(val));
770+ val = SWAP_INT(val);
771+ GET_BITFIELD(val, size);
772+ return PyLong_FromUnsignedLong(val);
773+}
774+
775+static PyObject *
776+l_set(void *ptr, PyObject *value, unsigned size)
777+{
778+ long val;
779+ long x;
780+ if (get_long(value, &val) < 0)
781+ return NULL;
782+ memcpy(&x, ptr, sizeof(x));
783+ x = SET(x, val, size);
784+ memcpy(ptr, &x, sizeof(x));
785+ _RET(value);
786+}
787+
788+static PyObject *
789+l_set_sw(void *ptr, PyObject *value, unsigned size)
790+{
791+ long val;
792+ long field;
793+ if (get_long(value, &val) < 0)
794+ return NULL;
795+ memcpy(&field, ptr, sizeof(field));
796+ field = SWAP_LONG(field);
797+ field = (long)SET(field, val, size);
798+ field = SWAP_LONG(field);
799+ memcpy(ptr, &field, sizeof(field));
800+ _RET(value);
801+}
802+
803+
804+static PyObject *
805+l_get(void *ptr, unsigned size)
806+{
807+ long val;
808+ memcpy(&val, ptr, sizeof(val));
809+ GET_BITFIELD(val, size);
810+ return PyInt_FromLong(val);
811+}
812+
813+static PyObject *
814+l_get_sw(void *ptr, unsigned size)
815+{
816+ long val;
817+ memcpy(&val, ptr, sizeof(val));
818+ val = SWAP_LONG(val);
819+ GET_BITFIELD(val, size);
820+ return PyInt_FromLong(val);
821+}
822+
823+static PyObject *
824+L_set(void *ptr, PyObject *value, unsigned size)
825+{
826+ unsigned long val;
827+ unsigned long x;
828+ if (get_ulong(value, &val) < 0)
829+ return NULL;
830+ memcpy(&x, ptr, sizeof(x));
831+ x = SET(x, val, size);
832+ memcpy(ptr, &x, sizeof(x));
833+ _RET(value);
834+}
835+
836+static PyObject *
837+L_set_sw(void *ptr, PyObject *value, unsigned size)
838+{
839+ unsigned long val;
840+ unsigned long field;
841+ if (get_ulong(value, &val) < 0)
842+ return NULL;
843+ memcpy(&field, ptr, sizeof(field));
844+ field = SWAP_LONG(field);
845+ field = (unsigned long)SET(field, val, size);
846+ field = SWAP_LONG(field);
847+ memcpy(ptr, &field, sizeof(field));
848+ _RET(value);
849+}
850+
851+
852+static PyObject *
853+L_get(void *ptr, unsigned size)
854+{
855+ unsigned long val;
856+ memcpy(&val, ptr, sizeof(val));
857+ GET_BITFIELD(val, size);
858+ return PyLong_FromUnsignedLong(val);
859+}
860+
861+static PyObject *
862+L_get_sw(void *ptr, unsigned size)
863+{
864+ unsigned long val;
865+ memcpy(&val, ptr, sizeof(val));
866+ val = SWAP_LONG(val);
867+ GET_BITFIELD(val, size);
868+ return PyLong_FromUnsignedLong(val);
869+}
870+
871+#ifdef HAVE_LONG_LONG
872+static PyObject *
873+q_set(void *ptr, PyObject *value, unsigned size)
874+{
875+ PY_LONG_LONG val;
876+ PY_LONG_LONG x;
877+ if (get_longlong(value, &val) < 0)
878+ return NULL;
879+ memcpy(&x, ptr, sizeof(x));
880+ x = SET(x, val, size);
881+ memcpy(ptr, &x, sizeof(x));
882+ _RET(value);
883+}
884+
885+static PyObject *
886+q_set_sw(void *ptr, PyObject *value, unsigned size)
887+{
888+ PY_LONG_LONG val;
889+ PY_LONG_LONG field;
890+ if (get_longlong(value, &val) < 0)
891+ return NULL;
892+ memcpy(&field, ptr, sizeof(field));
893+ field = SWAP_8(field);
894+ field = (PY_LONG_LONG)SET(field, val, size);
895+ field = SWAP_8(field);
896+ memcpy(ptr, &field, sizeof(field));
897+ _RET(value);
898+}
899+
900+static PyObject *
901+q_get(void *ptr, unsigned size)
902+{
903+ PY_LONG_LONG val;
904+ memcpy(&val, ptr, sizeof(val));
905+ GET_BITFIELD(val, size);
906+ return PyLong_FromLongLong(val);
907+}
908+
909+static PyObject *
910+q_get_sw(void *ptr, unsigned size)
911+{
912+ PY_LONG_LONG val;
913+ memcpy(&val, ptr, sizeof(val));
914+ val = SWAP_8(val);
915+ GET_BITFIELD(val, size);
916+ return PyLong_FromLongLong(val);
917+}
918+
919+static PyObject *
920+Q_set(void *ptr, PyObject *value, unsigned size)
921+{
922+ unsigned PY_LONG_LONG val;
923+ unsigned PY_LONG_LONG x;
924+ if (get_ulonglong(value, &val) < 0)
925+ return NULL;
926+ memcpy(&x, ptr, sizeof(x));
927+ x = SET(x, val, size);
928+ memcpy(ptr, &x, sizeof(x));
929+ _RET(value);
930+}
931+
932+static PyObject *
933+Q_set_sw(void *ptr, PyObject *value, unsigned size)
934+{
935+ unsigned PY_LONG_LONG val;
936+ unsigned PY_LONG_LONG field;
937+ if (get_ulonglong(value, &val) < 0)
938+ return NULL;
939+ memcpy(&field, ptr, sizeof(field));
940+ field = SWAP_8(field);
941+ field = (unsigned PY_LONG_LONG)SET(field, val, size);
942+ field = SWAP_8(field);
943+ memcpy(ptr, &field, sizeof(field));
944+ _RET(value);
945+}
946+
947+static PyObject *
948+Q_get(void *ptr, unsigned size)
949+{
950+ unsigned PY_LONG_LONG val;
951+ memcpy(&val, ptr, sizeof(val));
952+ GET_BITFIELD(val, size);
953+ return PyLong_FromUnsignedLongLong(val);
954+}
955+
956+static PyObject *
957+Q_get_sw(void *ptr, unsigned size)
958+{
959+ unsigned PY_LONG_LONG val;
960+ memcpy(&val, ptr, sizeof(val));
961+ val = SWAP_8(val);
962+ GET_BITFIELD(val, size);
963+ return PyLong_FromUnsignedLongLong(val);
964+}
965+#endif
966+
967+/*****************************************************************
968+ * non-integer accessor methods, not supporting bit fields
969+ */
970+
971+
972+
973+static PyObject *
974+d_set(void *ptr, PyObject *value, unsigned size)
975+{
976+ double x;
977+
978+ x = PyFloat_AsDouble(value);
979+ if (x == -1 && PyErr_Occurred()) {
980+ PyErr_Format(PyExc_TypeError,
981+ " float expected instead of %s instance",
982+ value->ob_type->tp_name);
983+ return NULL;
984+ }
985+ memcpy(ptr, &x, sizeof(double));
986+ _RET(value);
987+}
988+
989+static PyObject *
990+d_get(void *ptr, unsigned size)
991+{
992+ double val;
993+ memcpy(&val, ptr, sizeof(val));
994+ return PyFloat_FromDouble(val);
995+}
996+
997+static PyObject *
998+d_set_sw(void *ptr, PyObject *value, unsigned size)
999+{
1000+ double x;
1001+
1002+ x = PyFloat_AsDouble(value);
1003+ if (x == -1 && PyErr_Occurred()) {
1004+ PyErr_Format(PyExc_TypeError,
1005+ " float expected instead of %s instance",
1006+ value->ob_type->tp_name);
1007+ return NULL;
1008+ }
1009+#ifdef WORDS_BIGENDIAN
1010+ if (_PyFloat_Pack8(x, (unsigned char *)ptr, 1))
1011+ return NULL;
1012+#else
1013+ if (_PyFloat_Pack8(x, (unsigned char *)ptr, 0))
1014+ return NULL;
1015+#endif
1016+ _RET(value);
1017+}
1018+
1019+static PyObject *
1020+d_get_sw(void *ptr, unsigned size)
1021+{
1022+#ifdef WORDS_BIGENDIAN
1023+ return PyFloat_FromDouble(_PyFloat_Unpack8(ptr, 1));
1024+#else
1025+ return PyFloat_FromDouble(_PyFloat_Unpack8(ptr, 0));
1026+#endif
1027+}
1028+
1029+static PyObject *
1030+f_set(void *ptr, PyObject *value, unsigned size)
1031+{
1032+ float x;
1033+
1034+ x = (float)PyFloat_AsDouble(value);
1035+ if (x == -1 && PyErr_Occurred()) {
1036+ PyErr_Format(PyExc_TypeError,
1037+ " float expected instead of %s instance",
1038+ value->ob_type->tp_name);
1039+ return NULL;
1040+ }
1041+ memcpy(ptr, &x, sizeof(x));
1042+ _RET(value);
1043+}
1044+
1045+static PyObject *
1046+f_get(void *ptr, unsigned size)
1047+{
1048+ float val;
1049+ memcpy(&val, ptr, sizeof(val));
1050+ return PyFloat_FromDouble(val);
1051+}
1052+
1053+static PyObject *
1054+f_set_sw(void *ptr, PyObject *value, unsigned size)
1055+{
1056+ float x;
1057+
1058+ x = (float)PyFloat_AsDouble(value);
1059+ if (x == -1 && PyErr_Occurred()) {
1060+ PyErr_Format(PyExc_TypeError,
1061+ " float expected instead of %s instance",
1062+ value->ob_type->tp_name);
1063+ return NULL;
1064+ }
1065+#ifdef WORDS_BIGENDIAN
1066+ if (_PyFloat_Pack4(x, (unsigned char *)ptr, 1))
1067+ return NULL;
1068+#else
1069+ if (_PyFloat_Pack4(x, (unsigned char *)ptr, 0))
1070+ return NULL;
1071+#endif
1072+ _RET(value);
1073+}
1074+
1075+static PyObject *
1076+f_get_sw(void *ptr, unsigned size)
1077+{
1078+#ifdef WORDS_BIGENDIAN
1079+ return PyFloat_FromDouble(_PyFloat_Unpack4(ptr, 1));
1080+#else
1081+ return PyFloat_FromDouble(_PyFloat_Unpack4(ptr, 0));
1082+#endif
1083+}
1084+
1085+/*
1086+ py_object refcounts:
1087+
1088+ 1. If we have a py_object instance, O_get must Py_INCREF the returned
1089+ object, of course. If O_get is called from a function result, no py_object
1090+ instance is created - so callproc.c::GetResult has to call Py_DECREF.
1091+
1092+ 2. The memory block in py_object owns a refcount. So, py_object must call
1093+ Py_DECREF on destruction. Maybe only when b_needsfree is non-zero.
1094+*/
1095+static PyObject *
1096+O_get(void *ptr, unsigned size)
1097+{
1098+ PyObject *ob = *(PyObject **)ptr;
1099+ if (ob == NULL) {
1100+ if (!PyErr_Occurred())
1101+ /* Set an error if not yet set */
1102+ PyErr_SetString(PyExc_ValueError,
1103+ "PyObject is NULL");
1104+ return NULL;
1105+ }
1106+ Py_INCREF(ob);
1107+ return ob;
1108+}
1109+
1110+static PyObject *
1111+O_set(void *ptr, PyObject *value, unsigned size)
1112+{
1113+ /* Hm, does the memory block need it's own refcount or not? */
1114+ *(PyObject **)ptr = value;
1115+ Py_INCREF(value);
1116+ return value;
1117+}
1118+
1119+
1120+static PyObject *
1121+c_set(void *ptr, PyObject *value, unsigned size)
1122+{
1123+ if (!PyString_Check(value) || (1 != PyString_Size(value))) {
1124+ PyErr_Format(PyExc_TypeError,
1125+ "one character string expected");
1126+ return NULL;
1127+ }
1128+ *(char *)ptr = PyString_AS_STRING(value)[0];
1129+ _RET(value);
1130+}
1131+
1132+
1133+static PyObject *
1134+c_get(void *ptr, unsigned size)
1135+{
1136+ return PyString_FromStringAndSize((char *)ptr, 1);
1137+}
1138+
1139+#ifdef CTYPES_UNICODE
1140+/* u - a single wchar_t character */
1141+static PyObject *
1142+u_set(void *ptr, PyObject *value, unsigned size)
1143+{
1144+ int len;
1145+
1146+ if (PyString_Check(value)) {
1147+ value = PyUnicode_FromEncodedObject(value,
1148+ conversion_mode_encoding,
1149+ conversion_mode_errors);
1150+ if (!value)
1151+ return NULL;
1152+ } else if (!PyUnicode_Check(value)) {
1153+ PyErr_Format(PyExc_TypeError,
1154+ "unicode string expected instead of %s instance",
1155+ value->ob_type->tp_name);
1156+ return NULL;
1157+ } else
1158+ Py_INCREF(value);
1159+
1160+ len = PyUnicode_GET_SIZE(value);
1161+ if (len != 1) {
1162+ Py_DECREF(value);
1163+ PyErr_SetString(PyExc_TypeError,
1164+ "one character unicode string expected");
1165+ return NULL;
1166+ }
1167+
1168+ *(wchar_t *)ptr = PyUnicode_AS_UNICODE(value)[0];
1169+ Py_DECREF(value);
1170+
1171+ _RET(value);
1172+}
1173+
1174+
1175+static PyObject *
1176+u_get(void *ptr, unsigned size)
1177+{
1178+ return PyUnicode_FromWideChar((wchar_t *)ptr, 1);
1179+}
1180+
1181+/* U - a unicode string */
1182+static PyObject *
1183+U_get(void *ptr, unsigned size)
1184+{
1185+ PyObject *result;
1186+ unsigned int len;
1187+ Py_UNICODE *p;
1188+
1189+ size /= sizeof(wchar_t); /* we count character units here, not bytes */
1190+
1191+ result = PyUnicode_FromWideChar((wchar_t *)ptr, size);
1192+ if (!result)
1193+ return NULL;
1194+ /* We need 'result' to be able to count the characters with wcslen,
1195+ since ptr may not be NUL terminated. If the length is smaller (if
1196+ it was actually NUL terminated, we construct a new one and throw
1197+ away the result.
1198+ */
1199+ /* chop off at the first NUL character, if any. */
1200+ p = PyUnicode_AS_UNICODE(result);
1201+ for (len = 0; len < size; ++len)
1202+ if (!p[len])
1203+ break;
1204+
1205+ if (len < size) {
1206+ PyObject *ob = PyUnicode_FromWideChar((wchar_t *)ptr, len);
1207+ Py_DECREF(result);
1208+ return ob;
1209+ }
1210+ return result;
1211+}
1212+
1213+static PyObject *
1214+U_set(void *ptr, PyObject *value, unsigned length)
1215+{
1216+ unsigned int size;
1217+
1218+ /* It's easier to calculate in characters than in bytes */
1219+ length /= sizeof(wchar_t);
1220+
1221+ if (PyString_Check(value)) {
1222+ value = PyUnicode_FromEncodedObject(value,
1223+ conversion_mode_encoding,
1224+ conversion_mode_errors);
1225+ if (!value)
1226+ return NULL;
1227+ } else if (!PyUnicode_Check(value)) {
1228+ PyErr_Format(PyExc_TypeError,
1229+ "unicode string expected instead of %s instance",
1230+ value->ob_type->tp_name);
1231+ return NULL;
1232+ } else
1233+ Py_INCREF(value);
1234+ size = PyUnicode_GET_SIZE(value);
1235+ if (size > length) {
1236+ PyErr_Format(PyExc_ValueError,
1237+ "string too long (%d, maximum length %d)",
1238+ size, length);
1239+ Py_DECREF(value);
1240+ return NULL;
1241+ } else if (size < length-1)
1242+ /* copy terminating NUL character if there is space */
1243+ size += 1;
1244+ PyUnicode_AsWideChar((PyUnicodeObject *)value, (wchar_t *)ptr, size);
1245+ return value;
1246+}
1247+
1248+#endif
1249+
1250+static PyObject *
1251+s_get(void *ptr, unsigned size)
1252+{
1253+ PyObject *result;
1254+
1255+ result = PyString_FromString((char *)ptr);
1256+ if (!result)
1257+ return NULL;
1258+ /* chop off at the first NUL character, if any.
1259+ * On error, result will be deallocated and set to NULL.
1260+ */
1261+ size = min(size, strlen(PyString_AS_STRING(result)));
1262+ if (result->ob_refcnt == 1) {
1263+ /* shorten the result */
1264+ _PyString_Resize(&result, size);
1265+ return result;
1266+ } else
1267+ /* cannot shorten the result */
1268+ return PyString_FromStringAndSize(ptr, size);
1269+}
1270+
1271+static PyObject *
1272+s_set(void *ptr, PyObject *value, unsigned length)
1273+{
1274+ char *data;
1275+ unsigned size;
1276+
1277+ data = PyString_AsString(value);
1278+ if (!data)
1279+ return NULL;
1280+ size = strlen(data);
1281+ if (size < length) {
1282+ /* This will copy the leading NUL character
1283+ * if there is space for it.
1284+ */
1285+ ++size;
1286+ } else if (size > length) {
1287+ PyErr_Format(PyExc_ValueError,
1288+ "string too long (%d, maximum length %d)",
1289+ size, length);
1290+ return NULL;
1291+ }
1292+ /* Also copy the terminating NUL character if there is space */
1293+ memcpy((char *)ptr, data, size);
1294+ _RET(value);
1295+}
1296+
1297+static PyObject *
1298+z_set(void *ptr, PyObject *value, unsigned size)
1299+{
1300+ if (value == Py_None) {
1301+ *(char **)ptr = NULL;
1302+ Py_INCREF(value);
1303+ return value;
1304+ }
1305+ if (PyString_Check(value)) {
1306+ *(char **)ptr = PyString_AS_STRING(value);
1307+ Py_INCREF(value);
1308+ return value;
1309+ } else if (PyUnicode_Check(value)) {
1310+ PyObject *str = PyUnicode_AsEncodedString(value,
1311+ conversion_mode_encoding,
1312+ conversion_mode_errors);
1313+ if (str == NULL)
1314+ return NULL;
1315+ *(char **)ptr = PyString_AS_STRING(str);
1316+ return str;
1317+ } else if (PyInt_Check(value) || PyLong_Check(value)) {
1318+ *(char **)ptr = (char *)PyInt_AsUnsignedLongMask(value);
1319+ _RET(value);
1320+ }
1321+ PyErr_Format(PyExc_TypeError,
1322+ "string or integer address expected instead of %s instance",
1323+ value->ob_type->tp_name);
1324+ return NULL;
1325+}
1326+
1327+static PyObject *
1328+z_get(void *ptr, unsigned size)
1329+{
1330+ /* XXX What about invalid pointers ??? */
1331+ if (*(void **)ptr) {
1332+#if defined(MS_WIN32) && !defined(_WIN32_WCE)
1333+ if (IsBadStringPtrA(*(char **)ptr, -1)) {
1334+ PyErr_Format(PyExc_ValueError,
1335+ "invalid string pointer %p",
1336+ ptr);
1337+ return NULL;
1338+ }
1339+#endif
1340+ return PyString_FromString(*(char **)ptr);
1341+ } else {
1342+ Py_INCREF(Py_None);
1343+ return Py_None;
1344+ }
1345+}
1346+
1347+#ifdef CTYPES_UNICODE
1348+static PyObject *
1349+Z_set(void *ptr, PyObject *value, unsigned size)
1350+{
1351+ if (value == Py_None) {
1352+ *(wchar_t **)ptr = NULL;
1353+ Py_INCREF(value);
1354+ return value;
1355+ }
1356+ if (PyString_Check(value)) {
1357+ value = PyUnicode_FromEncodedObject(value,
1358+ conversion_mode_encoding,
1359+ conversion_mode_errors);
1360+ if (!value)
1361+ return NULL;
1362+ } else if (PyInt_Check(value) || PyLong_Check(value)) {
1363+ *(wchar_t **)ptr = (wchar_t *)PyInt_AsUnsignedLongMask(value);
1364+ Py_INCREF(Py_None);
1365+ return Py_None;
1366+ } else if (!PyUnicode_Check(value)) {
1367+ PyErr_Format(PyExc_TypeError,
1368+ "unicode string or integer address expected instead of %s instance",
1369+ value->ob_type->tp_name);
1370+ return NULL;
1371+ } else
1372+ Py_INCREF(value);
1373+#ifdef HAVE_USABLE_WCHAR_T
1374+ /* HAVE_USABLE_WCHAR_T means that Py_UNICODE and wchar_t is the same
1375+ type. So we can copy directly. Hm, are unicode objects always NUL
1376+ terminated in Python, internally?
1377+ */
1378+ *(wchar_t **)ptr = PyUnicode_AS_UNICODE(value);
1379+ return value;
1380+#else
1381+ {
1382+ /* We must create a wchar_t* buffer from the unicode object,
1383+ and keep it alive */
1384+ PyObject *keep;
1385+ wchar_t *buffer;
1386+
1387+ int size = PyUnicode_GET_SIZE(value);
1388+ size += 1; /* terminating NUL */
1389+ size *= sizeof(wchar_t);
1390+ buffer = (wchar_t *)PyMem_Malloc(size);
1391+ if (!buffer)
1392+ return NULL;
1393+ memset(buffer, 0, size);
1394+ keep = PyCObject_FromVoidPtr(buffer, PyMem_Free);
1395+ if (!keep) {
1396+ PyMem_Free(buffer);
1397+ return NULL;
1398+ }
1399+ *(wchar_t **)ptr = (wchar_t *)buffer;
1400+ if (-1 == PyUnicode_AsWideChar((PyUnicodeObject *)value,
1401+ buffer, PyUnicode_GET_SIZE(value))) {
1402+ Py_DECREF(value);
1403+ Py_DECREF(keep);
1404+ return NULL;
1405+ }
1406+ Py_DECREF(value);
1407+ return keep;
1408+ }
1409+#endif
1410+}
1411+
1412+static PyObject *
1413+Z_get(void *ptr, unsigned size)
1414+{
1415+ wchar_t *p;
1416+ p = *(wchar_t **)ptr;
1417+ if (p)
1418+ return PyUnicode_FromWideChar(p, wcslen(p));
1419+ else {
1420+ Py_INCREF(Py_None);
1421+ return Py_None;
1422+ }
1423+}
1424+#endif
1425+
1426+#ifdef MS_WIN32
1427+static PyObject *
1428+BSTR_set(void *ptr, PyObject *value, unsigned size)
1429+{
1430+ BSTR bstr;
1431+
1432+ /* convert value into a PyUnicodeObject or NULL */
1433+ if (Py_None == value) {
1434+ value = NULL;
1435+ } else if (PyString_Check(value)) {
1436+ value = PyUnicode_FromEncodedObject(value,
1437+ conversion_mode_encoding,
1438+ conversion_mode_errors);
1439+ if (!value)
1440+ return NULL;
1441+ } else if (PyUnicode_Check(value)) {
1442+ Py_INCREF(value); /* for the descref below */
1443+ } else {
1444+ PyErr_Format(PyExc_TypeError,
1445+ "unicode string expected instead of %s instance",
1446+ value->ob_type->tp_name);
1447+ return NULL;
1448+ }
1449+
1450+ /* create a BSTR from value */
1451+ if (value) {
1452+ bstr = SysAllocStringLen(PyUnicode_AS_UNICODE(value),
1453+ PyUnicode_GET_SIZE(value));
1454+ Py_DECREF(value);
1455+ } else
1456+ bstr = NULL;
1457+
1458+ /* free the previous contents, if any */
1459+ if (*(BSTR *)ptr)
1460+ SysFreeString(*(BSTR *)ptr);
1461+
1462+ /* and store it */
1463+ *(BSTR *)ptr = bstr;
1464+
1465+ /* We don't need to keep any other object */
1466+ _RET(value);
1467+}
1468+
1469+
1470+static PyObject *
1471+BSTR_get(void *ptr, unsigned size)
1472+{
1473+ BSTR p;
1474+ p = *(BSTR *)ptr;
1475+ if (p)
1476+ return PyUnicode_FromWideChar(p, SysStringLen(p));
1477+ else {
1478+ /* Hm, it seems NULL pointer and zero length string are the
1479+ same in BSTR, see Don Box, p 81
1480+ */
1481+ Py_INCREF(Py_None);
1482+ return Py_None;
1483+ }
1484+}
1485+#endif
1486+
1487+static PyObject *
1488+P_set(void *ptr, PyObject *value, unsigned size)
1489+{
1490+ void *v;
1491+ if (value == Py_None) {
1492+ *(void **)ptr = NULL;
1493+ _RET(value);
1494+ }
1495+
1496+ if (!PyInt_Check(value) && !PyLong_Check(value)) {
1497+ PyErr_SetString(PyExc_TypeError,
1498+ "cannot be converted to pointer");
1499+ return NULL;
1500+ }
1501+
1502+#if SIZEOF_VOID_P <= SIZEOF_LONG
1503+ v = (void *)PyInt_AsUnsignedLongMask(value);
1504+#else
1505+#ifndef HAVE_LONG_LONG
1506+# error "PyLong_AsVoidPtr: sizeof(void*) > sizeof(long), but no long long"
1507+#elif SIZEOF_LONG_LONG < SIZEOF_VOID_P
1508+# error "PyLong_AsVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)"
1509+#endif
1510+ v = (void *)PyInt_AsUnsignedLongLongMask(value);
1511+#endif
1512+
1513+ if (PyErr_Occurred())
1514+ return NULL;
1515+
1516+ *(void **)ptr = v;
1517+ _RET(value);
1518+}
1519+
1520+static PyObject *
1521+P_get(void *ptr, unsigned size)
1522+{
1523+ if (*(void **)ptr == NULL) {
1524+ Py_INCREF(Py_None);
1525+ return Py_None;
1526+ }
1527+ return PyLong_FromVoidPtr(*(void **)ptr);
1528+}
1529+
1530+static struct fielddesc formattable[] = {
1531+ { 's', s_set, s_get, &ffi_type_pointer},
1532+ { 'b', b_set, b_get, &ffi_type_schar},
1533+ { 'B', B_set, B_get, &ffi_type_uchar},
1534+ { 'c', c_set, c_get, &ffi_type_schar},
1535+ { 'd', d_set, d_get, &ffi_type_double, d_set_sw, d_get_sw},
1536+ { 'f', f_set, f_get, &ffi_type_float, f_set_sw, f_get_sw},
1537+ { 'h', h_set, h_get, &ffi_type_sshort, h_set_sw, h_get_sw},
1538+ { 'H', H_set, H_get, &ffi_type_ushort, H_set_sw, H_get_sw},
1539+ { 'i', i_set, i_get, &ffi_type_sint, i_set_sw, i_get_sw},
1540+ { 'I', I_set, I_get, &ffi_type_uint, I_set_sw, I_get_sw},
1541+/* XXX Hm, sizeof(int) == sizeof(long) doesn't hold on every platform */
1542+/* As soon as we can get rid of the type codes, this is no longer a problem */
1543+#if SIZEOF_LONG == 4
1544+ { 'l', l_set, l_get, &ffi_type_sint, l_set_sw, l_get_sw},
1545+ { 'L', L_set, L_get, &ffi_type_uint, L_set_sw, L_get_sw},
1546+#elif SIZEOF_LONG == 8
1547+ { 'l', l_set, l_get, &ffi_type_slong, l_set_sw, l_get_sw},
1548+ { 'L', L_set, L_get, &ffi_type_ulong, L_set_sw, L_get_sw},
1549+#else
1550+# error
1551+#endif
1552+#ifdef HAVE_LONG_LONG
1553+ { 'q', q_set, q_get, &ffi_type_slong, q_set_sw, q_get_sw},
1554+ { 'Q', Q_set, Q_get, &ffi_type_ulong, Q_set_sw, Q_get_sw},
1555+#endif
1556+ { 'P', P_set, P_get, &ffi_type_pointer},
1557+ { 'z', z_set, z_get, &ffi_type_pointer},
1558+#ifdef CTYPES_UNICODE
1559+ { 'u', u_set, u_get, NULL}, /* ffi_type set later */
1560+ { 'U', U_set, U_get, &ffi_type_pointer},
1561+ { 'Z', Z_set, Z_get, &ffi_type_pointer},
1562+#endif
1563+#ifdef MS_WIN32
1564+ { 'X', BSTR_set, BSTR_get, &ffi_type_pointer},
1565+ { 'v', vBOOL_set, vBOOL_get, &ffi_type_sshort},
1566+#endif
1567+ { 'O', O_set, O_get, &ffi_type_pointer},
1568+ { 0, NULL, NULL, NULL},
1569+};
1570+
1571+/*
1572+ Ideas: Implement VARIANT in this table, using 'V' code.
1573+ Use '?' as code for BOOL.
1574+*/
1575+
1576+struct fielddesc *
1577+getentry(char *fmt)
1578+{
1579+ static int initialized = 0;
1580+ struct fielddesc *table = formattable;
1581+
1582+ if (!initialized) {
1583+ initialized = 1;
1584+#ifdef CTYPES_UNICODE
1585+ if (sizeof(wchar_t) == sizeof(short))
1586+ getentry("u")->pffi_type = &ffi_type_sshort;
1587+ else if (sizeof(wchar_t) == sizeof(int))
1588+ getentry("u")->pffi_type = &ffi_type_sint;
1589+ else if (sizeof(wchar_t) == sizeof(long))
1590+ getentry("u")->pffi_type = &ffi_type_slong;
1591+#endif
1592+ }
1593+
1594+ for (; table->code; ++table) {
1595+ if (table->code == fmt[0])
1596+ return table;
1597+ }
1598+ return NULL;
1599+}
1600+
1601+typedef struct { char c; char x; } s_char;
1602+typedef struct { char c; short x; } s_short;
1603+typedef struct { char c; int x; } s_int;
1604+typedef struct { char c; long x; } s_long;
1605+typedef struct { char c; float x; } s_float;
1606+typedef struct { char c; double x; } s_double;
1607+typedef struct { char c; char *x; } s_char_p;
1608+typedef struct { char c; void *x; } s_void_p;
1609+
1610+/*
1611+#define CHAR_ALIGN (sizeof(s_char) - sizeof(char))
1612+#define SHORT_ALIGN (sizeof(s_short) - sizeof(short))
1613+#define INT_ALIGN (sizeof(s_int) - sizeof(int))
1614+#define LONG_ALIGN (sizeof(s_long) - sizeof(long))
1615+*/
1616+#define FLOAT_ALIGN (sizeof(s_float) - sizeof(float))
1617+#define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double))
1618+/* #define CHAR_P_ALIGN (sizeof(s_char_p) - sizeof(char*)) */
1619+#define VOID_P_ALIGN (sizeof(s_void_p) - sizeof(void*))
1620+
1621+/*
1622+#ifdef HAVE_USABLE_WCHAR_T
1623+typedef struct { char c; wchar_t x; } s_wchar;
1624+typedef struct { char c; wchar_t *x; } s_wchar_p;
1625+
1626+#define WCHAR_ALIGN (sizeof(s_wchar) - sizeof(wchar_t))
1627+#define WCHAR_P_ALIGN (sizeof(s_wchar_p) - sizeof(wchar_t*))
1628+#endif
1629+*/
1630+
1631+#ifdef HAVE_LONG_LONG
1632+typedef struct { char c; PY_LONG_LONG x; } s_long_long;
1633+#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))
1634+#endif
1635+
1636+/* from ffi.h:
1637+typedef struct _ffi_type
1638+{
1639+ size_t size;
1640+ unsigned short alignment;
1641+ unsigned short type;
1642+ struct _ffi_type **elements;
1643+} ffi_type;
1644+*/
1645+
1646+/* align and size are bogus for void, but they must not be zero */
1647+ffi_type ffi_type_void = { 1, 1, FFI_TYPE_VOID };
1648+
1649+ffi_type ffi_type_uint8 = { 1, 1, FFI_TYPE_UINT8 };
1650+ffi_type ffi_type_sint8 = { 1, 1, FFI_TYPE_SINT8 };
1651+
1652+ffi_type ffi_type_uint16 = { 2, 2, FFI_TYPE_UINT16 };
1653+ffi_type ffi_type_sint16 = { 2, 2, FFI_TYPE_SINT16 };
1654+
1655+ffi_type ffi_type_uint32 = { 4, 4, FFI_TYPE_UINT32 };
1656+ffi_type ffi_type_sint32 = { 4, 4, FFI_TYPE_SINT32 };
1657+
1658+ffi_type ffi_type_uint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_UINT64 };
1659+ffi_type ffi_type_sint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_SINT64 };
1660+
1661+ffi_type ffi_type_float = { sizeof(float), FLOAT_ALIGN, FFI_TYPE_FLOAT };
1662+ffi_type ffi_type_double = { sizeof(double), DOUBLE_ALIGN, FFI_TYPE_DOUBLE };
1663+
1664+/* ffi_type ffi_type_longdouble */
1665+
1666+ffi_type ffi_type_pointer = { sizeof(void *), VOID_P_ALIGN, FFI_TYPE_POINTER };
1667+
1668+/*---------------- EOF ----------------*/
sys/src/cmd/python/Modules/_ctypes/ctypes.h+407−0
@@ -0,0 +1,407 @@
1+/*****************************************************************
2+ This file should be kept compatible with Python 2.3, see PEP 291.
3+ *****************************************************************/
4+
5+#if (PY_VERSION_HEX < 0x02050000)
6+typedef int Py_ssize_t;
7+#endif
8+
9+#ifndef MS_WIN32
10+#define max(a, b) ((a) > (b) ? (a) : (b))
11+#define min(a, b) ((a) < (b) ? (a) : (b))
12+
13+#define PARAMFLAG_FIN 0x1
14+#define PARAMFLAG_FOUT 0x2
15+#define PARAMFLAG_FLCID 0x4
16+#endif
17+
18+/*
19+ Backwards compatibility:
20+ Python2.2 used LONG_LONG instead of PY_LONG_LONG
21+*/
22+#if defined(HAVE_LONG_LONG) && !defined(PY_LONG_LONG)
23+#define PY_LONG_LONG LONG_LONG
24+#endif
25+
26+typedef struct tagPyCArgObject PyCArgObject;
27+typedef struct tagCDataObject CDataObject;
28+typedef PyObject *(* GETFUNC)(void *, unsigned size);
29+typedef PyObject *(* SETFUNC)(void *, PyObject *value, unsigned size);
30+typedef PyCArgObject *(* PARAMFUNC)(CDataObject *obj);
31+
32+/* A default buffer in CDataObject, which can be used for small C types. If
33+this buffer is too small, PyMem_Malloc will be called to create a larger one,
34+and this one is not used.
35+
36+Making CDataObject a variable size object would be a better solution, but more
37+difficult in the presence of CFuncPtrObject. Maybe later.
38+*/
39+union value {
40+ char c[16];
41+ short s;
42+ int i;
43+ long l;
44+ float f;
45+ double d;
46+#ifdef HAVE_LONG_LONG
47+ PY_LONG_LONG ll;
48+#endif
49+};
50+
51+/*
52+ Hm. Are there CDataObject's which do not need the b_objects member? In
53+ this case we probably should introduce b_flags to mark it as present... If
54+ b_objects is not present/unused b_length is unneeded as well.
55+*/
56+
57+struct tagCDataObject {
58+ PyObject_HEAD
59+ char *b_ptr; /* pointer to memory block */
60+ int b_needsfree; /* need _we_ free the memory? */
61+ CDataObject *b_base; /* pointer to base object or NULL */
62+ Py_ssize_t b_size; /* size of memory block in bytes */
63+ Py_ssize_t b_length; /* number of references we need */
64+ Py_ssize_t b_index; /* index of this object into base's
65+ b_object list */
66+ PyObject *b_objects; /* dictionary of references we need to keep, or Py_None */
67+ union value b_value;
68+};
69+
70+typedef struct {
71+ ffi_closure *pcl; /* the C callable */
72+ ffi_cif cif;
73+ PyObject *converters;
74+ PyObject *callable;
75+ SETFUNC setfunc;
76+ ffi_type *restype;
77+ ffi_type *atypes[0];
78+} ffi_info;
79+
80+typedef struct {
81+ /* First part identical to tagCDataObject */
82+ PyObject_HEAD
83+ char *b_ptr; /* pointer to memory block */
84+ int b_needsfree; /* need _we_ free the memory? */
85+ CDataObject *b_base; /* pointer to base object or NULL */
86+ Py_ssize_t b_size; /* size of memory block in bytes */
87+ Py_ssize_t b_length; /* number of references we need */
88+ Py_ssize_t b_index; /* index of this object into base's
89+ b_object list */
90+ PyObject *b_objects; /* list of references we need to keep */
91+ union value b_value;
92+ /* end of tagCDataObject, additional fields follow */
93+
94+ ffi_info *thunk;
95+ PyObject *callable;
96+
97+ /* These two fields will override the ones in the type's stgdict if
98+ they are set */
99+ PyObject *converters;
100+ PyObject *argtypes;
101+ PyObject *restype;
102+ PyObject *checker;
103+ PyObject *errcheck;
104+#ifdef MS_WIN32
105+ int index;
106+ GUID *iid;
107+#endif
108+ PyObject *paramflags;
109+} CFuncPtrObject;
110+
111+extern PyTypeObject StgDict_Type;
112+#define StgDict_CheckExact(v) ((v)->ob_type == &StgDict_Type)
113+#define StgDict_Check(v) PyObject_TypeCheck(v, &StgDict_Type)
114+
115+extern int StructUnionType_update_stgdict(PyObject *fields, PyObject *type, int isStruct);
116+extern int PyType_stginfo(PyTypeObject *self, Py_ssize_t *psize, Py_ssize_t *palign, Py_ssize_t *plength);
117+extern int PyObject_stginfo(PyObject *self, Py_ssize_t *psize, Py_ssize_t *palign, Py_ssize_t *plength);
118+
119+
120+
121+extern PyTypeObject CData_Type;
122+#define CDataObject_CheckExact(v) ((v)->ob_type == &CData_Type)
123+#define CDataObject_Check(v) PyObject_TypeCheck(v, &CData_Type)
124+
125+extern PyTypeObject SimpleType_Type;
126+#define SimpleTypeObject_CheckExact(v) ((v)->ob_type == &SimpleType_Type)
127+#define SimpleTypeObject_Check(v) PyObject_TypeCheck(v, &SimpleType_Type)
128+
129+extern PyTypeObject CField_Type;
130+extern struct fielddesc *getentry(char *fmt);
131+
132+
133+extern PyObject *
134+CField_FromDesc(PyObject *desc, int index,
135+ int *pfield_size, int bitsize, int *pbitofs,
136+ int *psize, int *poffset, int *palign,
137+ int pack, int is_big_endian);
138+
139+extern PyObject *CData_AtAddress(PyObject *type, void *buf);
140+extern PyObject *CData_FromBytes(PyObject *type, char *data, Py_ssize_t length);
141+
142+extern PyTypeObject ArrayType_Type;
143+extern PyTypeObject Array_Type;
144+extern PyTypeObject PointerType_Type;
145+extern PyTypeObject Pointer_Type;
146+extern PyTypeObject CFuncPtr_Type;
147+extern PyTypeObject CFuncPtrType_Type;
148+extern PyTypeObject StructType_Type;
149+
150+#define ArrayTypeObject_Check(v) PyObject_TypeCheck(v, &ArrayType_Type)
151+#define ArrayObject_Check(v) PyObject_TypeCheck(v, &Array_Type)
152+#define PointerObject_Check(v) PyObject_TypeCheck(v, &Pointer_Type)
153+#define PointerTypeObject_Check(v) PyObject_TypeCheck(v, &PointerType_Type)
154+#define CFuncPtrObject_Check(v) PyObject_TypeCheck(v, &CFuncPtr_Type)
155+#define CFuncPtrTypeObject_Check(v) PyObject_TypeCheck(v, &CFuncPtrType_Type)
156+#define StructTypeObject_Check(v) PyObject_TypeCheck(v, &StructType_Type)
157+
158+extern PyObject *
159+CreateArrayType(PyObject *itemtype, Py_ssize_t length);
160+
161+extern void init_callbacks_in_module(PyObject *m);
162+
163+extern PyMethodDef module_methods[];
164+
165+extern ffi_info *AllocFunctionCallback(PyObject *callable,
166+ PyObject *converters,
167+ PyObject *restype,
168+ int stdcall);
169+/* a table entry describing a predefined ctypes type */
170+struct fielddesc {
171+ char code;
172+ SETFUNC setfunc;
173+ GETFUNC getfunc;
174+ ffi_type *pffi_type; /* always statically allocated */
175+ SETFUNC setfunc_swapped;
176+ GETFUNC getfunc_swapped;
177+};
178+
179+typedef struct {
180+ PyObject_HEAD
181+ Py_ssize_t offset;
182+ Py_ssize_t size;
183+ Py_ssize_t index; /* Index into CDataObject's
184+ object array */
185+ PyObject *proto; /* a type or NULL */
186+ GETFUNC getfunc; /* getter function if proto is NULL */
187+ SETFUNC setfunc; /* setter function if proto is NULL */
188+ int anonymous;
189+} CFieldObject;
190+
191+/* A subclass of PyDictObject, used as the instance dictionary of ctypes
192+ metatypes */
193+typedef struct {
194+ PyDictObject dict; /* first part identical to PyDictObject */
195+/* The size and align fields are unneeded, they are in ffi_type as well. As
196+ an experiment shows, it's trivial to get rid of them, the only thing to
197+ remember is that in ArrayType_new the ffi_type fields must be filled in -
198+ so far it was unneeded because libffi doesn't support arrays at all
199+ (because they are passed as pointers to function calls anyway). But it's
200+ too much risk to change that now, and there are other fields which doen't
201+ belong into this structure anyway. Maybe in ctypes 2.0... (ctypes 2000?)
202+*/
203+ Py_ssize_t size; /* number of bytes */
204+ Py_ssize_t align; /* alignment requirements */
205+ Py_ssize_t length; /* number of fields */
206+ ffi_type ffi_type_pointer;
207+ PyObject *proto; /* Only for Pointer/ArrayObject */
208+ SETFUNC setfunc; /* Only for simple objects */
209+ GETFUNC getfunc; /* Only for simple objects */
210+ PARAMFUNC paramfunc;
211+
212+ /* Following fields only used by CFuncPtrType_Type instances */
213+ PyObject *argtypes; /* tuple of CDataObjects */
214+ PyObject *converters; /* tuple([t.from_param for t in argtypes]) */
215+ PyObject *restype; /* CDataObject or NULL */
216+ PyObject *checker;
217+ int flags; /* calling convention and such */
218+} StgDictObject;
219+
220+/****************************************************************
221+ StgDictObject fields
222+
223+ setfunc and getfunc is only set for simple data types, it is copied from the
224+ corresponding fielddesc entry. These are functions to set and get the value
225+ in a memory block.
226+ They should probably by used by other types as well.
227+
228+ proto is only used for Pointer and Array types - it points to the item type
229+ object.
230+
231+ Probably all the magic ctypes methods (like from_param) should have C
232+ callable wrappers in the StgDictObject. For simple data type, for example,
233+ the fielddesc table could have entries for C codec from_param functions or
234+ other methods as well, if a subtype overrides this method in Python at
235+ construction time, or assigns to it later, tp_setattro should update the
236+ StgDictObject function to a generic one.
237+
238+ Currently, CFuncPtr types have 'converters' and 'checker' entries in their
239+ type dict. They are only used to cache attributes from other entries, whihc
240+ is wrong.
241+
242+ One use case is the .value attribute that all simple types have. But some
243+ complex structures, like VARIANT, represent a single value also, and should
244+ have this attribute.
245+
246+ Another use case is a _check_retval_ function, which is called when a ctypes
247+ type is used as return type of a function to validate and compute the return
248+ value.
249+
250+ Common ctypes protocol:
251+
252+ - setfunc: store a python value in a memory block
253+ - getfunc: convert data from a memory block into a python value
254+
255+ - checkfunc: validate and convert a return value from a function call
256+ - toparamfunc: convert a python value into a function argument
257+
258+*****************************************************************/
259+
260+/* May return NULL, but does not set an exception! */
261+extern StgDictObject *PyType_stgdict(PyObject *obj);
262+
263+/* May return NULL, but does not set an exception! */
264+extern StgDictObject *PyObject_stgdict(PyObject *self);
265+
266+extern int StgDict_clone(StgDictObject *src, StgDictObject *dst);
267+
268+typedef int(* PPROC)(void);
269+
270+PyObject *_CallProc(PPROC pProc,
271+ PyObject *arguments,
272+#ifdef MS_WIN32
273+ IUnknown *pIUnk,
274+ GUID *iid,
275+#endif
276+ int flags,
277+ PyObject *argtypes,
278+ PyObject *restype,
279+ PyObject *checker);
280+
281+
282+#define FUNCFLAG_STDCALL 0x0
283+#define FUNCFLAG_CDECL 0x1
284+#define FUNCFLAG_HRESULT 0x2
285+#define FUNCFLAG_PYTHONAPI 0x4
286+
287+#define DICTFLAG_FINAL 0x1000
288+
289+struct tagPyCArgObject {
290+ PyObject_HEAD
291+ ffi_type *pffi_type;
292+ char tag;
293+ union {
294+ char c;
295+ char b;
296+ short h;
297+ int i;
298+ long l;
299+#ifdef HAVE_LONG_LONG
300+ PY_LONG_LONG q;
301+#endif
302+ double d;
303+ float f;
304+ void *p;
305+ } value;
306+ PyObject *obj;
307+ int size; /* for the 'V' tag */
308+};
309+
310+extern PyTypeObject PyCArg_Type;
311+extern PyCArgObject *new_CArgObject(void);
312+#define PyCArg_CheckExact(v) ((v)->ob_type == &PyCArg_Type)
313+extern PyCArgObject *new_CArgObject(void);
314+
315+extern PyObject *
316+CData_get(PyObject *type, GETFUNC getfunc, PyObject *src,
317+ Py_ssize_t index, Py_ssize_t size, char *ptr);
318+
319+extern int
320+CData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
321+ Py_ssize_t index, Py_ssize_t size, char *ptr);
322+
323+extern void Extend_Error_Info(PyObject *exc_class, char *fmt, ...);
324+
325+struct basespec {
326+ CDataObject *base;
327+ Py_ssize_t index;
328+ char *adr;
329+};
330+
331+extern char basespec_string[];
332+
333+extern ffi_type *GetType(PyObject *obj);
334+
335+/* exception classes */
336+extern PyObject *PyExc_ArgError;
337+
338+extern char *conversion_mode_encoding;
339+extern char *conversion_mode_errors;
340+
341+/* Python 2.4 macros, which are not available in Python 2.3 */
342+
343+#ifndef Py_CLEAR
344+#define Py_CLEAR(op) \
345+ do { \
346+ if (op) { \
347+ PyObject *tmp = (PyObject *)(op); \
348+ (op) = NULL; \
349+ Py_DECREF(tmp); \
350+ } \
351+ } while (0)
352+#endif
353+
354+#ifndef Py_VISIT
355+/* Utility macro to help write tp_traverse functions.
356+ * To use this macro, the tp_traverse function must name its arguments
357+ * "visit" and "arg". This is intended to keep tp_traverse functions
358+ * looking as much alike as possible.
359+ */
360+#define Py_VISIT(op) \
361+ do { \
362+ if (op) { \
363+ int vret = visit((op), arg); \
364+ if (vret) \
365+ return vret; \
366+ } \
367+ } while (0)
368+#endif
369+
370+/* Python's PyUnicode_*WideChar functions are broken ... */
371+#if defined(Py_USING_UNICODE) && defined(HAVE_WCHAR_H)
372+# define CTYPES_UNICODE
373+#endif
374+
375+
376+#ifdef CTYPES_UNICODE
377+# undef PyUnicode_FromWideChar
378+# define PyUnicode_FromWideChar My_PyUnicode_FromWideChar
379+
380+# undef PyUnicode_AsWideChar
381+# define PyUnicode_AsWideChar My_PyUnicode_AsWideChar
382+
383+extern PyObject *My_PyUnicode_FromWideChar(const wchar_t *, Py_ssize_t);
384+extern int My_PyUnicode_AsWideChar(PyUnicodeObject *, wchar_t *, Py_ssize_t);
385+
386+#endif
387+
388+extern void FreeClosure(void *);
389+extern void *MallocClosure(void);
390+
391+extern void _AddTraceback(char *, char *, int);
392+
393+extern PyObject *CData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr);
394+
395+/* XXX better name needed! */
396+extern int IsSimpleSubType(PyObject *obj);
397+
398+
399+#ifdef MS_WIN32
400+extern PyObject *ComError;
401+#endif
402+
403+/*
404+ Local Variables:
405+ compile-command: "python setup.py -q build install --home ~"
406+ End:
407+*/
sys/src/cmd/python/Modules/_ctypes/ctypes_dlfcn.h+31−0
@@ -0,0 +1,31 @@
1+/*****************************************************************
2+ This file should be kept compatible with Python 2.3, see PEP 291.
3+ *****************************************************************/
4+
5+#ifndef _CTYPES_DLFCN_H_
6+#define _CTYPES_DLFCN_H_
7+
8+#ifdef __cplusplus
9+extern "C" {
10+#endif /* __cplusplus */
11+
12+#ifndef MS_WIN32
13+
14+#include <dlfcn.h>
15+
16+#ifndef CTYPES_DARWIN_DLFCN
17+
18+#define ctypes_dlsym dlsym
19+#define ctypes_dlerror dlerror
20+#define ctypes_dlopen dlopen
21+#define ctypes_dlclose dlclose
22+#define ctypes_dladdr dladdr
23+
24+#endif /* !CTYPES_DARWIN_DLFCN */
25+
26+#endif /* !MS_WIN32 */
27+
28+#ifdef __cplusplus
29+}
30+#endif /* __cplusplus */
31+#endif /* _CTYPES_DLFCN_H_ */
sys/src/cmd/python/Modules/_ctypes/darwin/LICENSE+31−0
@@ -0,0 +1,31 @@
1+Copyright (c) 2002 Jorge Acereda <jacereda@users.sourceforge.net> &
2+ Peter O'Gorman <ogorman@users.sourceforge.net>
3+
4+Portions may be copyright others, see the AUTHORS file included with this
5+distribution.
6+
7+Maintained by Peter O'Gorman <ogorman@users.sourceforge.net>
8+
9+Bug Reports and other queries should go to <ogorman@users.sourceforge.net>
10+
11+
12+Permission is hereby granted, free of charge, to any person obtaining
13+a copy of this software and associated documentation files (the
14+"Software"), to deal in the Software without restriction, including
15+without limitation the rights to use, copy, modify, merge, publish,
16+distribute, sublicense, and/or sell copies of the Software, and to
17+permit persons to whom the Software is furnished to do so, subject to
18+the following conditions:
19+
20+The above copyright notice and this permission notice shall be
21+included in all copies or substantial portions of the Software.
22+
23+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30+
31+
sys/src/cmd/python/Modules/_ctypes/darwin/README+95−0
@@ -0,0 +1,95 @@
1+dlcompat for Darwin
2+=========================
3+
4+This is dlcompat, a small library that emulates the dlopen()
5+interface on top of Darwin's dyld API.
6+
7+dlcompat allows loading a ".dylib" library (as long as the RTLD_LOCAL
8+flag isn't passed to dlopen()). It can be configured to yield a warning
9+when trying to close it (dynamic libraries cannot currently be unloaded).
10+
11+It automatically searches for modules in several directories when no
12+absolute path is specified and the module is not found in the current
13+directory.
14+
15+The paths searched are those specified in the environment variables
16+LD_LIBRARY_PATH and DYLD_LIBRARY_PATH plus /lib, /usr/local/lib and
17+/usr/lib or the path specified in the environment variable
18+DYLD_FALLBACK_LIBRARY_PATH.
19+
20+In the default install the behavior of dlsym is to automatically prepend
21+an underscore to passed in symbol names, this allows easier porting of
22+applications which were written specifically for ELF based lifeforms.
23+
24+Installation
25+--------------
26+Type:
27+ ./configure
28+ make
29+ sudo make install
30+
31+This will compile the source file, generate both a static and shared
32+library called libdl and install it into /usr/local/lib. The header
33+file dlfcn.h will be installed in /usr/local/include.
34+
35+If you want to place the files somewhere else, run
36+
37+ make clean
38+ ./configure --prefix=<prefix>
39+ make
40+ sudo make install
41+
42+where <prefix> is the hierarchy you want to install into, e.g. /usr
43+for /usr/lib and /usr/include (_NOT_ recommended!).
44+
45+To enable debugging output (useful for me), run
46+
47+ make clean
48+ ./configure --enable-debug
49+ make
50+ sudo make install
51+
52+If you want old dlcompat style behavior of not prepending the underscore
53+on calls to dlsym then type:
54+
55+ make clean
56+ ./configure --enable-fink
57+ make
58+ sudo make install
59+
60+Usage
61+-------
62+Software that uses GNU autoconf will likely check for a library called
63+libdl, that's why I named it that way. For software that doesn't find
64+the library on its own, you must add a '-ldl' to the appropriate
65+Makefile (or environment) variable, usually LIBS.
66+
67+If you installed dlcompat into a directory other than /usr/local/lib,
68+you must tell the compiler where to find it. Add '-L<prefix>/lib' to
69+LDFLAGS (or CFLAGS) and '-I<prefix>/include' to CPPFLAGS (or CFLAGS).
70+
71+Notes
72+-----
73+If you are writing new software and plan to have Mac OX X compatibility you
74+should look at the dyld api's in /usr/include/mach-o/dyld.h, rather than
75+using dlcompat, using the native api's is the supported method of loading
76+dynamically on Mac OS X, if you want an small example, look at dlfcn_simple.c,
77+which should help get you started.
78+
79+Also note that the functions in dlcompat are not thread safe, and while it is not
80+POSIX spec compliant, it is about as close to compliance as it is going to get though.
81+
82+You can always get the latest version from opendarwin cvs:
83+
84+ cvs -d :pserver:anonymous@anoncvs.opendarwin.org:/cvs/od login
85+ cvs -z3 -d :pserver:anonymous@anoncvs.opendarwin.org:/cvs/od \
86+ co -d dlcompat proj/dlcompat
87+
88+
89+It is hoped that this library will be useful, and as bug free as possible, if you find
90+any bugs please let us know about them so they can be fixed.
91+
92+Please send bug reports to Peter O'Gorman <ogorman@users.sourceforge.net>
93+
94+Thanks.
95+
sys/src/cmd/python/Modules/_ctypes/darwin/README.ctypes+11−0
@@ -0,0 +1,11 @@
1+The files in this directory are taken from
2+http://www.opendarwin.org/cgi-bin/cvsweb.cgi/~checkout~/proj/dlcompat/
3+
4+The LICENSE in this directory applies to these files.
5+
6+Thomas Heller, Jan 2003
7+
8+These files have been modified so they fall back to the system
9+dlfcn calls if available in libSystem.
10+
11+Bob Ippolito, Feb 2006
sys/src/cmd/python/Modules/_ctypes/darwin/dlfcn.h+84−0
@@ -0,0 +1,84 @@
1+/*
2+Copyright (c) 2002 Jorge Acereda <jacereda@users.sourceforge.net> &
3+ Peter O'Gorman <ogorman@users.sourceforge.net>
4+
5+Portions may be copyright others, see the AUTHORS file included with this
6+distribution.
7+
8+Maintained by Peter O'Gorman <ogorman@users.sourceforge.net>
9+
10+Bug Reports and other queries should go to <ogorman@users.sourceforge.net>
11+
12+Permission is hereby granted, free of charge, to any person obtaining
13+a copy of this software and associated documentation files (the
14+"Software"), to deal in the Software without restriction, including
15+without limitation the rights to use, copy, modify, merge, publish,
16+distribute, sublicense, and/or sell copies of the Software, and to
17+permit persons to whom the Software is furnished to do so, subject to
18+the following conditions:
19+
20+The above copyright notice and this permission notice shall be
21+included in all copies or substantial portions of the Software.
22+
23+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30+*/
31+#ifndef _DLFCN_H_
32+#define _DLFCN_H_
33+
34+#include <AvailabilityMacros.h>
35+
36+#ifdef __cplusplus
37+extern "C" {
38+#endif
39+
40+
41+/*
42+ * Structure filled in by dladdr().
43+ */
44+
45+typedef struct dl_info {
46+ const char *dli_fname; /* Pathname of shared object */
47+ void *dli_fbase; /* Base address of shared object */
48+ const char *dli_sname; /* Name of nearest symbol */
49+ void *dli_saddr; /* Address of nearest symbol */
50+} Dl_info;
51+
52+
53+#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_2
54+#warning CTYPES_DARWIN_DLFCN
55+#define CTYPES_DARWIN_DLFCN
56+extern void * (*ctypes_dlopen)(const char *path, int mode);
57+extern void * (*ctypes_dlsym)(void * handle, const char *symbol);
58+extern const char * (*ctypes_dlerror)(void);
59+extern int (*ctypes_dlclose)(void * handle);
60+extern int (*ctypes_dladdr)(const void *, Dl_info *);
61+#else
62+extern void * dlopen(const char *path, int mode);
63+extern void * dlsym(void * handle, const char *symbol);
64+extern const char * dlerror(void);
65+extern int dlclose(void * handle);
66+extern int dladdr(const void *, Dl_info *);
67+#endif
68+
69+#define RTLD_LAZY 0x1
70+#define RTLD_NOW 0x2
71+#define RTLD_LOCAL 0x4
72+#define RTLD_GLOBAL 0x8
73+#define RTLD_NOLOAD 0x10
74+#define RTLD_NODELETE 0x80
75+
76+/* These are from the Mac OS X 10.4 headers */
77+#define RTLD_NEXT ((void *) -1) /* Search subsequent objects. */
78+#define RTLD_DEFAULT ((void *) -2) /* Use default search algorithm. */
79+
80+#ifdef __cplusplus
81+}
82+#endif
83+
84+#endif /* _DLFCN_H_ */
sys/src/cmd/python/Modules/_ctypes/darwin/dlfcn_simple.c+272−0
@@ -0,0 +1,272 @@
1+/*
2+Copyright (c) 2002 Peter O'Gorman <ogorman@users.sourceforge.net>
3+
4+Permission is hereby granted, free of charge, to any person obtaining
5+a copy of this software and associated documentation files (the
6+"Software"), to deal in the Software without restriction, including
7+without limitation the rights to use, copy, modify, merge, publish,
8+distribute, sublicense, and/or sell copies of the Software, and to
9+permit persons to whom the Software is furnished to do so, subject to
10+the following conditions:
11+
12+The above copyright notice and this permission notice shall be
13+included in all copies or substantial portions of the Software.
14+
15+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22+*/
23+
24+
25+/* Just to prove that it isn't that hard to add Mac calls to your code :)
26+ This works with pretty much everything, including kde3 xemacs and the gimp,
27+ I'd guess that it'd work in at least 95% of cases, use this as your starting
28+ point, rather than the mess that is dlfcn.c, assuming that your code does not
29+ require ref counting or symbol lookups in dependent libraries
30+*/
31+
32+#include <stdio.h>
33+#include <stdlib.h>
34+#include <string.h>
35+#include <sys/types.h>
36+#include <sys/stat.h>
37+#include <stdarg.h>
38+#include <limits.h>
39+#include <mach-o/dyld.h>
40+#include <AvailabilityMacros.h>
41+#include "dlfcn.h"
42+
43+#ifdef CTYPES_DARWIN_DLFCN
44+
45+#define ERR_STR_LEN 256
46+
47+#ifndef MAC_OS_X_VERSION_10_3
48+#define MAC_OS_X_VERSION_10_3 1030
49+#endif
50+
51+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
52+#define DARWIN_HAS_DLOPEN
53+extern void * dlopen(const char *path, int mode) __attribute__((weak_import));
54+extern void * dlsym(void * handle, const char *symbol) __attribute__((weak_import));
55+extern const char * dlerror(void) __attribute__((weak_import));
56+extern int dlclose(void * handle) __attribute__((weak_import));
57+extern int dladdr(const void *, Dl_info *) __attribute__((weak_import));
58+#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 */
59+
60+#ifndef DARWIN_HAS_DLOPEN
61+#define dlopen darwin_dlopen
62+#define dlsym darwin_dlsym
63+#define dlerror darwin_dlerror
64+#define dlclose darwin_dlclose
65+#define dladdr darwin_dladdr
66+#endif
67+
68+void * (*ctypes_dlopen)(const char *path, int mode);
69+void * (*ctypes_dlsym)(void * handle, const char *symbol);
70+const char * (*ctypes_dlerror)(void);
71+int (*ctypes_dlclose)(void * handle);
72+int (*ctypes_dladdr)(const void *, Dl_info *);
73+
74+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3
75+/* Mac OS X 10.3+ has dlopen, so strip all this dead code to avoid warnings */
76+
77+static void *dlsymIntern(void *handle, const char *symbol);
78+
79+static const char *error(int setget, const char *str, ...);
80+
81+/* Set and get the error string for use by dlerror */
82+static const char *error(int setget, const char *str, ...)
83+{
84+ static char errstr[ERR_STR_LEN];
85+ static int err_filled = 0;
86+ const char *retval;
87+ va_list arg;
88+ if (setget == 0)
89+ {
90+ va_start(arg, str);
91+ strncpy(errstr, "dlcompat: ", ERR_STR_LEN);
92+ vsnprintf(errstr + 10, ERR_STR_LEN - 10, str, arg);
93+ va_end(arg);
94+ err_filled = 1;
95+ retval = NULL;
96+ }
97+ else
98+ {
99+ if (!err_filled)
100+ retval = NULL;
101+ else
102+ retval = errstr;
103+ err_filled = 0;
104+ }
105+ return retval;
106+}
107+
108+/* darwin_dlopen */
109+static void *darwin_dlopen(const char *path, int mode)
110+{
111+ void *module = 0;
112+ NSObjectFileImage ofi = 0;
113+ NSObjectFileImageReturnCode ofirc;
114+
115+ /* If we got no path, the app wants the global namespace, use -1 as the marker
116+ in this case */
117+ if (!path)
118+ return (void *)-1;
119+
120+ /* Create the object file image, works for things linked with the -bundle arg to ld */
121+ ofirc = NSCreateObjectFileImageFromFile(path, &ofi);
122+ switch (ofirc)
123+ {
124+ case NSObjectFileImageSuccess:
125+ /* It was okay, so use NSLinkModule to link in the image */
126+ module = NSLinkModule(ofi, path,
127+ NSLINKMODULE_OPTION_RETURN_ON_ERROR
128+ | (mode & RTLD_GLOBAL) ? 0 : NSLINKMODULE_OPTION_PRIVATE
129+ | (mode & RTLD_LAZY) ? 0 : NSLINKMODULE_OPTION_BINDNOW);
130+ NSDestroyObjectFileImage(ofi);
131+ break;
132+ case NSObjectFileImageInappropriateFile:
133+ /* It may have been a dynamic library rather than a bundle, try to load it */
134+ module = (void *)NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR);
135+ break;
136+ default:
137+ /* God knows what we got */
138+ error(0, "Can not open \"%s\"", path);
139+ return 0;
140+ }
141+ if (!module)
142+ error(0, "Can not open \"%s\"", path);
143+ return module;
144+
145+}
146+
147+/* dlsymIntern is used by dlsym to find the symbol */
148+static void *dlsymIntern(void *handle, const char *symbol)
149+{
150+ NSSymbol nssym = 0;
151+ /* If the handle is -1, if is the app global context */
152+ if (handle == (void *)-1)
153+ {
154+ /* Global context, use NSLookupAndBindSymbol */
155+ if (NSIsSymbolNameDefined(symbol))
156+ {
157+ nssym = NSLookupAndBindSymbol(symbol);
158+ }
159+
160+ }
161+ /* Now see if the handle is a struch mach_header* or not, use NSLookupSymbol in image
162+ for libraries, and NSLookupSymbolInModule for bundles */
163+ else
164+ {
165+ /* Check for both possible magic numbers depending on x86/ppc byte order */
166+ if ((((struct mach_header *)handle)->magic == MH_MAGIC) ||
167+ (((struct mach_header *)handle)->magic == MH_CIGAM))
168+ {
169+ if (NSIsSymbolNameDefinedInImage((struct mach_header *)handle, symbol))
170+ {
171+ nssym = NSLookupSymbolInImage((struct mach_header *)handle,
172+ symbol,
173+ NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
174+ | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
175+ }
176+
177+ }
178+ else
179+ {
180+ nssym = NSLookupSymbolInModule(handle, symbol);
181+ }
182+ }
183+ if (!nssym)
184+ {
185+ error(0, "Symbol \"%s\" Not found", symbol);
186+ return NULL;
187+ }
188+ return NSAddressOfSymbol(nssym);
189+}
190+
191+static const char *darwin_dlerror(void)
192+{
193+ return error(1, (char *)NULL);
194+}
195+
196+static int darwin_dlclose(void *handle)
197+{
198+ if ((((struct mach_header *)handle)->magic == MH_MAGIC) ||
199+ (((struct mach_header *)handle)->magic == MH_CIGAM))
200+ {
201+ error(0, "Can't remove dynamic libraries on darwin");
202+ return 0;
203+ }
204+ if (!NSUnLinkModule(handle, 0))
205+ {
206+ error(0, "unable to unlink module %s", NSNameOfModule(handle));
207+ return 1;
208+ }
209+ return 0;
210+}
211+
212+
213+/* dlsym, prepend the underscore and call dlsymIntern */
214+static void *darwin_dlsym(void *handle, const char *symbol)
215+{
216+ static char undersym[257]; /* Saves calls to malloc(3) */
217+ int sym_len = strlen(symbol);
218+ void *value = NULL;
219+ char *malloc_sym = NULL;
220+
221+ if (sym_len < 256)
222+ {
223+ snprintf(undersym, 256, "_%s", symbol);
224+ value = dlsymIntern(handle, undersym);
225+ }
226+ else
227+ {
228+ malloc_sym = malloc(sym_len + 2);
229+ if (malloc_sym)
230+ {
231+ sprintf(malloc_sym, "_%s", symbol);
232+ value = dlsymIntern(handle, malloc_sym);
233+ free(malloc_sym);
234+ }
235+ else
236+ {
237+ error(0, "Unable to allocate memory");
238+ }
239+ }
240+ return value;
241+}
242+
243+static int darwin_dladdr(const void *handle, Dl_info *info) {
244+ return 0;
245+}
246+#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 */
247+
248+#if __GNUC__ < 4
249+#pragma CALL_ON_LOAD ctypes_dlfcn_init
250+#else
251+static void __attribute__ ((constructor)) ctypes_dlfcn_init(void);
252+static
253+#endif
254+void ctypes_dlfcn_init(void) {
255+ if (dlopen != NULL) {
256+ ctypes_dlsym = dlsym;
257+ ctypes_dlopen = dlopen;
258+ ctypes_dlerror = dlerror;
259+ ctypes_dlclose = dlclose;
260+ ctypes_dladdr = dladdr;
261+ } else {
262+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3
263+ ctypes_dlsym = darwin_dlsym;
264+ ctypes_dlopen = darwin_dlopen;
265+ ctypes_dlerror = darwin_dlerror;
266+ ctypes_dlclose = darwin_dlclose;
267+ ctypes_dladdr = darwin_dladdr;
268+#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 */
269+ }
270+}
271+
272+#endif /* CTYPES_DARWIN_DLFCN */
sys/src/cmd/python/Modules/_ctypes/libffi/LICENSE+20−0
@@ -0,0 +1,20 @@
1+libffi - Copyright (c) 1996-2003 Red Hat, Inc.
2+
3+Permission is hereby granted, free of charge, to any person obtaining
4+a copy of this software and associated documentation files (the
5+``Software''), to deal in the Software without restriction, including
6+without limitation the rights to use, copy, modify, merge, publish,
7+distribute, sublicense, and/or sell copies of the Software, and to
8+permit persons to whom the Software is furnished to do so, subject to
9+the following conditions:
10+
11+The above copyright notice and this permission notice shall be included
12+in all copies or substantial portions of the Software.
13+
14+THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
15+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17+IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+OTHER DEALINGS IN THE SOFTWARE.
sys/src/cmd/python/Modules/_ctypes/libffi/README+500−0
@@ -0,0 +1,500 @@
1+This directory contains the libffi package, which is not part of GCC but
2+shipped with GCC as convenience.
3+
4+Status
5+======
6+
7+libffi-2.00 has not been released yet! This is a development snapshot!
8+
9+libffi-1.20 was released on October 5, 1998. Check the libffi web
10+page for updates: <URL:http://sources.redhat.com/libffi/>.
11+
12+
13+What is libffi?
14+===============
15+
16+Compilers for high level languages generate code that follow certain
17+conventions. These conventions are necessary, in part, for separate
18+compilation to work. One such convention is the "calling
19+convention". The "calling convention" is essentially a set of
20+assumptions made by the compiler about where function arguments will
21+be found on entry to a function. A "calling convention" also specifies
22+where the return value for a function is found.
23+
24+Some programs may not know at the time of compilation what arguments
25+are to be passed to a function. For instance, an interpreter may be
26+told at run-time about the number and types of arguments used to call
27+a given function. Libffi can be used in such programs to provide a
28+bridge from the interpreter program to compiled code.
29+
30+The libffi library provides a portable, high level programming
31+interface to various calling conventions. This allows a programmer to
32+call any function specified by a call interface description at run
33+time.
34+
35+Ffi stands for Foreign Function Interface. A foreign function
36+interface is the popular name for the interface that allows code
37+written in one language to call code written in another language. The
38+libffi library really only provides the lowest, machine dependent
39+layer of a fully featured foreign function interface. A layer must
40+exist above libffi that handles type conversions for values passed
41+between the two languages.
42+
43+
44+Supported Platforms and Prerequisites
45+=====================================
46+
47+Libffi has been ported to:
48+
49+ SunOS 4.1.3 & Solaris 2.x (SPARC-V8, SPARC-V9)
50+
51+ Irix 5.3 & 6.2 (System V/o32 & n32)
52+
53+ Intel x86 - Linux (System V ABI)
54+
55+ Alpha - Linux and OSF/1
56+
57+ m68k - Linux (System V ABI)
58+
59+ PowerPC - Linux (System V ABI, Darwin, AIX)
60+
61+ ARM - Linux (System V ABI)
62+
63+Libffi has been tested with the egcs 1.0.2 gcc compiler. Chances are
64+that other versions will work. Libffi has also been built and tested
65+with the SGI compiler tools.
66+
67+On PowerPC, the tests failed (see the note below).
68+
69+You must use GNU make to build libffi. SGI's make will not work.
70+Sun's probably won't either.
71+
72+If you port libffi to another platform, please let me know! I assume
73+that some will be easy (x86 NetBSD), and others will be more difficult
74+(HP).
75+
76+
77+Installing libffi
78+=================
79+
80+[Note: before actually performing any of these installation steps,
81+ you may wish to read the "Platform Specific Notes" below.]
82+
83+First you must configure the distribution for your particular
84+system. Go to the directory you wish to build libffi in and run the
85+"configure" program found in the root directory of the libffi source
86+distribution.
87+
88+You may want to tell configure where to install the libffi library and
89+header files. To do that, use the --prefix configure switch. Libffi
90+will install under /usr/local by default.
91+
92+If you want to enable extra run-time debugging checks use the the
93+--enable-debug configure switch. This is useful when your program dies
94+mysteriously while using libffi.
95+
96+Another useful configure switch is --enable-purify-safety. Using this
97+will add some extra code which will suppress certain warnings when you
98+are using Purify with libffi. Only use this switch when using
99+Purify, as it will slow down the library.
100+
101+Configure has many other options. Use "configure --help" to see them all.
102+
103+Once configure has finished, type "make". Note that you must be using
104+GNU make. SGI's make will not work. Sun's probably won't either.
105+You can ftp GNU make from prep.ai.mit.edu:/pub/gnu.
106+
107+To ensure that libffi is working as advertised, type "make test".
108+
109+To install the library and header files, type "make install".
110+
111+
112+Using libffi
113+============
114+
115+ The Basics
116+ ----------
117+
118+Libffi assumes that you have a pointer to the function you wish to
119+call and that you know the number and types of arguments to pass it,
120+as well as the return type of the function.
121+
122+The first thing you must do is create an ffi_cif object that matches
123+the signature of the function you wish to call. The cif in ffi_cif
124+stands for Call InterFace. To prepare a call interface object, use the
125+following function:
126+
127+ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi,
128+ unsigned int nargs,
129+ ffi_type *rtype, ffi_type **atypes);
130+
131+ CIF is a pointer to the call interface object you wish
132+ to initialize.
133+
134+ ABI is an enum that specifies the calling convention
135+ to use for the call. FFI_DEFAULT_ABI defaults
136+ to the system's native calling convention. Other
137+ ABI's may be used with care. They are system
138+ specific.
139+
140+ NARGS is the number of arguments this function accepts.
141+ libffi does not yet support vararg functions.
142+
143+ RTYPE is a pointer to an ffi_type structure that represents
144+ the return type of the function. Ffi_type objects
145+ describe the types of values. libffi provides
146+ ffi_type objects for many of the native C types:
147+ signed int, unsigned int, signed char, unsigned char,
148+ etc. There is also a pointer ffi_type object and
149+ a void ffi_type. Use &ffi_type_void for functions that
150+ don't return values.
151+
152+ ATYPES is a vector of ffi_type pointers. ARGS must be NARGS long.
153+ If NARGS is 0, this is ignored.
154+
155+
156+ffi_prep_cif will return a status code that you are responsible
157+for checking. It will be one of the following:
158+
159+ FFI_OK - All is good.
160+
161+ FFI_BAD_TYPEDEF - One of the ffi_type objects that ffi_prep_cif
162+ came across is bad.
163+
164+
165+Before making the call, the VALUES vector should be initialized
166+with pointers to the appropriate argument values.
167+
168+To call the the function using the initialized ffi_cif, use the
169+ffi_call function:
170+
171+void ffi_call(ffi_cif *cif, void *fn, void *rvalue, void **avalues);
172+
173+ CIF is a pointer to the ffi_cif initialized specifically
174+ for this function.
175+
176+ FN is a pointer to the function you want to call.
177+
178+ RVALUE is a pointer to a chunk of memory that is to hold the
179+ result of the function call. Currently, it must be
180+ at least one word in size (except for the n32 version
181+ under Irix 6.x, which must be a pointer to an 8 byte
182+ aligned value (a long long). It must also be at least
183+ word aligned (depending on the return type, and the
184+ system's alignment requirements). If RTYPE is
185+ &ffi_type_void, this is ignored. If RVALUE is NULL,
186+ the return value is discarded.
187+
188+ AVALUES is a vector of void* that point to the memory locations
189+ holding the argument values for a call.
190+ If NARGS is 0, this is ignored.
191+
192+
193+If you are expecting a return value from FN it will have been stored
194+at RVALUE.
195+
196+
197+
198+ An Example
199+ ----------
200+
201+Here is a trivial example that calls puts() a few times.
202+
203+ #include <stdio.h>
204+ #include <ffi.h>
205+
206+ int main()
207+ {
208+ ffi_cif cif;
209+ ffi_type *args[1];
210+ void *values[1];
211+ char *s;
212+ int rc;
213+
214+ /* Initialize the argument info vectors */
215+ args[0] = &ffi_type_uint;
216+ values[0] = &s;
217+
218+ /* Initialize the cif */
219+ if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
220+ &ffi_type_uint, args) == FFI_OK)
221+ {
222+ s = "Hello World!";
223+ ffi_call(&cif, puts, &rc, values);
224+ /* rc now holds the result of the call to puts */
225+
226+ /* values holds a pointer to the function's arg, so to
227+ call puts() again all we need to do is change the
228+ value of s */
229+ s = "This is cool!";
230+ ffi_call(&cif, puts, &rc, values);
231+ }
232+
233+ return 0;
234+ }
235+
236+
237+
238+ Aggregate Types
239+ ---------------
240+
241+Although libffi has no special support for unions or bit-fields, it is
242+perfectly happy passing structures back and forth. You must first
243+describe the structure to libffi by creating a new ffi_type object
244+for it. Here is the definition of ffi_type:
245+
246+ typedef struct _ffi_type
247+ {
248+ unsigned size;
249+ short alignment;
250+ short type;
251+ struct _ffi_type **elements;
252+ } ffi_type;
253+
254+All structures must have type set to FFI_TYPE_STRUCT. You may set
255+size and alignment to 0. These will be calculated and reset to the
256+appropriate values by ffi_prep_cif().
257+
258+elements is a NULL terminated array of pointers to ffi_type objects
259+that describe the type of the structure elements. These may, in turn,
260+be structure elements.
261+
262+The following example initializes a ffi_type object representing the
263+tm struct from Linux's time.h:
264+
265+ struct tm {
266+ int tm_sec;
267+ int tm_min;
268+ int tm_hour;
269+ int tm_mday;
270+ int tm_mon;
271+ int tm_year;
272+ int tm_wday;
273+ int tm_yday;
274+ int tm_isdst;
275+ /* Those are for future use. */
276+ long int __tm_gmtoff__;
277+ __const char *__tm_zone__;
278+ };
279+
280+ {
281+ ffi_type tm_type;
282+ ffi_type *tm_type_elements[12];
283+ int i;
284+
285+ tm_type.size = tm_type.alignment = 0;
286+ tm_type.elements = &tm_type_elements;
287+
288+ for (i = 0; i < 9; i++)
289+ tm_type_elements[i] = &ffi_type_sint;
290+
291+ tm_type_elements[9] = &ffi_type_slong;
292+ tm_type_elements[10] = &ffi_type_pointer;
293+ tm_type_elements[11] = NULL;
294+
295+ /* tm_type can now be used to represent tm argument types and
296+ return types for ffi_prep_cif() */
297+ }
298+
299+
300+
301+Platform Specific Notes
302+=======================
303+
304+ Intel x86
305+ ---------
306+
307+There are no known problems with the x86 port.
308+
309+ Sun SPARC - SunOS 4.1.3 & Solaris 2.x
310+ -------------------------------------
311+
312+You must use GNU Make to build libffi on Sun platforms.
313+
314+ MIPS - Irix 5.3 & 6.x
315+ ---------------------
316+
317+Irix 6.2 and better supports three different calling conventions: o32,
318+n32 and n64. Currently, libffi only supports both o32 and n32 under
319+Irix 6.x, but only o32 under Irix 5.3. Libffi will automatically be
320+configured for whichever calling convention it was built for.
321+
322+By default, the configure script will try to build libffi with the GNU
323+development tools. To build libffi with the SGI development tools, set
324+the environment variable CC to either "cc -32" or "cc -n32" before
325+running configure under Irix 6.x (depending on whether you want an o32
326+or n32 library), or just "cc" for Irix 5.3.
327+
328+With the n32 calling convention, when returning structures smaller
329+than 16 bytes, be sure to provide an RVALUE that is 8 byte aligned.
330+Here's one way of forcing this:
331+
332+ double struct_storage[2];
333+ my_small_struct *s = (my_small_struct *) struct_storage;
334+ /* Use s for RVALUE */
335+
336+If you don't do this you are liable to get spurious bus errors.
337+
338+"long long" values are not supported yet.
339+
340+You must use GNU Make to build libffi on SGI platforms.
341+
342+ ARM - System V ABI
343+ ------------------
344+
345+The ARM port was performed on a NetWinder running ARM Linux ELF
346+(2.0.31) and gcc 2.8.1.
347+
348+
349+
350+ PowerPC System V ABI
351+ --------------------
352+
353+There are two `System V ABI's which libffi implements for PowerPC.
354+They differ only in how small structures are returned from functions.
355+
356+In the FFI_SYSV version, structures that are 8 bytes or smaller are
357+returned in registers. This is what GCC does when it is configured
358+for solaris, and is what the System V ABI I have (dated September
359+1995) says.
360+
361+In the FFI_GCC_SYSV version, all structures are returned the same way:
362+by passing a pointer as the first argument to the function. This is
363+what GCC does when it is configured for linux or a generic sysv
364+target.
365+
366+EGCS 1.0.1 (and probably other versions of EGCS/GCC) also has a
367+inconsistency with the SysV ABI: When a procedure is called with many
368+floating-point arguments, some of them get put on the stack. They are
369+all supposed to be stored in double-precision format, even if they are
370+only single-precision, but EGCS stores single-precision arguments as
371+single-precision anyway. This causes one test to fail (the `many
372+arguments' test).
373+
374+
375+What's With The Crazy Comments?
376+===============================
377+
378+You might notice a number of cryptic comments in the code, delimited
379+by /*@ and @*/. These are annotations read by the program LCLint, a
380+tool for statically checking C programs. You can read all about it at
381+<http://larch-www.lcs.mit.edu:8001/larch/lclint/index.html>.
382+
383+
384+History
385+=======
386+
387+1.20 Oct-5-98
388+ Raffaele Sena produces ARM port.
389+
390+1.19 Oct-5-98
391+ Fixed x86 long double and long long return support.
392+ m68k bug fixes from Andreas Schwab.
393+ Patch for DU assembler compatibility for the Alpha from Richard
394+ Henderson.
395+
396+1.18 Apr-17-98
397+ Bug fixes and MIPS configuration changes.
398+
399+1.17 Feb-24-98
400+ Bug fixes and m68k port from Andreas Schwab. PowerPC port from
401+ Geoffrey Keating. Various bug x86, Sparc and MIPS bug fixes.
402+
403+1.16 Feb-11-98
404+ Richard Henderson produces Alpha port.
405+
406+1.15 Dec-4-97
407+ Fixed an n32 ABI bug. New libtool, auto* support.
408+
409+1.14 May-13-97
410+ libtool is now used to generate shared and static libraries.
411+ Fixed a minor portability problem reported by Russ McManus
412+ <mcmanr@eq.gs.com>.
413+
414+1.13 Dec-2-96
415+ Added --enable-purify-safety to keep Purify from complaining
416+ about certain low level code.
417+ Sparc fix for calling functions with < 6 args.
418+ Linux x86 a.out fix.
419+
420+1.12 Nov-22-96
421+ Added missing ffi_type_void, needed for supporting void return
422+ types. Fixed test case for non MIPS machines. Cygnus Support
423+ is now Cygnus Solutions.
424+
425+1.11 Oct-30-96
426+ Added notes about GNU make.
427+
428+1.10 Oct-29-96
429+ Added configuration fix for non GNU compilers.
430+
431+1.09 Oct-29-96
432+ Added --enable-debug configure switch. Clean-ups based on LCLint
433+ feedback. ffi_mips.h is always installed. Many configuration
434+ fixes. Fixed ffitest.c for sparc builds.
435+
436+1.08 Oct-15-96
437+ Fixed n32 problem. Many clean-ups.
438+
439+1.07 Oct-14-96
440+ Gordon Irlam rewrites v8.S again. Bug fixes.
441+
442+1.06 Oct-14-96
443+ Gordon Irlam improved the sparc port.
444+
445+1.05 Oct-14-96
446+ Interface changes based on feedback.
447+
448+1.04 Oct-11-96
449+ Sparc port complete (modulo struct passing bug).
450+
451+1.03 Oct-10-96
452+ Passing struct args, and returning struct values works for
453+ all architectures/calling conventions. Expanded tests.
454+
455+1.02 Oct-9-96
456+ Added SGI n32 support. Fixed bugs in both o32 and Linux support.
457+ Added "make test".
458+
459+1.01 Oct-8-96
460+ Fixed float passing bug in mips version. Restructured some
461+ of the code. Builds cleanly with SGI tools.
462+
463+1.00 Oct-7-96
464+ First release. No public announcement.
465+
466+
467+Authors & Credits
468+=================
469+
470+libffi was written by Anthony Green <green@cygnus.com>.
471+
472+Portions of libffi were derived from Gianni Mariani's free gencall
473+library for Silicon Graphics machines.
474+
475+The closure mechanism was designed and implemented by Kresten Krab
476+Thorup.
477+
478+The Sparc port was derived from code contributed by the fine folks at
479+Visible Decisions Inc <http://www.vdi.com>. Further enhancements were
480+made by Gordon Irlam at Cygnus Solutions <http://www.cygnus.com>.
481+
482+The Alpha port was written by Richard Henderson at Cygnus Solutions.
483+
484+Andreas Schwab ported libffi to m68k Linux and provided a number of
485+bug fixes.
486+
487+Geoffrey Keating ported libffi to the PowerPC.
488+
489+Raffaele Sena ported libffi to the ARM.
490+
491+Jesper Skov and Andrew Haley both did more than their fair share of
492+stepping through the code and tracking down bugs.
493+
494+Thanks also to Tom Tromey for bug fixes and configuration help.
495+
496+Thanks to Jim Blandy, who provided some useful feedback on the libffi
497+interface.
498+
499+If you have a problem, or have found a bug, please send a note to
500+green@cygnus.com.
sys/src/cmd/python/Modules/_ctypes/libffi/aclocal.m4+92−0
@@ -0,0 +1,92 @@
1+# mmap(2) blacklisting. Some platforms provide the mmap library routine
2+# but don't support all of the features we need from it.
3+AC_DEFUN([AC_FUNC_MMAP_BLACKLIST],
4+[
5+AC_CHECK_HEADER([sys/mman.h],
6+ [libffi_header_sys_mman_h=yes], [libffi_header_sys_mman_h=no])
7+AC_CHECK_FUNC([mmap], [libffi_func_mmap=yes], [libffi_func_mmap=no])
8+if test "$libffi_header_sys_mman_h" != yes \
9+ || test "$libffi_func_mmap" != yes; then
10+ ac_cv_func_mmap_file=no
11+ ac_cv_func_mmap_dev_zero=no
12+ ac_cv_func_mmap_anon=no
13+else
14+ AC_CACHE_CHECK([whether read-only mmap of a plain file works],
15+ ac_cv_func_mmap_file,
16+ [# Add a system to this blacklist if
17+ # mmap(0, stat_size, PROT_READ, MAP_PRIVATE, fd, 0) doesn't return a
18+ # memory area containing the same data that you'd get if you applied
19+ # read() to the same fd. The only system known to have a problem here
20+ # is VMS, where text files have record structure.
21+ case "$host_os" in
22+ vms* | ultrix*)
23+ ac_cv_func_mmap_file=no ;;
24+ *)
25+ ac_cv_func_mmap_file=yes;;
26+ esac])
27+ AC_CACHE_CHECK([whether mmap from /dev/zero works],
28+ ac_cv_func_mmap_dev_zero,
29+ [# Add a system to this blacklist if it has mmap() but /dev/zero
30+ # does not exist, or if mmapping /dev/zero does not give anonymous
31+ # zeroed pages with both the following properties:
32+ # 1. If you map N consecutive pages in with one call, and then
33+ # unmap any subset of those pages, the pages that were not
34+ # explicitly unmapped remain accessible.
35+ # 2. If you map two adjacent blocks of memory and then unmap them
36+ # both at once, they must both go away.
37+ # Systems known to be in this category are Windows (all variants),
38+ # VMS, and Darwin.
39+ case "$host_os" in
40+ vms* | cygwin* | pe | mingw* | darwin* | ultrix* | hpux10* | hpux11.00)
41+ ac_cv_func_mmap_dev_zero=no ;;
42+ *)
43+ ac_cv_func_mmap_dev_zero=yes;;
44+ esac])
45+
46+ # Unlike /dev/zero, the MAP_ANON(YMOUS) defines can be probed for.
47+ AC_CACHE_CHECK([for MAP_ANON(YMOUS)], ac_cv_decl_map_anon,
48+ [AC_TRY_COMPILE(
49+[#include <sys/types.h>
50+#include <sys/mman.h>
51+#include <unistd.h>
52+
53+#ifndef MAP_ANONYMOUS
54+#define MAP_ANONYMOUS MAP_ANON
55+#endif
56+],
57+[int n = MAP_ANONYMOUS;],
58+ ac_cv_decl_map_anon=yes,
59+ ac_cv_decl_map_anon=no)])
60+
61+ if test $ac_cv_decl_map_anon = no; then
62+ ac_cv_func_mmap_anon=no
63+ else
64+ AC_CACHE_CHECK([whether mmap with MAP_ANON(YMOUS) works],
65+ ac_cv_func_mmap_anon,
66+ [# Add a system to this blacklist if it has mmap() and MAP_ANON or
67+ # MAP_ANONYMOUS, but using mmap(..., MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
68+ # doesn't give anonymous zeroed pages with the same properties listed
69+ # above for use of /dev/zero.
70+ # Systems known to be in this category are Windows, VMS, and SCO Unix.
71+ case "$host_os" in
72+ vms* | cygwin* | pe | mingw* | sco* | udk* )
73+ ac_cv_func_mmap_anon=no ;;
74+ *)
75+ ac_cv_func_mmap_anon=yes;;
76+ esac])
77+ fi
78+fi
79+
80+if test $ac_cv_func_mmap_file = yes; then
81+ AC_DEFINE(HAVE_MMAP_FILE, 1,
82+ [Define if read-only mmap of a plain file works.])
83+fi
84+if test $ac_cv_func_mmap_dev_zero = yes; then
85+ AC_DEFINE(HAVE_MMAP_DEV_ZERO, 1,
86+ [Define if mmap of /dev/zero works.])
87+fi
88+if test $ac_cv_func_mmap_anon = yes; then
89+ AC_DEFINE(HAVE_MMAP_ANON, 1,
90+ [Define if mmap with MAP_ANON(YMOUS) works.])
91+fi
92+])
sys/src/cmd/python/Modules/_ctypes/libffi/config.guess+1453−0
@@ -0,0 +1,1453 @@
1+#! /bin/sh
2+# Attempt to guess a canonical system name.
3+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
4+# 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
5+
6+timestamp='2004-11-12'
7+
8+# This file is free software; you can redistribute it and/or modify it
9+# under the terms of the GNU General Public License as published by
10+# the Free Software Foundation; either version 2 of the License, or
11+# (at your option) any later version.
12+#
13+# This program is distributed in the hope that it will be useful, but
14+# WITHOUT ANY WARRANTY; without even the implied warranty of
15+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16+# General Public License for more details.
17+#
18+# You should have received a copy of the GNU General Public License
19+# along with this program; if not, write to the Free Software
20+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21+#
22+# As a special exception to the GNU General Public License, if you
23+# distribute this file as part of a program that contains a
24+# configuration script generated by Autoconf, you may include it under
25+# the same distribution terms that you use for the rest of that program.
26+
27+# Originally written by Per Bothner <per@bothner.com>.
28+# Please send patches to <config-patches@gnu.org>. Submit a context
29+# diff and a properly formatted ChangeLog entry.
30+#
31+# This script attempts to guess a canonical system name similar to
32+# config.sub. If it succeeds, it prints the system name on stdout, and
33+# exits with 0. Otherwise, it exits with 1.
34+#
35+# The plan is that this can be called by configure scripts if you
36+# don't specify an explicit build system type.
37+
38+me=`echo "$0" | sed -e 's,.*/,,'`
39+
40+usage="\
41+Usage: $0 [OPTION]
42+
43+Output the configuration name of the system \`$me' is run on.
44+
45+Operation modes:
46+ -h, --help print this help, then exit
47+ -t, --time-stamp print date of last modification, then exit
48+ -v, --version print version number, then exit
49+
50+Report bugs and patches to <config-patches@gnu.org>."
51+
52+version="\
53+GNU config.guess ($timestamp)
54+
55+Originally written by Per Bothner.
56+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
57+Free Software Foundation, Inc.
58+
59+This is free software; see the source for copying conditions. There is NO
60+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
61+
62+help="
63+Try \`$me --help' for more information."
64+
65+# Parse command line
66+while test $# -gt 0 ; do
67+ case $1 in
68+ --time-stamp | --time* | -t )
69+ echo "$timestamp" ; exit 0 ;;
70+ --version | -v )
71+ echo "$version" ; exit 0 ;;
72+ --help | --h* | -h )
73+ echo "$usage"; exit 0 ;;
74+ -- ) # Stop option processing
75+ shift; break ;;
76+ - ) # Use stdin as input.
77+ break ;;
78+ -* )
79+ echo "$me: invalid option $1$help" >&2
80+ exit 1 ;;
81+ * )
82+ break ;;
83+ esac
84+done
85+
86+if test $# != 0; then
87+ echo "$me: too many arguments$help" >&2
88+ exit 1
89+fi
90+
91+trap 'exit 1' 1 2 15
92+
93+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
94+# compiler to aid in system detection is discouraged as it requires
95+# temporary files to be created and, as you can see below, it is a
96+# headache to deal with in a portable fashion.
97+
98+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
99+# use `HOST_CC' if defined, but it is deprecated.
100+
101+# Portable tmp directory creation inspired by the Autoconf team.
102+
103+set_cc_for_build='
104+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
105+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
106+: ${TMPDIR=/tmp} ;
107+ { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
108+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
109+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
110+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
111+dummy=$tmp/dummy ;
112+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
113+case $CC_FOR_BUILD,$HOST_CC,$CC in
114+ ,,) echo "int x;" > $dummy.c ;
115+ for c in cc gcc c89 c99 ; do
116+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
117+ CC_FOR_BUILD="$c"; break ;
118+ fi ;
119+ done ;
120+ if test x"$CC_FOR_BUILD" = x ; then
121+ CC_FOR_BUILD=no_compiler_found ;
122+ fi
123+ ;;
124+ ,,*) CC_FOR_BUILD=$CC ;;
125+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
126+esac ;'
127+
128+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
129+# (ghazi@noc.rutgers.edu 1994-08-24)
130+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
131+ PATH=$PATH:/.attbin ; export PATH
132+fi
133+
134+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
135+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
136+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
137+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
138+
139+# Note: order is significant - the case branches are not exclusive.
140+
141+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
142+ *:NetBSD:*:*)
143+ # NetBSD (nbsd) targets should (where applicable) match one or
144+ # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
145+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
146+ # switched to ELF, *-*-netbsd* would select the old
147+ # object file format. This provides both forward
148+ # compatibility and a consistent mechanism for selecting the
149+ # object file format.
150+ #
151+ # Note: NetBSD doesn't particularly care about the vendor
152+ # portion of the name. We always set it to "unknown".
153+ sysctl="sysctl -n hw.machine_arch"
154+ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
155+ /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
156+ case "${UNAME_MACHINE_ARCH}" in
157+ armeb) machine=armeb-unknown ;;
158+ arm*) machine=arm-unknown ;;
159+ sh3el) machine=shl-unknown ;;
160+ sh3eb) machine=sh-unknown ;;
161+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
162+ esac
163+ # The Operating System including object format, if it has switched
164+ # to ELF recently, or will in the future.
165+ case "${UNAME_MACHINE_ARCH}" in
166+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
167+ eval $set_cc_for_build
168+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
169+ | grep __ELF__ >/dev/null
170+ then
171+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
172+ # Return netbsd for either. FIX?
173+ os=netbsd
174+ else
175+ os=netbsdelf
176+ fi
177+ ;;
178+ *)
179+ os=netbsd
180+ ;;
181+ esac
182+ # The OS release
183+ # Debian GNU/NetBSD machines have a different userland, and
184+ # thus, need a distinct triplet. However, they do not need
185+ # kernel version information, so it can be replaced with a
186+ # suitable tag, in the style of linux-gnu.
187+ case "${UNAME_VERSION}" in
188+ Debian*)
189+ release='-gnu'
190+ ;;
191+ *)
192+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
193+ ;;
194+ esac
195+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
196+ # contains redundant information, the shorter form:
197+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
198+ echo "${machine}-${os}${release}"
199+ exit 0 ;;
200+ amd64:OpenBSD:*:*)
201+ echo x86_64-unknown-openbsd${UNAME_RELEASE}
202+ exit 0 ;;
203+ amiga:OpenBSD:*:*)
204+ echo m68k-unknown-openbsd${UNAME_RELEASE}
205+ exit 0 ;;
206+ cats:OpenBSD:*:*)
207+ echo arm-unknown-openbsd${UNAME_RELEASE}
208+ exit 0 ;;
209+ hp300:OpenBSD:*:*)
210+ echo m68k-unknown-openbsd${UNAME_RELEASE}
211+ exit 0 ;;
212+ luna88k:OpenBSD:*:*)
213+ echo m88k-unknown-openbsd${UNAME_RELEASE}
214+ exit 0 ;;
215+ mac68k:OpenBSD:*:*)
216+ echo m68k-unknown-openbsd${UNAME_RELEASE}
217+ exit 0 ;;
218+ macppc:OpenBSD:*:*)
219+ echo powerpc-unknown-openbsd${UNAME_RELEASE}
220+ exit 0 ;;
221+ mvme68k:OpenBSD:*:*)
222+ echo m68k-unknown-openbsd${UNAME_RELEASE}
223+ exit 0 ;;
224+ mvme88k:OpenBSD:*:*)
225+ echo m88k-unknown-openbsd${UNAME_RELEASE}
226+ exit 0 ;;
227+ mvmeppc:OpenBSD:*:*)
228+ echo powerpc-unknown-openbsd${UNAME_RELEASE}
229+ exit 0 ;;
230+ sgi:OpenBSD:*:*)
231+ echo mips64-unknown-openbsd${UNAME_RELEASE}
232+ exit 0 ;;
233+ sun3:OpenBSD:*:*)
234+ echo m68k-unknown-openbsd${UNAME_RELEASE}
235+ exit 0 ;;
236+ *:OpenBSD:*:*)
237+ echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
238+ exit 0 ;;
239+ *:ekkoBSD:*:*)
240+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
241+ exit 0 ;;
242+ macppc:MirBSD:*:*)
243+ echo powerppc-unknown-mirbsd${UNAME_RELEASE}
244+ exit 0 ;;
245+ *:MirBSD:*:*)
246+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
247+ exit 0 ;;
248+ alpha:OSF1:*:*)
249+ case $UNAME_RELEASE in
250+ *4.0)
251+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
252+ ;;
253+ *5.*)
254+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
255+ ;;
256+ esac
257+ # According to Compaq, /usr/sbin/psrinfo has been available on
258+ # OSF/1 and Tru64 systems produced since 1995. I hope that
259+ # covers most systems running today. This code pipes the CPU
260+ # types through head -n 1, so we only detect the type of CPU 0.
261+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
262+ case "$ALPHA_CPU_TYPE" in
263+ "EV4 (21064)")
264+ UNAME_MACHINE="alpha" ;;
265+ "EV4.5 (21064)")
266+ UNAME_MACHINE="alpha" ;;
267+ "LCA4 (21066/21068)")
268+ UNAME_MACHINE="alpha" ;;
269+ "EV5 (21164)")
270+ UNAME_MACHINE="alphaev5" ;;
271+ "EV5.6 (21164A)")
272+ UNAME_MACHINE="alphaev56" ;;
273+ "EV5.6 (21164PC)")
274+ UNAME_MACHINE="alphapca56" ;;
275+ "EV5.7 (21164PC)")
276+ UNAME_MACHINE="alphapca57" ;;
277+ "EV6 (21264)")
278+ UNAME_MACHINE="alphaev6" ;;
279+ "EV6.7 (21264A)")
280+ UNAME_MACHINE="alphaev67" ;;
281+ "EV6.8CB (21264C)")
282+ UNAME_MACHINE="alphaev68" ;;
283+ "EV6.8AL (21264B)")
284+ UNAME_MACHINE="alphaev68" ;;
285+ "EV6.8CX (21264D)")
286+ UNAME_MACHINE="alphaev68" ;;
287+ "EV6.9A (21264/EV69A)")
288+ UNAME_MACHINE="alphaev69" ;;
289+ "EV7 (21364)")
290+ UNAME_MACHINE="alphaev7" ;;
291+ "EV7.9 (21364A)")
292+ UNAME_MACHINE="alphaev79" ;;
293+ esac
294+ # A Pn.n version is a patched version.
295+ # A Vn.n version is a released version.
296+ # A Tn.n version is a released field test version.
297+ # A Xn.n version is an unreleased experimental baselevel.
298+ # 1.2 uses "1.2" for uname -r.
299+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
300+ exit 0 ;;
301+ Alpha\ *:Windows_NT*:*)
302+ # How do we know it's Interix rather than the generic POSIX subsystem?
303+ # Should we change UNAME_MACHINE based on the output of uname instead
304+ # of the specific Alpha model?
305+ echo alpha-pc-interix
306+ exit 0 ;;
307+ 21064:Windows_NT:50:3)
308+ echo alpha-dec-winnt3.5
309+ exit 0 ;;
310+ Amiga*:UNIX_System_V:4.0:*)
311+ echo m68k-unknown-sysv4
312+ exit 0;;
313+ *:[Aa]miga[Oo][Ss]:*:*)
314+ echo ${UNAME_MACHINE}-unknown-amigaos
315+ exit 0 ;;
316+ *:[Mm]orph[Oo][Ss]:*:*)
317+ echo ${UNAME_MACHINE}-unknown-morphos
318+ exit 0 ;;
319+ *:OS/390:*:*)
320+ echo i370-ibm-openedition
321+ exit 0 ;;
322+ *:z/VM:*:*)
323+ echo s390-ibm-zvmoe
324+ exit 0 ;;
325+ *:OS400:*:*)
326+ echo powerpc-ibm-os400
327+ exit 0 ;;
328+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
329+ echo arm-acorn-riscix${UNAME_RELEASE}
330+ exit 0;;
331+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
332+ echo hppa1.1-hitachi-hiuxmpp
333+ exit 0;;
334+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
335+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
336+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
337+ echo pyramid-pyramid-sysv3
338+ else
339+ echo pyramid-pyramid-bsd
340+ fi
341+ exit 0 ;;
342+ NILE*:*:*:dcosx)
343+ echo pyramid-pyramid-svr4
344+ exit 0 ;;
345+ DRS?6000:unix:4.0:6*)
346+ echo sparc-icl-nx6
347+ exit 0 ;;
348+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
349+ case `/usr/bin/uname -p` in
350+ sparc) echo sparc-icl-nx7 && exit 0 ;;
351+ esac ;;
352+ sun4H:SunOS:5.*:*)
353+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
354+ exit 0 ;;
355+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
356+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
357+ exit 0 ;;
358+ i86pc:SunOS:5.*:*)
359+ echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
360+ exit 0 ;;
361+ sun4*:SunOS:6*:*)
362+ # According to config.sub, this is the proper way to canonicalize
363+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
364+ # it's likely to be more like Solaris than SunOS4.
365+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
366+ exit 0 ;;
367+ sun4*:SunOS:*:*)
368+ case "`/usr/bin/arch -k`" in
369+ Series*|S4*)
370+ UNAME_RELEASE=`uname -v`
371+ ;;
372+ esac
373+ # Japanese Language versions have a version number like `4.1.3-JL'.
374+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
375+ exit 0 ;;
376+ sun3*:SunOS:*:*)
377+ echo m68k-sun-sunos${UNAME_RELEASE}
378+ exit 0 ;;
379+ sun*:*:4.2BSD:*)
380+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
381+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
382+ case "`/bin/arch`" in
383+ sun3)
384+ echo m68k-sun-sunos${UNAME_RELEASE}
385+ ;;
386+ sun4)
387+ echo sparc-sun-sunos${UNAME_RELEASE}
388+ ;;
389+ esac
390+ exit 0 ;;
391+ aushp:SunOS:*:*)
392+ echo sparc-auspex-sunos${UNAME_RELEASE}
393+ exit 0 ;;
394+ # The situation for MiNT is a little confusing. The machine name
395+ # can be virtually everything (everything which is not
396+ # "atarist" or "atariste" at least should have a processor
397+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
398+ # to the lowercase version "mint" (or "freemint"). Finally
399+ # the system name "TOS" denotes a system which is actually not
400+ # MiNT. But MiNT is downward compatible to TOS, so this should
401+ # be no problem.
402+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
403+ echo m68k-atari-mint${UNAME_RELEASE}
404+ exit 0 ;;
405+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
406+ echo m68k-atari-mint${UNAME_RELEASE}
407+ exit 0 ;;
408+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
409+ echo m68k-atari-mint${UNAME_RELEASE}
410+ exit 0 ;;
411+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
412+ echo m68k-milan-mint${UNAME_RELEASE}
413+ exit 0 ;;
414+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
415+ echo m68k-hades-mint${UNAME_RELEASE}
416+ exit 0 ;;
417+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
418+ echo m68k-unknown-mint${UNAME_RELEASE}
419+ exit 0 ;;
420+ m68k:machten:*:*)
421+ echo m68k-apple-machten${UNAME_RELEASE}
422+ exit 0 ;;
423+ powerpc:machten:*:*)
424+ echo powerpc-apple-machten${UNAME_RELEASE}
425+ exit 0 ;;
426+ RISC*:Mach:*:*)
427+ echo mips-dec-mach_bsd4.3
428+ exit 0 ;;
429+ RISC*:ULTRIX:*:*)
430+ echo mips-dec-ultrix${UNAME_RELEASE}
431+ exit 0 ;;
432+ VAX*:ULTRIX*:*:*)
433+ echo vax-dec-ultrix${UNAME_RELEASE}
434+ exit 0 ;;
435+ 2020:CLIX:*:* | 2430:CLIX:*:*)
436+ echo clipper-intergraph-clix${UNAME_RELEASE}
437+ exit 0 ;;
438+ mips:*:*:UMIPS | mips:*:*:RISCos)
439+ eval $set_cc_for_build
440+ sed 's/^ //' << EOF >$dummy.c
441+#ifdef __cplusplus
442+#include <stdio.h> /* for printf() prototype */
443+ int main (int argc, char *argv[]) {
444+#else
445+ int main (argc, argv) int argc; char *argv[]; {
446+#endif
447+ #if defined (host_mips) && defined (MIPSEB)
448+ #if defined (SYSTYPE_SYSV)
449+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
450+ #endif
451+ #if defined (SYSTYPE_SVR4)
452+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
453+ #endif
454+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
455+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
456+ #endif
457+ #endif
458+ exit (-1);
459+ }
460+EOF
461+ $CC_FOR_BUILD -o $dummy $dummy.c \
462+ && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
463+ && exit 0
464+ echo mips-mips-riscos${UNAME_RELEASE}
465+ exit 0 ;;
466+ Motorola:PowerMAX_OS:*:*)
467+ echo powerpc-motorola-powermax
468+ exit 0 ;;
469+ Motorola:*:4.3:PL8-*)
470+ echo powerpc-harris-powermax
471+ exit 0 ;;
472+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
473+ echo powerpc-harris-powermax
474+ exit 0 ;;
475+ Night_Hawk:Power_UNIX:*:*)
476+ echo powerpc-harris-powerunix
477+ exit 0 ;;
478+ m88k:CX/UX:7*:*)
479+ echo m88k-harris-cxux7
480+ exit 0 ;;
481+ m88k:*:4*:R4*)
482+ echo m88k-motorola-sysv4
483+ exit 0 ;;
484+ m88k:*:3*:R3*)
485+ echo m88k-motorola-sysv3
486+ exit 0 ;;
487+ AViiON:dgux:*:*)
488+ # DG/UX returns AViiON for all architectures
489+ UNAME_PROCESSOR=`/usr/bin/uname -p`
490+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
491+ then
492+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
493+ [ ${TARGET_BINARY_INTERFACE}x = x ]
494+ then
495+ echo m88k-dg-dgux${UNAME_RELEASE}
496+ else
497+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
498+ fi
499+ else
500+ echo i586-dg-dgux${UNAME_RELEASE}
501+ fi

952 more lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/config.sub+1569−0

This diff is large: its 1570 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/configure+6864−0

This diff is large: its 6865 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/configure.ac+243−0

This diff is large: its 244 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/fficonfig.h.in+148−0

This diff is large: its 149 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/fficonfig.py.in+45−0

This diff is large: its 46 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/include/ffi.h.in+313−0

This diff is large: its 314 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/include/ffi_common.h+95−0

This diff is large: its 96 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/install-sh+294−0

This diff is large: its 295 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/alpha/ffi.c+252−0

This diff is large: its 253 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/alpha/ffitarget.h+48−0

This diff is large: its 49 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/alpha/osf.S+359−0

This diff is large: its 360 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/arm/ffi.c+185−0

This diff is large: its 186 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/arm/ffitarget.h+47−0

This diff is large: its 48 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/arm/sysv.S+209−0

This diff is large: its 210 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/cris/ffi.c+381−0

This diff is large: its 382 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/cris/ffitarget.h+50−0

This diff is large: its 51 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/cris/sysv.S+215−0

This diff is large: its 216 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/darwin/ffitarget.h+25−0

This diff is large: its 26 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/frv/eabi.S+130−0

This diff is large: its 131 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/frv/ffi.c+287−0

This diff is large: its 288 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/frv/ffitarget.h+60−0

This diff is large: its 61 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/ia64/ffi.c+562−0

This diff is large: its 563 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/ia64/ffitarget.h+49−0

This diff is large: its 50 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/ia64/ia64_flags.h+39−0

This diff is large: its 40 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/ia64/unix.S+555−0

This diff is large: its 556 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/m32r/ffi.c+247−0

This diff is large: its 248 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/m32r/ffitarget.h+48−0

This diff is large: its 49 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/m32r/sysv.S+121−0

This diff is large: its 122 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/m68k/ffi.c+176−0

This diff is large: its 177 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/m68k/ffitarget.h+47−0

This diff is large: its 48 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/m68k/sysv.S+97−0

This diff is large: its 98 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/mips/ffi.c+648−0

This diff is large: its 649 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/mips/ffitarget.h+167−0

This diff is large: its 168 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/mips/n32.S+320−0

This diff is large: its 321 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/mips/o32.S+377−0

This diff is large: its 378 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/pa/ffi.c+625−0

This diff is large: its 626 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/pa/ffitarget.h+59−0

This diff is large: its 60 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/pa/linux.S+307−0

This diff is large: its 308 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/aix.S+225−0

This diff is large: its 226 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/aix_closure.S+247−0

This diff is large: its 248 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/asm.h+125−0

This diff is large: its 126 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/darwin.S+247−0

This diff is large: its 248 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/darwin_closure.S+319−0

This diff is large: its 320 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/ffi.c+1249−0

This diff is large: its 1250 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c+771−0

This diff is large: its 772 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/ffitarget.h+100−0

This diff is large: its 101 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/linux64.S+180−0

This diff is large: its 181 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/linux64_closure.S+206−0

This diff is large: its 207 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/ppc_closure.S+323−0

This diff is large: its 324 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/powerpc/sysv.S+217−0

This diff is large: its 218 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/prep_cif.c+210−0

This diff is large: its 211 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/s390/ffi.c+751−0

This diff is large: its 752 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/s390/ffitarget.h+59−0

This diff is large: its 60 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/s390/sysv.S+429−0

This diff is large: its 430 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/sh/ffi.c+728−0

This diff is large: its 729 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/sh/ffitarget.h+48−0

This diff is large: its 49 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/sh/sysv.S+845−0

This diff is large: its 846 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/sh64/ffi.c+451−0

This diff is large: its 452 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/sh64/ffitarget.h+52−0

This diff is large: its 53 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/sh64/sysv.S+525−0

This diff is large: its 526 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/sparc/ffi.c+608−0

This diff is large: its 609 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/sparc/ffitarget.h+65−0

This diff is large: its 66 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/sparc/v8.S+267−0

This diff is large: its 268 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/sparc/v9.S+302−0

This diff is large: its 303 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/darwin.S+243−0

This diff is large: its 244 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/ffi.c+469−0

This diff is large: its 470 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/ffi64.c+569−0

This diff is large: its 570 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/ffi_darwin.c+594−0

This diff is large: its 595 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/ffitarget.h+81−0

This diff is large: its 82 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/sysv.S+382−0

This diff is large: its 383 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/unix64.S+412−0

This diff is large: its 413 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi/src/x86/win32.S+373−0

This diff is large: its 374 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/debug.c+59−0

This diff is large: its 60 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/ffi.c+310−0

This diff is large: its 311 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/ffi.h+317−0

This diff is large: its 318 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/ffi_common.h+111−0

This diff is large: its 112 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/fficonfig.h+152−0

This diff is large: its 153 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/ffitarget.h+49−0

This diff is large: its 50 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/prep_cif.c+175−0

This diff is large: its 176 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi_arm_wince/sysv.asm+228−0

This diff is large: its 229 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi_msvc/LICENSE+20−0

This diff is large: its 21 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi_msvc/README+500−0

This diff is large: its 501 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi_msvc/README.ctypes+7−0

This diff is large: its 8 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi_msvc/ffi.c+394−0

This diff is large: its 395 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi_msvc/ffi.h+317−0

This diff is large: its 318 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi_msvc/ffi_common.h+77−0

This diff is large: its 78 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi_msvc/fficonfig.h+96−0

This diff is large: its 97 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi_msvc/ffitarget.h+79−0

This diff is large: its 80 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi_msvc/prep_cif.c+175−0

This diff is large: its 176 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi_msvc/types.c+104−0

This diff is large: its 105 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi_msvc/win32.S+243−0

This diff is large: its 244 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/libffi_msvc/win32.c+267−0

This diff is large: its 268 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/malloc_closure.c+110−0

This diff is large: its 111 lines aren’t shown here.

sys/src/cmd/python/Modules/_ctypes/stgdict.c+494−0

This diff is large: its 495 lines aren’t shown here.

sys/src/cmd/python/Modules/_curses_panel.c+480−0

This diff is large: its 481 lines aren’t shown here.

sys/src/cmd/python/Modules/_cursesmodule.c+2760−0

This diff is large: its 2761 lines aren’t shown here.

sys/src/cmd/python/Modules/_elementtree.c+2815−0

This diff is large: its 2816 lines aren’t shown here.

sys/src/cmd/python/Modules/_functoolsmodule.c+277−0

This diff is large: its 278 lines aren’t shown here.

sys/src/cmd/python/Modules/_hashopenssl.c+487−0

This diff is large: its 488 lines aren’t shown here.

sys/src/cmd/python/Modules/_heapqmodule.c+619−0

This diff is large: its 620 lines aren’t shown here.

sys/src/cmd/python/Modules/_hotshot.c+1647−0

This diff is large: its 1648 lines aren’t shown here.

sys/src/cmd/python/Modules/_localemodule.c+788−0

This diff is large: its 789 lines aren’t shown here.

sys/src/cmd/python/Modules/_lsprof.c+875−0

This diff is large: its 876 lines aren’t shown here.

sys/src/cmd/python/Modules/_randommodule.c+580−0

This diff is large: its 581 lines aren’t shown here.

sys/src/cmd/python/Modules/_sqlite/cache.c+375−0

This diff is large: its 376 lines aren’t shown here.

sys/src/cmd/python/Modules/_sqlite/cache.h+73−0

This diff is large: its 74 lines aren’t shown here.

sys/src/cmd/python/Modules/_sqlite/connection.c+1255−0

This diff is large: its 1256 lines aren’t shown here.

sys/src/cmd/python/Modules/_sqlite/connection.h+129−0

This diff is large: its 130 lines aren’t shown here.

sys/src/cmd/python/Modules/_sqlite/cursor.c+1057−0

This diff is large: its 1058 lines aren’t shown here.

sys/src/cmd/python/Modules/_sqlite/cursor.h+71−0

This diff is large: its 72 lines aren’t shown here.

sys/src/cmd/python/Modules/_sqlite/microprotocols.c+142−0

This diff is large: its 143 lines aren’t shown here.

sys/src/cmd/python/Modules/_sqlite/microprotocols.h+59−0

This diff is large: its 60 lines aren’t shown here.

sys/src/cmd/python/Modules/_sqlite/module.c+409−0

This diff is large: its 410 lines aren’t shown here.

sys/src/cmd/python/Modules/_sqlite/module.h+57−0

This diff is large: its 58 lines aren’t shown here.

sys/src/cmd/python/Modules/_sqlite/prepare_protocol.c+84−0

This diff is large: its 85 lines aren’t shown here.

sys/src/cmd/python/Modules/_sqlite/prepare_protocol.h+41−0

This diff is large: its 42 lines aren’t shown here.

sys/src/cmd/python/Modules/_sqlite/row.c+202−0

This diff is large: its 203 lines aren’t shown here.

sys/src/cmd/python/Modules/_sqlite/row.h+39−0

This diff is large: its 40 lines aren’t shown here.

sys/src/cmd/python/Modules/_sqlite/sqlitecompat.h+34−0

This diff is large: its 35 lines aren’t shown here.

sys/src/cmd/python/Modules/_sqlite/statement.c+432−0

This diff is large: its 433 lines aren’t shown here.

sys/src/cmd/python/Modules/_sqlite/statement.h+59−0

This diff is large: its 60 lines aren’t shown here.

sys/src/cmd/python/Modules/_sqlite/util.c+96−0

This diff is large: its 97 lines aren’t shown here.

sys/src/cmd/python/Modules/_sqlite/util.h+38−0

This diff is large: its 39 lines aren’t shown here.

sys/src/cmd/python/Modules/_sre.c+3429−0

This diff is large: its 3430 lines aren’t shown here.

sys/src/cmd/python/Modules/_ssl.c+726−0

This diff is large: its 727 lines aren’t shown here.

sys/src/cmd/python/Modules/_struct.c+1896−0

This diff is large: its 1897 lines aren’t shown here.

sys/src/cmd/python/Modules/_testcapimodule.c+898−0

This diff is large: its 899 lines aren’t shown here.

sys/src/cmd/python/Modules/_tkinter.c+3165−0

This diff is large: its 3166 lines aren’t shown here.

sys/src/cmd/python/Modules/_typesmodule.c+94−0

This diff is large: its 95 lines aren’t shown here.

sys/src/cmd/python/Modules/_weakref.c+112−0

This diff is large: its 113 lines aren’t shown here.

sys/src/cmd/python/Modules/addrinfo.h+176−0

This diff is large: its 177 lines aren’t shown here.

sys/src/cmd/python/Modules/almodule.c+3226−0

This diff is large: its 3227 lines aren’t shown here.

sys/src/cmd/python/Modules/ar_beos+73−0

This diff is large: its 74 lines aren’t shown here.

sys/src/cmd/python/Modules/arraymodule.c+2141−0

This diff is large: its 2142 lines aren’t shown here.

sys/src/cmd/python/Modules/audioop.c+1612−0

This diff is large: its 1613 lines aren’t shown here.

sys/src/cmd/python/Modules/binascii.c+1350−0

This diff is large: its 1351 lines aren’t shown here.

sys/src/cmd/python/Modules/bsddbmodule.c+858−0

This diff is large: its 859 lines aren’t shown here.

sys/src/cmd/python/Modules/bz2module.c+2230−0

This diff is large: its 2231 lines aren’t shown here.

sys/src/cmd/python/Modules/cPickle.c+5757−0

This diff is large: its 5758 lines aren’t shown here.

sys/src/cmd/python/Modules/cStringIO.c+745−0

This diff is large: its 746 lines aren’t shown here.

sys/src/cmd/python/Modules/cdmodule.c+796−0

This diff is large: its 797 lines aren’t shown here.

sys/src/cmd/python/Modules/cgen.py+520−0

This diff is large: its 521 lines aren’t shown here.

sys/src/cmd/python/Modules/cgensupport.c+310−0

This diff is large: its 311 lines aren’t shown here.

sys/src/cmd/python/Modules/cgensupport.h+64−0

This diff is large: its 65 lines aren’t shown here.

sys/src/cmd/python/Modules/cjkcodecs/README+79−0

This diff is large: its 80 lines aren’t shown here.

sys/src/cmd/python/Modules/cjkcodecs/_codecs_cn.c+443−0

This diff is large: its 444 lines aren’t shown here.

sys/src/cmd/python/Modules/cjkcodecs/_codecs_hk.c+143−0

This diff is large: its 144 lines aren’t shown here.

sys/src/cmd/python/Modules/cjkcodecs/_codecs_iso2022.c+1131−0

This diff is large: its 1132 lines aren’t shown here.

sys/src/cmd/python/Modules/cjkcodecs/_codecs_jp.c+731−0

This diff is large: its 732 lines aren’t shown here.

sys/src/cmd/python/Modules/cjkcodecs/_codecs_kr.c+355−0

This diff is large: its 356 lines aren’t shown here.

sys/src/cmd/python/Modules/cjkcodecs/_codecs_tw.c+132−0

This diff is large: its 133 lines aren’t shown here.

sys/src/cmd/python/Modules/cjkcodecs/alg_jisx0201.h+24−0

This diff is large: its 25 lines aren’t shown here.

sys/src/cmd/python/Modules/cjkcodecs/cjkcodecs.h+398−0

This diff is large: its 399 lines aren’t shown here.

sys/src/cmd/python/Modules/cjkcodecs/emu_jisx0213_2000.h+43−0

This diff is large: its 44 lines aren’t shown here.

sys/src/cmd/python/Modules/cjkcodecs/mappings_cn.h+4103−0

This diff is large: its 4104 lines aren’t shown here.

sys/src/cmd/python/Modules/cjkcodecs/mappings_hk.h+2340−0

This diff is large: its 2341 lines aren’t shown here.

sys/src/cmd/python/Modules/cjkcodecs/mappings_jisx0213_pair.h+59−0

This diff is large: its 60 lines aren’t shown here.

sys/src/cmd/python/Modules/cjkcodecs/mappings_jp.h+4765−0

This diff is large: its 4766 lines aren’t shown here.

sys/src/cmd/python/Modules/cjkcodecs/mappings_kr.h+3251−0

This diff is large: its 3252 lines aren’t shown here.

sys/src/cmd/python/Modules/cjkcodecs/mappings_tw.h+2633−0

This diff is large: its 2634 lines aren’t shown here.

sys/src/cmd/python/Modules/cjkcodecs/multibytecodec.c+1793−0

This diff is large: its 1794 lines aren’t shown here.

sys/src/cmd/python/Modules/cjkcodecs/multibytecodec.h+138−0

This diff is large: its 139 lines aren’t shown here.

sys/src/cmd/python/Modules/clmodule.c+2559−0

This diff is large: its 2560 lines aren’t shown here.

sys/src/cmd/python/Modules/cmathmodule.c+426−0

This diff is large: its 427 lines aren’t shown here.

sys/src/cmd/python/Modules/collectionsmodule.c+1370−0

This diff is large: its 1371 lines aren’t shown here.

sys/src/cmd/python/Modules/config+54−0

This diff is large: its 55 lines aren’t shown here.

sys/src/cmd/python/Modules/config.c.in+66−0

This diff is large: its 67 lines aren’t shown here.

sys/src/cmd/python/Modules/cryptmodule.c+49−0

This diff is large: its 50 lines aren’t shown here.

sys/src/cmd/python/Modules/cstubs+1364−0

This diff is large: its 1365 lines aren’t shown here.

sys/src/cmd/python/Modules/datetimemodule.c+4988−0

This diff is large: its 4989 lines aren’t shown here.

sys/src/cmd/python/Modules/dbmmodule.c+370−0

This diff is large: its 371 lines aren’t shown here.

sys/src/cmd/python/Modules/dlmodule.c+278−0

This diff is large: its 279 lines aren’t shown here.

sys/src/cmd/python/Modules/errnomodule.c+788−0

This diff is large: its 789 lines aren’t shown here.

sys/src/cmd/python/Modules/expat/amigaconfig.h+96−0

This diff is large: its 97 lines aren’t shown here.

sys/src/cmd/python/Modules/expat/ascii.h+85−0

This diff is large: its 86 lines aren’t shown here.

sys/src/cmd/python/Modules/expat/asciitab.h+36−0

This diff is large: its 37 lines aren’t shown here.

sys/src/cmd/python/Modules/expat/expat.h+1013−0

This diff is large: its 1014 lines aren’t shown here.

sys/src/cmd/python/Modules/expat/expat_config.h+19−0

This diff is large: its 20 lines aren’t shown here.

sys/src/cmd/python/Modules/expat/expat_external.h+119−0

This diff is large: its 120 lines aren’t shown here.

sys/src/cmd/python/Modules/expat/iasciitab.h+37−0

This diff is large: its 38 lines aren’t shown here.

sys/src/cmd/python/Modules/expat/internal.h+73−0

This diff is large: its 74 lines aren’t shown here.

sys/src/cmd/python/Modules/expat/latin1tab.h+36−0

This diff is large: its 37 lines aren’t shown here.

sys/src/cmd/python/Modules/expat/macconfig.h+53−0

This diff is large: its 54 lines aren’t shown here.

sys/src/cmd/python/Modules/expat/nametab.h+150−0

This diff is large: its 151 lines aren’t shown here.

sys/src/cmd/python/Modules/expat/pyexpatns.h+124−0

This diff is large: its 125 lines aren’t shown here.

sys/src/cmd/python/Modules/expat/utf8tab.h+37−0

This diff is large: its 38 lines aren’t shown here.

sys/src/cmd/python/Modules/expat/winconfig.h+30−0

This diff is large: its 31 lines aren’t shown here.

sys/src/cmd/python/Modules/expat/xmlparse.c+6268−0

This diff is large: its 6269 lines aren’t shown here.

sys/src/cmd/python/Modules/expat/xmlrole.c+1330−0

This diff is large: its 1331 lines aren’t shown here.

sys/src/cmd/python/Modules/expat/xmlrole.h+114−0

This diff is large: its 115 lines aren’t shown here.

sys/src/cmd/python/Modules/expat/xmltok.c+1639−0

This diff is large: its 1640 lines aren’t shown here.

sys/src/cmd/python/Modules/expat/xmltok.h+316−0

This diff is large: its 317 lines aren’t shown here.

sys/src/cmd/python/Modules/expat/xmltok_impl.c+1779−0

This diff is large: its 1780 lines aren’t shown here.

sys/src/cmd/python/Modules/expat/xmltok_impl.h+46−0

This diff is large: its 47 lines aren’t shown here.

sys/src/cmd/python/Modules/expat/xmltok_ns.c+106−0

This diff is large: its 107 lines aren’t shown here.

sys/src/cmd/python/Modules/fcntlmodule.c+607−0

This diff is large: its 608 lines aren’t shown here.

sys/src/cmd/python/Modules/flmodule.c+2139−0

This diff is large: its 2140 lines aren’t shown here.

sys/src/cmd/python/Modules/fmmodule.c+264−0

This diff is large: its 265 lines aren’t shown here.

sys/src/cmd/python/Modules/fpectlmodule.c+303−0

This diff is large: its 304 lines aren’t shown here.

sys/src/cmd/python/Modules/fpetestmodule.c+186−0

This diff is large: its 187 lines aren’t shown here.

sys/src/cmd/python/Modules/gc_weakref.txt+219−0

This diff is large: its 220 lines aren’t shown here.

sys/src/cmd/python/Modules/gcmodule.c+1390−0

This diff is large: its 1391 lines aren’t shown here.

sys/src/cmd/python/Modules/gdbmmodule.c+515−0

This diff is large: its 516 lines aren’t shown here.

sys/src/cmd/python/Modules/getaddrinfo.c+638−0

This diff is large: its 639 lines aren’t shown here.

sys/src/cmd/python/Modules/getbuildinfo.c+48−0

This diff is large: its 49 lines aren’t shown here.

sys/src/cmd/python/Modules/getnameinfo.c+214−0

This diff is large: its 215 lines aren’t shown here.

sys/src/cmd/python/Modules/getpath.c+694−0

This diff is large: its 695 lines aren’t shown here.

sys/src/cmd/python/Modules/glmodule.c+7628−0

This diff is large: its 7629 lines aren’t shown here.

sys/src/cmd/python/Modules/grpmodule.c+194−0

This diff is large: its 195 lines aren’t shown here.

sys/src/cmd/python/Modules/imageop.c+785−0

This diff is large: its 786 lines aren’t shown here.

sys/src/cmd/python/Modules/imgfile.c+504−0

This diff is large: its 505 lines aren’t shown here.

sys/src/cmd/python/Modules/itertoolsmodule.c+2550−0

This diff is large: its 2551 lines aren’t shown here.

sys/src/cmd/python/Modules/ld_so_aix+187−0

This diff is large: its 188 lines aren’t shown here.

sys/src/cmd/python/Modules/ld_so_beos+78−0

This diff is large: its 79 lines aren’t shown here.

sys/src/cmd/python/Modules/linuxaudiodev.c+502−0

This diff is large: its 503 lines aren’t shown here.

sys/src/cmd/python/Modules/main.c+584−0

This diff is large: its 585 lines aren’t shown here.

sys/src/cmd/python/Modules/makesetup+297−0

This diff is large: its 298 lines aren’t shown here.

sys/src/cmd/python/Modules/makexp_aix+81−0

This diff is large: its 82 lines aren’t shown here.

sys/src/cmd/python/Modules/mathmodule.c+376−0

This diff is large: its 377 lines aren’t shown here.

sys/src/cmd/python/Modules/md5.c+381−0

This diff is large: its 382 lines aren’t shown here.

sys/src/cmd/python/Modules/md5.h+91−0

This diff is large: its 92 lines aren’t shown here.

sys/src/cmd/python/Modules/md5module.c+312−0

This diff is large: its 313 lines aren’t shown here.

sys/src/cmd/python/Modules/mkfile+135−0

This diff is large: its 136 lines aren’t shown here.

sys/src/cmd/python/Modules/mmapmodule.c+1186−0

This diff is large: its 1187 lines aren’t shown here.

sys/src/cmd/python/Modules/nismodule.c+444−0

This diff is large: its 445 lines aren’t shown here.

sys/src/cmd/python/Modules/operator.c+602−0

This diff is large: its 603 lines aren’t shown here.

sys/src/cmd/python/Modules/ossaudiodev.c+1138−0

This diff is large: its 1139 lines aren’t shown here.

sys/src/cmd/python/Modules/parsermodule.c+3279−0

This diff is large: its 3280 lines aren’t shown here.

sys/src/cmd/python/Modules/posixmodule.c+8752−0

This diff is large: its 8753 lines aren’t shown here.

sys/src/cmd/python/Modules/puremodule.c+988−0

This diff is large: its 989 lines aren’t shown here.

sys/src/cmd/python/Modules/pwdmodule.c+198−0

This diff is large: its 199 lines aren’t shown here.

sys/src/cmd/python/Modules/pyexpat.c+2149−0

This diff is large: its 2150 lines aren’t shown here.

sys/src/cmd/python/Modules/python.c+24−0

This diff is large: its 25 lines aren’t shown here.

sys/src/cmd/python/Modules/readline.c+941−0

This diff is large: its 942 lines aren’t shown here.

sys/src/cmd/python/Modules/resource.c+325−0

This diff is large: its 326 lines aren’t shown here.

sys/src/cmd/python/Modules/rgbimgmodule.c+780−0

This diff is large: its 781 lines aren’t shown here.

sys/src/cmd/python/Modules/rotatingtree.c+121−0

This diff is large: its 122 lines aren’t shown here.

sys/src/cmd/python/Modules/rotatingtree.h+27−0

This diff is large: its 28 lines aren’t shown here.

sys/src/cmd/python/Modules/selectmodule.c+734−0

This diff is large: its 735 lines aren’t shown here.

sys/src/cmd/python/Modules/sgimodule.c+55−0

This diff is large: its 56 lines aren’t shown here.

sys/src/cmd/python/Modules/sha256module.c+701−0

This diff is large: its 702 lines aren’t shown here.

sys/src/cmd/python/Modules/sha512module.c+769−0

This diff is large: its 770 lines aren’t shown here.

sys/src/cmd/python/Modules/shamodule.c+593−0

This diff is large: its 594 lines aren’t shown here.

sys/src/cmd/python/Modules/signalmodule.c+676−0

This diff is large: its 677 lines aren’t shown here.

sys/src/cmd/python/Modules/socketmodule.c+5100−0

This diff is large: its 5101 lines aren’t shown here.

sys/src/cmd/python/Modules/socketmodule.h+252−0

This diff is large: its 253 lines aren’t shown here.

sys/src/cmd/python/Modules/spwdmodule.c+183−0

This diff is large: its 184 lines aren’t shown here.

sys/src/cmd/python/Modules/sre.h+94−0

This diff is large: its 95 lines aren’t shown here.

sys/src/cmd/python/Modules/sre_constants.h+86−0

This diff is large: its 87 lines aren’t shown here.

sys/src/cmd/python/Modules/stropmodule.c+1248−0

This diff is large: its 1249 lines aren’t shown here.

sys/src/cmd/python/Modules/sunaudiodev.c+465−0

This diff is large: its 466 lines aren’t shown here.

sys/src/cmd/python/Modules/svmodule.c+966−0

This diff is large: its 967 lines aren’t shown here.

sys/src/cmd/python/Modules/symtablemodule.c+84−0

This diff is large: its 85 lines aren’t shown here.

sys/src/cmd/python/Modules/syslogmodule.c+223−0

This diff is large: its 224 lines aren’t shown here.

sys/src/cmd/python/Modules/termios.c+926−0

This diff is large: its 927 lines aren’t shown here.

sys/src/cmd/python/Modules/testcapi_long.h+166−0

This diff is large: its 167 lines aren’t shown here.

sys/src/cmd/python/Modules/threadmodule.c+720−0

This diff is large: its 721 lines aren’t shown here.

sys/src/cmd/python/Modules/timemodule.c+1030−0

This diff is large: its 1031 lines aren’t shown here.

sys/src/cmd/python/Modules/timing.h+67−0

This diff is large: its 68 lines aren’t shown here.

sys/src/cmd/python/Modules/timingmodule.c+58−0

This diff is large: its 59 lines aren’t shown here.

sys/src/cmd/python/Modules/tkappinit.c+149−0

This diff is large: its 150 lines aren’t shown here.

sys/src/cmd/python/Modules/unicodedata.c+1223−0

This diff is large: its 1224 lines aren’t shown here.

sys/src/cmd/python/Modules/unicodedata_db.h+5135−0

This diff is large: its 5136 lines aren’t shown here.

sys/src/cmd/python/Modules/unicodename_db.h+12543−0

This diff is large: its 12544 lines aren’t shown here.

sys/src/cmd/python/Modules/xxmodule.c+376−0

This diff is large: its 377 lines aren’t shown here.

sys/src/cmd/python/Modules/xxsubtype.c+299−0

This diff is large: its 300 lines aren’t shown here.

sys/src/cmd/python/Modules/yuv.h+99−0

This diff is large: its 100 lines aren’t shown here.

sys/src/cmd/python/Modules/yuvconvert.c+118−0

This diff is large: its 119 lines aren’t shown here.

sys/src/cmd/python/Modules/zipimport.c+1191−0

This diff is large: its 1192 lines aren’t shown here.

sys/src/cmd/python/Modules/zlib/ChangeLog+855−0

This diff is large: its 856 lines aren’t shown here.

sys/src/cmd/python/Modules/zlib/FAQ+339−0

This diff is large: its 340 lines aren’t shown here.

sys/src/cmd/python/Modules/zlib/INDEX+51−0

This diff is large: its 52 lines aren’t shown here.

sys/src/cmd/python/Modules/zlib/Makefile+154−0

This diff is large: its 155 lines aren’t shown here.

sys/src/cmd/python/Modules/zlib/Makefile.in+154−0

This diff is large: its 155 lines aren’t shown here.

sys/src/cmd/python/Modules/zlib/README+125−0

This diff is large: its 126 lines aren’t shown here.

sys/src/cmd/python/Modules/zlib/adler32.c+149−0

This diff is large: its 150 lines aren’t shown here.

sys/src/cmd/python/Modules/zlib/algorithm.txt+209−0

This diff is large: its 210 lines aren’t shown here.

sys/src/cmd/python/Modules/zlib/compress.c+79−0

This diff is large: its 80 lines aren’t shown here.

sys/src/cmd/python/Modules/zlib/configure+459−0

This diff is large: its 460 lines aren’t shown here.

sys/src/cmd/python/Modules/zlib/crc32.c+423−0

This diff is large: its 424 lines aren’t shown here.

sys/src/cmd/python/Modules/zlib/crc32.h+441−0

This diff is large: its 442 lines aren’t shown here.

sys/src/cmd/python/Modules/zlib/deflate.c+1736−0

This diff is large: its 1737 lines aren’t shown here.

sys/src/cmd/python/Modules/zlib/deflate.h+331−0

This diff is large: its 332 lines aren’t shown here.

sys/src/cmd/python/Modules/zlib/example.c+565−0

This diff is large: its 566 lines aren’t shown here.

sys/src/cmd/python/Modules/zlib/gzio.c+1026−0

This diff is large: its 1027 lines aren’t shown here.

sys/src/cmd/python/Modules/zlib/infback.c+623−0

This diff is large: its 624 lines aren’t shown here.

sys/src/cmd/python/Modules/zlib/inffast.c+318−0

This diff is large: its 319 lines aren’t shown here.

sys/src/cmd/python/Modules/zlib/inffast.h+11−0

This diff is large: its 12 lines aren’t shown here.

This diff is larger than a page shows: the files after these aren’t listed. Clone the repository to see all of it.