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.
76DESTLIB=$(LIBDEST)
77MACHDESTLIB=$(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.
85DESTPATH=
86
87# Site specific path components -- should begin with : if non-empty
88SITEPATH=
89
90# Standard path components for test modules
91TESTPATH=
92
93# Path components for machine- or system-dependent modules and shared libraries
94MACHDEPPATH=:plat-$(MACHDEP)
95EXTRAMACHDEPPATH=
96
97# Path component for the Tkinter-related modules
98# The TKPATH variable is always enabled, to save you the effort.
99TKPATH=:lib-tk
100
101COREPYTHONPATH=$(DESTPATH)$(SITEPATH)$(TESTPATH)$(MACHDEPPATH)$(EXTRAMACHDEPPATH)$(TKPATH)
102PYTHONPATH=$(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
112posix posixmodule.c # posix (UNIX) system calls
113errno errnomodule.c # posix (UNIX) errno values
114pwd 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.
122zipimport 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
139GLHACK=-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
488xxsubtype 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
10signal 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.
76DESTLIB=$(LIBDEST)
77MACHDESTLIB=$(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.
85DESTPATH=
86
87# Site specific path components -- should begin with : if non-empty
88SITEPATH=
89
90# Standard path components for test modules
91TESTPATH=
92
93# Path components for machine- or system-dependent modules and shared libraries
94MACHDEPPATH=:plat-$(MACHDEP)
95EXTRAMACHDEPPATH=
96
97# Path component for the Tkinter-related modules
98# The TKPATH variable is always enabled, to save you the effort.
99TKPATH=:lib-tk
100
101COREPYTHONPATH=$(DESTPATH)$(SITEPATH)$(TESTPATH)$(MACHDEPPATH)$(EXTRAMACHDEPPATH)$(TKPATH)
102PYTHONPATH=$(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
112posix posixmodule.c # posix (UNIX) system calls
113errno errnomodule.c # posix (UNIX) errno values
114pwd 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.
121zipimport 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
138GLHACK=-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
487xxsubtype 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
3Converted to C by Dmitry Vasiliev (dima at hlabs.spb.ru).
4*/
5
6#include "Python.h"
7
8static int
9internal_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
36static PyObject *
37bisect_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
54PyDoc_STRVAR(bisect_right_doc,
55"bisect_right(a, x[, lo[, hi]]) -> index\n\
56\n\
57Return the index where to insert item x in list a, assuming a is sorted.\n\
58\n\
59The return value i is such that all e in a[:i] have e <= x, and all e in\n\
60a[i:] have e > x. So if x already appears in the list, i points just\n\
61beyond the rightmost x already there\n\
62\n\
63Optional args lo (default 0) and hi (default len(a)) bound the\n\
64slice of a to be searched.\n");
65
66static PyObject *
67insort_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
95PyDoc_STRVAR(insort_right_doc,
96"insort_right(a, x[, lo[, hi]])\n\
97\n\
98Insert item x in list a, and keep it sorted assuming a is sorted.\n\
99\n\
100If x is already in a, insert it to the right of the rightmost x.\n\
101\n\
102Optional args lo (default 0) and hi (default len(a)) bound the\n\
103slice of a to be searched.\n");
104
105static int
106internal_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
133static PyObject *
134bisect_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
151PyDoc_STRVAR(bisect_left_doc,
152"bisect_left(a, x[, lo[, hi]]) -> index\n\
153\n\
154Return the index where to insert item x in list a, assuming a is sorted.\n\
155\n\
156The return value i is such that all e in a[:i] have e < x, and all e in\n\
157a[i:] have e >= x. So if x already appears in the list, i points just\n\
158before the leftmost x already there.\n\
159\n\
160Optional args lo (default 0) and hi (default len(a)) bound the\n\
161slice of a to be searched.\n");
162
163static PyObject *
164insort_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
192PyDoc_STRVAR(insort_left_doc,
193"insort_left(a, x[, lo[, hi]])\n\
194\n\
195Insert item x in list a, and keep it sorted assuming a is sorted.\n\
196\n\
197If x is already in a, insert it to the left of the leftmost x.\n\
198\n\
199Optional args lo (default 0) and hi (default len(a)) bound the\n\
200slice of a to be searched.\n");
201
202PyDoc_STRVAR(bisect_doc, "Alias for bisect_right().\n");
203PyDoc_STRVAR(insort_doc, "Alias for insort_right().\n");
204
205static 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
221PyDoc_STRVAR(module_doc,
222"Bisection algorithms.\n\
223\n\
224This module provides support for maintaining a list in sorted order without\n\
225having to sort the list after each insertion. For long lists of items with\n\
226expensive comparison operations, this can be an improvement over the more\n\
227common approach.\n");
228
229PyMODINIT_FUNC
230init_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"
102static char *rcs_id = "$Id: _bsddb.c 53254 2007-01-05 02:09:06Z gregory.p.smith $";
103
104
105#if (PY_VERSION_HEX < 0x02050000)
106typedef 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 */
128static 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
159static PyObject* DBError; /* Base class, all others derive from this */
160static PyObject* DBCursorClosedError; /* raised when trying to use a closed cursor object */
161static PyObject* DBKeyEmptyError; /* DB_KEYEMPTY: also derives from KeyError */
162static PyObject* DBKeyExistError; /* DB_KEYEXIST */
163static PyObject* DBLockDeadlockError; /* DB_LOCK_DEADLOCK */
164static PyObject* DBLockNotGrantedError; /* DB_LOCK_NOTGRANTED */
165static PyObject* DBNotFoundError; /* DB_NOTFOUND: also derives from KeyError */
166static PyObject* DBOldVersionError; /* DB_OLD_VERSION */
167static PyObject* DBRunRecoveryError; /* DB_RUNRECOVERY */
168static PyObject* DBVerifyBadError; /* DB_VERIFY_BAD */
169static PyObject* DBNoServerError; /* DB_NOSERVER */
170static PyObject* DBNoServerHomeError; /* DB_NOSERVER_HOME */
171static PyObject* DBNoServerIDError; /* DB_NOSERVER_ID */
172#if (DBVER >= 33)
173static PyObject* DBPageNotFoundError; /* DB_PAGE_NOTFOUND */
174static PyObject* DBSecondaryBadError; /* DB_SECONDARY_BAD */
175#endif
176
177#if !INCOMPLETE_IS_WARNING
178static PyObject* DBIncompleteError; /* DB_INCOMPLETE */
179#endif
180
181static PyObject* DBInvalidArgError; /* EINVAL */
182static PyObject* DBAccessError; /* EACCES */
183static PyObject* DBNoSpaceError; /* ENOSPC */
184static PyObject* DBNoMemoryError; /* DB_BUFFER_SMALL (ENOMEM when < 4.3) */
185static PyObject* DBAgainError; /* EAGAIN */
186static PyObject* DBBusyError; /* EBUSY */
187static PyObject* DBFileExistsError; /* EEXIST */
188static PyObject* DBNoSuchFileError; /* ENOENT */
189static 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
218struct 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
230typedef 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
242typedef 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
261typedef 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
271typedef 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
281typedef 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)
290typedef 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;
298staticforward PyTypeObject DBSequence_Type;
299#endif
300
301staticforward 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
355static int makeDBError(int err);
356
357
358/* Return the access method type of the DBObject */
359static 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. */
377static 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. */
396static int
397make_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. */
475static 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) */
494unsigned 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. */
512static char _db_errmsg[1024];
513#if (DBVER <= 42)
514static void _db_errorCallback(const char* prefix, char* msg)
515#else
516static 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. */
525static 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 */
616static 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 */
624static 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. */
642static 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. */
659static 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 */
674static 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 */
744static 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 */
754static 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
769static DBObject*
770newDBObject(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
830static void
831DB_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
873static DBCursorObject*
874newDBCursorObject(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
890static void
891DBCursor_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
920static DBEnvObject*
921newDBEnvObject(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
950static void
951DBEnv_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
968static DBTxnObject*
969newDBTxnObject(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
997static void
998DBTxn_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
1026static DBLockObject*
1027newDBLockObject(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
1055static void
1056DBLock_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)
1070static DBSequenceObject*
1071newDBSequenceObject(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
1097static void
1098DBSequence_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
1114static PyObject*
1115DB_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
1148static 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
1222static PyObject*
1223DB_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
1314static PyObject*
1315DB_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)
1332static 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
1387static PyObject*
1388DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
1389{
1390 return _DB_consume(self, args, kwargs, DB_CONSUME);
1391}
1392
1393static PyObject*
1394DB_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
1403static PyObject*
1404DB_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
1427static PyObject*
1428DB_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
1458static PyObject*
1459DB_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
1475static PyObject*
1476DB_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)
1543static PyObject*
1544DB_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 */
1647static PyObject*
1648DB_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
1689static PyObject*
1690DB_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
1747static PyObject*
1748DB_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
1773static PyObject*
1774DB_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
1789static PyObject*
1790DB_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
1848static PyObject*
1849DB_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
1878static PyObject*
1879DB_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
1974static PyObject*
1975DB_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
2019static PyObject*
2020DB_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
2040static PyObject*
2041DB_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
2061static PyObject*
2062DB_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)
2078static 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
2099static 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
2151static PyObject*
2152DB_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
2220static PyObject*
2221DB_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
2239static PyObject*
2240DB_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
2258static PyObject*
2259DB_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
2275static PyObject*
2276DB_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
2292static PyObject*
2293DB_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
2309static PyObject*
2310DB_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
2326static PyObject*
2327DB_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
2347static PyObject*
2348DB_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
2364static PyObject*
2365DB_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
2385static PyObject*
2386DB_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)
2404static PyObject*
2405DB_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
2422static PyObject*
2423DB_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
2547static PyObject*
2548DB_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)
2566static PyObject*
2567DB_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
2591static PyObject*
2592DB_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
2609static PyObject*
2610DB_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
2651static PyObject*
2652DB_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)
2671static PyObject*
2672DB_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
2697Py_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;
2718redo_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
2754PyObject* 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
2790static int
2791DB_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
2834static PyObject*
2835DB_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
2880static 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
2990static PyObject*
2991DB_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
3004static PyObject*
3005DB_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
3018static PyObject*
3019DB_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
3035static PyObject*
3036DBC_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
3054static PyObject*
3055DBC_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
3075static PyObject*
3076DBC_current(DBCursorObject* self, PyObject* args, PyObject *kwargs)
3077{
3078 return _DBCursor_get(self,DB_CURRENT,args,kwargs,"|iii:current");
3079}
3080
3081
3082static PyObject*
3083DBC_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
3102static PyObject*
3103DBC_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
3121static PyObject*
3122DBC_first(DBCursorObject* self, PyObject* args, PyObject* kwargs)
3123{
3124 return _DBCursor_get(self,DB_FIRST,args,kwargs,"|iii:first");
3125}
3126
3127
3128static PyObject*
3129DBC_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)
3215static PyObject*
3216DBC_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
3330static PyObject*
3331DBC_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
3363static PyObject*
3364DBC_last(DBCursorObject* self, PyObject* args, PyObject *kwargs)
3365{
3366 return _DBCursor_get(self,DB_LAST,args,kwargs,"|iii:last");
3367}
3368
3369
3370static PyObject*
3371DBC_next(DBCursorObject* self, PyObject* args, PyObject *kwargs)
3372{
3373 return _DBCursor_get(self,DB_NEXT,args,kwargs,"|iii:next");
3374}
3375
3376
3377static PyObject*
3378DBC_prev(DBCursorObject* self, PyObject* args, PyObject *kwargs)
3379{
3380 return _DBCursor_get(self,DB_PREV,args,kwargs,"|iii:prev");
3381}
3382
3383
3384static PyObject*
3385DBC_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
3420static PyObject*
3421DBC_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
3490static PyObject*
3491DBC_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
3562static 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
3611static PyObject*
3612DBC_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 */
3628static PyObject*
3629DBC_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
3660static PyObject*
3661DBC_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
3677static PyObject*
3678DBC_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
3740static PyObject*
3741DBC_consume(DBCursorObject* self, PyObject* args, PyObject *kwargs)
3742{
3743 return _DBCursor_get(self,DB_CONSUME,args,kwargs,"|iii:consume");
3744}
3745
3746
3747static PyObject*
3748DBC_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
3754static PyObject*
3755DBC_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
3761static PyObject*
3762DBC_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
3768static PyObject*
3769DBC_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
3812static PyObject*
3813DBEnv_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
3833static PyObject*
3834DBEnv_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
3854static PyObject*
3855DBEnv_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)
3871static PyObject*
3872DBEnv_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
3898static PyObject*
3899DBEnv_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
3927static PyObject*
3928DBEnv_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)
3950static PyObject*
3951DBEnv_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
3972static PyObject*
3973DBEnv_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
3987static PyObject*
3988DBEnv_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)
4006static PyObject*
4007DBEnv_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
4025static PyObject*
4026DBEnv_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
4043static PyObject*
4044DBEnv_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
4060static PyObject*
4061DBEnv_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
4077static PyObject*
4078DBEnv_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)
4095static PyObject*
4096DBEnv_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
4113static PyObject*
4114DBEnv_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)
4131static PyObject*
4132DBEnv_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
4151static PyObject*
4152DBEnv_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
4168static PyObject*
4169DBEnv_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
4185static PyObject*
4186DBEnv_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
4204static PyObject*
4205DBEnv_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
4221static PyObject*
4222DBEnv_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
4239static PyObject*
4240DBEnv_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
4259static PyObject*
4260DBEnv_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
4280static PyObject*
4281DBEnv_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
4295static PyObject*
4296DBEnv_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
4312static PyObject*
4313DBEnv_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
4334static PyObject*
4335DBEnv_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
4353static PyObject*
4354DBEnv_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
4376static PyObject*
4377DBEnv_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)
4398static PyObject*
4399DBEnv_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)
4420static PyObject*
4421DBEnv_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
4485static PyObject*
4486DBEnv_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
4556static PyObject*
4557DBEnv_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
4605static PyObject*
4606DBEnv_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
4655static PyObject*
4656DBEnv_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
4679static PyObject*
4680DBTxn_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
4708static PyObject*
4709DBTxn_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
4763static PyObject*
4764DBTxn_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
4793static PyObject*
4794DBTxn_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
4823static PyObject*
4824DBSequence_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
4841static PyObject*
4842DBSequence_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
4866static PyObject*
4867DBSequence_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
4876static PyObject*
4877DBSequence_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
4891static PyObject*
4892DBSequence_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
4909static PyObject*
4910DBSequence_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
4938static PyObject*
4939DBSequence_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
4962static PyObject*
4963DBSequence_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
4978static PyObject*
4979DBSequence_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
4994static PyObject*
4995DBSequence_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
32Written by Marc-Andre Lemburg (mal@lemburg.com).
33
34Copyright (c) Corporation for National Research Initiatives.
35
36 ------------------------------------------------------------------------ */
37
38#define PY_SSIZE_T_CLEAN
39#include "Python.h"
40
41/* --- Registry ----------------------------------------------------------- */
42
43PyDoc_STRVAR(register__doc__,
44"register(search_function)\n\
45\n\
46Register a codec search function. Search functions are expected to take\n\
47one argument, the encoding name in all lower case letters, and return\n\
48a tuple of functions (encoder, decoder, stream_reader, stream_writer).");
49
50static
51PyObject *codec_register(PyObject *self, PyObject *search_function)
52{
53 if (PyCodec_Register(search_function))
54 return NULL;
55
56 Py_RETURN_NONE;
57}
58
59PyDoc_STRVAR(lookup__doc__,
60"lookup(encoding) -> (encoder, decoder, stream_reader, stream_writer)\n\
61\n\
62Looks up a codec tuple in the Python codec registry and returns\n\
63a tuple of functions.");
64
65static
66PyObject *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
76PyDoc_STRVAR(encode__doc__,
77"encode(obj, [encoding[,errors]]) -> object\n\
78\n\
79Encodes obj using the codec registered for encoding. encoding defaults\n\
80to the default encoding. errors may be given to set a different error\n\
81handling scheme. Default is 'strict' meaning that encoding errors raise\n\
82a ValueError. Other possible values are 'ignore', 'replace' and\n\
83'xmlcharrefreplace' as well as any other name registered with\n\
84codecs.register_error that can handle ValueErrors.");
85
86static PyObject *
87codec_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
110PyDoc_STRVAR(decode__doc__,
111"decode(obj, [encoding[,errors]]) -> object\n\
112\n\
113Decodes obj using the codec registered for encoding. encoding defaults\n\
114to the default encoding. errors may be given to set a different error\n\
115handling scheme. Default is 'strict' meaning that encoding errors raise\n\
116a ValueError. Other possible values are 'ignore' and 'replace'\n\
117as well as any other name registerd with codecs.register_error that is\n\
118able to handle ValueErrors.");
119
120static PyObject *
121codec_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
146static
147PyObject *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 ------------------------------------------------------ */
159static PyObject *
160escape_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
174static PyObject *
175escape_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
204static PyObject *
205unicode_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
230static PyObject *
231utf_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
246static PyObject *
247utf_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
273static PyObject *
274utf_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
300static PyObject *
301utf_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
329static PyObject *
330utf_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
364static PyObject *
365utf_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
393static PyObject *
394unicode_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
409static PyObject *
410raw_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
425static PyObject *
426latin_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
441static PyObject *
442ascii_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
457static PyObject *
458charmap_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
478static PyObject *
479mbcs_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
503static PyObject *
504readbuffer_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
519static PyObject *
520charbuffer_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
535static PyObject *
536unicode_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
562static PyObject *
563utf_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
586static PyObject *
587utf_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
615static PyObject *
616utf_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
639static PyObject *
640utf_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
662static PyObject *
663utf_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
685static PyObject *
686unicode_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
706static PyObject *
707raw_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
728static PyObject *
729latin_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
751static PyObject *
752ascii_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
774static PyObject *
775charmap_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
801static PyObject*
802charmap_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
812static PyObject *
813mbcs_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
840PyDoc_STRVAR(register_error__doc__,
841"register_error(errors, handler)\n\
842\n\
843Register the specified error handler under the name\n\
844errors. handler must be a callable object, that\n\
845will be called with an exception instance containing\n\
846information about the location of the encoding/decoding\n\
847error and must return a (replacement, new position) tuple.");
848
849static 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
862PyDoc_STRVAR(lookup_error__doc__,
863"lookup_error(errors) -> handler\n\
864\n\
865Return the error handler for the specified error handling name\n\
866or raise a LookupError, if no handler exists under this name.");
867
868static 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
880static 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
930PyMODINIT_FUNC
931init_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
5This module provides the low-level underpinnings of a CSV reading/writing
6module. Users should not use this module directly, but import the csv.py
7module 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
67static PyObject *error_obj; /* CSV exception */
68static PyObject *dialects; /* Dialect registry */
69static long field_limit = 128 * 1024; /* max parsed field size */
70
71typedef 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
77typedef enum {
78 QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE
79} QuoteStyle;
80
81typedef struct {
82 QuoteStyle style;
83 char *name;
84} StyleDesc;
85
86static 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
94typedef 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
108staticforward PyTypeObject Dialect_Type;
109
110typedef 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
126staticforward PyTypeObject Reader_Type;
127
128#define ReaderObject_Check(v) ((v)->ob_type == &Reader_Type)
129
130typedef 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
143staticforward PyTypeObject Writer_Type;
144
145/*
146 * DIALECT class
147 */
148
149static PyObject *
150get_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
164static PyObject *
165get_string(PyObject *str)
166{
167 Py_XINCREF(str);
168 return str;
169}
170
171static PyObject *
172get_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
182static PyObject *
183Dialect_get_lineterminator(DialectObj *self)
184{
185 return get_string(self->lineterminator);
186}
187
188static PyObject *
189Dialect_get_escapechar(DialectObj *self)
190{
191 return get_nullchar_as_None(self->escapechar);
192}
193
194static PyObject *
195Dialect_get_quotechar(DialectObj *self)
196{
197 return get_nullchar_as_None(self->quotechar);
198}
199
200static PyObject *
201Dialect_get_quoting(DialectObj *self)
202{
203 return PyInt_FromLong(self->quoting);
204}
205
206static 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
216static 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
232static 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
256static 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
278static int
279dialect_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
293static 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
301static 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
309static void
310Dialect_dealloc(DialectObj *self)
311{
312 Py_XDECREF(self->lineterminator);
313 self->ob_type->tp_free((PyObject *)self);
314}
315
316static 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
329static PyObject *
330dialect_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);
442err:
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
457PyDoc_STRVAR(Dialect_Type_doc,
458"CSV dialect\n"
459"\n"
460"The Dialect type records CSV parsing and generation options.\n");
461
462static 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 */
510static 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 */
527static int
528parse_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
553static int
554parse_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
573static int
574parse_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
587static int
588parse_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
757static int
758parse_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
770static PyObject *
771Reader_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;
818err:
819 return fields;
820}
821
822static void
823Reader_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
834static int
835Reader_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
843static int
844Reader_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
852PyDoc_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
859static struct PyMethodDef Reader_methods[] = {
860 { NULL, NULL }
861};
862#define R_OFF(x) offsetof(ReaderObj, x)
863
864static 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
871static 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
908static PyObject *
909csv_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/* ---------------------------------------------------------------- */
954static void
955join_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 */
966static int
967join_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
1055static int
1056join_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
1081static int
1082join_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
1100static int
1101join_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
1123PyDoc_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
1129static PyObject *
1130csv_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
1201PyDoc_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
1207static PyObject *
1208csv_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
1235static 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
1243static struct PyMemberDef Writer_memberlist[] = {
1244 { "dialect", T_OBJECT, W_OFF(dialect), RO },
1245 { NULL }
1246};
1247
1248static void
1249Writer_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
1259static int
1260Writer_traverse(WriterObj *self, visitproc visit, void *arg)
1261{
1262 Py_VISIT(self->dialect);
1263 Py_VISIT(self->writeline);
1264 return 0;
1265}
1266
1267static int
1268Writer_clear(WriterObj *self)
1269{
1270 Py_CLEAR(self->dialect);
1271 Py_CLEAR(self->writeline);
1272 return 0;
1273}
1274
1275PyDoc_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
1282static 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
1318static PyObject *
1319csv_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 */
1358static PyObject *
1359csv_list_dialects(PyObject *module, PyObject *args)
1360{
1361 return PyDict_Keys(dialects);
1362}
1363
1364static PyObject *
1365csv_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
1389static PyObject *
1390csv_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
1398static PyObject *
1399csv_get_dialect(PyObject *module, PyObject *name_obj)
1400{
1401 return get_dialect_from_registry(name_obj);
1402}
1403
1404static PyObject *
1405csv_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
1427PyDoc_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
1485PyDoc_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
1500PyDoc_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
1514PyDoc_STRVAR(csv_list_dialects_doc,
1515"Return a list of all know dialect names.\n"
1516" names = csv.list_dialects()");
1517
1518PyDoc_STRVAR(csv_get_dialect_doc,
1519"Return the dialect instance associated with name.\n"
1520" dialect = csv.get_dialect(name)");
1521
1522PyDoc_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
1526PyDoc_STRVAR(csv_unregister_dialect_doc,
1527"Delete the name/dialect mapping associated with a string name.\n"
1528" csv.unregister_dialect(name)");
1529
1530PyDoc_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
1537static 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
1555PyMODINIT_FUNC
1556init_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
28Name methods, members, getsets
29==============================================================================
30
31StructType_Type __new__(), from_address(), __mul__(), from_param()
32UnionType_Type __new__(), from_address(), __mul__(), from_param()
33PointerType_Type __new__(), from_address(), __mul__(), from_param(), set_type()
34ArrayType_Type __new__(), from_address(), __mul__(), from_param()
35SimpleType_Type __new__(), from_address(), __mul__(), from_param()
36
37CData_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
43CField_Type
44StgDict_Type
45
46==============================================================================
47
48class methods
49-------------
50
51It has some similarity to the byref() construct compared to pointer()
52from_address(addr)
53 - construct an instance from a given memory block (sharing this memory block)
54
55from_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
60instance 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
67functions
68---------
69
70sizeof(cdata)
71 - return the number of bytes the buffer contains
72
73sizeof(ctype)
74 - return the number of bytes the buffer of an instance would contain
75
76byref(cdata)
77
78addressof(cdata)
79
80pointer(cdata)
81
82POINTER(ctype)
83
84bytes(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
128PyObject *PyExc_ArgError;
129static PyTypeObject Simple_Type;
130
131char *conversion_mode_encoding = NULL;
132char *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
143static PyCArgObject *
144StructUnionType_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
168static PyObject *
169StructUnionType_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
225static PyObject *
226StructType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
227{
228 return StructUnionType_new(type, args, kwds, 1);
229}
230
231static PyObject *
232UnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
233{
234 return StructUnionType_new(type, args, kwds, 0);
235}
236
237static char from_address_doc[] =
238"C.from_address(integer) -> C instance\naccess a C instance at the specified address";
239
240static PyObject *
241CDataType_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
255static char in_dll_doc[] =
256"C.in_dll(dll, name) -> C instance\naccess a C instance in a dll";
257
258static PyObject *
259CDataType_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
311static char from_param_doc[] =
312"Convert a Python object into a function call parameter.";
313
314static PyObject *
315CDataType_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
356static 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
363static PyObject *
364CDataType_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
377static 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
391static int
392CDataType_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
400static int
401CDataType_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
409static int
410StructType_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
423static int
424UnionType_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
437PyTypeObject 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
480static 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
528The PointerType_Type metaclass must ensure that the subclass of Pointer can be
529created. It must check for a _type_ attribute in the class. Since are no
530runtime created properties, a CField is probably *not* needed ?
531
532class IntPointer(Pointer):
533 _type_ = "i"
534
535The Pointer_Type provides the functionality: a contents method/property, a
536size property/method, and the sequence protocol.
537
538*/
539
540static int
541PointerType_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
559static PyCArgObject *
560PointerType_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
576static PyObject *
577PointerType_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
628static PyObject *
629PointerType_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
646staticforward PyObject *_byref(PyObject *);
647
648static PyObject *
649PointerType_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
687static 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
695PyTypeObject 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
748static int
749CharArray_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
771static PyObject *
772CharArray_get_raw(CDataObject *self)
773{
774 return PyString_FromStringAndSize(self->b_ptr, self->b_size);
775}
776
777static PyObject *
778CharArray_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
788static int
789CharArray_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
824static 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
833static PyObject *
834WCharArray_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
844static int
845WCharArray_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
881static 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/*
896static int
897add_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
912static int
913add_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
929static int
930add_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
945static PyCArgObject *
946ArrayType_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
959static PyObject *
960ArrayType_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
1055PyTypeObject 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
1105SimpleType_new ensures that the new Simple_Type subclass created has a valid
1106_type_ attribute.
1107
1108*/
1109
1110static char *SIMPLE_TYPE_CHARS = "cbBhHiIlLdfuzZqQPXOv";
1111
1112static PyObject *
1113c_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
1176static PyObject *
1177c_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
1240static PyObject *
1241c_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
1376static PyMethodDef c_void_p_method = { "from_param", c_void_p_from_param, METH_O };
1377static PyMethodDef c_char_p_method = { "from_param", c_char_p_from_param, METH_O };
1378static PyMethodDef c_wchar_p_method = { "from_param", c_wchar_p_from_param, METH_O };
1379
1380#else
1381#error
1382static PyMethodDef c_void_p_method = { "from_param", c_void_p_from_param, METH_VARARGS };
1383static PyMethodDef c_char_p_method = { "from_param", c_char_p_from_param, METH_VARARGS };
1384static PyMethodDef c_wchar_p_method = { "from_param", c_wchar_p_from_param, METH_VARARGS };
1385
1386#endif
1387
1388static 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
1455static PyCArgObject *
1456SimpleType_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
1483static PyObject *
1484SimpleType_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 */
1632static PyObject *
1633SimpleType_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
1681static 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
1688PyTypeObject 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
1736static PyObject *
1737converters_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
1778static int
1779make_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
1843static PyCArgObject *
1844CFuncPtrType_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
1860static PyObject *
1861CFuncPtrType_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
1898PyTypeObject 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
1946static CDataObject *
1947CData_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
1962static PyObject *
1963GetKeepedObjects(CDataObject *target)
1964{
1965 return CData_GetContainer(target)->b_objects;
1966}
1967
1968static PyObject *
1969unique_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 */
2017static int
2018KeepRef(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 */
2050static int
2051CData_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
2058static int
2059CData_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
2072static void
2073CData_dealloc(PyObject *self)
2074{
2075 CData_clear((CDataObject *)self);
2076 self->ob_type->tp_free(self);
2077}
2078
2079static 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
2092static 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
2103static Py_ssize_t CData_GetSegcount(PyObject *_self, Py_ssize_t *lenp)
2104{
2105 if (lenp)
2106 *lenp = 1;
2107 return 1;
2108}
2109
2110static 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 */
2120static long
2121CData_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 */
2130static PyObject *
2131CData_from_outparam(PyObject *self, PyObject *args)
2132{
2133 Py_INCREF(self);
2134 return self;
2135}
2136
2137static PyMethodDef CData_methods[] = {
2138 { "__ctypes_from_outparam__", CData_from_outparam, METH_NOARGS, },
2139 { NULL, NULL },
2140};
2141
2142PyTypeObject 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
2185static 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
2213PyObject *
2214CData_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*/
2255PyObject *
2256CData_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*/
2285int 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
2294PyObject *
2295CData_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*/
2311static 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 */
2409int
2410CData_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/******************************************************************/
2435static PyObject *
2436GenericCData_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
2469static int
2470CFuncPtr_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
2483static PyObject *
2484CFuncPtr_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
2494static int
2495CFuncPtr_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
2519static PyObject *
2520CFuncPtr_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
2538static int
2539CFuncPtr_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
2561static PyObject *
2562CFuncPtr_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
2580static 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
2592static 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. */
2629static 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 */
2659static 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
2718static 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
2740static PyObject *
2741CFuncPtr_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
2823static PyObject *
2824CFuncPtr_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*/
2864static PyObject *
2865CFuncPtr_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*/
2968static 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
2991static 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*/
3039static 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*/
3211static 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
3267static PyObject *
3268CFuncPtr_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
3397static int
3398CFuncPtr_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
3410static int
3411CFuncPtr_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
3430static void
3431CFuncPtr_dealloc(CFuncPtrObject *self)
3432{
3433 CFuncPtr_clear(self);
3434 self->ob_type->tp_free((PyObject *)self);
3435}
3436
3437static PyObject *
3438CFuncPtr_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
3452PyTypeObject 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*/
3499static int
3500IBUG(char *msg)
3501{
3502 PyErr_Format(PyExc_RuntimeError,
3503 "inconsistent state in CDataObject (%s)", msg);
3504 return -1;
3505}
3506
3507static int
3508Struct_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
3581static 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
3624static 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*/
3672static int
3673Array_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
3693static PyObject *
3694Array_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
3719static PyObject *
3720Array_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
3765static int
3766Array_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
3794static int
3795Array_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
3836static Py_ssize_t
3837Array_length(PyObject *_self)
3838{
3839 CDataObject *self = (CDataObject *)_self;
3840 return self->b_length;
3841}
3842
3843static 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
3857PyTypeObject 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
3900PyObject *
3901CreateArrayType(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
3966static int
3967Simple_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
3982static int
3983Simple_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
3993static PyObject *
3994Simple_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
4003static PyGetSetDef Simple_getsets[] = {
4004 { "value", (getter)Simple_get_value, (setter)Simple_set_value,
4005 "current value", NULL },
4006 { NULL, NULL }
4007};
4008
4009static PyObject *
4010Simple_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
4020static PyMethodDef Simple_methods[] = {
4021 { "__ctypes_from_outparam__", Simple_from_outparm, METH_NOARGS, },
4022 { NULL, NULL },
4023};
4024
4025static 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
4030static 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 */
4046static PyObject *
4047PyTuple_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) */
4071static PyObject *
4072Simple_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
4109static 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*/
4156static PyObject *
4157Pointer_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
4187static int
4188Pointer_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
4225static PyObject *
4226Pointer_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
4243static int
4244Pointer_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
4285static 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
4292static int
4293Pointer_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
4304static PyObject *
4305Pointer_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
4316static PyObject *
4317Pointer_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
4358static 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
4372static int
4373Pointer_nonzero(CDataObject *self)
4374{
4375 return *(void **)self->b_ptr != NULL;
4376}
4377
4378static 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
4392PyTypeObject 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
4441static char *module_docs =
4442"Create and manipulate C compatible data types in Python.";
4443
4444#ifdef MS_WIN32
4445
4446static char comerror_doc[] = "Raised when a COM method call failed.";
4447
4448static PyObject *
4449comerror_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
4460static PyObject *
4461comerror_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
4491static PyMethodDef comerror_methods[] = {
4492 { "__str__", comerror_str, METH_O },
4493 { "__init__", comerror_init, METH_VARARGS },
4494 { NULL, NULL },
4495};
4496
4497PyObject *COMError;
4498
4499static int
4500create_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
4537static PyObject *
4538string_at(const char *ptr, int size)
4539{
4540 if (size == -1)
4541 return PyString_FromString(ptr);
4542 return PyString_FromStringAndSize(ptr, size);
4543}
4544
4545static int
4546cast_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
4570static PyObject *
4571cast(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
4622static PyObject *
4623wstring_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
4631PyMODINIT_FUNC
4632init_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
4796PyObject *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
4827int 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
28EXPORT(char *)my_strtok(char *token, const char *delim)
29{
30 return strtok(token, delim);
31}
32
33EXPORT(char *)my_strchr(const char *s, int c)
34{
35 return strchr(s, c);
36}
37
38
39EXPORT(double) my_sqrt(double a)
40{
41 return sqrt(a);
42}
43
44EXPORT(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
49EXPORT(int *) _testfunc_ai8(int a[8])
50{
51 return a;
52}
53
54EXPORT(void) _testfunc_v(int a, int b, int *presult)
55{
56 *presult = a + b;
57}
58
59EXPORT(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
67EXPORT(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
75EXPORT(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
83EXPORT(char *) _testfunc_p_p(void *s)
84{
85 return (char *)s;
86}
87
88EXPORT(void *) _testfunc_c_p_p(int *argcp, char **argv)
89{
90 return argv[(*argcp)-1];
91}
92
93EXPORT(void *) get_strchr(void)
94{
95 return (void *)strchr;
96}
97
98EXPORT(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
107EXPORT(void)my_free(void *ptr)
108{
109 free(ptr);
110}
111
112#ifdef HAVE_WCHAR_H
113EXPORT(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
123EXPORT(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
135typedef struct {
136 int (*c)(int, int);
137 int (__stdcall *s)(int, int);
138} FUNCS;
139
140EXPORT(int) _testfunc_callfuncp(FUNCS *fp)
141{
142 fp->c(1, 2);
143 fp->s(3, 4);
144 return 0;
145}
146
147EXPORT(int) _testfunc_deref_pointer(int *pi)
148{
149 return *pi;
150}
151
152#ifdef MS_WIN32
153EXPORT(int) _testfunc_piunk(IUnknown FAR *piunk)
154{
155 piunk->lpVtbl->AddRef(piunk);
156 return piunk->lpVtbl->Release(piunk);
157}
158#endif
159
160EXPORT(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
168EXPORT(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
174EXPORT(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
179EXPORT(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
189EXPORT(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
203typedef struct {
204 char *name;
205 char *value;
206} SPAM;
207
208typedef struct {
209 char *name;
210 int num_spams;
211 SPAM *spams;
212} EGG;
213
214SPAM my_spams[2] = {
215 { "name1", "value1" },
216 { "name2", "value2" },
217};
218
219EGG my_eggs[1] = {
220 { "first egg", 1, my_spams }
221};
222
223EXPORT(int) getSPAMANDEGGS(EGG **eggs)
224{
225 *eggs = my_eggs;
226 return 1;
227}
228
229typedef struct tagpoint {
230 int x;
231 int y;
232} point;
233
234EXPORT(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
243EXPORT (int) an_integer = 42;
244
245EXPORT(int) get_an_integer(void)
246{
247 return an_integer;
248}
249
250EXPORT(double)
251integrate(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
259typedef struct {
260 void (*initialize)(void *(*)(int), void(*)(void *));
261} xxx_library;
262
263static 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
274xxx_library _xxx_lib = {
275 _xxx_init
276};
277
278EXPORT(xxx_library) *library_get(void)
279{
280 return &_xxx_lib;
281}
282
283#ifdef MS_WIN32
284/* See Don Box (german), pp 79ff. */
285EXPORT(void) GetString(BSTR *pbstr)
286{
287 *pbstr = SysAllocString(L"Goodbye!");
288}
289#endif
290
291/*
292 * Some do-nothing functions, for speed tests
293 */
294PyObject *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
304EXPORT(void) _py_func_si(char *s, int i)
305{
306}
307
308PyObject *py_func(PyObject *self, PyObject *args)
309{
310 Py_INCREF(Py_None);
311 return Py_None;
312}
313
314EXPORT(void) _py_func(void)
315{
316}
317
318EXPORT(PY_LONG_LONG) last_tf_arg_s;
319EXPORT(unsigned PY_LONG_LONG) last_tf_arg_u;
320
321struct 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
326DL_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
349DL_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
373PyMethodDef 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
385EXPORT(signed char) tf_b(signed char c) { S; return c/3; }
386EXPORT(unsigned char) tf_B(unsigned char c) { U; return c/3; }
387EXPORT(short) tf_h(short c) { S; return c/3; }
388EXPORT(unsigned short) tf_H(unsigned short c) { U; return c/3; }
389EXPORT(int) tf_i(int c) { S; return c/3; }
390EXPORT(unsigned int) tf_I(unsigned int c) { U; return c/3; }
391EXPORT(long) tf_l(long c) { S; return c/3; }
392EXPORT(unsigned long) tf_L(unsigned long c) { U; return c/3; }
393EXPORT(PY_LONG_LONG) tf_q(PY_LONG_LONG c) { S; return c/3; }
394EXPORT(unsigned PY_LONG_LONG) tf_Q(unsigned PY_LONG_LONG c) { U; return c/3; }
395EXPORT(float) tf_f(float c) { S; return c/3; }
396EXPORT(double) tf_d(double c) { S; return c/3; }
397
398#ifdef MS_WIN32
399EXPORT(signed char) __stdcall s_tf_b(signed char c) { S; return c/3; }
400EXPORT(unsigned char) __stdcall s_tf_B(unsigned char c) { U; return c/3; }
401EXPORT(short) __stdcall s_tf_h(short c) { S; return c/3; }
402EXPORT(unsigned short) __stdcall s_tf_H(unsigned short c) { U; return c/3; }
403EXPORT(int) __stdcall s_tf_i(int c) { S; return c/3; }
404EXPORT(unsigned int) __stdcall s_tf_I(unsigned int c) { U; return c/3; }
405EXPORT(long) __stdcall s_tf_l(long c) { S; return c/3; }
406EXPORT(unsigned long) __stdcall s_tf_L(unsigned long c) { U; return c/3; }
407EXPORT(PY_LONG_LONG) __stdcall s_tf_q(PY_LONG_LONG c) { S; return c/3; }
408EXPORT(unsigned PY_LONG_LONG) __stdcall s_tf_Q(unsigned PY_LONG_LONG c) { U; return c/3; }
409EXPORT(float) __stdcall s_tf_f(float c) { S; return c/3; }
410EXPORT(double) __stdcall s_tf_d(double c) { S; return c/3; }
411#endif
412/*******/
413
414EXPORT(signed char) tf_bb(signed char x, signed char c) { S; return c/3; }
415EXPORT(unsigned char) tf_bB(signed char x, unsigned char c) { U; return c/3; }
416EXPORT(short) tf_bh(signed char x, short c) { S; return c/3; }
417EXPORT(unsigned short) tf_bH(signed char x, unsigned short c) { U; return c/3; }
418EXPORT(int) tf_bi(signed char x, int c) { S; return c/3; }
419EXPORT(unsigned int) tf_bI(signed char x, unsigned int c) { U; return c/3; }
420EXPORT(long) tf_bl(signed char x, long c) { S; return c/3; }
421EXPORT(unsigned long) tf_bL(signed char x, unsigned long c) { U; return c/3; }
422EXPORT(PY_LONG_LONG) tf_bq(signed char x, PY_LONG_LONG c) { S; return c/3; }
423EXPORT(unsigned PY_LONG_LONG) tf_bQ(signed char x, unsigned PY_LONG_LONG c) { U; return c/3; }
424EXPORT(float) tf_bf(signed char x, float c) { S; return c/3; }
425EXPORT(double) tf_bd(signed char x, double c) { S; return c/3; }
426EXPORT(void) tv_i(int c) { S; return; }
427
428#ifdef MS_WIN32
429EXPORT(signed char) __stdcall s_tf_bb(signed char x, signed char c) { S; return c/3; }
430EXPORT(unsigned char) __stdcall s_tf_bB(signed char x, unsigned char c) { U; return c/3; }
431EXPORT(short) __stdcall s_tf_bh(signed char x, short c) { S; return c/3; }
432EXPORT(unsigned short) __stdcall s_tf_bH(signed char x, unsigned short c) { U; return c/3; }
433EXPORT(int) __stdcall s_tf_bi(signed char x, int c) { S; return c/3; }
434EXPORT(unsigned int) __stdcall s_tf_bI(signed char x, unsigned int c) { U; return c/3; }
435EXPORT(long) __stdcall s_tf_bl(signed char x, long c) { S; return c/3; }
436EXPORT(unsigned long) __stdcall s_tf_bL(signed char x, unsigned long c) { U; return c/3; }
437EXPORT(PY_LONG_LONG) __stdcall s_tf_bq(signed char x, PY_LONG_LONG c) { S; return c/3; }
438EXPORT(unsigned PY_LONG_LONG) __stdcall s_tf_bQ(signed char x, unsigned PY_LONG_LONG c) { U; return c/3; }
439EXPORT(float) __stdcall s_tf_bf(signed char x, float c) { S; return c/3; }
440EXPORT(double) __stdcall s_tf_bd(signed char x, double c) { S; return c/3; }
441EXPORT(void) __stdcall s_tv_i(int c) { S; return; }
442#endif
443
444/********/
445
446#ifndef MS_WIN32
447
448typedef struct {
449 long x;
450 long y;
451} POINT;
452
453typedef struct {
454 long left;
455 long top;
456 long right;
457 long bottom;
458} RECT;
459
460#endif
461
462EXPORT(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
475typedef struct {
476 short x;
477 short y;
478} S2H;
479
480EXPORT(S2H) ret_2h_func(S2H inp)
481{
482 inp.x *= 2;
483 inp.y *= 3;
484 return inp;
485}
486
487typedef struct {
488 int a, b, c, d, e, f, g, h;
489} S8I;
490
491EXPORT(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
504EXPORT(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
515EXPORT(void) TwoOutArgs(int a, int *pi, int b, int *pj)
516{
517 *pi += a;
518 *pj += b;
519}
520
521#ifdef MS_WIN32
522EXPORT(S2H) __stdcall s_ret_2h_func(S2H inp) { return ret_2h_func(inp); }
523EXPORT(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
531EXPORT (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
544DL_EXPORT(void)
545init_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 @@
1extern 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
15static void
16PrintError(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 */
32void _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 */
99static void
100TryAddRef(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 */
119static 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) \
204if (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
245static 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
260ffi_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
343void init_callbacks_in_module(PyObject *m)
344{
345 if (PyType_Ready((PyTypeObject *)&PyType_Type) < 0)
346 return;
347}
348
349#ifdef MS_WIN32
350
351static 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
363long 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
403STDAPI 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
423long 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
468STDAPI 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
482BOOL 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
86PyObject *ComError;
87
88static 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
108void 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
259static 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
268static PyObject *
269check_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
283PyCArgObject *
284new_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
297static void
298PyCArg_dealloc(PyCArgObject *self)
299{
300 Py_XDECREF(self->obj);
301 PyObject_Del(self);
302}
303
304static PyObject *
305PyCArg_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
375static PyMemberDef PyCArgType_members[] = {
376 { "_obj", T_OBJECT,
377 offsetof(PyCArgObject, obj), READONLY,
378 "the wrapped object" },
379 { NULL },
380};
381
382PyTypeObject 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
443union 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
457struct 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 */
466static 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
578ffi_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 */
613static 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 */
722static 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 */
765void 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);
796error:
797 Py_XDECREF(tp);
798 Py_XDECREF(v);
799 Py_XDECREF(tb);
800 Py_XDECREF(s);
801}
802
803
804#ifdef MS_WIN32
805
806static PyObject *
807GetComError(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 */
890PyObject *_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
1040static char format_error_doc[] =
1041"FormatError([integer]) -> string\n\
1042\n\
1043Convert a win32 error code into a string. If the error code is not\n\
1044given, the return value of a call to GetLastError() is used.\n";
1045static 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
1064static char load_library_doc[] =
1065"LoadLibrary(name) -> handle\n\
1066\n\
1067Load an executable (usually a DLL), and return a handle to it.\n\
1068The handle may be used to locate exported functions in this\n\
1069module.\n";
1070static 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
1105static char free_library_doc[] =
1106"FreeLibrary(handle) -> void\n\
1107\n\
1108Free the handle of an executable previously loaded by LoadLibrary.\n";
1109static 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) */
1122static PyObject *
1123call_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
1176static char copy_com_pointer_doc[] =
1177"CopyComPointer(src, dst) -> HRESULT value\n";
1178
1179static PyObject *
1180copy_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
1209static 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
1231static 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
1246static 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 */
1269static PyObject *
1270call_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 */
1300static PyObject *
1301call_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 */
1329static 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
1334static PyObject *
1335sizeof_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
1350static 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
1355static PyObject *
1356align_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
1373static 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 */
1382static PyObject *
1383byref(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
1405static char addressof_doc[] =
1406"addressof(C instance) -> integer\n"
1407"Return the address of the C instance internal buffer";
1408
1409static PyObject *
1410addressof(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
1419static int
1420converter(PyObject *obj, void **address)
1421{
1422 *address = PyLong_AsVoidPtr(obj);
1423 return *address != NULL;
1424}
1425
1426static PyObject *
1427My_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
1436static PyObject *
1437My_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
1444static PyObject *
1445My_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
1454static char set_conversion_mode_doc[] =
1455"set_conversion_mode(encoding, errors) -> (previous-encoding, previous-errors)\n\
1456\n\
1457Set the encoding and error handling ctypes uses when converting\n\
1458between unicode and strings. Returns the previous values.\n";
1459
1460static PyObject *
1461set_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
1483static PyObject *
1484resize(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
1547PyMethodDef 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*/
17static PyObject *
18CField_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 */
37PyObject *
38CField_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
194static int
195CField_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
206static PyObject *
207CField_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
220static PyObject *
221CField_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
230static PyObject *
231CField_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
240static 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
246static int
247CField_traverse(CFieldObject *self, visitproc visit, void *arg)
248{
249 Py_VISIT(self->proto);
250 return 0;
251}
252
253static int
254CField_clear(CFieldObject *self)
255{
256 Py_CLEAR(self->proto);
257 return 0;
258}
259
260static void
261CField_dealloc(PyObject *self)
262{
263 CField_clear((CFieldObject *)self);
264 self->ob_type->tp_free((PyObject *)self);
265}
266
267static PyObject *
268CField_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
296PyTypeObject 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
349static int
350get_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
368static int
369get_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
389static int
390get_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
408static int
409get_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
521static PyObject *
522b_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
532static PyObject *
533b_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
540static PyObject *
541B_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
552static PyObject *
553B_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
560static PyObject *
561h_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
574static PyObject *
575h_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
589static PyObject *
590h_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
598static PyObject *
599h_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
608static PyObject *
609H_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
621static PyObject *
622H_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
637static PyObject *
638H_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
646static PyObject *
647H_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
656static PyObject *
657i_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
669static PyObject *
670i_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
685static PyObject *
686i_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
694static PyObject *
695i_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 */
706static PyObject *
707vBOOL_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
721static PyObject *
722vBOOL_get(void *ptr, unsigned size)
723{
724 return PyBool_FromLong((long)*(short int *)ptr);
725}
726#endif
727
728static PyObject *
729I_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
741static PyObject *
742I_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
756static PyObject *
757I_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
765static PyObject *
766I_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
775static PyObject *
776l_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
788static PyObject *
789l_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
804static PyObject *
805l_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
813static PyObject *
814l_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
823static PyObject *
824L_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
836static PyObject *
837L_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
852static PyObject *
853L_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
861static PyObject *
862L_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
872static PyObject *
873q_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
885static PyObject *
886q_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
900static PyObject *
901q_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
909static PyObject *
910q_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
919static PyObject *
920Q_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
932static PyObject *
933Q_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
947static PyObject *
948Q_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
956static PyObject *
957Q_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
973static PyObject *
974d_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
989static PyObject *
990d_get(void *ptr, unsigned size)
991{
992 double val;
993 memcpy(&val, ptr, sizeof(val));
994 return PyFloat_FromDouble(val);
995}
996
997static PyObject *
998d_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
1019static PyObject *
1020d_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
1029static PyObject *
1030f_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
1045static PyObject *
1046f_get(void *ptr, unsigned size)
1047{
1048 float val;
1049 memcpy(&val, ptr, sizeof(val));
1050 return PyFloat_FromDouble(val);
1051}
1052
1053static PyObject *
1054f_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
1075static PyObject *
1076f_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*/
1095static PyObject *
1096O_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
1110static PyObject *
1111O_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
1120static PyObject *
1121c_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
1133static PyObject *
1134c_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 */
1141static PyObject *
1142u_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
1175static PyObject *
1176u_get(void *ptr, unsigned size)
1177{
1178 return PyUnicode_FromWideChar((wchar_t *)ptr, 1);
1179}
1180
1181/* U - a unicode string */
1182static PyObject *
1183U_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
1213static PyObject *
1214U_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
1250static PyObject *
1251s_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
1271static PyObject *
1272s_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
1297static PyObject *
1298z_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
1327static PyObject *
1328z_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
1348static PyObject *
1349Z_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
1412static PyObject *
1413Z_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
1427static PyObject *
1428BSTR_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
1470static PyObject *
1471BSTR_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
1487static PyObject *
1488P_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
1520static PyObject *
1521P_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
1530static 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
1576struct fielddesc *
1577getentry(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
1601typedef struct { char c; char x; } s_char;
1602typedef struct { char c; short x; } s_short;
1603typedef struct { char c; int x; } s_int;
1604typedef struct { char c; long x; } s_long;
1605typedef struct { char c; float x; } s_float;
1606typedef struct { char c; double x; } s_double;
1607typedef struct { char c; char *x; } s_char_p;
1608typedef 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
1623typedef struct { char c; wchar_t x; } s_wchar;
1624typedef 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
1632typedef 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:
1637typedef 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 */
1647ffi_type ffi_type_void = { 1, 1, FFI_TYPE_VOID };
1648
1649ffi_type ffi_type_uint8 = { 1, 1, FFI_TYPE_UINT8 };
1650ffi_type ffi_type_sint8 = { 1, 1, FFI_TYPE_SINT8 };
1651
1652ffi_type ffi_type_uint16 = { 2, 2, FFI_TYPE_UINT16 };
1653ffi_type ffi_type_sint16 = { 2, 2, FFI_TYPE_SINT16 };
1654
1655ffi_type ffi_type_uint32 = { 4, 4, FFI_TYPE_UINT32 };
1656ffi_type ffi_type_sint32 = { 4, 4, FFI_TYPE_SINT32 };
1657
1658ffi_type ffi_type_uint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_UINT64 };
1659ffi_type ffi_type_sint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_SINT64 };
1660
1661ffi_type ffi_type_float = { sizeof(float), FLOAT_ALIGN, FFI_TYPE_FLOAT };
1662ffi_type ffi_type_double = { sizeof(double), DOUBLE_ALIGN, FFI_TYPE_DOUBLE };
1663
1664/* ffi_type ffi_type_longdouble */
1665
1666ffi_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)
6typedef 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
26typedef struct tagPyCArgObject PyCArgObject;
27typedef struct tagCDataObject CDataObject;
28typedef PyObject *(* GETFUNC)(void *, unsigned size);
29typedef PyObject *(* SETFUNC)(void *, PyObject *value, unsigned size);
30typedef PyCArgObject *(* PARAMFUNC)(CDataObject *obj);
31
32/* A default buffer in CDataObject, which can be used for small C types. If
33this buffer is too small, PyMem_Malloc will be called to create a larger one,
34and this one is not used.
35
36Making CDataObject a variable size object would be a better solution, but more
37difficult in the presence of CFuncPtrObject. Maybe later.
38*/
39union 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
57struct 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
70typedef 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
80typedef 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
111extern PyTypeObject StgDict_Type;
112#define StgDict_CheckExact(v) ((v)->ob_type == &StgDict_Type)
113#define StgDict_Check(v) PyObject_TypeCheck(v, &StgDict_Type)
114
115extern int StructUnionType_update_stgdict(PyObject *fields, PyObject *type, int isStruct);
116extern int PyType_stginfo(PyTypeObject *self, Py_ssize_t *psize, Py_ssize_t *palign, Py_ssize_t *plength);
117extern int PyObject_stginfo(PyObject *self, Py_ssize_t *psize, Py_ssize_t *palign, Py_ssize_t *plength);
118
119
120
121extern PyTypeObject CData_Type;
122#define CDataObject_CheckExact(v) ((v)->ob_type == &CData_Type)
123#define CDataObject_Check(v) PyObject_TypeCheck(v, &CData_Type)
124
125extern PyTypeObject SimpleType_Type;
126#define SimpleTypeObject_CheckExact(v) ((v)->ob_type == &SimpleType_Type)
127#define SimpleTypeObject_Check(v) PyObject_TypeCheck(v, &SimpleType_Type)
128
129extern PyTypeObject CField_Type;
130extern struct fielddesc *getentry(char *fmt);
131
132
133extern PyObject *
134CField_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
139extern PyObject *CData_AtAddress(PyObject *type, void *buf);
140extern PyObject *CData_FromBytes(PyObject *type, char *data, Py_ssize_t length);
141
142extern PyTypeObject ArrayType_Type;
143extern PyTypeObject Array_Type;
144extern PyTypeObject PointerType_Type;
145extern PyTypeObject Pointer_Type;
146extern PyTypeObject CFuncPtr_Type;
147extern PyTypeObject CFuncPtrType_Type;
148extern 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
158extern PyObject *
159CreateArrayType(PyObject *itemtype, Py_ssize_t length);
160
161extern void init_callbacks_in_module(PyObject *m);
162
163extern PyMethodDef module_methods[];
164
165extern ffi_info *AllocFunctionCallback(PyObject *callable,
166 PyObject *converters,
167 PyObject *restype,
168 int stdcall);
169/* a table entry describing a predefined ctypes type */
170struct 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
179typedef 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 */
193typedef 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! */
261extern StgDictObject *PyType_stgdict(PyObject *obj);
262
263/* May return NULL, but does not set an exception! */
264extern StgDictObject *PyObject_stgdict(PyObject *self);
265
266extern int StgDict_clone(StgDictObject *src, StgDictObject *dst);
267
268typedef int(* PPROC)(void);
269
270PyObject *_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
289struct 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
310extern PyTypeObject PyCArg_Type;
311extern PyCArgObject *new_CArgObject(void);
312#define PyCArg_CheckExact(v) ((v)->ob_type == &PyCArg_Type)
313extern PyCArgObject *new_CArgObject(void);
314
315extern PyObject *
316CData_get(PyObject *type, GETFUNC getfunc, PyObject *src,
317 Py_ssize_t index, Py_ssize_t size, char *ptr);
318
319extern int
320CData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
321 Py_ssize_t index, Py_ssize_t size, char *ptr);
322
323extern void Extend_Error_Info(PyObject *exc_class, char *fmt, ...);
324
325struct basespec {
326 CDataObject *base;
327 Py_ssize_t index;
328 char *adr;
329};
330
331extern char basespec_string[];
332
333extern ffi_type *GetType(PyObject *obj);
334
335/* exception classes */
336extern PyObject *PyExc_ArgError;
337
338extern char *conversion_mode_encoding;
339extern 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
383extern PyObject *My_PyUnicode_FromWideChar(const wchar_t *, Py_ssize_t);
384extern int My_PyUnicode_AsWideChar(PyUnicodeObject *, wchar_t *, Py_ssize_t);
385
386#endif
387
388extern void FreeClosure(void *);
389extern void *MallocClosure(void);
390
391extern void _AddTraceback(char *, char *, int);
392
393extern PyObject *CData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr);
394
395/* XXX better name needed! */
396extern int IsSimpleSubType(PyObject *obj);
397
398
399#ifdef MS_WIN32
400extern 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
9extern "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 @@
1Copyright (c) 2002 Jorge Acereda <jacereda@users.sourceforge.net> &
2 Peter O'Gorman <ogorman@users.sourceforge.net>
3
4Portions may be copyright others, see the AUTHORS file included with this
5distribution.
6
7Maintained by Peter O'Gorman <ogorman@users.sourceforge.net>
8
9Bug Reports and other queries should go to <ogorman@users.sourceforge.net>
10
11
12Permission is hereby granted, free of charge, to any person obtaining
13a copy of this software and associated documentation files (the
14"Software"), to deal in the Software without restriction, including
15without limitation the rights to use, copy, modify, merge, publish,
16distribute, sublicense, and/or sell copies of the Software, and to
17permit persons to whom the Software is furnished to do so, subject to
18the following conditions:
19
20The above copyright notice and this permission notice shall be
21included in all copies or substantial portions of the Software.
22
23THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29WITH 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 @@
1dlcompat for Darwin
2=========================
3
4This is dlcompat, a small library that emulates the dlopen()
5interface on top of Darwin's dyld API.
6
7dlcompat allows loading a ".dylib" library (as long as the RTLD_LOCAL
8flag isn't passed to dlopen()). It can be configured to yield a warning
9when trying to close it (dynamic libraries cannot currently be unloaded).
10
11It automatically searches for modules in several directories when no
12absolute path is specified and the module is not found in the current
13directory.
14
15The paths searched are those specified in the environment variables
16LD_LIBRARY_PATH and DYLD_LIBRARY_PATH plus /lib, /usr/local/lib and
17/usr/lib or the path specified in the environment variable
18DYLD_FALLBACK_LIBRARY_PATH.
19
20In the default install the behavior of dlsym is to automatically prepend
21an underscore to passed in symbol names, this allows easier porting of
22applications which were written specifically for ELF based lifeforms.
23
24Installation
25--------------
26Type:
27 ./configure
28 make
29 sudo make install
30
31This will compile the source file, generate both a static and shared
32library called libdl and install it into /usr/local/lib. The header
33file dlfcn.h will be installed in /usr/local/include.
34
35If you want to place the files somewhere else, run
36
37 make clean
38 ./configure --prefix=<prefix>
39 make
40 sudo make install
41
42where <prefix> is the hierarchy you want to install into, e.g. /usr
43for /usr/lib and /usr/include (_NOT_ recommended!).
44
45To enable debugging output (useful for me), run
46
47 make clean
48 ./configure --enable-debug
49 make
50 sudo make install
51
52If you want old dlcompat style behavior of not prepending the underscore
53on calls to dlsym then type:
54
55 make clean
56 ./configure --enable-fink
57 make
58 sudo make install
59
60Usage
61-------
62Software that uses GNU autoconf will likely check for a library called
63libdl, that's why I named it that way. For software that doesn't find
64the library on its own, you must add a '-ldl' to the appropriate
65Makefile (or environment) variable, usually LIBS.
66
67If you installed dlcompat into a directory other than /usr/local/lib,
68you must tell the compiler where to find it. Add '-L<prefix>/lib' to
69LDFLAGS (or CFLAGS) and '-I<prefix>/include' to CPPFLAGS (or CFLAGS).
70
71Notes
72-----
73If you are writing new software and plan to have Mac OX X compatibility you
74should look at the dyld api's in /usr/include/mach-o/dyld.h, rather than
75using dlcompat, using the native api's is the supported method of loading
76dynamically on Mac OS X, if you want an small example, look at dlfcn_simple.c,
77which should help get you started.
78
79Also note that the functions in dlcompat are not thread safe, and while it is not
80POSIX spec compliant, it is about as close to compliance as it is going to get though.
81
82You 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
89It is hoped that this library will be useful, and as bug free as possible, if you find
90any bugs please let us know about them so they can be fixed.
91
92Please send bug reports to Peter O'Gorman <ogorman@users.sourceforge.net>
93
94Thanks.
95
sys/src/cmd/python/Modules/_ctypes/darwin/README.ctypes+11−0
@@ -0,0 +1,11 @@
1The files in this directory are taken from
2http://www.opendarwin.org/cgi-bin/cvsweb.cgi/~checkout~/proj/dlcompat/
3
4The LICENSE in this directory applies to these files.
5
6Thomas Heller, Jan 2003
7
8These files have been modified so they fall back to the system
9dlfcn calls if available in libSystem.
10
11Bob Ippolito, Feb 2006
sys/src/cmd/python/Modules/_ctypes/darwin/dlfcn.h+84−0
@@ -0,0 +1,84 @@
1/*
2Copyright (c) 2002 Jorge Acereda <jacereda@users.sourceforge.net> &
3 Peter O'Gorman <ogorman@users.sourceforge.net>
4
5Portions may be copyright others, see the AUTHORS file included with this
6distribution.
7
8Maintained by Peter O'Gorman <ogorman@users.sourceforge.net>
9
10Bug Reports and other queries should go to <ogorman@users.sourceforge.net>
11
12Permission is hereby granted, free of charge, to any person obtaining
13a copy of this software and associated documentation files (the
14"Software"), to deal in the Software without restriction, including
15without limitation the rights to use, copy, modify, merge, publish,
16distribute, sublicense, and/or sell copies of the Software, and to
17permit persons to whom the Software is furnished to do so, subject to
18the following conditions:
19
20The above copyright notice and this permission notice shall be
21included in all copies or substantial portions of the Software.
22
23THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29WITH 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
37extern "C" {
38#endif
39
40
41/*
42 * Structure filled in by dladdr().
43 */
44
45typedef 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
56extern void * (*ctypes_dlopen)(const char *path, int mode);
57extern void * (*ctypes_dlsym)(void * handle, const char *symbol);
58extern const char * (*ctypes_dlerror)(void);
59extern int (*ctypes_dlclose)(void * handle);
60extern int (*ctypes_dladdr)(const void *, Dl_info *);
61#else
62extern void * dlopen(const char *path, int mode);
63extern void * dlsym(void * handle, const char *symbol);
64extern const char * dlerror(void);
65extern int dlclose(void * handle);
66extern 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/*
2Copyright (c) 2002 Peter O'Gorman <ogorman@users.sourceforge.net>
3
4Permission is hereby granted, free of charge, to any person obtaining
5a copy of this software and associated documentation files (the
6"Software"), to deal in the Software without restriction, including
7without limitation the rights to use, copy, modify, merge, publish,
8distribute, sublicense, and/or sell copies of the Software, and to
9permit persons to whom the Software is furnished to do so, subject to
10the following conditions:
11
12The above copyright notice and this permission notice shall be
13included in all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21WITH 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
53extern void * dlopen(const char *path, int mode) __attribute__((weak_import));
54extern void * dlsym(void * handle, const char *symbol) __attribute__((weak_import));
55extern const char * dlerror(void) __attribute__((weak_import));
56extern int dlclose(void * handle) __attribute__((weak_import));
57extern 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
68void * (*ctypes_dlopen)(const char *path, int mode);
69void * (*ctypes_dlsym)(void * handle, const char *symbol);
70const char * (*ctypes_dlerror)(void);
71int (*ctypes_dlclose)(void * handle);
72int (*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
77static void *dlsymIntern(void *handle, const char *symbol);
78
79static const char *error(int setget, const char *str, ...);
80
81/* Set and get the error string for use by dlerror */
82static 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 */
109static 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 */
148static 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
191static const char *darwin_dlerror(void)
192{
193 return error(1, (char *)NULL);
194}
195
196static 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 */
214static 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
243static 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
251static void __attribute__ ((constructor)) ctypes_dlfcn_init(void);
252static
253#endif
254void 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 @@
1libffi - Copyright (c) 1996-2003 Red Hat, Inc.
2
3Permission is hereby granted, free of charge, to any person obtaining
4a copy of this software and associated documentation files (the
5``Software''), to deal in the Software without restriction, including
6without limitation the rights to use, copy, modify, merge, publish,
7distribute, sublicense, and/or sell copies of the Software, and to
8permit persons to whom the Software is furnished to do so, subject to
9the following conditions:
10
11The above copyright notice and this permission notice shall be included
12in all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
15OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20OTHER DEALINGS IN THE SOFTWARE.
sys/src/cmd/python/Modules/_ctypes/libffi/README+500−0
@@ -0,0 +1,500 @@
1This directory contains the libffi package, which is not part of GCC but
2shipped with GCC as convenience.
3
4Status
5======
6
7libffi-2.00 has not been released yet! This is a development snapshot!
8
9libffi-1.20 was released on October 5, 1998. Check the libffi web
10page for updates: <URL:http://sources.redhat.com/libffi/>.
11
12
13What is libffi?
14===============
15
16Compilers for high level languages generate code that follow certain
17conventions. These conventions are necessary, in part, for separate
18compilation to work. One such convention is the "calling
19convention". The "calling convention" is essentially a set of
20assumptions made by the compiler about where function arguments will
21be found on entry to a function. A "calling convention" also specifies
22where the return value for a function is found.
23
24Some programs may not know at the time of compilation what arguments
25are to be passed to a function. For instance, an interpreter may be
26told at run-time about the number and types of arguments used to call
27a given function. Libffi can be used in such programs to provide a
28bridge from the interpreter program to compiled code.
29
30The libffi library provides a portable, high level programming
31interface to various calling conventions. This allows a programmer to
32call any function specified by a call interface description at run
33time.
34
35Ffi stands for Foreign Function Interface. A foreign function
36interface is the popular name for the interface that allows code
37written in one language to call code written in another language. The
38libffi library really only provides the lowest, machine dependent
39layer of a fully featured foreign function interface. A layer must
40exist above libffi that handles type conversions for values passed
41between the two languages.
42
43
44Supported Platforms and Prerequisites
45=====================================
46
47Libffi 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
63Libffi has been tested with the egcs 1.0.2 gcc compiler. Chances are
64that other versions will work. Libffi has also been built and tested
65with the SGI compiler tools.
66
67On PowerPC, the tests failed (see the note below).
68
69You must use GNU make to build libffi. SGI's make will not work.
70Sun's probably won't either.
71
72If you port libffi to another platform, please let me know! I assume
73that some will be easy (x86 NetBSD), and others will be more difficult
74(HP).
75
76
77Installing 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
83First you must configure the distribution for your particular
84system. 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
86distribution.
87
88You may want to tell configure where to install the libffi library and
89header files. To do that, use the --prefix configure switch. Libffi
90will install under /usr/local by default.
91
92If you want to enable extra run-time debugging checks use the the
93--enable-debug configure switch. This is useful when your program dies
94mysteriously while using libffi.
95
96Another useful configure switch is --enable-purify-safety. Using this
97will add some extra code which will suppress certain warnings when you
98are using Purify with libffi. Only use this switch when using
99Purify, as it will slow down the library.
100
101Configure has many other options. Use "configure --help" to see them all.
102
103Once configure has finished, type "make". Note that you must be using
104GNU make. SGI's make will not work. Sun's probably won't either.
105You can ftp GNU make from prep.ai.mit.edu:/pub/gnu.
106
107To ensure that libffi is working as advertised, type "make test".
108
109To install the library and header files, type "make install".
110
111
112Using libffi
113============
114
115 The Basics
116 ----------
117
118Libffi assumes that you have a pointer to the function you wish to
119call and that you know the number and types of arguments to pass it,
120as well as the return type of the function.
121
122The first thing you must do is create an ffi_cif object that matches
123the signature of the function you wish to call. The cif in ffi_cif
124stands for Call InterFace. To prepare a call interface object, use the
125following function:
126
127ffi_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
156ffi_prep_cif will return a status code that you are responsible
157for 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
165Before making the call, the VALUES vector should be initialized
166with pointers to the appropriate argument values.
167
168To call the the function using the initialized ffi_cif, use the
169ffi_call function:
170
171void 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
193If you are expecting a return value from FN it will have been stored
194at RVALUE.
195
196
197
198 An Example
199 ----------
200
201Here 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
241Although libffi has no special support for unions or bit-fields, it is
242perfectly happy passing structures back and forth. You must first
243describe the structure to libffi by creating a new ffi_type object
244for 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
254All structures must have type set to FFI_TYPE_STRUCT. You may set
255size and alignment to 0. These will be calculated and reset to the
256appropriate values by ffi_prep_cif().
257
258elements is a NULL terminated array of pointers to ffi_type objects
259that describe the type of the structure elements. These may, in turn,
260be structure elements.
261
262The following example initializes a ffi_type object representing the
263tm 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
301Platform Specific Notes
302=======================
303
304 Intel x86
305 ---------
306
307There are no known problems with the x86 port.
308
309 Sun SPARC - SunOS 4.1.3 & Solaris 2.x
310 -------------------------------------
311
312You must use GNU Make to build libffi on Sun platforms.
313
314 MIPS - Irix 5.3 & 6.x
315 ---------------------
316
317Irix 6.2 and better supports three different calling conventions: o32,
318n32 and n64. Currently, libffi only supports both o32 and n32 under
319Irix 6.x, but only o32 under Irix 5.3. Libffi will automatically be
320configured for whichever calling convention it was built for.
321
322By default, the configure script will try to build libffi with the GNU
323development tools. To build libffi with the SGI development tools, set
324the environment variable CC to either "cc -32" or "cc -n32" before
325running configure under Irix 6.x (depending on whether you want an o32
326or n32 library), or just "cc" for Irix 5.3.
327
328With the n32 calling convention, when returning structures smaller
329than 16 bytes, be sure to provide an RVALUE that is 8 byte aligned.
330Here'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
336If you don't do this you are liable to get spurious bus errors.
337
338"long long" values are not supported yet.
339
340You must use GNU Make to build libffi on SGI platforms.
341
342 ARM - System V ABI
343 ------------------
344
345The 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
353There are two `System V ABI's which libffi implements for PowerPC.
354They differ only in how small structures are returned from functions.
355
356In the FFI_SYSV version, structures that are 8 bytes or smaller are
357returned in registers. This is what GCC does when it is configured
358for solaris, and is what the System V ABI I have (dated September
3591995) says.
360
361In the FFI_GCC_SYSV version, all structures are returned the same way:
362by passing a pointer as the first argument to the function. This is
363what GCC does when it is configured for linux or a generic sysv
364target.
365
366EGCS 1.0.1 (and probably other versions of EGCS/GCC) also has a
367inconsistency with the SysV ABI: When a procedure is called with many
368floating-point arguments, some of them get put on the stack. They are
369all supposed to be stored in double-precision format, even if they are
370only single-precision, but EGCS stores single-precision arguments as
371single-precision anyway. This causes one test to fail (the `many
372arguments' test).
373
374
375What's With The Crazy Comments?
376===============================
377
378You might notice a number of cryptic comments in the code, delimited
379by /*@ and @*/. These are annotations read by the program LCLint, a
380tool 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
384History
385=======
386
3871.20 Oct-5-98
388 Raffaele Sena produces ARM port.
389
3901.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
3961.18 Apr-17-98
397 Bug fixes and MIPS configuration changes.
398
3991.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
4031.16 Feb-11-98
404 Richard Henderson produces Alpha port.
405
4061.15 Dec-4-97
407 Fixed an n32 ABI bug. New libtool, auto* support.
408
4091.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
4141.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
4201.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
4251.11 Oct-30-96
426 Added notes about GNU make.
427
4281.10 Oct-29-96
429 Added configuration fix for non GNU compilers.
430
4311.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
4361.08 Oct-15-96
437 Fixed n32 problem. Many clean-ups.
438
4391.07 Oct-14-96
440 Gordon Irlam rewrites v8.S again. Bug fixes.
441
4421.06 Oct-14-96
443 Gordon Irlam improved the sparc port.
444
4451.05 Oct-14-96
446 Interface changes based on feedback.
447
4481.04 Oct-11-96
449 Sparc port complete (modulo struct passing bug).
450
4511.03 Oct-10-96
452 Passing struct args, and returning struct values works for
453 all architectures/calling conventions. Expanded tests.
454
4551.02 Oct-9-96
456 Added SGI n32 support. Fixed bugs in both o32 and Linux support.
457 Added "make test".
458
4591.01 Oct-8-96
460 Fixed float passing bug in mips version. Restructured some
461 of the code. Builds cleanly with SGI tools.
462
4631.00 Oct-7-96
464 First release. No public announcement.
465
466
467Authors & Credits
468=================
469
470libffi was written by Anthony Green <green@cygnus.com>.
471
472Portions of libffi were derived from Gianni Mariani's free gencall
473library for Silicon Graphics machines.
474
475The closure mechanism was designed and implemented by Kresten Krab
476Thorup.
477
478The Sparc port was derived from code contributed by the fine folks at
479Visible Decisions Inc <http://www.vdi.com>. Further enhancements were
480made by Gordon Irlam at Cygnus Solutions <http://www.cygnus.com>.
481
482The Alpha port was written by Richard Henderson at Cygnus Solutions.
483
484Andreas Schwab ported libffi to m68k Linux and provided a number of
485bug fixes.
486
487Geoffrey Keating ported libffi to the PowerPC.
488
489Raffaele Sena ported libffi to the ARM.
490
491Jesper Skov and Andrew Haley both did more than their fair share of
492stepping through the code and tracking down bugs.
493
494Thanks also to Tom Tromey for bug fixes and configuration help.
495
496Thanks to Jim Blandy, who provided some useful feedback on the libffi
497interface.
498
499If you have a problem, or have found a bug, please send a note to
500green@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.
3AC_DEFUN([AC_FUNC_MMAP_BLACKLIST],
4[
5AC_CHECK_HEADER([sys/mman.h],
6 [libffi_header_sys_mman_h=yes], [libffi_header_sys_mman_h=no])
7AC_CHECK_FUNC([mmap], [libffi_func_mmap=yes], [libffi_func_mmap=no])
8if 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
13else
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
78fi
79
80if 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.])
83fi
84if 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.])
87fi
88if test $ac_cv_func_mmap_anon = yes; then
89 AC_DEFINE(HAVE_MMAP_ANON, 1,
90 [Define if mmap with MAP_ANON(YMOUS) works.])
91fi
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
6timestamp='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
38me=`echo "$0" | sed -e 's,.*/,,'`
39
40usage="\
41Usage: $0 [OPTION]
42
43Output the configuration name of the system \`$me' is run on.
44
45Operation 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
50Report bugs and patches to <config-patches@gnu.org>."
51
52version="\
53GNU config.guess ($timestamp)
54
55Originally written by Per Bothner.
56Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
57Free Software Foundation, Inc.
58
59This is free software; see the source for copying conditions. There is NO
60warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
61
62help="
63Try \`$me --help' for more information."
64
65# Parse command line
66while 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
84done
85
86if test $# != 0; then
87 echo "$me: too many arguments$help" >&2
88 exit 1
89fi
90
91trap '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
103set_cc_for_build='
104trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
105trap "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 ; } ;
111dummy=$tmp/dummy ;
112tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
113case $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 ;;
126esac ;'
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)
130if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
131 PATH=$PATH:/.attbin ; export PATH
132fi
133
134UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
135UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
136UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
137UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
138
139# Note: order is significant - the case branches are not exclusive.
140
141case "${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 }
460EOF
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.