From 379061dbfffe74b645456e3101e87adb38c229c1 Mon Sep 17 00:00:00 2001 From: Apex Liu Date: Fri, 22 Nov 2019 02:12:01 +0800 Subject: [PATCH] fix: update to Python 3.7.5 and new PIL module, can not save JPEG image. --- build/builder/build-pysrt.py | 8 +- .../libffi-806b1a9d.so.6.0.4 | Bin 0 -> 46632 bytes ...fi_backend.cpython-37m-x86_64-linux-gnu.so | Bin 0 -> 853840 bytes .../packages-linux/x64/cffi/__init__.py | 14 + .../packages-linux/x64/cffi/_cffi_errors.h | 147 ++ .../packages-linux/x64/cffi/_cffi_include.h | 308 ++++ .../packages-linux/x64/cffi/_embedding.h | 520 ++++++ .../packages/packages-linux/x64/cffi/api.py | 961 ++++++++++ .../packages-linux/x64/cffi/backend_ctypes.py | 1121 ++++++++++++ .../packages-linux/x64/cffi/cffi_opcode.py | 187 ++ .../packages-linux/x64/cffi/commontypes.py | 80 + .../packages-linux/x64/cffi/cparser.py | 963 ++++++++++ .../packages/packages-linux/x64/cffi/error.py | 31 + .../packages-linux/x64/cffi/ffiplatform.py | 127 ++ .../packages/packages-linux/x64/cffi/lock.py | 30 + .../packages/packages-linux/x64/cffi/model.py | 614 +++++++ .../packages-linux/x64/cffi/parse_c_type.h | 181 ++ .../packages-linux/x64/cffi/pkgconfig.py | 121 ++ .../packages-linux/x64/cffi/recompiler.py | 1543 +++++++++++++++++ .../packages-linux/x64/cffi/setuptools_ext.py | 217 +++ .../packages-linux/x64/cffi/vengine_cpy.py | 1015 +++++++++++ .../packages-linux/x64/cffi/vengine_gen.py | 675 +++++++ .../packages-linux/x64/cffi/verifier.py | 306 ++++ 23 files changed, 9165 insertions(+), 4 deletions(-) create mode 100755 server/www/packages/packages-linux/x64/.libs_cffi_backend/libffi-806b1a9d.so.6.0.4 create mode 100755 server/www/packages/packages-linux/x64/_cffi_backend.cpython-37m-x86_64-linux-gnu.so create mode 100644 server/www/packages/packages-linux/x64/cffi/__init__.py create mode 100644 server/www/packages/packages-linux/x64/cffi/_cffi_errors.h create mode 100644 server/www/packages/packages-linux/x64/cffi/_cffi_include.h create mode 100644 server/www/packages/packages-linux/x64/cffi/_embedding.h create mode 100644 server/www/packages/packages-linux/x64/cffi/api.py create mode 100644 server/www/packages/packages-linux/x64/cffi/backend_ctypes.py create mode 100644 server/www/packages/packages-linux/x64/cffi/cffi_opcode.py create mode 100644 server/www/packages/packages-linux/x64/cffi/commontypes.py create mode 100644 server/www/packages/packages-linux/x64/cffi/cparser.py create mode 100644 server/www/packages/packages-linux/x64/cffi/error.py create mode 100644 server/www/packages/packages-linux/x64/cffi/ffiplatform.py create mode 100644 server/www/packages/packages-linux/x64/cffi/lock.py create mode 100644 server/www/packages/packages-linux/x64/cffi/model.py create mode 100644 server/www/packages/packages-linux/x64/cffi/parse_c_type.h create mode 100644 server/www/packages/packages-linux/x64/cffi/pkgconfig.py create mode 100644 server/www/packages/packages-linux/x64/cffi/recompiler.py create mode 100644 server/www/packages/packages-linux/x64/cffi/setuptools_ext.py create mode 100644 server/www/packages/packages-linux/x64/cffi/vengine_cpy.py create mode 100644 server/www/packages/packages-linux/x64/cffi/vengine_gen.py create mode 100644 server/www/packages/packages-linux/x64/cffi/verifier.py diff --git a/build/builder/build-pysrt.py b/build/builder/build-pysrt.py index 965340e..637763c 100644 --- a/build/builder/build-pysrt.py +++ b/build/builder/build-pysrt.py @@ -13,11 +13,11 @@ ctx = BuildContext() MODULES_WIN = ['_asyncio', '_bz2', '_ctypes', '_hashlib', '_lzma', '_overlapped', '_socket', '_sqlite3', '_ssl', 'select', 'sqlite3', 'libcrypto-1_1', 'libssl-1_1', 'unicodedata'] -PY_LIB_REMOVE_WIN = ['ctypes/test', 'curses', 'dbm', 'distutils', 'email/test', 'ensurepip', 'idlelib', 'lib2to3', +PY_LIB_REMOVE_WIN = ['ctypes/test', 'curses', 'dbm', 'distutils/test', 'email/tests', 'ensurepip', 'idlelib', 'lib2to3', 'lib-dynload', 'pydoc_data', 'site-packages', 'sqlite3/test', 'test', 'tkinter', 'turtledemo', 'unittest', 'venv', 'wsgiref', 'doctest.py', 'pdb.py', 'py_compile.py', 'pydoc.py', 'this.py', 'wave.py', 'webbrowser.py', 'zipapp.py'] -PY_LIB_REMOVE_LINUX = ['ctypes/test', 'curses', 'dbm', 'distutils', 'ensurepip', 'idlelib', 'lib2to3', +PY_LIB_REMOVE_LINUX = ['ctypes/test', 'curses', 'dbm', 'distutils/tests', 'ensurepip', 'idlelib', 'lib2to3', 'lib-dynload', 'pydoc_data', 'site-packages', 'sqlite3/test', 'test', 'tkinter', 'turtledemo', 'unittest', 'venv', 'wsgiref', 'doctest.py', 'pdb.py', 'py_compile.py', 'pydoc.py', 'this.py', 'wave.py', 'webbrowser.py', 'zipapp.py'] PY_MODULE_REMOVE_LINUX = ['_ctypes_test', '_testbuffer', '_testcapi', '_testimportmultiple', '_testmultiphase', '_xxtestfuzz'] @@ -46,7 +46,7 @@ class PYSBase: utils.sys_exec('{} -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pip --upgrade'.format(env.py_exec)) pip = self._get_pip() - pypi_modules = ['cryptography', 'ldap3', 'mako', 'Pillow', 'psutil', 'pyasn1', 'pymysql', 'qrcode', 'tornado', 'wheezy.captcha'] + pypi_modules = ['cffi', 'cryptography', 'ldap3', 'mako', 'Pillow', 'psutil', 'pyasn1', 'pymysql', 'qrcode', 'tornado', 'wheezy.captcha'] for p in pypi_modules: cc.n('install {} ...'.format(p)) utils.sys_exec('{} install -i https://pypi.tuna.tsinghua.edu.cn/simple {}'.format(pip, p), direct_output=True) @@ -111,7 +111,7 @@ class PYSBase: utils.ensure_file_exists(out_file) cc.v('remove temp folder...') - utils.remove(_tmp_) + # utils.remove(_tmp_) def _make_py_ver_file(self): pass diff --git a/server/www/packages/packages-linux/x64/.libs_cffi_backend/libffi-806b1a9d.so.6.0.4 b/server/www/packages/packages-linux/x64/.libs_cffi_backend/libffi-806b1a9d.so.6.0.4 new file mode 100755 index 0000000000000000000000000000000000000000..a74aa9041fd420b073f41bbd2d2592bec4039ea4 GIT binary patch literal 46632 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 SH}#FnsCntZ7tXLZ75^7aC(SGX literal 0 HcmV?d00001 diff --git a/server/www/packages/packages-linux/x64/_cffi_backend.cpython-37m-x86_64-linux-gnu.so b/server/www/packages/packages-linux/x64/_cffi_backend.cpython-37m-x86_64-linux-gnu.so new file mode 100755 index 0000000000000000000000000000000000000000..7b041a62e04a4539c95695ba9f6de3eb5d63c57f GIT binary patch literal 853840 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≥36&cZ>yqx@rI0* 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

tf zSMnhCPZ}M$N#w%rV5h%S!%h4J-(m@iKApNy-(vHU=U<^_HVC|x6EVfYv7AG4IIFMl zj!rl&;X-RKYJS{WR8bmZ0E(gK5tE;tdqyK^=0 zp3YUldplPF@8et<{8r~m;CDDz1b<$+u7lw!q2wRd)XPmUkf7ya3LLMhk{gwFhY`j_ z5V-FMK}OS*6(c~LlexWITi;x30jZ@d2_ViSuC>fHaw>vAoJj>4xgXK@N=Q-N{Ad74 zm27rE6sGrbj0P<72JmR3T0opg=Z5+CjM`sde$;_iD3$Ez;GZbhJ@_+N?sI|T)Q_%Q zXtS#Fd-^;e0n3*UOJKt7-ncM0$O5ec2{iWx=Tx(qI^d!6ikDhXci`+7gWmp@p~e$Lu!ueJ8t`|NY7 zy0T*BH2cTo&a;0^uA5+q%x)@F$7aEoslcs6{KM}b`=%{oyM1G{PIW~fF21gE>D=K7 zlh+@ESVO*;QQ-Qba-+0xy5vJ1^8RG-xdl8RxH165%glT$_Qx#1d{pD8|HynY~umG z82a`C*A8I~0tqBHN6W)XzSTxpD~7P90Nzxg93I2x^WNu6#bkE4%ioiT0p zHE$r3_RpEYxSC3*3vXB(g=O-VP-2GwSuR%Rz+!>@_f}5qZ^>O8Z`q(My}$!Bdv@do z7G3-A?NzC3$$o=t?DzlETmO$jyv@|RVz+BhMYC z;XaxLeB4GWwXI3RcQ(`P15W`)jI<}1)NbX8XZ+8t-7;XuME)TYowsG z4S(Mx9lI3(anT+p`g9d`O#NFUkoU4Oh?_3RBb*>7oIoAc=Y3stk@tl$RYvr*`Ht-vw@=~SscUJ_iu0eA} zTAPYBi@-Aj)epQNP<_Cei8*3_{yaRlS3xI zWYS~fc8c!!PdJq5cKo&F65WpfghPpL$6s6CP~j1pJ^B)zS4#3Os7JlF4f$#S-OvDr zW(BPQ;8>sl?Ee>pJqsSlrUz@CTFzlFdBjF;tAuIw$D z-3GyZ&Q-w&IadQ8;#?j49_PBjhdS2-KHRxU;O}f7ZXR=&qw#%_=HMjo1J3n;f9PB{ z_(A9D;D?;6fq&v$75uPsUEoJ|EjSpL;hu`{m*X9Cp+EZRy> zH)B1yhhLPmr*q)v6p&Tgtn;2!!!u zSLTk{CU+$Jo(}jV_jqoZ$8&?n4|y1K&pU4C+*HplA-1{a?Wsn;WH!#F!fS?Uy>#w* zZ%|{PNG{#$p2TZ=TqZ3W?vQ(86maW6HGpG*Y69m6Y6$q*9Ya+2pGV_%kv0JEN1|SD zpD1VFpngl&tLu$aHXeIe{4Yb7Uf}Rf!Oaf|KIGIBg3mcMUTI%V(uN1F6R0Net$`W> z9w5pp?fzsk&00K_Mx_(k6DIN+pYi+8qw%On>kDMU?KTikw`s+beNR%NKG}zD7iMGr z^rO@$)b0GTr7=G&jY8edpH8s1seUaf^QSLNi+TR^CFOwF+P&lG+GHHxWs2_;lD206 zSJA4pL;+cx_JRml*b3&9t_BtQi~UWv44)6Czy?_4^PzdM zz)ni1Xi?b|Eh?L$MPZ5xTg#$losC7)OJ-wHvLVjVlK7V7gv#laQ!49?(WXl5kd7B* z)u_oTb`qI=&NNNj`C%cnC=xufp6quY(!OUD@N!Xh3$9!#{54m5E%S4u7u2nScW=wC z)BL*Ny^@*t;P1H_@CSkF{jnfR&k8o(e4A{(Y@3;VF#D$U1pZcAWTpl_C+vPr_Q+>N zWolsGB%5rKY=fB^n0?R&1#(Bu)VPDPO_&8ii!l*-22tUtZ7VcuGA42@k1nz|@eH20Lo{^6FFJg2e| zKN&Wv7O=1dEePxRqnbb43>HkM!F=0h03`KoJsRAaOb^J^wDp)9vfn0YFcr3lfQ2n> zL9*zVw53tfHo%OqyDsvh(Ts2k__oJ8<2-Ka6t2Yq+*SqKwz!iTXBWx1jN6)V(Y8s_ zK#8`=xJcV%oSU+eY%9hE*e2r=T*iz&95Pmzyoba6sNnU(W#`6+lbclLHH(W?V-7xC zc5Zw)xpi%-ZK@G=t_E;FKS?YM6}(W>Y?B9^;PbR_db|ahCkv;u;S?fX817tW>O5f< zfgCZ~ooT%4dO)_EwjMcPQ)!d&cG4!9&X(>NZ8DzDm-V2tO<39u;3QF5zw>w!V{^AK zPS%Z*N;E3A{xjWbeiiOM4d9|c9l}bOtPI;9eE|&+qNgMl1#R<4ZLG_Swi#MA6yEH=5=#n^b9s%$GF zR||bWAnCJp^TFh9koDzu@Yj&kgLl?i@oOM$k@xIWt?`7G?6 zGm>rcLXE*=u)S{$zhoL4C|-**7Td9{f$l4W^J@dRYM_#!V?#FRzEkxT3oH^*@!HZI zDtRVN9zf&KOAc-&hctR!77kQXfaKL?WZ`-EPxx(e>5li(?^ofmq8C^&HG4QVMZbd5 z!lVLFDkL>jKqrIDqs=mqF-rc}vSfrXrJY8=o069VvAL27L4_>Y^DYoSE%#}{exM2b zU|6Tk^e~$|KbQmYJ-WoFx@=w>Y!9&ZIrZ8$ml{fTJ`5F{OnW5{5*O%v^Vx9DX#oo- z`dLYNJfnST6`fLS&4oV)J6`q3@WpF9)9@5qycSP-$rwYd`I0fhwURNywWW<=U*5#@ zC1F`j!Qyb(pr!yX_e0g(WTnLs*wYBs3-1E3{-I#K^ufQA>n~_3teSz$N_!_^MB-_a zj9G9$-2+nh8yGt?B&Pwy{_>SmZyXt8fRBZs8bHR(72~kzh*s%th|;o@QHgHHazK~a zwQ>L!{JArEe5BuNoI<*h8QVC43|F3{H*4ALU9$YvRK_{l6qgwJ;#s(OEuM&yF-~Fm zm5dRtm5dRtEo}_DO~j^+!s7QsEgcM;E6S=Qos~EO`#>nQ-iP%s1?zo4tY`1t;{Pzd zU3gCG1u`q`(q+W8gZW+{Gt}0@4aO|3dj@3$D;Vr!%qUF#APm_6V!gbq=!jOS4=6DO zHbKBbzjQX}M{;d8fb=WNGu?>5;sesHJec{4{#TM_ybC;GxBQi-aaC~Dxi0YP&Q-y6 z=eocr^eF{PqU{vKpybpj%#*&7vl6|?K(?Oc486;fK}Q0!`!KNBF?D@U zncrJ7t0C|{&Q-zhbgl;8-?=*Y0Oz{FBfE#1>;YfkTsQbb&eg#eI#&Z<RcCi zi?{l?;4Pi&2EWC*I=IKV8hBghs^C4H>jL*W*8`s7TsOGoTpc{jqDCt`45&Tn&7iol(e zTo3A)PXoqRF4BcTlw|T8d$tGgwz0DAE^GD1R1R4 z3z%0bnPk#Rgh<%;jiTb%l8plTwDvI!8>ne9)9h_Vv3)TGM#TZItAID~!UDRV$*(rO zs8IeYIiYfD<$aa)$7rt_tn~ud4pakAms26yQ+Mpv7iD<4&}-mP!9O{Lp-qFKfwZ`j zw>*UG@hyW&lDIA8#@4}|2G9*BmCg=bSjWUuSjTZT=tT-_9_dx6oRXR#F(oxYqDpFl z;T{R0^)j40*^BM%L-Kp6H@BTk?B>$mBlPNbuDBQDMw_l{}I(m3bagzYo{+kXL;?CuMZn%;|+p4Iu(yjueV5L&1|~6dM0-D zyeX7PGU=~Mnea-Ug;JGdl`pSg+)6T?+#gteB?p>RB^fAHN%oHP7L!;>RT3*-Q(k`T z`3C+hP*dV57*!rF3zKWVUoL!wb5-ysoU4InIadc?>0CGX8s~bzpLT8%_^dtihXMP; zq#5IAoGa3vGADtjJJ$mqcCH&d!?`;6eCKN54?0%`&vdQ}{F1n~gPk(^O+{vBXdph? z83Onrnaa+PePgt45NnFSI|J1R{7s9d0NcZiwN2tc=+QhQNmd)%VjVpCunF?k<(y z(5nGFN|e1NojHOJR~5;)0;cF9J?-g*ezV;^khyQ$k4>eS`R7eCwoeK^{qrU{PQhZy zBl40%b;-0Z+Z@Mtr0r5fZGJB z4_LI7zFNIP9X=mAPT5w094u*{zQwM;L)wcZSE~H!2QTKKR#sFu#w}j!WapGHdhe}* z4>~m{i$@2CdOt4sMW;I1zA_l<$M&O6Vf!n=Q2!%>1W>a75Kb-q$!yhwCpuRJZ{}PLyt#9A@D|Q>gD3Bk7o?5R1AeD--QagSR|oI! zTn*goTortwHnR9jU70%Vbvz)7fXFJyg{2FU()R45N^kki}&y8#hViALf3W3Cm? zLJ7l}3>QCb?vC)A4#r#+%A`EJ^##CdQ*`jY`K$UWDGK z_(+)DZYL_NeM5N39heL}uHJT+eIBLx;>b?%8g4Te#cTLaa*EgDSz&y<-oXC6a+4YS zH*WP007tgSz7&lb?wb0@64c`emSUZtnER!u6DM`C6!mxxm!jS&Q{UID*vlQld)X;M zxGYTh0BeHH(mHOU70e8kyeMK~?hUs48Lk>^_cPq6Q)Gqx+E!;eT=F|048z1)uMK3A z@-r&V$>-&q=cI9}dW{5+8oi44V9Aoh3K<;ly?{Ra0HJ-^wSXkqGRZs>bxCqZ<;kUz z+4%*0g>zN#DevH3c4ifPcHqwH0S(^Z{SqH}971_=2a(dVVjX^_R&( z5xCkrb1GM)b%|KB2%No`BCXfUV^ahYL~gND7!QRoTEO+>v;Bs{!eJV?p5NnWZLUDt zsx)2}nXA$omEUbu8n~aU(t5b4N@GzW?$#Ksmx`)1CMX%XRa)eu?ZDF0(OZ&^Cri`O zJ64j8Cx^?@(K}X>jwgr9($PCsl8z^b%hJ(XmX0Tf%hJ(1R+5exUf(^8fth7@Z+Me^C`8jjd~Sk&lj)>`|j5@mBCddBZ+!e-{Z{E|k-mv%*q7O|jar=|3?3n2bFUZifwE zA=(9D2Ps6mV7MgO1;ZuLE*LI}cENB-vu9{#P?S=jw^0hWyRKGs|?7l!z!jt z@hrCbSTbxqW(OGWLX;M}#bS0K*)kZMHoL`QogmpV=tP@+V`*DRr{p{tw&D^v=Vjo&V5kB7L!eqf5^RPT?uM{4w}5!CvfU!Kn`p;_2^&vZKhABzy@{bZ z8bI=6pMZ7>onkN*d|_UV!oUH+c4BCXE-fKDsQjbT#Pk&MR+5J}!snIvl|pKhuL1GI zu>grUAB2|2pS+8iD$C^54({>f zQ}*QL|8FTu;~!w=e;#IjfC>Fsn9uLjY3!0%&6UxIi_4=LV{Io!}jTY5?7- zCQdDbhoz>K*K71mJ%T=a#k71u(rA@|Z!Y_JSH1xxXlKiut*fVWs1G2vIosHD8 zL7F0v-7#0BMIm+EE8_tEpry_D{})~PyIk4WmrCqyRhO1QI8cLl{!9s%Q<%W|}g&hkhQ);y2r0{+X`|&V*1L(H<@rb&!n`LS{`3ms6 zlF(Whni4{50g1NkOVo@z5V|FQn}7;t?9nS^OQ5a|XJg6siC1`{b5-!0oU4JmovVX4 zbFLe_xpO_>w>UQmeE$LAfV!|k;|C(m!AamBI@be!(7A5#L(bK~KXI-Ge#E&d_)+J& zz^{n26ZFCgjaOZ961Z|;9*H^K6R>mLZBvR~-e0v7tsUWR_XCH>O7)K*I9-jeoO7x>OV4FQ{hY5{h|soq9lUu2b^` zpK|IgQ*!(JOPUu~3tk_nWUnEN=R(kf8_8$FvJ)I(Y}d%gFba5(s4n{n?U4!gZ=8<7 zT%#*h`*pAU7cF;~nCWah_BCDEF8DQwi?@n$b1?H<`R{@gRl?>Da1T-Gpj;V{hK~S4 zg_^l|JshH(93JMg0rWIAuh-SPT?_bhpqh^>`gMHnfYgTF@AlHwBU}r3exRDn|DOWY z0D5wpr118T!UoW@+9a#vLslC=vTJ^g>gtWI1^jZLnvV&3N|QrxOIyT|VXJ5W=cpKM zORU5NnsF;CnR_UnjHB!sG2`O@rfaAt!;t;4c{|u)oe4II`oBHQVm}l5C#NXu?`wjs zBNKXDn4f-TkEt^)GQVy}U_WX0oF)(JMDstLt>KWZWDaqG-D5dh=wsxMnP`)proxT) z0^OMH7O62KI~iLuY+?iHybfT>7wiD@+8t(WfJyY_Gr;okRWOil8Ogzl+9V@MGY>DcVHb$$`{%vf5{;*X3agO7eKSF0o(RVUJB_pHL4CAosJf`xurui&}vI zS(F9iSSl$a)~TOdlR4v-$D*~{Ra}g*O4)Zi(BV8}{sGJIjM!!az5j ztROZ?cAhNHtVK5bjAPU1hMaNSlsV;;%@Ow34x3zm+^r;)^!h;P)x@crLya^!%Hor) zzSMS-Ogz~r*lqwxf_cPn%!9C7(fhY9&xZu}0 z*9~6LxjJ}d=W5_povVV^aIOpdZwL9f;I*CW2G^XcgV%Ge243H}DtIgBy1)lH*Ao{v z^F3a9vUifeHwUU8NCvYHe)`5}jZ>^vhd@Hk6=`kbiolCS<%+bfc17TZ{dw|oMOviH zh6YYnw7DX!hFDVsl9pVtQ(`8BEVO`R!**XFsmN@#N)j_rmYCKUiP<>BI{+jVxkXyv zbwwbl$Q5aArF5B(z~>4XY>m;Pz)TTHf^v(rNLR@{XI15B?U1VmkObMefE?}STEMpj zstMdLPz@k!)ohWt3qn4cq-eHNB%>!Jqe5C#U>0xR7%f)XKY!8fuawUZsc+!j6=7N%_%Sg|YlCV1vr`ka;#UeQKRKWD zM>9RXvQx+g<(_fz-f&{lZ&FAOo9_6^q_KGO$++0o2NPR6hqdXpc24?TmGql5M#$bT z9q&Jre!C>L?~~5YCCmK2Qu9HnbgUYjAsKls#k)$*#>rt2W<2}T)Yx9e#nv(|w#B~i zy--NaxLe6)aGSL0m7O8uZe{1nc(hCh8?Ocrl6%pTOnu$E0m+MfxDuzuDEyofRzN?H z>Mr?I=9e1g#V}m5Zf?~j01sJIt*%7el#k~|pgrAw%kO>ubV|yKODBern$ra@3RDB=Q6x_u7fbtU?{%Bt zH=LRyc%M^o?7QmHey#%a;Rn+sChtQ_Li@CA;#o;T@a&N=d=e^`3hu-~aLZouNg?jF zmrCvJq2wAs?wBR(WIbuW(R%^CSMtZ`hf3R3k~pVnxgIW=J%WLcbgl|M%DEc&80YHX z6P)V?pXgi<_$=opfxmNbe)?{Ib(zNZMVfzb5-y> z=eod83>F-WCzy<$rpW9e2Y73sn!x7|DL!e?n*5%ewb}(9erQpV*89YoA`s`wZ*q8d zZg8aq{Hh|gGdJ*IQJJmQ7_EN!Y>L457Q$$a(b_VEF#vo>RBn;hln}-MkO*@{S|hFq zEXJGuBGSc*lZfo2h%}6;ILt7nh4~+a5vPs~b-(zI~AA6n#$J1 zkjMs*gqGYeD4Bc0)HQ&A4OH{(nz9du*=#;1*d2yzULbg@Q{xoq>LK9f4uWrYDh_3? zM*fXtb{GPC&ilzZu2^{FoSHX^a=;a%-l(B*r6ezuG{a_hNwB*xn7S~CH!CO$Sx<01 zWM(k+bP%WUIO_>^?+1ZIk*R?_qCp^~oTE6EHt^`=kdp?(ZyGlG8YwX;*4rN~4{Rg>5qJq^Hf0+k#k zZAOUsf{>X30`ybe07tk_1gDZm^8+-@YaWgqytd&^)NqAKCX^*l-xBgmlqLCHHrq_p z5)56cJpU==yO$cfJk&)mhK54ElfS{b>Yr_B$!Wu*C4}}(d30Y0tpR*hls&6f;&3w# z>%^OJ@qb$>J-dW7HGroEs-Gl&GEfa5bzO2|{+|59Pdli^ZWcl_cA!FjC26lNq1vWS~?fxs$e(U$>H^ z>n^FVRocECuMRGeeA~kaZV9)I3CgVZO2+=9#`f*G0rXz|jCE|7ss_-9PqOo8*>*$A z;xsp*D}5}WkCi0oL}{Pyy@1|pC{F7arTs|gmCRq7!z9l6>iug;+upjsPdZlx|JJ!0 z_z%w2!Ou9?4PNM65BM+6O#;sy%2#~*og$5gM4E$>z(01b2mG*e-QY)^tApn`R|Egd zxhijuB-Tpc`aTAl?9xCUO%xhlBJxi0XIhZQmy z7YseO>4k@PGBCUJH znnmD`7gMA~_$8+$f+rmNrG4Ov!H+>8v1ESqj?sD`DE0!0&~BGN!pr;8B0^IHE?WGBT%v51({BAa1qw zaO`o{1LA924{uiv-u41F71h>@Yx2S*W66W{lBJpT1iKFdsSnA_;=@FZmstXD@M#aiZklfD3CC@&Mkz^8j=g`ePT$^U%L6c{o-B zx%Htmnq=EQE$KDzW-TJmL9$_;tzH*|;6krG!xBt-q3s?HqU~cP=Z~2h?pzK03+Jlf`ObBL zM-LBAWOL%(t-`dOppN!L1|&K5`V4rhw6e2j-x#fLcwZo~SYO~T7wbz4=S(s74cE>H z=37AK$W9+XoXL;HwD8BCB7vmT`T}t#?@Mc6<;@g<1A%G*J%D6GN(1O60Q}2F>@7)T zFWxe8u1Jf)?O_RsANFf=ljBUDuMFN2GTGQrk@SR!lG|^;v{^WIXTt3t1w%~??G_9* z@$!79E)>MelDizk5qa^S+lHGP#vNpq7~h_1fecc#5T}F)++qWZ&xS!7KrENIO)pnT z3OQ9tN+nfEZaL4(EgvYclBy(DDw>G3!rU}~>jx_N@&y^aOe)#t4!**Zp{>jtmtTphfcb2ael&Q-x{ zIM)R}Oq|^WZW%}8a95lJKEk;k@Oz!>1|RKQ9ek{FHSqDyRl%n?*9AWEs6qy5yjNtF zLGV$|^?;9Yt{Z%ub9L|u&egytIadXr>|7W4q@xQC#w(bbyhF8NcP`-i3f5i#%p0b$ zp-9sMx_#4Iy8RaRsUo{+0h#pt7D9`$O%b?BaH9oe&P@w=g0ymTw8*_F0!dY_NQ=Ns zap__864q}+CI^57lHY!45sTd!fy82WB;b?~=>YK3LRh_Hw4QixKFwwhxTmTiAD0$& zW{SYu7gMC=@h5v^S~gRNf0ZNfqX}FsP>ldXSVQ9k$xG(#lrdVQ#%>xwQez*R0ZEN% z0h#XH94)eC59>g(WqpC9%Cvy2V$%XrC;14pu2L?oFOY=hinKhv$s^98vN05F^#U1u z{mOFh9m>DCx7?lk<>0hR&s)03Rn}f}3@x16phVlUjCx$&zfcXcf!nblP2gaftwF{k za_bn|{=IBd3E9&$_=Qj?1HeV1?1xfE#%NG7R>G-YN%@;r>Q_?Izlr>^`NJ(Au9*&3 zQZ&tUxMYe$8p1-Dn%bV4rg&;lXC_omwSNs`<1yOqWO5Syv!-eJu)j2bB*ivYQt|=UihWp9 zm%LY!kW?jcCsj%Qxdl`g zFP8f{k+O_rd`JcxDjBS;+Xk5#Epg^FzeHwvXV1xOLw z6vu{MkO5RnN-x&v+IXl@87RkStBqvl(Z|?`R-S1=vIz?tr z4d&140-x<%6+Gfx4SczCJ>X9|R|C&-t_q&*To?FZ=X${NoU4IB zRzVSbrE@*ttDNfwU*lXIJmy>t{AuT^;2WLm0)Od*@Zx1*oX`px9j}hIB!HI(svr0n zQF*n}svpOrc0X`TRIW&Cp(_GEdVJnDSERM2T(-gh?kXx*q(y9|7>7n=n}jf0z&8h~ z4|wFU?ni5k*6Ctx-2oXf^CMjn42oI1(*nt%Jq7|vU}md#j245NBJjlEM=!7zaybAb z&AB;RWZKLDNpr49YvYjg0U&A46={(Ivlu7+3}yEGkm1&gf-gA*TvuV)@hJUy;F|QA zG@An;DYaq+lG4o6R+7q`{f267exc@CW2-1^V$OAmwNWU$*4TU0I(ISl2DQjbZXr$$ z@!+YIY&zrpv5%$|J7`qwol&uCM#X*^6+5-HlDtEhoCffmKsE96QKx`U2C4yM!tHjz z1XIUGr2#h6Xqss>%`}?i@!~Ey^FVN_e|MFbd$25NL7T;9%NWRFv*HJ`(z1E)9izo! zTk5(aBc@1YGUY~DLwl$o{Yd7{IXUkk^C9dSUu{Sx} z$sukVR-r)Bn04$cNoqg&W&6q%X%UZEjDs<%ERwz?5>t%BFe;8=8*RjsB(oQZV1lr2 z@6e_*U9!Z|f2daRy}d2Q-nYrv|27%dM4OBQXp?aWmuuizlJ-Oeyf#ox;7ST~xypHS zDl~}H?9U#dv7o3)gBfaT(wMERv~AKTTEd9+Dp=At6@V5Tq5-nNIC99O;83?wg9wT^epc+6QZt9D=`ub2}4XUo? z6wnKCDjC~Bc_?|JrpkS|p)|T74DA{WCGX+lBDY%tQ_CzGl^SZsGiX}OA5&#iJWQyL0QnG~d+Cue7y_#X_lP#iTEH;We zLUp%D>_wphlQ$?=N!xo(c}0|0;FNUIreOQBU^{tbgaHndCA)mAQhsNQwX(ZPJVCd} zk6R_Pr(y7yovVU>bYlLDGrn?W6+Aa^XLW%$KiT!bJ%Kx`3w+pVuGh)8zl2=%0bdH# z6d>N%KeWDRn8pLA=H_jEE*Pfqlt?@J1AqCxf*y^(iM02XK-_KH>*OyU+0h7irBc-X zSKw*1g7G`0|#tJ2!_l;HKu5gG?8x?GhOvA3<#_;pA`3rOs3JsQu2 zM6`h8HE(S_8g-HR(6ruGRHZ>8bJeA1vX@Nad)BdcjMl>;l3pOr=Zds`6GG_)7G3F0 z7D%rqiAl>A5mWW2Q20G#;Pp<*=fv)Rz;!iww$(Co8*1h7^|4)aB8vjGe&5T13PyBNr#P)CZkC*HV(;X#$`})hS^Gy?-b^;0UQm~0EJCX z?0yL(Y;%6$a5|R*vGZ-c)ct|ywNn2aR%`?Kw?GXLq)+caI=#uWDQorpA)+ZjmalEV zqa%d*8`lFC!kjTen3Ka?P5~a_B|Bpz4zoSMaR_ZP4x&xQRl2dC8e zh5DKocFD~`!iR|IKv9`F@IgVX0c6#gBS3Z!%l5pI&2%WPOY0g}rBR&{^br-{_{wSZ zH1yNz_|H1Y^kQ4vYV9yFR*#elo*0$hpppl(ljICe*?}t_>lTf*MW}~=aIDyn{gPdJ zuWggD<83nb>#OqXaY=hS2*g#Jz?mZ?W<4FEOb`2qIu%=gFp9eD<8*X>BHiUGr}m7| zz!y6r199thnOhS!N!QTRGW1^|qy~__CC^{1`z5ckIKVBnvc42nSo0TxtS~E~cu5!) z8{+onh6cWx7)ow#C2^#N2Je@lSAvt_#4|DEC^@5?A?*u7uS0>HORO^HCSOl}m-PEX zzXtHVfocIUY4sGRWH%iwIAYmoi-uX46knT+d!C^UiUUuHagIF?NOeW~hy1pi`2Nbq zo78?Q>h&QveLyC%pv~qnOAEVjiQ~{u!U?Gl_?W1Ib{qsA{>pdTmE{p`*x8=pj}H4v z1BgefcxV$gN#2Z*9u3nYLb^lJ1IB2 zO15{cIH#wm|EZGMTL$nY&Q-xrifjM59F3<6is0Wm*9Bhdbe@Xs5C3SaBhp5$g6qz8 zf%hzS?i9wbMz!4$h(or;0P!b#0PP#2#o(q0tZB?#krtkmY+9uAL&1+0@ajPI0Wp-B zPd{z`syfUK9UHj%d#B<|d|H=?b*W*mrWj3e83KG(=Kt&-0AC*rCEq6`(7mOSRT+36 z=c?d+ovVT0?OYvvpmW{ergJ^ugPfZL{-n5eCDXX7pa{O&xgPMf&UJ%lJ68vP#zQ?_4+d8RzQYXPv8o7dlr3FLJI6eCHX35%}Csp)hC*h?jP_ z0ODf4bZOzGDFSgZSETih;P3zt7js2g?r`!Jc=Ug}VG3R=~^PQUnzU@rkpT^O+L!>!434Et> zJ>a{Y>jvNBTpj#%=W5_N&Q-zpI@bmM_&Eg!;|-LIZmo{Cfdc85t;fFPjR_sUuawxc zH*k+&>pj4tt@I3nt%riGULXd{Jg{gheP92iY%Cv~I2cG^<11&>!5Cd33v!csoSr|* z+B(776d)GNS~qxcYu&N6MY8s~v+^0SKR>W9I?$?#wWlWFj%ODYY3(c46oHmyiAj{P4{HM6;$m; zZ6vt2Q$vE}%e3NTy;J_-`uNIrWB5+Dj9XeiyZO`Y+acsZg85wtX7JL)^FiFaIC!4C zCWzg%NEq&4J;O&u8MdEgc=^!$&pwl^mguf9xa_)LZ!Wv;hMnw^SD(hI7i#)^8mFey zIF)InY)WpGsqKMTvVCnRkp|F*8(_FuVF@&VHwJ3pCxX8XR0HS>WdJ`<59O8|18+$J zPE@`tl_!GV$*U!nu*Z=sKb-%HdkiEPJNM$LXEt%?cQUZZ4H4&wAmI{CUbV@1pTIAAS~T>-38Ug(k7>0 z*)C+K1tcMvId1xgNG;>y+?*t5$3h|ofYhknR`*v?5r@6~B{!5<$%0*=ML8W0l#On$Lt)epVOwI_Ik3&pB5E-{@Q& z{CVfP!8bYA1HRR{N#GghhUe}16&fE9nY|DIpYL1`_=C=MgFozC9X!*y8u()8s^C%Q zx&oeFaB#dD6C^VS!LM_!2fU(l-Qbm-tAkf{t_EJsxhlBoTo-tF6N4~HgZMa zc7bXE@jCBI%VS7(G&TYpw|65zmWSP|fOwsm?+r0frlttQ>s*l*j+-KI%Me2^5U=yT zv^<97qtrBpDa625U>hm07{inh1545rfq0$yF=dPvj+-KoIZ`{>#^lI@uw6{NXMGB(rMCgY&nWE^&zj7N?KwgnasYg9a_QSp#Q z#RD4EX}JG(F~xpoNsS%PxY+ZIi(SvS*!PT!|BL%AdzRy#%a$y9En!WeLbWezD43iT zR!IYhDf={xq&)0eKwnGAI*$#N{Zw_VV}r%nj#Wx$Bw9AMvf~L~!eVD%S>hHGyER|A z__d_D)dhaRxhnY2&egzwb*>JcI2?|M3oA4>6={Ri!EbV|2JUvQ3hr^P3p`DnouU?2 zXdK~+b?}kS)xbwNR|TKqTo?Fn;@X3BO5amTfgRO=^vmvi>8D@h{rS+b1?)aAPo3EU z7Hy@UeqE#vSA>oY;2Y(I_YJBC?Ztx}ICbaLpnYCO^wE_hYvs^Ha}tAVS|)xqmI*A0H7 zb3Nc6iL+%fI*!JJ1x4^&=eof^cCHS7*tr_`QRk}Q`ObBLXUqt@&FDB99}sD~O%M2d z=eofkbgmBmuyZx=Oy{cLQRlkA{U0be(`nk)Rus0#f%gZhANW&I`5r=RPYr722K=n3 zT#*)@l+-2Vvu+r)1sn)e9}s^s^R2PikDSGoDZ#r2kW8B&7wPJ3*8<|TX#oi!AE8q& zHxCZ?0&(2l0RxM+(og+~@cXh=_BS3)`Fy7P4kRo)L(Lrdw5}6H$+`L{4a2bGE4zlY z;%LUjA;@OC?)qYN#JWOyqy3ygnGkx1>*KOLRMaLR+HS@e|q--HxBo z{!adG5T$b2B#VXU}?ctKyF&KQ5b5-y$&eg!jIadcC?_4+d1m}9dr#LqWeA)To zK61-A8kdVS2Pc8AaIOdZ3Fo@Ovz)7gKjmBve6@2`@NDP0z;}GG;9#eWUZKeBMhB!{ zezWS-aWr&n0qJN3v~W1?_r?oyZzf9GY5_hFsQzCH{w7cj;Io11KUk45V95>iYH8mS zdL_Thd9*Ga7gQQR_h{hCWUS=8`$Z*x?_g*Uh#`B4WIsJUVn2CIgdWZy;hd+TY>fbk z(EG=EjYlf!T(ag~lFMrcmm9!Fpqi<#&D7WA!2Bas#*ZbJubeWkGDho(z@BC-t&hkb z`{T1k!xJ_+ccDsz>OnXFzC!uXJPHCxcb7bz9lBG&4TQ(A# z_;^I47>|vlq&(R0aNbndw^&^zz0Og-y;ncIZVa1M@=o^#^;*Ii;FhJUY_0(at~5Vf z^vDx$xP;>++ua-u^-am_mo;Kf1N-RdnH@o?`4c=|H*-$ zq3C9Wyf%OLYVfQO69-a>@`q$PJ|8-^ zfEy@FW(!!fm419QNgY;@_x7%?=Q#bQ*ydf|4t30(hOj9Gs&$#o8h6(bAA;=bxxH5A;*X8FVGcFGCktD={FUbGzNm>el z#9{YeD&&trtN%s8m4aLSKuV|N#{I6ygZ6h^Ni*4Llca~-x5+r510r*_>vqepbAzjc z=Lx#^gLuDl@P2SFLA)?qu@5Didc11eUtDJ0ULg1ED+R=Op?qoU(IDfdN7Bi7TaSeH z$i+5EW5*Ce1Lz?P0llQ`+t!p6HPg07gM^oSRf2df3vo4ol$P~kC`KtUbde0uEBj`3 z+^y`})^R^uka4$?H5&J7mr~rXw7zD`&+9y3Ag)`H$EHf^K2=G+ZOx2(mHvZkta7pL z^GG{qj2B+jxhi-y=W5{9ovVY_aIPD?rgJ^uH#;{8e499XSeQMI#vKJk@SV=}fbVv$ z8+?y*b@11ntAXb@R|VheTo?Ew{~pd6vvXA3Yt&&~Njn<=zZj?{5R>`QgVvv25%|?h z@{w{yT5tJC&RQV@j~A6I(mKl(fzuaLr1c|L1n%+C;?T5OVr^*P5sN9(`l~Af*Hr>@ zA8G9()+_=KT1=4^`7c?%)bsiwgDv1*f$9TdDDxvdtYK@D(6JYY0lN${bGc7yhxuZyFe%Km&k?q@fVd)4jR zl18zlp9)KQ;6sXzg=ktVst<(KmwYCc4%cKjwkKPPK=!8pw^LOrOk&ASb!;^EOZwVI ziEhWQZItMC{Mtr|ZpW`}FymfegBPl>yub$20vn{jJQvC9oz!;!EZM#`6mJ9Q!}T-V zN5ZOY0Iv>I|91s{7N`c$7eYUN9v>D$^1A0sNx+H9eNuTm_?`S=J@-|QBYA0r^PhK* zfdpf(obl8%o4E713_Rn8i1Wx0X9I{qd*)q~d}5XQ)Q3-GvHdsn*vG5VKdi?udRjE} z!-Oa$(VP`A8A|acUMDZGtWAZ<+|Sg6uzYts00sHX;SyympsnFhzRc4r#<`s@P-i=An3WNUY(adJ_U z23c-vl3osSZIVXa%M7@^DAOAqp~2j=JI9m4rZY1ndjR;+K(&Bm)$VTO6n~AvTLv^L z9_~KbWbW*Q70;Mat0^&L+5SzHTAVafD@oa+VY0JD$W9ALLNarlgL|cxaj~-}%h^wd zMDzoxQM>(2QT-5yl`FZS#7Y+2)6s%!Klsv*xZ5Owljt@Xr@HjH`B{zO&JKQ0p{yT@ zesE(!pW8wFSSM8X;D*tZ*h`q$F{5I)N?z5(yFmM`2m8R}km)8)^Yqo$qv5%30&%~s zN8(ouE6m=v&{!)()c}%kn@*so+qzOzR84yj8t)2~mfUS7DxR%FTn!+_W$$Ik8l#lF zs(F(P&?|c_6L%|nRTK9stWqB>S*3BW#Y&ETr6sq!{M^d}2I9IchS>9x^^vM1uWCxx zV!VP!H8q!oRen|%_!G`m!Jl-l2EN|8I{0Siy1{SxSpG0?FIVP|qp`I}`w*ua+~Zsw zysdLJ@b=DC!8pNEiztOoWxb9pR_`**W2JV#lYm_Q` z{snHTAZ*%!#F9VS(3=U)q(6}PpagEo@Gz3aX;J6=r$>&vPsfz2}x_F>1mRP zV?!d6-7OuipW&D;OCOM7^YqbTy8bWD+^?c+FX?%)M7QJfVu^0Y=fx7;j?ata*r#;x zXicSOb1~F1b6Wwg=9Z?cq=^4WJJ6ukE1|=Q~53 z4Il>X%zjJqyqNmbhfid&{Z|Iq$E(smJ-{z|E?fRt)V~PZO8br&Pi0gr-K&TZdw64hp*OO=ily zYNlQ#g&gJ}B)&0DkU6nf7eGH|i=8^?fBq1uJq8!xEw zcgdoS164FblI;#`X5T21;}jtavuI^g#kGTE@fzMDKddnS-8XI^k=se(Y{lfU4HDZ- zg<)Ec3O?=B*7EtSl6EqPW3-NOghs{j8I^9^gXy+C$hQ4xnD0U6dF61c9VA7*jV5o; z<20;P`P2Mk^DmWE;(QdZ#fd3ii!)Tb7U!jSElyDJTAZokwK!$PYjN(1*Wx4=uf^Fc zUW?OOyhg<#CksMiDFW zY^@AmG|3jmUV)1J&g_hlF=BpP26C3xg0SHFfULn>F%C0l<4AKh4mM}wcypE=hGmqq zM2n0=vZ~liU(c)%82%Qo#a#Ss**#c>p`#nBY65eqVo$tF7v#i%#}qhiO6 ziv2YzcGIZXJEL$08Q-%^h4q8KMlIW7!6x#t=zeI2jC6@5hr_s6`@Lb@uk>XiPZEC# zH>L*AZ%qBMsgiRaXV4FX<63_`xho}y4Gdo=)fKa6u@}3x`pd3kP`B&S_{!);VD8Zc zbrOigGF|N57?9rftd^dQ>4(zz%AU#jc{QC1CQ4?%_{+AmdAR!}dk)<=Ok}3%M%k4O z_r_$n(Tx}yTkRtZ#_%Ca8JGduiX;ii2w1c7#TNZa*1_KLs}<5Px)B&lrNhM?ZEo-c zi3)bg@^XzHd9U|JUm!I0Ks=mnWq&+D zhnIMe;yOC_%}-V+`v`Y8i$Hn!mnX&+*PFp53mm%3!su-3v%NuxLqv!aYj z-z9YP)17LjPBl}fnyFLG)T!`-gIlNFXLwJ;tAB8XGaCgUWu$v6$A2MX5J(_y9?K%eRG z!I0;@KOWMSNj#uYgo0dICG*y>c6$kE+wf@G3*1SReXD0qg#nLqJ>cm@J-iroJ>Zo^ zz0as|v+DtGE$ZPqk`O#S|9Dwq6N&9zLVEguWNdup%o-RM+9xCOxNC@~56HB&^~fVh zv%5Kvt)#6-9!Z+%0ZCn3kH%MgTp;^UTaOr#^h2ra_cvo5+jQuTM1?WUO(2#_hyP}> zQzdJARGY!I7x)I}s^A-)tARi7TpfIibKT(UuF7AE*+=Db$I-Z6WcGBs~%vl{i8#=atUk_9tuxKm&%=sa8I8JG^{p<^Zn=2rrb`h*zlgDG!u7a;R z_4aG?t4B(j7VsERcJ^L4e3lyDcD<(rUva87mRtKb{Yi*fJ6Z5Mp9yX}EBMRL2I?ij zb(DPTxV_-+PMsl0dQ6LnLHY0Ag_^ncuw-f z$Dx|7I8vhs^jZaDRJzL!rn~GQyX;59ybdy-bDSa{e{d>J1Douf0!@QKsuK`Dbo+7vUmG?XhAn6 zvyWKVNPiaYT*=-+H!3kRO*hJ?Y`FcC;YK%NXt#A%1zWg~B@FEL)3X!yv1LVwDY}(Z z^C|M`{E&pvjlfvSjz;l+aX*`wPAYCD{g~@ZdJw(CpG|@Oh%~sT9vu&qw0D{ujNay_ zAvW_>!)a)cgAuE-BmwbowjbSjmiEnfkm9v?wBogR*y6P~OY!*TVmz!-@n}ZHgOtR^ ze(z^ikBt)?C-o)y7~8R-;_fA*KchJ<+e(J*%rcff_}&?$MGkinA>X$|&x}{`}w3Pj{-BI@L^_YNk##Q>U7|BH<2hcZPMe zZE@o^idQ6OgdMG!M$=5AN!~d8MvLz+VG$0zB*=Rldy@Z?U0!U(C0aM?0-Ztla7+lSJJfn<8u{n z7qRX3Z9Pswn~amtCgU`eo(fo3>xRYD0QyY#$Aj9Mh=(*P9?+;bq+K=4NnyBNY(E`} zp%?h9sP^Y847gF4!d~DOqS|_R@ebDmHi~+OsBwhr0gox_bqc}L^N*KhC)>w`^z;GA zSoZk}7#G^dBJ%jBkjFkCyGC1&Jd!lKn*-TO+Ir-Xq?sO&)V1|!oDlNZ2V@^=>&3Cs z52dotS7M!#&sR`kOmh>6<SOH+YV7b?`Tx ztAW4mToru3b6w!AZ!Sa}7spXb(K(W~^8yLlc9;8P_6L%t1;l#E9<;V>?&P))`dseI z8Ioq`V!<1o`k~(u8+cR#;rFnFfVC4&edV}B+{C1 zs0Pr7Yckwtf>slFzbN|yy4kO6+;)8o4)5&RjAwLhbGbPrS-chpJ}BGo55qQqIA-H?&NG$YAd z5PC6dS*&qQWn65kEGO&8gLk;!KD5J&3!4b*l<75p;@K_9|Bec1e-A9K z3I@ljwJ|Eyd$?r=(D*1xsi<0<-{Qe3#`ibN`$)8K2hrDh=jy^AWv*cZp=pom6 zU5@UOoFh3;5DC#jhf_^lJrB~E`E;WWQ}uBhw%*ngh%YHQ{e_mn(XazJvbB;z7i5WkjW+#fyU zHf!Z*AIbYA7f7Oq92GxH@>7y`bkJX0Kdi}KUz1*JZ$gi*q_6n>-s~I__J#Ve|{nUMXqm>+o?$|jQ2tDGbKMJ`Ekj4k_#j~vK*mzovtsE96vGE%-h%M`m*Yy zcbod*2jj$}d{KJKs(+#Uyj1dj$sc#{AHAz|{m!Ug?9ZRylrt~CIhQ-=AFi34`~x=m z^=Z;OLGo-#`p5P!()CLvKQ4KL>Z-KoxEA@`3%XOH_zKWTjp|q z$vD3G9r|yujQyWc{}&|xE?JWw@p$mt>iQ0nyL8Yep1XAY>yr2v+eiN*>3vl43zD(^ zcg6os@{f{#m3&F^70G|K{?}=qZkD`F@<)=fzwirm{TazWchEm$i`>F_k{^(~TymD= z^^);;b5(c0k?eU(uCbeBtpC_+)W`0N>Q|Rt#)<7eBfVwSUuCP@!hMqSB^f8SKTX%q zl&s31PWmUjMt$tgRKJSsGfwQ!`O;ffee^!1ehZ^iN8y7q2%&C<@!5plk>Yten#>($+%ZT{6UiUOFk(1kmP*H zxc?#B=FFhvG|9sy=SePnj? zk0ah1_srW|Uqjcomh7a@^}VFGkK}-4Jj%u5Mt)$;~BW{p!1N<_(hXlw9TAIlrdl+LCq29?3l=Z zSpVa%QU7Pse@?Q#e{ON2WNd%IYt-LGcJ`O-m7LbW{>9>FOI{~=O9%ZgACP6If>a#@wEOTJAq za<_7)`hQdM3fT$vq7HwRUPXG#OTJrj*QJbyUZ3@L*J$Ra%TKjK%Xl`+5$+t?* zl&lWq*VmDZ$N!e}ekQq4GX0T_yywHOQGZX3d#>ax$uD&9=Q;5&Nd8rFufcr$X_CiD zo-H{l8OL{%_(P`VS5A?fFZnyk=OsJ!zg2d=BDtpYv3Gih{_hgc__wQlm*gBt{E5f! zAIh0Q$)hAcC>iUoHZ5n~B{@y@Lv|9>0t=%1=~C;eM>eYwMO8Lz?!VW2b7nuu%29cHeaTpVw)h7m7fPOZbgY@Tx&D&$8qzzegZ_=; zza;selK<5~|FC27an6#QactfmmAp>!7RlJlbJg!7l3$TrDA`cIVT=BSAGjFdh{!+=0OU~+`zk&FPl5dtgTykmsryZY< zJ1jXW`E$tyl9dz6{XId~&yajZav}YqZVlOaSaQ;dxxy)uUy+FuoR$4JhQ{J11`?pOO^$=Ker z|6hCO9ba{I|NoC7f;(=isBv!$Q(QGnK^c+Z)|+*KU`S$y1ZP|oTSuJ59jyaxsd3|u zt5Rp&SXb1dXdT!(>-xRV=ly)&adJ-+YTNJc5AFlG|@*IX)IV5bSk~O6Gw_g1-J=kbejK(9`$jE3i`q)`Beo`-|X5)T*T- z@Mdr!*jVR#(sIpm%3pz<8^AvGYG+H(_tLVQ@@DrX^!@^NfWG~s@H-1^u{au3vI#s3 z^!4vpPWdQccYeVBeeio7tDbAXMW7$gr*o9~JJ|a;Ew2IQfdjzC6ZCi!=-WFGxtZWu z$ek0AuSKrG?1Ptq^U(WUK>t4EUIHyH^Xtd=HgcOCuSd27cLMu?gTdXwR4 zQ_%Eo3F!Zb+)5l@4croZ415yw^U>!-W%`0UgHMCL{1Etkz(VkZfPC#qYT;P$Jn#bW z4lr@D?@7xKaQrdw39v^%eqod99eIl4NnjJ$47P%8;G1CYQ&n#qsHODZL*QQoJHUab zsZ1ewFPPTk9ej7?7a{)?_!amq_#=4u>76{q#Q(K^L|prVBf*0L@mf8e-0W#Bd7eDE32kM|Jl z6>|JPWiNr{kZjc@_RAu+OhG;>~`eSO{JK`t>pSh~pc9%d5WyezykC0nPu& zfdA)_dl_5|T0DNdJ7dS}TD_J8><|8#@=v25vi~*5w>VoP9SZJqj+TqT+d#iQCZEso zA>i`r?~C6N-~!P6mk0cRj@*~vH=xDi$9n*F%&yg|=efS5mZ$zq`H#^L+20ty`+|pn zN1mtto4^-9KT4A?TLwM@n*Y-S{?~=y5bOh5Jbt`KbKLA&y|!)kCAHk} zGv(LBZpi)~9RC(v<$U$q3tSCs0?!051pTP@_w42UoB9W0XDWC*X!bS;`2WcBe-Ltq zg2i4ue*6nKe(eQ%WQPkC_Xdl>g`lthpr_wm`Nz@wGdK|cre7ZLcQSIPf@gphzaQT- z*lD{+kBqrk@i4FnTnzg9Z+ZINm0yD1hu~!VoBrtme^(;c0{#xP`2F}k!A{2|dSu3L z6^{d3z;8fb|3^>1yYfBpw;EUnn*MbGe-9wn20jW}{C<4B<|*?Xn18938$n;b4|2bKk+KXc~>j8f(u);-0K=e|L@z_e-AYIPtfz_KSXX&C>~E?0&)j}Q$edw zZ{lAQTo2qF^vp#&!WV+W!HM7u@MQ25@Eouiya@E|-vvKBkWXLU>d{QSmR+k7eSham zYT0kMU0akN3=RW}Ks}oN`xJg&2j2s&AEYJq-Ko^$Oz7 z>Q@TpUFUnw?SFO`_8wbKdlz4K4+HBVPiB^c!zb zi+6(U;8M`{cP9LK;6zl8i2)Mp1UR6k#TDfMl* zS&uvdE(N~<3&`(u+T{W8?_elDzFo6p`P~iuJ;8mzLeP)5D|^2DiNt@0SC2gd{iTTf zT?$&ioR9q7p!HMV-`N~L&yz2pU;nS=A103V@!uB=#q$IGyvH3HX>V|Q(2u_rzVJ>x zQVdprzWg%y`FH7&HgM&;wcH0>3i|q6B7Y$Gco*_3EmRA=!8O4=a0Bppu<#z0F9Uu5 zEz2o?9d^C~^X^rPMc_AJ@B4gDTKqyYrt#4HqeiEo@dY3_vL+mUD;popjv1*Y}0ZFc;CZXegf1| z`tPmiJ@Ieqo8R6Ksm+CLitV7qv5ay7aSR2U!InULFAHOkzk{+L&w<#v9b63NJ)x32fJ4ATz!orn zk;)ANOTeo^-`|JW{|aox&IzC|Z+ROGChV(6|3Rajk>BeB?~um*0jscLa9SjuhTjz295j2r{52f!@vI)n2TQ>wupJ!#oXS;! z=YWrbzWx5_?FlXf?+1N(^D`#k$Cv*WJ3oSJqG$TP{FHWO7J|#b-p?!F3buhOy`cPB zV94I7*f|57`yaAD9Xlt2%NySX=v@L{3R?aB`WXKfa+Zfh;%1hCoom-YBJVBRZQo)6v) zDx3cMJ@$KGr#DytrX}@V4g7InSN1Pmta|ycDJ}w|zi7D+*#C7c{}LPrDx3bh*t54T za=!kkfPRPP|785%2&O&hJBzQF<6nU0*ZhRyHN9Er9RoIizP}>kYX$v!`SQ2Eq0E|Z zDlP_#-_mjoI2SDJP`(&^^gS)V3Ti3+_jBxxL%#^U?&`0Gp6PexZ@gEJ8E@M2n%t2)I?6dwlDmh{~h z=nd+oy!m|$|GUz!_YCy!cI5KOqs3|c%JlqxyB_W2$NQmY&-5qZe?Hh4X@?`b4 zesA-F<>3SR-OtT~%`<*JES@#Icq+)p|2m%6KF|n10sjvE6ZGScmMZhvM~cONQ|$Rk zC&`$|NB$3>$xlPC5xf{&21XyNy?n3$YzA9E-)j+mrhy2Y^k;TR-ysnf;N-nf)&*`|^9jcURuz4nfcChT@-qTzBOyPft_d zJoK%f`0+oCTzBP7?hW)J?3*9o{`1InSKj2T|8@BDg6F{GY(Dbm6;C`G$2>LuGdfzg8!twn-*CUU7t=JCw^2Z`~$lvuy z@jn!6z+1rCUnzeTcpvuu2L1%D`i;tM0&WQo0`+M6@7egj$>PP|+FxY*YsYU|Q{O%B z#c%OG;@R00d&5AhkJ;^ReSH7D$=g`a;`aSrf#2)E5nrmMBJfaf8dwdU0G0mv00(cg9K6n*)EqD{S0K6Tv_WgwNS72}Y<+_3XY2)HB+SkU#@4Rtw67@1aHtxC_ z7k+>8{T+v&|CYa{-nchEHjb=bHtua6v2kzXdcQ#awjq9-SIpi;Ok!31IOm zE5!oUpkMzpkel(79x=IxkZ)X7_2+@lf$xKN_R`}ofUki+fR(-V_*r0Yewc0Nzz?*o zL>xW9b-)e4O~FvSetf=vzy1@kcPQxV`|_8Pmn*@mLCcpfZ*ewazX*A27hirpa>bG6 z&FmiDQ_Gh3@<86lk!P#7Z+|cBP5_HQ^XJR=z|SV&5nb3fxowfRcudc?zYlW5z>%QU z&zGN0yd7X6`Lw+H@+McalIHJGuOFMA)9~x-e}$iaSKss&uB`ssz#V#M+1j;%_H6=f z+_e(#J)p&D#q`VT1O3zFw)Ogl>G|~^irhY6AvhW|Ki0o|ed}+1 z>2I5Z*8hC@TR8qEX!CxkKki2UegkgG_#O({IIwYSe)q<{?|%t)z5%bKo;QHLeADVW zE;m|3u^DUycV1KZ0idtHLpSw~4CpTm_zB5Bj{KA0bKnc$%iw#UAMbj^v9(vP(Si78 zuch@r9y|^F4R|j20qFbNeQnhr12%)#fxi4c>!^GSSeU2f)7MoD$zSEkFGa5pdi#S1 zg7pD==I`ItKMcR^U|0T1k(&-44OW52fG2}~{cnSR0yKXmf%>(Qrx(Db;Gls0&#*IP zJ5yh5UNpM&K{NzTi%vAMe5NGr$J$ z*8zFU(?R5G4tOGXD!2#r-v=xNi$KehpJzY5Td?;w_%iKb?c&SdM%;IT3&H!r$H0v@ z()Mfuo55Ca5!eBK4f_5Lg)ak>;7ri$UQXH9AG)!|@e|mikCxX4^TC#1DBlWRw5gVT zdk15u1e^iR0*?ou1e?r0n1|ib0sCtp=f~&UX+_SD@BdnVN8+jiXM^31{|n^(_IR3h zc@=ycT(pU{lb_ea0{NYb-i4sGLs39}F!uKZ_W?(M73ehv^lOnj7Muf~3|gFK$8XOI zk-Hph0j=J?eAJhGY^GQM-nF@w9{`^Pi?&eyM$osnCiYsvh2V4Gi{LAu`I~{?`CyIb zuO#4aICf@%7GFsIG3-ADehL=g&#%vM@S%M8@~r{+$Kd}2T0VXKJc|bm`L%jlJKPh< z&u8#|2fqV<0{i4^dyWMsgKgk4aMG44cMy0eSO!*tetot=e+Td&(Cq)O<&VPuHQ){4 zJ)j@YhFfX9+ra&|*7DKYDqaD81^W7v(VGjN4PFRd0s8hU@#EVw{&bE%kKfk={^udL zcpHuP4X^_&KyL#0DHy8HC+PhMF7fpIc;BFYdBm{+xDn{fZ@itxxha?rZVeWIdx68j z(cqZvRsR6cw?Cu{eP4dxfS)4xL%}1#iTIrq@IMZ@kiPG~75Ue|4sg|g{ny|Z?x1xNac6eRkD)UIn&+tMpU84_FH}fjxH9v@=~yLsFqI#uK;K6p?txfisyqz z?4@NtzMTgse;|J557F}OyDOG}XMmrA>)>x=a6-WUmH2-J+>|&%@mT#Vj_&%kd{})$ ze*OBNIaup?HR#9b%P&IC;S zz@^|}`>K8^cpm82e*yl#0z2^k4R~A^`l}+h2KWnb3h4W@`uToB^|kseqh8w*k6%BF z)Ax5RahSj5)xRO2zY}px2SffXkKL`GAO9EB`#bO_Fdx6Zd^5*?2eyJ8pf7(Xb{+xm zDAazl2=wJmu8!k#!E?b2!5cxd^B!g2-Z%K2$?^Y`y&bXlDj4!ViR05iKYl-6KR&D9 zbLhVSnqOakzhRo+i@=3oG+g;S@KCTAJQth?{t;XVJ_{}ezXyAaP`ev~emsl1@bBCA z^&7GK4EQ>@-$?a)2zV~o3VsFl9;I?Kz>xjNvD@(v2DxpR2#T{*ES|8n6Lu1dj*L0{wUw!ao68{dxrIXL%Y(p7sX2TW{b0Tjc!*@F#F{ z?E3P5TTc0Xv2!tK?Ro_D_1o3=Hy^z}fVY5FUtj)6@>UGigR{XCz}Lb5-}IY^>ml$l z@RdNkpTM_F(D87^B*p8&4)6!iuWv8()&SQ6j|7hfL-xCCuMc(_JbS*r`FRYvMc`B5 zQ0g&0P@lVyYwM=`%!!(>6G5|kM8N*tp-_McM6gEB1Gotb8+g2lyK3 z+xrSXeX)1Ma_aAb-kDv*V|IQ2rgtv-7l2kjU*7ob57c@t0j(V^57tk8ebYM?J?qC^ zo9N&PaP1W+n;HBUO2P@wfJQ(!jGx;qJQu$qx8v_<~p}#G9pM$=h@6Y1y zNt|neCxIdPl{mg0ctSva82l)33^*Ymzm)n7J4EYW1U>>T2EPGk9IA5PfQt{)@=Av* zZVnCx{rZ@{!PuJ$wt@d?f2E%Nxx~HD;`i#~$GaiN`-1u4DA1Sp^D>D%l!7ONcY=?A zZyu@n^X*L_zlVapJzstna@H;(e^(!&{?@^7GT`6r9fw`BcN1~@{*CwR=lk0Re`C7v zZ~57icz+H4Tziib|DVClJo^`V`RQ)F+oQJ=xGOja^z&uB)zAD|{e1Zm*x4VP2p$7A zfQ_K9ACj}Y`ttW+=V|a+up?mKc)wqT`uCUE`4O~!_$>Y6WiX_F3CAx5uK<4s`t@1$ zDDC%c3B?X@8TbYGE!ewQ<%X0f`u57OHxDdEz8q`@F9Lo22fTR9pV?W2-r|6M1##Aa zeUK{%$eY}0$eUbYK)w;V?#i3oh3J{xqJaIm$aPoV{`D3{LVwJyYjP$vjIFF zJPW)MydL~LcrW-C_#XHn_%Zky_yf2${c3%16L2$dTW~kfuU}X3`tn`H@5?W5eSH0A zOLg3=RIb<)>;0S9p1{yi`rs`iJCO(Ypt12YZn3Uf`Ob)x+!; zE~otmv43X3-o1f*+`63d=Ev$|b_WLHU4q}G;1}SQ0r^Ma+rgK>R|E2WW@tMc2hImS z1@kNP_zdu&qqW=t?p3MfBJeQqc<@H>7SM0+d+_rJScspIpf7K6499;F=*P7t{&oSo z8>jEDWv13|8F(f3tX{tSJ;?p3oATcww>I_gwu2p@FP~qf@mvqy0`{y{ z-j^?c-b_AkKxZD1St68H`n^6&fe?OVK;67Ln@??7LE zbK>3#+!-7S?hRUfyQ<$_$QFM27UYQ zBbUeV4Zw{8@~6UI2>uql47?6(1$Ssr|MNiKzu7yloAL)^=Wy^Sa9Y6rlkm@jpMhV1 z-+|Gw8fPB3F}O9j1Go#g8@LDf2k>F=;^WkwU*EADzuA*tM7gO^^_GF>&(U&k>?Od{ z!85^MgT6nD=f7qD=f-y_^}7nZ7Q7yu58eg(_4@$+8_@DoAIOL0-P&t;^WytodA7Ds zFK{ie3hYli4gswlw+zI$C3<7Q@nA9N`yY9{`mX_-!H0}LL60v4+rhU%-=5hy4*fjj zHVMcdaU%Y~+2Bdw!jts)GobHpWBAR%{lOyw@&)j_gZqM}=i8rlvie^Hc7W?QDL)_l zJ$NU0&?$P{x9973CI1Nao&cW$p9P->-v)huYZAw1;7;H#1Mxiy|0l2md=Fd-7M+^A ze*f3{%ZP6m;_DBN4#YbX{%o-QG_BX$pr6nB<&@tTJDY-=gWG`SXBlPR-*oun!1`C{x%2af?y1bz8O;QtK10=@~p1HKP_1g`lj zt!F;?8tB^}bB4+t0hWO?!FlK{2n3DCE{6#t)r5q5intAl+5{#O3A#=QpE7u*`$9=rv7 z7(Dyj-1R+x;|o0bMUkqXYS{yjy!MZ(e-=tN%vZry7j#`-_18?U0)QP6EqJ-*fO7cD6lF z{R{>R!Qu;)ZwG%rPs=-8s<_u>ie=z5umbelMgML4KR3SHsoz5Ie()ji5wIQf>$ehl z*~rV!4kXskr02~VX^24a#7;v0dUtfLz`7S(P>uq^B z1^Z1GE58ivbBUIl!B@Z!!F=*n2o{0GU<=p=`gt8mK8wKwxEq$ zzrN>E-+Mu;-*2ej&@SrtbK@J_MSSMJF_7Q?wtvgZ4 zE1!N)2>SBZ!T%Aw4YdB_%dg{&Q|k|w_mKRC=xqXS4*K#Txowc|%HN*I{Sq7w+PvcX z8%rK--de`E%)jVgkIQ?#aT$>}%d@qsjU$`KeE-+u|9Q~nf$tbEHV=gSb!Go`?7k2B z@%iysy^Ha0er+Bqrk*WcKe2h%=Iy!U-PZZ;jw^qj>1zFXigx-3_%*l=@%!~NzL4X~ z8=r5_&xc?CuHt{5`RdBcwZFB3yIi5=Lh#4ywCwx;o2NhKDwWH>T5-%ZiZ$Sl*J`;4 zT<3RM?hm%$=k9>NNyIl3Y{K7gJ8)z2JqX+fYyi&ztzFtEzYP8j z^z-4@uZTEmKwtg}>i-02^}mliG*fS@|8I!@KUJS4UDU_?w-d+z+P~%H1@hy!x1Y}? z$gN9%+7R3k^yOcqUET!W0j>Y|^81p1%Y*d?%VS7>6nguE<3V3OBsUrPuKZOXR|(dD z7O(H`aGUqYo6TcI%x5+ZZCa+BmX#!S{bR{@(@7-_BmYH-F1( z|6}Za4f^r=@mRf^8Gq*2=DB9--R|`hn}@C5_f!A3!S2pGp?M~>9(_kUZB4w}gZqMh z{fw{S`0~c*+w=3`*Wc#JQ2eXT*ZF=+u<2$kUk>{Ic0=w^F#5g9ZwmVI(*t%t#lGq7 zgnk0t?GI|#w|52heh1zR9(7Z89No3|HTpk-Yhq_Ba5r!S=*M#ae8|5qZ}oeRdcF@X z1Gk{wq56mPKSba6_Z@sM?5+-O5Xi5!%Qv)-pGV(*)UR&Ntoo8t!TMUo8TPKKx<1)& zdR0Te(uRu4@?9&+qqsDqq;5vkuY69GXe!p%>XBoUwRIKMRau3E9IH)MmN*68)l}9; z{VJ*|{SKwzRHJ^%5nuwIy>@&)&~0 z6Jck-c@tZ4WF@mI$|Ra<@gaZu#g5fUY^$t#)~sZe94t?kHcS^wB~{at;zNrSRnwdm zJycp+n>^M^l@(Pgk?->voz+!_`a>^yB|E`j-DT^bHq|$Tr~nzrfRPoT-)!`&z;S{#!i#d9|u< zIA{+P0nc32D!gkW*SF$V>sFxJ@#X#U%_8l%9+ntS-)J?OZa*vEFK^ay`VhU*@7>xx z|BFP=wXo^up`X`H{bxM=eDw3t-=PyVB(=&8G7nA9~sZI5p+El-2LbiT>b}@248{%wP{yNs)I+kc(Tba2# zWGm!n7bExc2-zb{1x)`ePu`d9DTL2Cl|$E2{{>y>ZxGNw3;m_nYaYyu?<+r`f6Sel z_}<Ko99XcAk|%OPni5 zcK(#j_lWGgD4Sm;vh$s6zGv!uCYxV1vh$N{zE@=D9oc;E$j&FS`PCvjPsrw1k8J(V z=GTa9UC-v%iXvNgGY<5Kqz!ZOYe%-uW{6AP)`@KW%;xhVTNktWt)j^KYsP^d(YleX zgBi5gUoW!tEt_9IvUMw)-ypK}D4VBKW|H#0N3@a0Xt77Mae&X=i+e=B2*_^|;N2|H z`PC!p+lh4Z&nnU9{Hjd)u(Q0f%p`vQ*(o4DSooE4wAXO#G;! zZN997&xf~qodjP1ZPn_;?l&fzsyp05Ro6NOW-a0yeTRb-+--P_?*tre9 z8QzwO2jN>h{z>>&c#HoP_%?VOf$ze1c=DgZFN3#{_D}e{6E(m+h;vn0m|T5};Pc_v zgRg0!KF?iX%Bv~<8$}b~o8c}0hnanN^Xo3h zT>KsI*I=i~?3}E`4e;j+zfvTvy}Gs|kL#l=;EQ`_^9$hHR?X(y;PZQC^Dmg4@3x9P zn*9#pU7UqY8pt@}`2@Zh-cEN^B0l1$-g=F4EraH59()R4qTJ z5KT4t)0A-MDeg55z6t(xrK4kncX{hrY3rD=dNm=RhhPHvOJeyAqJrI3-ulCh$k!mx z?VRWy_!f^}1m6yC{q{}xyff6{OZfeV@NS&84ca+bo?yFZmpjozE|kZ*~io zylzs6diT`)w|nyI3Lp3XW)(aW`OV;qE>R*Mekb^Rc=aAdd&0M4=Pl$%!MC2T#1#0$ z;q%;$AbIUby`~B8^4zjUcHU}{FT7CYuU3dog71Le0{&d#SB>QSke8$-eqD`xbdi=# z{xw$dX-TGDNt(!Z+ z7km6ZF)#Dj5{=Ww=>+79Jo!U}kJrJ4>TfvlRKpkEqr@rjr@^n||mdiu_gUTO>-#+k7@crSpgKvXB27WjA!iSWwdX0xKcv$%@sP7T*MUN<7f}LZ{ zKKwu7&o=&1B}Tzt1fTbq5@X@7gD-~v4!^e>|0fl^0QraDqbHQG^U|l`i{Pgq{|0<3 z{CN1!%+4Yuj9+PW`ak?Io`>{?{~q~bcv z^HTRYI~Yf=BcK0;+V4j^%ixRP`}WWSKf>31t!0aIleIK&%f3;bk9kBp!#6Xb4#xg3 z;oITAr(P3{|6T=c{wako{84$fmql~nm;I#tS=c{Q_&7hD&*Z^hf_#%4b+5m}&o_Q0 z<<}#gd*EAER>Jz*BKV?Jl;4m%zXET+3vB!n_~zc(@?XHWuCBa|>mF-sKJ(X9z7O`- zgD+e=o8JuBOC&5nCe zD6eysj!uGag`cH|qYH&!$?a~qbE{ag1%7_a%XuC1u<>_eC%-@i$B>7|;cEsc@9sak z*9-8=1}bp}{Cn`N?nbD*nz8eV@UEXk-u(PM@$v>a9Hjhd@LR%12P;2$bv-Z`zVK+}&y?!~_nHWw_oni15&um1 z;u7VbSMliAW~WqncfZ5EE*IYQ=a##+ip%-&-zd5s`R3^=KcD*E3Ey6;{8aM%Qfx<_ zM|k&bmLOlypz!72_ zCV#E^m4_MeD+%9rn(|jD9i0GgpRYfWdi@H%gU^{a!e1zSJnp>f&1=n$dq5zs>yTdn zpT~(qKJh$&oeppOJ{|KLM9aMUkgsE>iO=_3gq^>`x3M4d5?SZmYb`l(b@^%a>}(;t z>xYGWp5zJAv@d+#6-rFQ{y6xi7UgXoo(i9TgYxz2HmZPcf#)(cnhjrkqsos*{uKCD z_+I4g9FxCGr$x{4S2|uOAh8SKZ(G2(yr}YjAfWzc=RM_TV`rGjKc)P|$WMVU#P3n?Nwf31%3q6}TH_Zf z-vWQC*@xc`JLki9Jgf3a`0L?|+m&Ap{vP`?tDVY~^+2=Pe^>e6Ab+*VzoPv2`2C~F|3mo} zvQx;^8X2AYx zzsQ}RjRO4E0lt5L9~0oq1N>~^bJh1Z0r?i;bM?1d0`m6;`1Sz*UV#5Hz^}VW?tE?) z;P(#jlLLHtfIl_B&kOML1NCu@`O^dZC9$2(es2~&SN!(|>?{iKe+lp(1^Dj+e4cEi$(8^9 z!sqI@!vp-}0ACj18w31Y;d8}vX+Zvl0KYI`XK_IOs{p_1=DG8*w(z;)+$tbn5a9O{ zK39J@D8MI$&*ir;ovQ=#3j*>F2%pREivc@-3-CV$_`EH0=XvV@KP1495I$F& z2M6S*2jq_r$e$bFuMXI`Cm{bqfPW{ze-YqUm6M-bA0d3McBu*Q z=LhWkAt3K=FXW2f-A2g8yW5Pp_@4rN-qyL}-$wX6xi30{eMi;^0{r;_{<;8vyYRW%YmxBz>0y|9_eQ|Zrvd(l0KegOx%0VG zfFBv)ivs*n0lqT8A0Ob)3GkN(_&)^rdjtFv0sf5u|Do`?+Uv)F{QBDm@*Lpz4e*Bx zpQ}GK1mw>O@RtSn1p)qE;bn>G^m;}3^`g$7V|^oF=c54sLx5jh9(d)NS2q_vSN?Yo z$d3>{*L)T2)=*cwTV+M*ZvFZ>7&2(LvfBEJe$`P~No8eX`mE}zL|uJJZG9wkU46r} zY5mHgL}LFDlM>^`PM(rTMCHla#J+)5+x0dk$eSBO=Yq^S>A8Rz<~u~IfqcfeLs$V&rL$UuBLWQq~DKI-Y{#{98t+A zCEVBQWQiuqrcJ9zl$MkoovbRC*k_d{Dw9>y>u0!k^|dALJA0DueOYC)q&6z6pHq`8 zPu7)5ZR}tMhmiXYooThzvq~GLWr#U;dRa}HNz^Cn>ZdhSl}W|yZU6M!0qM5`({Bf* z-wui9^y@!pVE>GxyQh!#&$OChwtt4*Ox6AwmirIRurnm%eWv}P8T=mU_X9Hg4#@C3 zAj9tf3AwDiGEti>sjN6IY3*JiUp7=HX)c?QsH?7(Ru`%2DrtiHM16IlY=$(zh>?=T z#1v@-eLHb>RYleGPQ-pAGN{qg6vL${(pvkCDAH1yYZPnoxFM$}>l0;F^8HHM)~t{%c$`fTJRVB4^66KOE_bp0sD91_vsz@fJ ze6$*H`WYe>$;$Fn(G9FbT|-Tcq%}n*T;(L^$=Vtj!}ZBTc|}=$R8n7Gn{Wx}*MCUC z-~myoR(eKBRe5ESijAtRO&nY+4yRVtmQ>W0l**B!IioA2M#JhHNV+Pk>yk1wT_sCu z>KbCsrO>scL@kY0UftjnHCGc$XC}+)MSXa6b)`6sgLB_NB{Pg0baienh^HIPoN~x% zVT4QB$arwNciBxA_Z}I?b(Ixm$;j2bp{nAThGc9!;(b|3*^H#jPMvz?=+R@P&egRp zFgH|XWKYvB@8XnFRv{tZuT|;}Xh%x81}`g-Ij}rYQ(G~sqQ2r-iLRu)T=FBW6pa`i zH&z_9_JwJc)g>|(Wco=YYip~j6V+9fbF|$ZS+1-^S|?LwmP~3U8LS~7somFATfUL2 zK@weAGN-zsUSuS=ngp#IJGYrjCo@SIHI!P)bTeqk?vcIg? z?Ve_~Hd&K3kH+PAE)ZUp7?~90jgAcGI&QF%+Uc2dZ+S(Q2`450BGpyspA%kKE8DgR`Eg@ggmaMJH zlpM7C&}de~{%4~Qk>^{Ki_dT55{!9!$vomQJn z>hk3d>#%qAEw79#6pfP_#2u(qrQ$iFf1-f+WL2G2UG7Fn^-CtI8fGaQC1*9rA~~x@ zR%JIsl*_s-b#M)&J)%0EyQi0>SH!sgrD*Md@tk36t!t;$!W&PGwI#DR@6Wc5%)YMhTT;#fz8%?pO#3aRPnFQi#f1I1#hSg0aDpz#>rBAb%$&i+QkSbQo3MT`8 zcE1`qk?J>4)?ruYQknOi*?tvuwI%%q4RT{m12f<06P4PEvKj7FsYL25Q=G&V&l>44 zOG+!!1(`J(9@x~lCLXT-He9%a%pLArA#lOnX0m$#x3cl5LN$nQJ;tkxR83pUi;M6EZg*TU}9JV;#V) zkG$8j(MC71mepj8&_M%+7N`iG;wj8oPB%qX*GP2(sdBy=&+2Z0WAP;Zs_LralJVN) z%vgS;kGW1GgIFSPL2Dxm=TUGU zj+eQ7;9!|9IDo<<7rcEW3Mxnwm>&d*I7ESOL#n- z+?kl06691&PJ?Z0kRxmjJ${H%}~W~GT)Njb5UGqQ|6K48eeXtq1Sb>lM; zpN;9_Vv~!TRdhPhbTKv6X!C0eiMks+@)fQ+6!gr;tx>5Z&ZjyJ|IC?Pt;F9it8e|e zLOP7={qeeZY)NfJd|qBE^FWPU-)2^?|KOo+$k*4(Wl0t<7i{TjGu>&$)3odJ)7_;; zeCfhu8`qzVSdO&g=Q_gFlj~3h=axZto55Y3>*5jLbf}qAKSO4_S#{Ip3Z=hX!d6rr zD-*w*VIwL%A?cRF1g#Mtk*Q;PL;Q8NMRUeZ94@nDeBv{)bS5)F(w(@(6NjDu%ZZ5$ z`$TnZJjEues%NJz4fIfyx_~XS*;It%X*YeSHd)pXfA6nMTgOVTcLTzv?0@A?&jR9r z++-j#V7y>wG}quk19y)nij28CP9Oa~-Jb^!8Zsb?mo|496t_zxcT%jPl_kf`p#qW& z8<3r<6kp6~)5-Z^!BDwLpfi`A0?WxG?V3u0OsAs6d~9AEV%rxq$Hm%h@6<9G&Rp&sAeMK1T&nAq23f}X7xZ`IU593Bz`Gh^SNo9baoOi(nVo3hpdpbB7#l)j ze_C~-zCmtLxDH_h%k{%lA+vYwu{#$$d&nB#q|z5g@>Z@C;tQYni0NnWdJQUf3a6FG zd1?CWG0vp~AEUc|j$;v!tCrz<$8LOlO*1k%O(p@kvsW&67u}?=`|k0IU}vk9C35bX zB_KDcGK?f;LMg9{n{gKJ8FG?Gy{y!$@N&8N;*MlWr5anj>rwh^s+^e&MABJE5pvmT z2DqlnD92~rb~s~bN~b86%2e5PE%V{t zOHZjTbB&$FdU4rUOv!NCnkwsjmM+HYRH~@MGgZ{pEiTGfu$Ix`Vx{=5;l$ZhGMW;z zN@{A{vZr?va}lx-l)7_%9kfzqDRFJ2C*fu`K9|t58F$I9MYFFZrefD=^lcnyA~AZ> zu<@f3qb7`$TjYAb+}@YhRolf#V&tI{hK(OPLL{b)A7Rq_jhi@p*to>R(W57inv$3@ zZ1}iQ3Ay_=HRCSi=<3>8a{tJAb=itfz(i!6yEig{0TmzM7F^LBSqI(ix3TVP=Zofy zYAj1ko+CG`W{rw3Rh=O>Mt%$&#ZdC8yOza+g@|HmKF9RkE1K zBZu<+k}lm7;tnUb3?{ptFBb(8v8+zn0ZZ+Vl_eHOYAxNub+RH16;tDrv*bQ>(%p{D zbSQpYqY3MRm8_1IOKEvqRV~zr(Of~gzA>s%7~W9y{9)K^SzsBWlpA-cXS6`360&sC#! zam?yxSXKFC*Y#3Sh-_9AE)fTp)K*D_6Uq2oRvIZCT5?uReSA{n<_b;QglfrdwOnDQ zvZ!sH_92fQM#?FkiOV2#k2hpAX?J$rz`BRbl&Q44K&QBaaUv$mnNKt=zN?qr1Ja{V z?ybAqTcVN39u87>xw$I=B-~wi9m29Yx^;C_l{}=-%4p9>l$0IQP$8$u@gsy(WMV@4 zUrmnwN9dE}X4436Hl=2m2I+t9axng_in{t*xi^&^e9FFiG$TXWwXBo_1V1@hIZdXm*s6{M?Jjtk zT9>SKokH`3&e*!K@m0A@@iq0_zLN8TnxxEz6=m6Bq+3|(>84tZ{-Bb|hE#PhJ3d}4 zMIdvaO81e+ooKn~P-|S?;7wmebK;I~BPcarjnW&R33n=9U)@mY&J^YLbV+4)m_>6^ z8ZtVk%&4f#2*QOF&u?pf;!3MKWvB{z^{a7~cu)5R^NREHm5BKHa9(M_sx zTsIk-F2)zuQI4*jUd~3!>0^0voJ{Lg{nLuhj@+9_HETTOrM$Q<;O<PUT}CHZr!?j*V6JSUQ* zmCdO2lNOJ3rxJHhC*vK=jqk{? zdRx%`e{#85JG!K@E-ATk6Rp%KwFN@X_&r3d8xAN|1ufV4LPZj#lRU( zbtTt+6U*e@M6EoTNu7a>kb464NjH7QJ#<)I+$1tp&x#)%E9hCAvv1Rct-{o9M8@hS z)G+t#AU(e1Tw%myd7dF>%6_hFewCim)%@ywjE}F@61slMV%w?zNqdR&M3KAgsKKVz zT3I=(tQoau947b1M^+qL;eMpa60T=`!|E8>b#?M6-tQBxOUC`8zNFIh;t7C89_He5 z+0wNm4%0nu&t7-OxZjPEN9_7+$d6l2XQboC&myUA%AQ?4#pYZGol@Ii6`NM>dSrHg zOeEyjon&fsyLQrz;^v|QWTS&P8tHEAl~=moud?=#i~U4d+%>XoF`J|pIvH!pMoU6G zuIYZRx!lQhVuU;M700Q8P_NUCP;u{`;BJ`8gy?R``p)7$=_1WMFU_cg^sFhPb$xNO zQF=sF%1J=#S|@fR*^E!iEsS`zK1g<$=#(`&e!`{aCT@0?FNRMq?ONT;5o^$( z)O2bt;?*>E;7;Tx%X54+kx>C%k}|Yid%B)c#Es?DK$S}#i^0SJf2@N+9;l^glDpH=V?QW#(6 zTX32ESvMLmHE9Zq^laU_@rcCKDm{Z2A1?C=*)x~9@Vm2*c)5-Pt&=ssHsjpHE%_^6 zD>ASm11mDHA_FTjup$F1GVuRR1`b*AT9JVj8Ca2l6&YBOffX58k%1K%SdoDh8Ca2l z6&YBOffX6(UIyf9zK8sOPyV}aCs|eg&uzee=Oh8(+GL9G9=0j_vF>VQTc~#HSwJII4ep`(b4peo^r9 zqkA2-X@5EVAAiZuI>fJ0ywPu0iK1P+@^kY08}4Pt-}cHMQs!&=Q@>*_Kc^DE?0XgE zYd|6N+au)b8{=1RP`(CJ%lwYGeC?o?!7qROsoK4@-*fK?Z@<^>a_?UDyY76wcvMV% z_!{y^zTP!{xps3e`X*Ik_uGxP-+8xs3>~BjtD$H9e*8(} zx8IBZiL%A9jPf}7{tNf|mNH*IujGI7ueYH?pOopYwtux_H2g3x`#D^c$nhXnb}702 zsqTTKJXduO&FpckV1fsf*-z?I&z9{Go_iLV`S?C9?jG*(bTjY>+usPtK837(1*u21 zxi^mxz&W}B1c29jX_K~Ew2z1(=l1iYYC~F^T&PU8V zYt8X2-STQ%9pVih@~s*1mk^{MSnDHQ%<$koRVkNB+xMhT%|*iXAgP+{2-dx)(mLMe z7bAH7>>!bT{4RBmA6v)USL@;(pk4!~{AWE@c3W=$<;GpvNNEq8Gd7~}R6KU+LeJb0 z!m&8OI9Q1-=Qg19C~+nC;3Zl+0UrD?L18Pw$xrzLd@7>+iAOY=goa6#RD(3V_o}&Zi7js!u4v~ zh9Fw(>v97kz5m_v;;NaNyW(a_?_1QFE^DulGm^0#Epxjc(}Zn%v)!ofBL|Y9bd^Ow z%G$YdH+!yKR2h3FWTTG^q= z65H0Mn||VNO|o5W^x@3yw0s~Wz3njl2@!2r*P?Es@%GZ?-jA4?4Q!jLZaxtkF2gd( z#ha9M<6*=`DciJ}u|GA^ZGNKmuXagGrnK5QKhu%YWJh+kuq|?#2BiDCt>3ogE@KO% z%R#(%P(8^C;*uMG1($3rGzICpwrA2+So%<>En0!@ig@;BQ<=ikCnd5{ralam8V)jF zil&YCc*LcSW$c-E{V?z;1sl6b+XE;gP@NK~16O<7XUfTi_AT8|mO7?;P<7v;?ggb@ zG7RNY8`1;f&1mt=B3;3@tmfR!mFlT30D|cBDIME*N6oW#;n}h59mwgyr8BnfH~bf$ z)kuAC%JpAqQaz8cZS}UnJ-yG7o$slgz?JEJk0~y-ciwf8?1s@Cr6irTPP_H9j><0M zRGIyisj~BvdE8mc+@!^5m~;s`Nal7|M|JuH6`uv5TV{XO#5FJ`{HFL9`=-9Z;`hbOg@F(4-?wcFZrPS8=?2iMc_xh!+${dyY3`IOz z<88gH$6|3KbPtLRF~hZJnhDZvpZZ{veEeIY=vP^fwSBjt-g z_#9lu266c&rSix=);Tcs&TZmUN4pL!7*g85WRLRLZoh(lgQ9IFP8z%4*a^G!6N$R) zk9Ym6OZ6U6=kLjM@;xHCYr_2x(;p@`I&yvQWiJuU^*xs7$ql7k@&n}tNG|zJ1M=(1 z4UAlNwiCa(zHih0ZecF@KS=z!%l-jyfl!{=K^sql>U$_&dGszb`A8C zTLbgtS%G+_1?&_C;=Dt~SFSi01oCitpnt9rkgp1i-xCAve!KLOT=DE0=s#lu_D_{O z=d!bQK>p%Dey$6QuOEfaW&hQ{`1)-i{<1)S*dV~K8tAtl2HO2~@tf;B;TM7ab9X@g zkHY7w?~Z|X-#0K{9TmvWWdS=!1o&xzagmTbz6(sIR0g%9sEC>x)3%4i4BkIxt?g546kIp?NHj z=i0!0vUPxeDllF?4#d+K@LL^d$1?--?TrEXTLbbN1^hl5m=Bi(+U2ysxNyJkoohTU z3iR7o19>Y5*!jKWKbQSA19o}^;`~FPT`mmdbBh4KP9Sdw1>~O%lKbXh?D)j&M22l~mFKs#<0$XipO-|iWx@5dsas~?s~ z{Q2_Vf0YH|tO~^WP@ukx0(tvYpxv(z^tX=#^U0lo{PYjl=^e<=LxFg93d~nq1>`Rb z3`JXF4LjwK3JW#LS1o+pbU2^4lV4z;@;y2g%)sJy~JO6I-y0Wh;*YDQ# mg!g~n&DAy6?-R+--3#CO_kRzJ=gH2$=lfJV4|o1Ovi}DkdD8j- literal 0 HcmV?d00001 diff --git a/server/www/packages/packages-linux/x64/cffi/__init__.py b/server/www/packages/packages-linux/x64/cffi/__init__.py new file mode 100644 index 0000000..ddc3614 --- /dev/null +++ b/server/www/packages/packages-linux/x64/cffi/__init__.py @@ -0,0 +1,14 @@ +__all__ = ['FFI', 'VerificationError', 'VerificationMissing', 'CDefError', + 'FFIError'] + +from .api import FFI +from .error import CDefError, FFIError, VerificationError, VerificationMissing +from .error import PkgConfigError + +__version__ = "1.13.2" +__version_info__ = (1, 13, 2) + +# The verifier module file names are based on the CRC32 of a string that +# contains the following version number. It may be older than __version__ +# if nothing is clearly incompatible. +__version_verifier_modules__ = "0.8.6" diff --git a/server/www/packages/packages-linux/x64/cffi/_cffi_errors.h b/server/www/packages/packages-linux/x64/cffi/_cffi_errors.h new file mode 100644 index 0000000..83cdad0 --- /dev/null +++ b/server/www/packages/packages-linux/x64/cffi/_cffi_errors.h @@ -0,0 +1,147 @@ +#ifndef CFFI_MESSAGEBOX +# ifdef _MSC_VER +# define CFFI_MESSAGEBOX 1 +# else +# define CFFI_MESSAGEBOX 0 +# endif +#endif + + +#if CFFI_MESSAGEBOX +/* Windows only: logic to take the Python-CFFI embedding logic + initialization errors and display them in a background thread + with MessageBox. The idea is that if the whole program closes + as a result of this problem, then likely it is already a console + program and you can read the stderr output in the console too. + If it is not a console program, then it will likely show its own + dialog to complain, or generally not abruptly close, and for this + case the background thread should stay alive. +*/ +static void *volatile _cffi_bootstrap_text; + +static PyObject *_cffi_start_error_capture(void) +{ + PyObject *result = NULL; + PyObject *x, *m, *bi; + + if (InterlockedCompareExchangePointer(&_cffi_bootstrap_text, + (void *)1, NULL) != NULL) + return (PyObject *)1; + + m = PyImport_AddModule("_cffi_error_capture"); + if (m == NULL) + goto error; + + result = PyModule_GetDict(m); + if (result == NULL) + goto error; + +#if PY_MAJOR_VERSION >= 3 + bi = PyImport_ImportModule("builtins"); +#else + bi = PyImport_ImportModule("__builtin__"); +#endif + if (bi == NULL) + goto error; + PyDict_SetItemString(result, "__builtins__", bi); + Py_DECREF(bi); + + x = PyRun_String( + "import sys\n" + "class FileLike:\n" + " def write(self, x):\n" + " try:\n" + " of.write(x)\n" + " except: pass\n" + " self.buf += x\n" + "fl = FileLike()\n" + "fl.buf = ''\n" + "of = sys.stderr\n" + "sys.stderr = fl\n" + "def done():\n" + " sys.stderr = of\n" + " return fl.buf\n", /* make sure the returned value stays alive */ + Py_file_input, + result, result); + Py_XDECREF(x); + + error: + if (PyErr_Occurred()) + { + PyErr_WriteUnraisable(Py_None); + PyErr_Clear(); + } + return result; +} + +#pragma comment(lib, "user32.lib") + +static DWORD WINAPI _cffi_bootstrap_dialog(LPVOID ignored) +{ + Sleep(666); /* may be interrupted if the whole process is closing */ +#if PY_MAJOR_VERSION >= 3 + MessageBoxW(NULL, (wchar_t *)_cffi_bootstrap_text, + L"Python-CFFI error", + MB_OK | MB_ICONERROR); +#else + MessageBoxA(NULL, (char *)_cffi_bootstrap_text, + "Python-CFFI error", + MB_OK | MB_ICONERROR); +#endif + _cffi_bootstrap_text = NULL; + return 0; +} + +static void _cffi_stop_error_capture(PyObject *ecap) +{ + PyObject *s; + void *text; + + if (ecap == (PyObject *)1) + return; + + if (ecap == NULL) + goto error; + + s = PyRun_String("done()", Py_eval_input, ecap, ecap); + if (s == NULL) + goto error; + + /* Show a dialog box, but in a background thread, and + never show multiple dialog boxes at once. */ +#if PY_MAJOR_VERSION >= 3 + text = PyUnicode_AsWideCharString(s, NULL); +#else + text = PyString_AsString(s); +#endif + + _cffi_bootstrap_text = text; + + if (text != NULL) + { + HANDLE h; + h = CreateThread(NULL, 0, _cffi_bootstrap_dialog, + NULL, 0, NULL); + if (h != NULL) + CloseHandle(h); + } + /* decref the string, but it should stay alive as 'fl.buf' + in the small module above. It will really be freed only if + we later get another similar error. So it's a leak of at + most one copy of the small module. That's fine for this + situation which is usually a "fatal error" anyway. */ + Py_DECREF(s); + PyErr_Clear(); + return; + + error: + _cffi_bootstrap_text = NULL; + PyErr_Clear(); +} + +#else + +static PyObject *_cffi_start_error_capture(void) { return NULL; } +static void _cffi_stop_error_capture(PyObject *ecap) { } + +#endif diff --git a/server/www/packages/packages-linux/x64/cffi/_cffi_include.h b/server/www/packages/packages-linux/x64/cffi/_cffi_include.h new file mode 100644 index 0000000..37ea74f --- /dev/null +++ b/server/www/packages/packages-linux/x64/cffi/_cffi_include.h @@ -0,0 +1,308 @@ +#define _CFFI_ + +/* We try to define Py_LIMITED_API before including Python.h. + + Mess: we can only define it if Py_DEBUG, Py_TRACE_REFS and + Py_REF_DEBUG are not defined. This is a best-effort approximation: + we can learn about Py_DEBUG from pyconfig.h, but it is unclear if + the same works for the other two macros. Py_DEBUG implies them, + but not the other way around. + + Issue #350 is still open: on Windows, the code here causes it to link + with PYTHON36.DLL (for example) instead of PYTHON3.DLL. A fix was + attempted in 164e526a5515 and 14ce6985e1c3, but reverted: virtualenv + does not make PYTHON3.DLL available, and so the "correctly" compiled + version would not run inside a virtualenv. We will re-apply the fix + after virtualenv has been fixed for some time. For explanation, see + issue #355. For a workaround if you want PYTHON3.DLL and don't worry + about virtualenv, see issue #350. See also 'py_limited_api' in + setuptools_ext.py. +*/ +#if !defined(_CFFI_USE_EMBEDDING) && !defined(Py_LIMITED_API) +# include +# if !defined(Py_DEBUG) && !defined(Py_TRACE_REFS) && !defined(Py_REF_DEBUG) +# define Py_LIMITED_API +# endif +#endif + +#include +#ifdef __cplusplus +extern "C" { +#endif +#include +#include "parse_c_type.h" + +/* this block of #ifs should be kept exactly identical between + c/_cffi_backend.c, cffi/vengine_cpy.py, cffi/vengine_gen.py + and cffi/_cffi_include.h */ +#if defined(_MSC_VER) +# include /* for alloca() */ +# if _MSC_VER < 1600 /* MSVC < 2010 */ + typedef __int8 int8_t; + typedef __int16 int16_t; + typedef __int32 int32_t; + typedef __int64 int64_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; + typedef unsigned __int64 uint64_t; + typedef __int8 int_least8_t; + typedef __int16 int_least16_t; + typedef __int32 int_least32_t; + typedef __int64 int_least64_t; + typedef unsigned __int8 uint_least8_t; + typedef unsigned __int16 uint_least16_t; + typedef unsigned __int32 uint_least32_t; + typedef unsigned __int64 uint_least64_t; + typedef __int8 int_fast8_t; + typedef __int16 int_fast16_t; + typedef __int32 int_fast32_t; + typedef __int64 int_fast64_t; + typedef unsigned __int8 uint_fast8_t; + typedef unsigned __int16 uint_fast16_t; + typedef unsigned __int32 uint_fast32_t; + typedef unsigned __int64 uint_fast64_t; + typedef __int64 intmax_t; + typedef unsigned __int64 uintmax_t; +# else +# include +# endif +# if _MSC_VER < 1800 /* MSVC < 2013 */ +# ifndef __cplusplus + typedef unsigned char _Bool; +# endif +# endif +#else +# include +# if (defined (__SVR4) && defined (__sun)) || defined(_AIX) || defined(__hpux) +# include +# endif +#endif + +#ifdef __GNUC__ +# define _CFFI_UNUSED_FN __attribute__((unused)) +#else +# define _CFFI_UNUSED_FN /* nothing */ +#endif + +#ifdef __cplusplus +# ifndef _Bool + typedef bool _Bool; /* semi-hackish: C++ has no _Bool; bool is builtin */ +# endif +#endif + +/********** CPython-specific section **********/ +#ifndef PYPY_VERSION + + +#if PY_MAJOR_VERSION >= 3 +# define PyInt_FromLong PyLong_FromLong +#endif + +#define _cffi_from_c_double PyFloat_FromDouble +#define _cffi_from_c_float PyFloat_FromDouble +#define _cffi_from_c_long PyInt_FromLong +#define _cffi_from_c_ulong PyLong_FromUnsignedLong +#define _cffi_from_c_longlong PyLong_FromLongLong +#define _cffi_from_c_ulonglong PyLong_FromUnsignedLongLong +#define _cffi_from_c__Bool PyBool_FromLong + +#define _cffi_to_c_double PyFloat_AsDouble +#define _cffi_to_c_float PyFloat_AsDouble + +#define _cffi_from_c_int(x, type) \ + (((type)-1) > 0 ? /* unsigned */ \ + (sizeof(type) < sizeof(long) ? \ + PyInt_FromLong((long)x) : \ + sizeof(type) == sizeof(long) ? \ + PyLong_FromUnsignedLong((unsigned long)x) : \ + PyLong_FromUnsignedLongLong((unsigned long long)x)) : \ + (sizeof(type) <= sizeof(long) ? \ + PyInt_FromLong((long)x) : \ + PyLong_FromLongLong((long long)x))) + +#define _cffi_to_c_int(o, type) \ + ((type)( \ + sizeof(type) == 1 ? (((type)-1) > 0 ? (type)_cffi_to_c_u8(o) \ + : (type)_cffi_to_c_i8(o)) : \ + sizeof(type) == 2 ? (((type)-1) > 0 ? (type)_cffi_to_c_u16(o) \ + : (type)_cffi_to_c_i16(o)) : \ + sizeof(type) == 4 ? (((type)-1) > 0 ? (type)_cffi_to_c_u32(o) \ + : (type)_cffi_to_c_i32(o)) : \ + sizeof(type) == 8 ? (((type)-1) > 0 ? (type)_cffi_to_c_u64(o) \ + : (type)_cffi_to_c_i64(o)) : \ + (Py_FatalError("unsupported size for type " #type), (type)0))) + +#define _cffi_to_c_i8 \ + ((int(*)(PyObject *))_cffi_exports[1]) +#define _cffi_to_c_u8 \ + ((int(*)(PyObject *))_cffi_exports[2]) +#define _cffi_to_c_i16 \ + ((int(*)(PyObject *))_cffi_exports[3]) +#define _cffi_to_c_u16 \ + ((int(*)(PyObject *))_cffi_exports[4]) +#define _cffi_to_c_i32 \ + ((int(*)(PyObject *))_cffi_exports[5]) +#define _cffi_to_c_u32 \ + ((unsigned int(*)(PyObject *))_cffi_exports[6]) +#define _cffi_to_c_i64 \ + ((long long(*)(PyObject *))_cffi_exports[7]) +#define _cffi_to_c_u64 \ + ((unsigned long long(*)(PyObject *))_cffi_exports[8]) +#define _cffi_to_c_char \ + ((int(*)(PyObject *))_cffi_exports[9]) +#define _cffi_from_c_pointer \ + ((PyObject *(*)(char *, struct _cffi_ctypedescr *))_cffi_exports[10]) +#define _cffi_to_c_pointer \ + ((char *(*)(PyObject *, struct _cffi_ctypedescr *))_cffi_exports[11]) +#define _cffi_get_struct_layout \ + not used any more +#define _cffi_restore_errno \ + ((void(*)(void))_cffi_exports[13]) +#define _cffi_save_errno \ + ((void(*)(void))_cffi_exports[14]) +#define _cffi_from_c_char \ + ((PyObject *(*)(char))_cffi_exports[15]) +#define _cffi_from_c_deref \ + ((PyObject *(*)(char *, struct _cffi_ctypedescr *))_cffi_exports[16]) +#define _cffi_to_c \ + ((int(*)(char *, struct _cffi_ctypedescr *, PyObject *))_cffi_exports[17]) +#define _cffi_from_c_struct \ + ((PyObject *(*)(char *, struct _cffi_ctypedescr *))_cffi_exports[18]) +#define _cffi_to_c_wchar_t \ + ((_cffi_wchar_t(*)(PyObject *))_cffi_exports[19]) +#define _cffi_from_c_wchar_t \ + ((PyObject *(*)(_cffi_wchar_t))_cffi_exports[20]) +#define _cffi_to_c_long_double \ + ((long double(*)(PyObject *))_cffi_exports[21]) +#define _cffi_to_c__Bool \ + ((_Bool(*)(PyObject *))_cffi_exports[22]) +#define _cffi_prepare_pointer_call_argument \ + ((Py_ssize_t(*)(struct _cffi_ctypedescr *, \ + PyObject *, char **))_cffi_exports[23]) +#define _cffi_convert_array_from_object \ + ((int(*)(char *, struct _cffi_ctypedescr *, PyObject *))_cffi_exports[24]) +#define _CFFI_CPIDX 25 +#define _cffi_call_python \ + ((void(*)(struct _cffi_externpy_s *, char *))_cffi_exports[_CFFI_CPIDX]) +#define _cffi_to_c_wchar3216_t \ + ((int(*)(PyObject *))_cffi_exports[26]) +#define _cffi_from_c_wchar3216_t \ + ((PyObject *(*)(int))_cffi_exports[27]) +#define _CFFI_NUM_EXPORTS 28 + +struct _cffi_ctypedescr; + +static void *_cffi_exports[_CFFI_NUM_EXPORTS]; + +#define _cffi_type(index) ( \ + assert((((uintptr_t)_cffi_types[index]) & 1) == 0), \ + (struct _cffi_ctypedescr *)_cffi_types[index]) + +static PyObject *_cffi_init(const char *module_name, Py_ssize_t version, + const struct _cffi_type_context_s *ctx) +{ + PyObject *module, *o_arg, *new_module; + void *raw[] = { + (void *)module_name, + (void *)version, + (void *)_cffi_exports, + (void *)ctx, + }; + + module = PyImport_ImportModule("_cffi_backend"); + if (module == NULL) + goto failure; + + o_arg = PyLong_FromVoidPtr((void *)raw); + if (o_arg == NULL) + goto failure; + + new_module = PyObject_CallMethod( + module, (char *)"_init_cffi_1_0_external_module", (char *)"O", o_arg); + + Py_DECREF(o_arg); + Py_DECREF(module); + return new_module; + + failure: + Py_XDECREF(module); + return NULL; +} + + +#ifdef HAVE_WCHAR_H +typedef wchar_t _cffi_wchar_t; +#else +typedef uint16_t _cffi_wchar_t; /* same random pick as _cffi_backend.c */ +#endif + +_CFFI_UNUSED_FN static uint16_t _cffi_to_c_char16_t(PyObject *o) +{ + if (sizeof(_cffi_wchar_t) == 2) + return (uint16_t)_cffi_to_c_wchar_t(o); + else + return (uint16_t)_cffi_to_c_wchar3216_t(o); +} + +_CFFI_UNUSED_FN static PyObject *_cffi_from_c_char16_t(uint16_t x) +{ + if (sizeof(_cffi_wchar_t) == 2) + return _cffi_from_c_wchar_t((_cffi_wchar_t)x); + else + return _cffi_from_c_wchar3216_t((int)x); +} + +_CFFI_UNUSED_FN static int _cffi_to_c_char32_t(PyObject *o) +{ + if (sizeof(_cffi_wchar_t) == 4) + return (int)_cffi_to_c_wchar_t(o); + else + return (int)_cffi_to_c_wchar3216_t(o); +} + +_CFFI_UNUSED_FN static PyObject *_cffi_from_c_char32_t(int x) +{ + if (sizeof(_cffi_wchar_t) == 4) + return _cffi_from_c_wchar_t((_cffi_wchar_t)x); + else + return _cffi_from_c_wchar3216_t(x); +} + + +/********** end CPython-specific section **********/ +#else +_CFFI_UNUSED_FN +static void (*_cffi_call_python_org)(struct _cffi_externpy_s *, char *); +# define _cffi_call_python _cffi_call_python_org +#endif + + +#define _cffi_array_len(array) (sizeof(array) / sizeof((array)[0])) + +#define _cffi_prim_int(size, sign) \ + ((size) == 1 ? ((sign) ? _CFFI_PRIM_INT8 : _CFFI_PRIM_UINT8) : \ + (size) == 2 ? ((sign) ? _CFFI_PRIM_INT16 : _CFFI_PRIM_UINT16) : \ + (size) == 4 ? ((sign) ? _CFFI_PRIM_INT32 : _CFFI_PRIM_UINT32) : \ + (size) == 8 ? ((sign) ? _CFFI_PRIM_INT64 : _CFFI_PRIM_UINT64) : \ + _CFFI__UNKNOWN_PRIM) + +#define _cffi_prim_float(size) \ + ((size) == sizeof(float) ? _CFFI_PRIM_FLOAT : \ + (size) == sizeof(double) ? _CFFI_PRIM_DOUBLE : \ + (size) == sizeof(long double) ? _CFFI__UNKNOWN_LONG_DOUBLE : \ + _CFFI__UNKNOWN_FLOAT_PRIM) + +#define _cffi_check_int(got, got_nonpos, expected) \ + ((got_nonpos) == (expected <= 0) && \ + (got) == (unsigned long long)expected) + +#ifdef MS_WIN32 +# define _cffi_stdcall __stdcall +#else +# define _cffi_stdcall /* nothing */ +#endif + +#ifdef __cplusplus +} +#endif diff --git a/server/www/packages/packages-linux/x64/cffi/_embedding.h b/server/www/packages/packages-linux/x64/cffi/_embedding.h new file mode 100644 index 0000000..abd474a --- /dev/null +++ b/server/www/packages/packages-linux/x64/cffi/_embedding.h @@ -0,0 +1,520 @@ + +/***** Support code for embedding *****/ + +#ifdef __cplusplus +extern "C" { +#endif + + +#if defined(_WIN32) +# define CFFI_DLLEXPORT __declspec(dllexport) +#elif defined(__GNUC__) +# define CFFI_DLLEXPORT __attribute__((visibility("default"))) +#else +# define CFFI_DLLEXPORT /* nothing */ +#endif + + +/* There are two global variables of type _cffi_call_python_fnptr: + + * _cffi_call_python, which we declare just below, is the one called + by ``extern "Python"`` implementations. + + * _cffi_call_python_org, which on CPython is actually part of the + _cffi_exports[] array, is the function pointer copied from + _cffi_backend. + + After initialization is complete, both are equal. However, the + first one remains equal to &_cffi_start_and_call_python until the + very end of initialization, when we are (or should be) sure that + concurrent threads also see a completely initialized world, and + only then is it changed. +*/ +#undef _cffi_call_python +typedef void (*_cffi_call_python_fnptr)(struct _cffi_externpy_s *, char *); +static void _cffi_start_and_call_python(struct _cffi_externpy_s *, char *); +static _cffi_call_python_fnptr _cffi_call_python = &_cffi_start_and_call_python; + + +#ifndef _MSC_VER + /* --- Assuming a GCC not infinitely old --- */ +# define cffi_compare_and_swap(l,o,n) __sync_bool_compare_and_swap(l,o,n) +# define cffi_write_barrier() __sync_synchronize() +# if !defined(__amd64__) && !defined(__x86_64__) && \ + !defined(__i386__) && !defined(__i386) +# define cffi_read_barrier() __sync_synchronize() +# else +# define cffi_read_barrier() (void)0 +# endif +#else + /* --- Windows threads version --- */ +# include +# define cffi_compare_and_swap(l,o,n) \ + (InterlockedCompareExchangePointer(l,n,o) == (o)) +# define cffi_write_barrier() InterlockedCompareExchange(&_cffi_dummy,0,0) +# define cffi_read_barrier() (void)0 +static volatile LONG _cffi_dummy; +#endif + +#ifdef WITH_THREAD +# ifndef _MSC_VER +# include + static pthread_mutex_t _cffi_embed_startup_lock; +# else + static CRITICAL_SECTION _cffi_embed_startup_lock; +# endif + static char _cffi_embed_startup_lock_ready = 0; +#endif + +static void _cffi_acquire_reentrant_mutex(void) +{ + static void *volatile lock = NULL; + + while (!cffi_compare_and_swap(&lock, NULL, (void *)1)) { + /* should ideally do a spin loop instruction here, but + hard to do it portably and doesn't really matter I + think: pthread_mutex_init() should be very fast, and + this is only run at start-up anyway. */ + } + +#ifdef WITH_THREAD + if (!_cffi_embed_startup_lock_ready) { +# ifndef _MSC_VER + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&_cffi_embed_startup_lock, &attr); +# else + InitializeCriticalSection(&_cffi_embed_startup_lock); +# endif + _cffi_embed_startup_lock_ready = 1; + } +#endif + + while (!cffi_compare_and_swap(&lock, (void *)1, NULL)) + ; + +#ifndef _MSC_VER + pthread_mutex_lock(&_cffi_embed_startup_lock); +#else + EnterCriticalSection(&_cffi_embed_startup_lock); +#endif +} + +static void _cffi_release_reentrant_mutex(void) +{ +#ifndef _MSC_VER + pthread_mutex_unlock(&_cffi_embed_startup_lock); +#else + LeaveCriticalSection(&_cffi_embed_startup_lock); +#endif +} + + +/********** CPython-specific section **********/ +#ifndef PYPY_VERSION + +#include "_cffi_errors.h" + + +#define _cffi_call_python_org _cffi_exports[_CFFI_CPIDX] + +PyMODINIT_FUNC _CFFI_PYTHON_STARTUP_FUNC(void); /* forward */ + +static void _cffi_py_initialize(void) +{ + /* XXX use initsigs=0, which "skips initialization registration of + signal handlers, which might be useful when Python is + embedded" according to the Python docs. But review and think + if it should be a user-controllable setting. + + XXX we should also give a way to write errors to a buffer + instead of to stderr. + + XXX if importing 'site' fails, CPython (any version) calls + exit(). Should we try to work around this behavior here? + */ + Py_InitializeEx(0); +} + +static int _cffi_initialize_python(void) +{ + /* This initializes Python, imports _cffi_backend, and then the + present .dll/.so is set up as a CPython C extension module. + */ + int result; + PyGILState_STATE state; + PyObject *pycode=NULL, *global_dict=NULL, *x; + PyObject *builtins; + + state = PyGILState_Ensure(); + + /* Call the initxxx() function from the present module. It will + create and initialize us as a CPython extension module, instead + of letting the startup Python code do it---it might reimport + the same .dll/.so and get maybe confused on some platforms. + It might also have troubles locating the .dll/.so again for all + I know. + */ + (void)_CFFI_PYTHON_STARTUP_FUNC(); + if (PyErr_Occurred()) + goto error; + + /* Now run the Python code provided to ffi.embedding_init_code(). + */ + pycode = Py_CompileString(_CFFI_PYTHON_STARTUP_CODE, + "", + Py_file_input); + if (pycode == NULL) + goto error; + global_dict = PyDict_New(); + if (global_dict == NULL) + goto error; + builtins = PyEval_GetBuiltins(); + if (builtins == NULL) + goto error; + if (PyDict_SetItemString(global_dict, "__builtins__", builtins) < 0) + goto error; + x = PyEval_EvalCode( +#if PY_MAJOR_VERSION < 3 + (PyCodeObject *) +#endif + pycode, global_dict, global_dict); + if (x == NULL) + goto error; + Py_DECREF(x); + + /* Done! Now if we've been called from + _cffi_start_and_call_python() in an ``extern "Python"``, we can + only hope that the Python code did correctly set up the + corresponding @ffi.def_extern() function. Otherwise, the + general logic of ``extern "Python"`` functions (inside the + _cffi_backend module) will find that the reference is still + missing and print an error. + */ + result = 0; + done: + Py_XDECREF(pycode); + Py_XDECREF(global_dict); + PyGILState_Release(state); + return result; + + error:; + { + /* Print as much information as potentially useful. + Debugging load-time failures with embedding is not fun + */ + PyObject *ecap; + PyObject *exception, *v, *tb, *f, *modules, *mod; + PyErr_Fetch(&exception, &v, &tb); + ecap = _cffi_start_error_capture(); + f = PySys_GetObject((char *)"stderr"); + if (f != NULL && f != Py_None) { + PyFile_WriteString( + "Failed to initialize the Python-CFFI embedding logic:\n\n", f); + } + + if (exception != NULL) { + PyErr_NormalizeException(&exception, &v, &tb); + PyErr_Display(exception, v, tb); + } + Py_XDECREF(exception); + Py_XDECREF(v); + Py_XDECREF(tb); + + if (f != NULL && f != Py_None) { + PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME + "\ncompiled with cffi version: 1.13.2" + "\n_cffi_backend module: ", f); + modules = PyImport_GetModuleDict(); + mod = PyDict_GetItemString(modules, "_cffi_backend"); + if (mod == NULL) { + PyFile_WriteString("not loaded", f); + } + else { + v = PyObject_GetAttrString(mod, "__file__"); + PyFile_WriteObject(v, f, 0); + Py_XDECREF(v); + } + PyFile_WriteString("\nsys.path: ", f); + PyFile_WriteObject(PySys_GetObject((char *)"path"), f, 0); + PyFile_WriteString("\n\n", f); + } + _cffi_stop_error_capture(ecap); + } + result = -1; + goto done; +} + +PyAPI_DATA(char *) _PyParser_TokenNames[]; /* from CPython */ + +static int _cffi_carefully_make_gil(void) +{ + /* This does the basic initialization of Python. It can be called + completely concurrently from unrelated threads. It assumes + that we don't hold the GIL before (if it exists), and we don't + hold it afterwards. + + (What it really does used to be completely different in Python 2 + and Python 3, with the Python 2 solution avoiding the spin-lock + around the Py_InitializeEx() call. However, after recent changes + to CPython 2.7 (issue #358) it no longer works. So we use the + Python 3 solution everywhere.) + + This initializes Python by calling Py_InitializeEx(). + Important: this must not be called concurrently at all. + So we use a global variable as a simple spin lock. This global + variable must be from 'libpythonX.Y.so', not from this + cffi-based extension module, because it must be shared from + different cffi-based extension modules. + + In Python < 3.8, we choose + _PyParser_TokenNames[0] as a completely arbitrary pointer value + that is never written to. The default is to point to the + string "ENDMARKER". We change it temporarily to point to the + next character in that string. (Yes, I know it's REALLY + obscure.) + + In Python >= 3.8, this string array is no longer writable, so + instead we pick PyCapsuleType.tp_version_tag. We can't change + Python < 3.8 because someone might use a mixture of cffi + embedded modules, some of which were compiled before this file + changed. + */ + +#ifdef WITH_THREAD +# if PY_VERSION_HEX < 0x03080000 + char *volatile *lock = (char *volatile *)_PyParser_TokenNames; + char *old_value, *locked_value; + + while (1) { /* spin loop */ + old_value = *lock; + locked_value = old_value + 1; + if (old_value[0] == 'E') { + assert(old_value[1] == 'N'); + if (cffi_compare_and_swap(lock, old_value, locked_value)) + break; + } + else { + assert(old_value[0] == 'N'); + /* should ideally do a spin loop instruction here, but + hard to do it portably and doesn't really matter I + think: PyEval_InitThreads() should be very fast, and + this is only run at start-up anyway. */ + } + } +# else + int volatile *lock = (int volatile *)&PyCapsule_Type.tp_version_tag; + int old_value, locked_value; + assert(!(PyCapsule_Type.tp_flags & Py_TPFLAGS_HAVE_VERSION_TAG)); + + while (1) { /* spin loop */ + old_value = *lock; + locked_value = -42; + if (old_value == 0) { + if (cffi_compare_and_swap(lock, old_value, locked_value)) + break; + } + else { + assert(old_value == locked_value); + /* should ideally do a spin loop instruction here, but + hard to do it portably and doesn't really matter I + think: PyEval_InitThreads() should be very fast, and + this is only run at start-up anyway. */ + } + } +# endif +#endif + + /* call Py_InitializeEx() */ + if (!Py_IsInitialized()) { + _cffi_py_initialize(); + PyEval_InitThreads(); + PyEval_SaveThread(); /* release the GIL */ + /* the returned tstate must be the one that has been stored into the + autoTLSkey by _PyGILState_Init() called from Py_Initialize(). */ + } + else { + PyGILState_STATE state = PyGILState_Ensure(); + PyEval_InitThreads(); + PyGILState_Release(state); + } + +#ifdef WITH_THREAD + /* release the lock */ + while (!cffi_compare_and_swap(lock, locked_value, old_value)) + ; +#endif + + return 0; +} + +/********** end CPython-specific section **********/ + + +#else + + +/********** PyPy-specific section **********/ + +PyMODINIT_FUNC _CFFI_PYTHON_STARTUP_FUNC(const void *[]); /* forward */ + +static struct _cffi_pypy_init_s { + const char *name; + void (*func)(const void *[]); + const char *code; +} _cffi_pypy_init = { + _CFFI_MODULE_NAME, + (void(*)(const void *[]))_CFFI_PYTHON_STARTUP_FUNC, + _CFFI_PYTHON_STARTUP_CODE, +}; + +extern int pypy_carefully_make_gil(const char *); +extern int pypy_init_embedded_cffi_module(int, struct _cffi_pypy_init_s *); + +static int _cffi_carefully_make_gil(void) +{ + return pypy_carefully_make_gil(_CFFI_MODULE_NAME); +} + +static int _cffi_initialize_python(void) +{ + return pypy_init_embedded_cffi_module(0xB011, &_cffi_pypy_init); +} + +/********** end PyPy-specific section **********/ + + +#endif + + +#ifdef __GNUC__ +__attribute__((noinline)) +#endif +static _cffi_call_python_fnptr _cffi_start_python(void) +{ + /* Delicate logic to initialize Python. This function can be + called multiple times concurrently, e.g. when the process calls + its first ``extern "Python"`` functions in multiple threads at + once. It can also be called recursively, in which case we must + ignore it. We also have to consider what occurs if several + different cffi-based extensions reach this code in parallel + threads---it is a different copy of the code, then, and we + can't have any shared global variable unless it comes from + 'libpythonX.Y.so'. + + Idea: + + * _cffi_carefully_make_gil(): "carefully" call + PyEval_InitThreads() (possibly with Py_InitializeEx() first). + + * then we use a (local) custom lock to make sure that a call to this + cffi-based extension will wait if another call to the *same* + extension is running the initialization in another thread. + It is reentrant, so that a recursive call will not block, but + only one from a different thread. + + * then we grab the GIL and (Python 2) we call Py_InitializeEx(). + At this point, concurrent calls to Py_InitializeEx() are not + possible: we have the GIL. + + * do the rest of the specific initialization, which may + temporarily release the GIL but not the custom lock. + Only release the custom lock when we are done. + */ + static char called = 0; + + if (_cffi_carefully_make_gil() != 0) + return NULL; + + _cffi_acquire_reentrant_mutex(); + + /* Here the GIL exists, but we don't have it. We're only protected + from concurrency by the reentrant mutex. */ + + /* This file only initializes the embedded module once, the first + time this is called, even if there are subinterpreters. */ + if (!called) { + called = 1; /* invoke _cffi_initialize_python() only once, + but don't set '_cffi_call_python' right now, + otherwise concurrent threads won't call + this function at all (we need them to wait) */ + if (_cffi_initialize_python() == 0) { + /* now initialization is finished. Switch to the fast-path. */ + + /* We would like nobody to see the new value of + '_cffi_call_python' without also seeing the rest of the + data initialized. However, this is not possible. But + the new value of '_cffi_call_python' is the function + 'cffi_call_python()' from _cffi_backend. So: */ + cffi_write_barrier(); + /* ^^^ we put a write barrier here, and a corresponding + read barrier at the start of cffi_call_python(). This + ensures that after that read barrier, we see everything + done here before the write barrier. + */ + + assert(_cffi_call_python_org != NULL); + _cffi_call_python = (_cffi_call_python_fnptr)_cffi_call_python_org; + } + else { + /* initialization failed. Reset this to NULL, even if it was + already set to some other value. Future calls to + _cffi_start_python() are still forced to occur, and will + always return NULL from now on. */ + _cffi_call_python_org = NULL; + } + } + + _cffi_release_reentrant_mutex(); + + return (_cffi_call_python_fnptr)_cffi_call_python_org; +} + +static +void _cffi_start_and_call_python(struct _cffi_externpy_s *externpy, char *args) +{ + _cffi_call_python_fnptr fnptr; + int current_err = errno; +#ifdef _MSC_VER + int current_lasterr = GetLastError(); +#endif + fnptr = _cffi_start_python(); + if (fnptr == NULL) { + fprintf(stderr, "function %s() called, but initialization code " + "failed. Returning 0.\n", externpy->name); + memset(args, 0, externpy->size_of_result); + } +#ifdef _MSC_VER + SetLastError(current_lasterr); +#endif + errno = current_err; + + if (fnptr != NULL) + fnptr(externpy, args); +} + + +/* The cffi_start_python() function makes sure Python is initialized + and our cffi module is set up. It can be called manually from the + user C code. The same effect is obtained automatically from any + dll-exported ``extern "Python"`` function. This function returns + -1 if initialization failed, 0 if all is OK. */ +_CFFI_UNUSED_FN +static int cffi_start_python(void) +{ + if (_cffi_call_python == &_cffi_start_and_call_python) { + if (_cffi_start_python() == NULL) + return -1; + } + cffi_read_barrier(); + return 0; +} + +#undef cffi_compare_and_swap +#undef cffi_write_barrier +#undef cffi_read_barrier + +#ifdef __cplusplus +} +#endif diff --git a/server/www/packages/packages-linux/x64/cffi/api.py b/server/www/packages/packages-linux/x64/cffi/api.py new file mode 100644 index 0000000..32fe620 --- /dev/null +++ b/server/www/packages/packages-linux/x64/cffi/api.py @@ -0,0 +1,961 @@ +import sys, types +from .lock import allocate_lock +from .error import CDefError +from . import model + +try: + callable +except NameError: + # Python 3.1 + from collections import Callable + callable = lambda x: isinstance(x, Callable) + +try: + basestring +except NameError: + # Python 3.x + basestring = str + +_unspecified = object() + + + +class FFI(object): + r''' + The main top-level class that you instantiate once, or once per module. + + Example usage: + + ffi = FFI() + ffi.cdef(""" + int printf(const char *, ...); + """) + + C = ffi.dlopen(None) # standard library + -or- + C = ffi.verify() # use a C compiler: verify the decl above is right + + C.printf("hello, %s!\n", ffi.new("char[]", "world")) + ''' + + def __init__(self, backend=None): + """Create an FFI instance. The 'backend' argument is used to + select a non-default backend, mostly for tests. + """ + if backend is None: + # You need PyPy (>= 2.0 beta), or a CPython (>= 2.6) with + # _cffi_backend.so compiled. + import _cffi_backend as backend + from . import __version__ + if backend.__version__ != __version__: + # bad version! Try to be as explicit as possible. + if hasattr(backend, '__file__'): + # CPython + raise Exception("Version mismatch: this is the 'cffi' package version %s, located in %r. When we import the top-level '_cffi_backend' extension module, we get version %s, located in %r. The two versions should be equal; check your installation." % ( + __version__, __file__, + backend.__version__, backend.__file__)) + else: + # PyPy + raise Exception("Version mismatch: this is the 'cffi' package version %s, located in %r. This interpreter comes with a built-in '_cffi_backend' module, which is version %s. The two versions should be equal; check your installation." % ( + __version__, __file__, backend.__version__)) + # (If you insist you can also try to pass the option + # 'backend=backend_ctypes.CTypesBackend()', but don't + # rely on it! It's probably not going to work well.) + + from . import cparser + self._backend = backend + self._lock = allocate_lock() + self._parser = cparser.Parser() + self._cached_btypes = {} + self._parsed_types = types.ModuleType('parsed_types').__dict__ + self._new_types = types.ModuleType('new_types').__dict__ + self._function_caches = [] + self._libraries = [] + self._cdefsources = [] + self._included_ffis = [] + self._windows_unicode = None + self._init_once_cache = {} + self._cdef_version = None + self._embedding = None + self._typecache = model.get_typecache(backend) + if hasattr(backend, 'set_ffi'): + backend.set_ffi(self) + for name in list(backend.__dict__): + if name.startswith('RTLD_'): + setattr(self, name, getattr(backend, name)) + # + with self._lock: + self.BVoidP = self._get_cached_btype(model.voidp_type) + self.BCharA = self._get_cached_btype(model.char_array_type) + if isinstance(backend, types.ModuleType): + # _cffi_backend: attach these constants to the class + if not hasattr(FFI, 'NULL'): + FFI.NULL = self.cast(self.BVoidP, 0) + FFI.CData, FFI.CType = backend._get_types() + else: + # ctypes backend: attach these constants to the instance + self.NULL = self.cast(self.BVoidP, 0) + self.CData, self.CType = backend._get_types() + self.buffer = backend.buffer + + def cdef(self, csource, override=False, packed=False, pack=None): + """Parse the given C source. This registers all declared functions, + types, and global variables. The functions and global variables can + then be accessed via either 'ffi.dlopen()' or 'ffi.verify()'. + The types can be used in 'ffi.new()' and other functions. + If 'packed' is specified as True, all structs declared inside this + cdef are packed, i.e. laid out without any field alignment at all. + Alternatively, 'pack' can be a small integer, and requests for + alignment greater than that are ignored (pack=1 is equivalent to + packed=True). + """ + self._cdef(csource, override=override, packed=packed, pack=pack) + + def embedding_api(self, csource, packed=False, pack=None): + self._cdef(csource, packed=packed, pack=pack, dllexport=True) + if self._embedding is None: + self._embedding = '' + + def _cdef(self, csource, override=False, **options): + if not isinstance(csource, str): # unicode, on Python 2 + if not isinstance(csource, basestring): + raise TypeError("cdef() argument must be a string") + csource = csource.encode('ascii') + with self._lock: + self._cdef_version = object() + self._parser.parse(csource, override=override, **options) + self._cdefsources.append(csource) + if override: + for cache in self._function_caches: + cache.clear() + finishlist = self._parser._recomplete + if finishlist: + self._parser._recomplete = [] + for tp in finishlist: + tp.finish_backend_type(self, finishlist) + + def dlopen(self, name, flags=0): + """Load and return a dynamic library identified by 'name'. + The standard C library can be loaded by passing None. + Note that functions and types declared by 'ffi.cdef()' are not + linked to a particular library, just like C headers; in the + library we only look for the actual (untyped) symbols. + """ + assert isinstance(name, basestring) or name is None + with self._lock: + lib, function_cache = _make_ffi_library(self, name, flags) + self._function_caches.append(function_cache) + self._libraries.append(lib) + return lib + + def dlclose(self, lib): + """Close a library obtained with ffi.dlopen(). After this call, + access to functions or variables from the library will fail + (possibly with a segmentation fault). + """ + type(lib).__cffi_close__(lib) + + def _typeof_locked(self, cdecl): + # call me with the lock! + key = cdecl + if key in self._parsed_types: + return self._parsed_types[key] + # + if not isinstance(cdecl, str): # unicode, on Python 2 + cdecl = cdecl.encode('ascii') + # + type = self._parser.parse_type(cdecl) + really_a_function_type = type.is_raw_function + if really_a_function_type: + type = type.as_function_pointer() + btype = self._get_cached_btype(type) + result = btype, really_a_function_type + self._parsed_types[key] = result + return result + + def _typeof(self, cdecl, consider_function_as_funcptr=False): + # string -> ctype object + try: + result = self._parsed_types[cdecl] + except KeyError: + with self._lock: + result = self._typeof_locked(cdecl) + # + btype, really_a_function_type = result + if really_a_function_type and not consider_function_as_funcptr: + raise CDefError("the type %r is a function type, not a " + "pointer-to-function type" % (cdecl,)) + return btype + + def typeof(self, cdecl): + """Parse the C type given as a string and return the + corresponding object. + It can also be used on 'cdata' instance to get its C type. + """ + if isinstance(cdecl, basestring): + return self._typeof(cdecl) + if isinstance(cdecl, self.CData): + return self._backend.typeof(cdecl) + if isinstance(cdecl, types.BuiltinFunctionType): + res = _builtin_function_type(cdecl) + if res is not None: + return res + if (isinstance(cdecl, types.FunctionType) + and hasattr(cdecl, '_cffi_base_type')): + with self._lock: + return self._get_cached_btype(cdecl._cffi_base_type) + raise TypeError(type(cdecl)) + + def sizeof(self, cdecl): + """Return the size in bytes of the argument. It can be a + string naming a C type, or a 'cdata' instance. + """ + if isinstance(cdecl, basestring): + BType = self._typeof(cdecl) + return self._backend.sizeof(BType) + else: + return self._backend.sizeof(cdecl) + + def alignof(self, cdecl): + """Return the natural alignment size in bytes of the C type + given as a string. + """ + if isinstance(cdecl, basestring): + cdecl = self._typeof(cdecl) + return self._backend.alignof(cdecl) + + def offsetof(self, cdecl, *fields_or_indexes): + """Return the offset of the named field inside the given + structure or array, which must be given as a C type name. + You can give several field names in case of nested structures. + You can also give numeric values which correspond to array + items, in case of an array type. + """ + if isinstance(cdecl, basestring): + cdecl = self._typeof(cdecl) + return self._typeoffsetof(cdecl, *fields_or_indexes)[1] + + def new(self, cdecl, init=None): + """Allocate an instance according to the specified C type and + return a pointer to it. The specified C type must be either a + pointer or an array: ``new('X *')`` allocates an X and returns + a pointer to it, whereas ``new('X[n]')`` allocates an array of + n X'es and returns an array referencing it (which works + mostly like a pointer, like in C). You can also use + ``new('X[]', n)`` to allocate an array of a non-constant + length n. + + The memory is initialized following the rules of declaring a + global variable in C: by default it is zero-initialized, but + an explicit initializer can be given which can be used to + fill all or part of the memory. + + When the returned object goes out of scope, the memory + is freed. In other words the returned object has + ownership of the value of type 'cdecl' that it points to. This + means that the raw data can be used as long as this object is + kept alive, but must not be used for a longer time. Be careful + about that when copying the pointer to the memory somewhere + else, e.g. into another structure. + """ + if isinstance(cdecl, basestring): + cdecl = self._typeof(cdecl) + return self._backend.newp(cdecl, init) + + def new_allocator(self, alloc=None, free=None, + should_clear_after_alloc=True): + """Return a new allocator, i.e. a function that behaves like ffi.new() + but uses the provided low-level 'alloc' and 'free' functions. + + 'alloc' is called with the size as argument. If it returns NULL, a + MemoryError is raised. 'free' is called with the result of 'alloc' + as argument. Both can be either Python function or directly C + functions. If 'free' is None, then no free function is called. + If both 'alloc' and 'free' are None, the default is used. + + If 'should_clear_after_alloc' is set to False, then the memory + returned by 'alloc' is assumed to be already cleared (or you are + fine with garbage); otherwise CFFI will clear it. + """ + compiled_ffi = self._backend.FFI() + allocator = compiled_ffi.new_allocator(alloc, free, + should_clear_after_alloc) + def allocate(cdecl, init=None): + if isinstance(cdecl, basestring): + cdecl = self._typeof(cdecl) + return allocator(cdecl, init) + return allocate + + def cast(self, cdecl, source): + """Similar to a C cast: returns an instance of the named C + type initialized with the given 'source'. The source is + casted between integers or pointers of any type. + """ + if isinstance(cdecl, basestring): + cdecl = self._typeof(cdecl) + return self._backend.cast(cdecl, source) + + def string(self, cdata, maxlen=-1): + """Return a Python string (or unicode string) from the 'cdata'. + If 'cdata' is a pointer or array of characters or bytes, returns + the null-terminated string. The returned string extends until + the first null character, or at most 'maxlen' characters. If + 'cdata' is an array then 'maxlen' defaults to its length. + + If 'cdata' is a pointer or array of wchar_t, returns a unicode + string following the same rules. + + If 'cdata' is a single character or byte or a wchar_t, returns + it as a string or unicode string. + + If 'cdata' is an enum, returns the value of the enumerator as a + string, or 'NUMBER' if the value is out of range. + """ + return self._backend.string(cdata, maxlen) + + def unpack(self, cdata, length): + """Unpack an array of C data of the given length, + returning a Python string/unicode/list. + + If 'cdata' is a pointer to 'char', returns a byte string. + It does not stop at the first null. This is equivalent to: + ffi.buffer(cdata, length)[:] + + If 'cdata' is a pointer to 'wchar_t', returns a unicode string. + 'length' is measured in wchar_t's; it is not the size in bytes. + + If 'cdata' is a pointer to anything else, returns a list of + 'length' items. This is a faster equivalent to: + [cdata[i] for i in range(length)] + """ + return self._backend.unpack(cdata, length) + + #def buffer(self, cdata, size=-1): + # """Return a read-write buffer object that references the raw C data + # pointed to by the given 'cdata'. The 'cdata' must be a pointer or + # an array. Can be passed to functions expecting a buffer, or directly + # manipulated with: + # + # buf[:] get a copy of it in a regular string, or + # buf[idx] as a single character + # buf[:] = ... + # buf[idx] = ... change the content + # """ + # note that 'buffer' is a type, set on this instance by __init__ + + def from_buffer(self, cdecl, python_buffer=_unspecified, + require_writable=False): + """Return a cdata of the given type pointing to the data of the + given Python object, which must support the buffer interface. + Note that this is not meant to be used on the built-in types + str or unicode (you can build 'char[]' arrays explicitly) + but only on objects containing large quantities of raw data + in some other format, like 'array.array' or numpy arrays. + + The first argument is optional and default to 'char[]'. + """ + if python_buffer is _unspecified: + cdecl, python_buffer = self.BCharA, cdecl + elif isinstance(cdecl, basestring): + cdecl = self._typeof(cdecl) + return self._backend.from_buffer(cdecl, python_buffer, + require_writable) + + def memmove(self, dest, src, n): + """ffi.memmove(dest, src, n) copies n bytes of memory from src to dest. + + Like the C function memmove(), the memory areas may overlap; + apart from that it behaves like the C function memcpy(). + + 'src' can be any cdata ptr or array, or any Python buffer object. + 'dest' can be any cdata ptr or array, or a writable Python buffer + object. The size to copy, 'n', is always measured in bytes. + + Unlike other methods, this one supports all Python buffer including + byte strings and bytearrays---but it still does not support + non-contiguous buffers. + """ + return self._backend.memmove(dest, src, n) + + def callback(self, cdecl, python_callable=None, error=None, onerror=None): + """Return a callback object or a decorator making such a + callback object. 'cdecl' must name a C function pointer type. + The callback invokes the specified 'python_callable' (which may + be provided either directly or via a decorator). Important: the + callback object must be manually kept alive for as long as the + callback may be invoked from the C level. + """ + def callback_decorator_wrap(python_callable): + if not callable(python_callable): + raise TypeError("the 'python_callable' argument " + "is not callable") + return self._backend.callback(cdecl, python_callable, + error, onerror) + if isinstance(cdecl, basestring): + cdecl = self._typeof(cdecl, consider_function_as_funcptr=True) + if python_callable is None: + return callback_decorator_wrap # decorator mode + else: + return callback_decorator_wrap(python_callable) # direct mode + + def getctype(self, cdecl, replace_with=''): + """Return a string giving the C type 'cdecl', which may be itself + a string or a object. If 'replace_with' is given, it gives + extra text to append (or insert for more complicated C types), like + a variable name, or '*' to get actually the C type 'pointer-to-cdecl'. + """ + if isinstance(cdecl, basestring): + cdecl = self._typeof(cdecl) + replace_with = replace_with.strip() + if (replace_with.startswith('*') + and '&[' in self._backend.getcname(cdecl, '&')): + replace_with = '(%s)' % replace_with + elif replace_with and not replace_with[0] in '[(': + replace_with = ' ' + replace_with + return self._backend.getcname(cdecl, replace_with) + + def gc(self, cdata, destructor, size=0): + """Return a new cdata object that points to the same + data. Later, when this new cdata object is garbage-collected, + 'destructor(old_cdata_object)' will be called. + + The optional 'size' gives an estimate of the size, used to + trigger the garbage collection more eagerly. So far only used + on PyPy. It tells the GC that the returned object keeps alive + roughly 'size' bytes of external memory. + """ + return self._backend.gcp(cdata, destructor, size) + + def _get_cached_btype(self, type): + assert self._lock.acquire(False) is False + # call me with the lock! + try: + BType = self._cached_btypes[type] + except KeyError: + finishlist = [] + BType = type.get_cached_btype(self, finishlist) + for type in finishlist: + type.finish_backend_type(self, finishlist) + return BType + + def verify(self, source='', tmpdir=None, **kwargs): + """Verify that the current ffi signatures compile on this + machine, and return a dynamic library object. The dynamic + library can be used to call functions and access global + variables declared in this 'ffi'. The library is compiled + by the C compiler: it gives you C-level API compatibility + (including calling macros). This is unlike 'ffi.dlopen()', + which requires binary compatibility in the signatures. + """ + from .verifier import Verifier, _caller_dir_pycache + # + # If set_unicode(True) was called, insert the UNICODE and + # _UNICODE macro declarations + if self._windows_unicode: + self._apply_windows_unicode(kwargs) + # + # Set the tmpdir here, and not in Verifier.__init__: it picks + # up the caller's directory, which we want to be the caller of + # ffi.verify(), as opposed to the caller of Veritier(). + tmpdir = tmpdir or _caller_dir_pycache() + # + # Make a Verifier() and use it to load the library. + self.verifier = Verifier(self, source, tmpdir, **kwargs) + lib = self.verifier.load_library() + # + # Save the loaded library for keep-alive purposes, even + # if the caller doesn't keep it alive itself (it should). + self._libraries.append(lib) + return lib + + def _get_errno(self): + return self._backend.get_errno() + def _set_errno(self, errno): + self._backend.set_errno(errno) + errno = property(_get_errno, _set_errno, None, + "the value of 'errno' from/to the C calls") + + def getwinerror(self, code=-1): + return self._backend.getwinerror(code) + + def _pointer_to(self, ctype): + with self._lock: + return model.pointer_cache(self, ctype) + + def addressof(self, cdata, *fields_or_indexes): + """Return the address of a . + If 'fields_or_indexes' are given, returns the address of that + field or array item in the structure or array, recursively in + case of nested structures. + """ + try: + ctype = self._backend.typeof(cdata) + except TypeError: + if '__addressof__' in type(cdata).__dict__: + return type(cdata).__addressof__(cdata, *fields_or_indexes) + raise + if fields_or_indexes: + ctype, offset = self._typeoffsetof(ctype, *fields_or_indexes) + else: + if ctype.kind == "pointer": + raise TypeError("addressof(pointer)") + offset = 0 + ctypeptr = self._pointer_to(ctype) + return self._backend.rawaddressof(ctypeptr, cdata, offset) + + def _typeoffsetof(self, ctype, field_or_index, *fields_or_indexes): + ctype, offset = self._backend.typeoffsetof(ctype, field_or_index) + for field1 in fields_or_indexes: + ctype, offset1 = self._backend.typeoffsetof(ctype, field1, 1) + offset += offset1 + return ctype, offset + + def include(self, ffi_to_include): + """Includes the typedefs, structs, unions and enums defined + in another FFI instance. Usage is similar to a #include in C, + where a part of the program might include types defined in + another part for its own usage. Note that the include() + method has no effect on functions, constants and global + variables, which must anyway be accessed directly from the + lib object returned by the original FFI instance. + """ + if not isinstance(ffi_to_include, FFI): + raise TypeError("ffi.include() expects an argument that is also of" + " type cffi.FFI, not %r" % ( + type(ffi_to_include).__name__,)) + if ffi_to_include is self: + raise ValueError("self.include(self)") + with ffi_to_include._lock: + with self._lock: + self._parser.include(ffi_to_include._parser) + self._cdefsources.append('[') + self._cdefsources.extend(ffi_to_include._cdefsources) + self._cdefsources.append(']') + self._included_ffis.append(ffi_to_include) + + def new_handle(self, x): + return self._backend.newp_handle(self.BVoidP, x) + + def from_handle(self, x): + return self._backend.from_handle(x) + + def release(self, x): + self._backend.release(x) + + def set_unicode(self, enabled_flag): + """Windows: if 'enabled_flag' is True, enable the UNICODE and + _UNICODE defines in C, and declare the types like TCHAR and LPTCSTR + to be (pointers to) wchar_t. If 'enabled_flag' is False, + declare these types to be (pointers to) plain 8-bit characters. + This is mostly for backward compatibility; you usually want True. + """ + if self._windows_unicode is not None: + raise ValueError("set_unicode() can only be called once") + enabled_flag = bool(enabled_flag) + if enabled_flag: + self.cdef("typedef wchar_t TBYTE;" + "typedef wchar_t TCHAR;" + "typedef const wchar_t *LPCTSTR;" + "typedef const wchar_t *PCTSTR;" + "typedef wchar_t *LPTSTR;" + "typedef wchar_t *PTSTR;" + "typedef TBYTE *PTBYTE;" + "typedef TCHAR *PTCHAR;") + else: + self.cdef("typedef char TBYTE;" + "typedef char TCHAR;" + "typedef const char *LPCTSTR;" + "typedef const char *PCTSTR;" + "typedef char *LPTSTR;" + "typedef char *PTSTR;" + "typedef TBYTE *PTBYTE;" + "typedef TCHAR *PTCHAR;") + self._windows_unicode = enabled_flag + + def _apply_windows_unicode(self, kwds): + defmacros = kwds.get('define_macros', ()) + if not isinstance(defmacros, (list, tuple)): + raise TypeError("'define_macros' must be a list or tuple") + defmacros = list(defmacros) + [('UNICODE', '1'), + ('_UNICODE', '1')] + kwds['define_macros'] = defmacros + + def _apply_embedding_fix(self, kwds): + # must include an argument like "-lpython2.7" for the compiler + def ensure(key, value): + lst = kwds.setdefault(key, []) + if value not in lst: + lst.append(value) + # + if '__pypy__' in sys.builtin_module_names: + import os + if sys.platform == "win32": + # we need 'libpypy-c.lib'. Current distributions of + # pypy (>= 4.1) contain it as 'libs/python27.lib'. + pythonlib = "python{0[0]}{0[1]}".format(sys.version_info) + if hasattr(sys, 'prefix'): + ensure('library_dirs', os.path.join(sys.prefix, 'libs')) + else: + # we need 'libpypy-c.{so,dylib}', which should be by + # default located in 'sys.prefix/bin' for installed + # systems. + if sys.version_info < (3,): + pythonlib = "pypy-c" + else: + pythonlib = "pypy3-c" + if hasattr(sys, 'prefix'): + ensure('library_dirs', os.path.join(sys.prefix, 'bin')) + # On uninstalled pypy's, the libpypy-c is typically found in + # .../pypy/goal/. + if hasattr(sys, 'prefix'): + ensure('library_dirs', os.path.join(sys.prefix, 'pypy', 'goal')) + else: + if sys.platform == "win32": + template = "python%d%d" + if hasattr(sys, 'gettotalrefcount'): + template += '_d' + else: + try: + import sysconfig + except ImportError: # 2.6 + from distutils import sysconfig + template = "python%d.%d" + if sysconfig.get_config_var('DEBUG_EXT'): + template += sysconfig.get_config_var('DEBUG_EXT') + pythonlib = (template % + (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)) + if hasattr(sys, 'abiflags'): + pythonlib += sys.abiflags + ensure('libraries', pythonlib) + if sys.platform == "win32": + ensure('extra_link_args', '/MANIFEST') + + def set_source(self, module_name, source, source_extension='.c', **kwds): + import os + if hasattr(self, '_assigned_source'): + raise ValueError("set_source() cannot be called several times " + "per ffi object") + if not isinstance(module_name, basestring): + raise TypeError("'module_name' must be a string") + if os.sep in module_name or (os.altsep and os.altsep in module_name): + raise ValueError("'module_name' must not contain '/': use a dotted " + "name to make a 'package.module' location") + self._assigned_source = (str(module_name), source, + source_extension, kwds) + + def set_source_pkgconfig(self, module_name, pkgconfig_libs, source, + source_extension='.c', **kwds): + from . import pkgconfig + if not isinstance(pkgconfig_libs, list): + raise TypeError("the pkgconfig_libs argument must be a list " + "of package names") + kwds2 = pkgconfig.flags_from_pkgconfig(pkgconfig_libs) + pkgconfig.merge_flags(kwds, kwds2) + self.set_source(module_name, source, source_extension, **kwds) + + def distutils_extension(self, tmpdir='build', verbose=True): + from distutils.dir_util import mkpath + from .recompiler import recompile + # + if not hasattr(self, '_assigned_source'): + if hasattr(self, 'verifier'): # fallback, 'tmpdir' ignored + return self.verifier.get_extension() + raise ValueError("set_source() must be called before" + " distutils_extension()") + module_name, source, source_extension, kwds = self._assigned_source + if source is None: + raise TypeError("distutils_extension() is only for C extension " + "modules, not for dlopen()-style pure Python " + "modules") + mkpath(tmpdir) + ext, updated = recompile(self, module_name, + source, tmpdir=tmpdir, extradir=tmpdir, + source_extension=source_extension, + call_c_compiler=False, **kwds) + if verbose: + if updated: + sys.stderr.write("regenerated: %r\n" % (ext.sources[0],)) + else: + sys.stderr.write("not modified: %r\n" % (ext.sources[0],)) + return ext + + def emit_c_code(self, filename): + from .recompiler import recompile + # + if not hasattr(self, '_assigned_source'): + raise ValueError("set_source() must be called before emit_c_code()") + module_name, source, source_extension, kwds = self._assigned_source + if source is None: + raise TypeError("emit_c_code() is only for C extension modules, " + "not for dlopen()-style pure Python modules") + recompile(self, module_name, source, + c_file=filename, call_c_compiler=False, **kwds) + + def emit_python_code(self, filename): + from .recompiler import recompile + # + if not hasattr(self, '_assigned_source'): + raise ValueError("set_source() must be called before emit_c_code()") + module_name, source, source_extension, kwds = self._assigned_source + if source is not None: + raise TypeError("emit_python_code() is only for dlopen()-style " + "pure Python modules, not for C extension modules") + recompile(self, module_name, source, + c_file=filename, call_c_compiler=False, **kwds) + + def compile(self, tmpdir='.', verbose=0, target=None, debug=None): + """The 'target' argument gives the final file name of the + compiled DLL. Use '*' to force distutils' choice, suitable for + regular CPython C API modules. Use a file name ending in '.*' + to ask for the system's default extension for dynamic libraries + (.so/.dll/.dylib). + + The default is '*' when building a non-embedded C API extension, + and (module_name + '.*') when building an embedded library. + """ + from .recompiler import recompile + # + if not hasattr(self, '_assigned_source'): + raise ValueError("set_source() must be called before compile()") + module_name, source, source_extension, kwds = self._assigned_source + return recompile(self, module_name, source, tmpdir=tmpdir, + target=target, source_extension=source_extension, + compiler_verbose=verbose, debug=debug, **kwds) + + def init_once(self, func, tag): + # Read _init_once_cache[tag], which is either (False, lock) if + # we're calling the function now in some thread, or (True, result). + # Don't call setdefault() in most cases, to avoid allocating and + # immediately freeing a lock; but still use setdefaut() to avoid + # races. + try: + x = self._init_once_cache[tag] + except KeyError: + x = self._init_once_cache.setdefault(tag, (False, allocate_lock())) + # Common case: we got (True, result), so we return the result. + if x[0]: + return x[1] + # Else, it's a lock. Acquire it to serialize the following tests. + with x[1]: + # Read again from _init_once_cache the current status. + x = self._init_once_cache[tag] + if x[0]: + return x[1] + # Call the function and store the result back. + result = func() + self._init_once_cache[tag] = (True, result) + return result + + def embedding_init_code(self, pysource): + if self._embedding: + raise ValueError("embedding_init_code() can only be called once") + # fix 'pysource' before it gets dumped into the C file: + # - remove empty lines at the beginning, so it starts at "line 1" + # - dedent, if all non-empty lines are indented + # - check for SyntaxErrors + import re + match = re.match(r'\s*\n', pysource) + if match: + pysource = pysource[match.end():] + lines = pysource.splitlines() or [''] + prefix = re.match(r'\s*', lines[0]).group() + for i in range(1, len(lines)): + line = lines[i] + if line.rstrip(): + while not line.startswith(prefix): + prefix = prefix[:-1] + i = len(prefix) + lines = [line[i:]+'\n' for line in lines] + pysource = ''.join(lines) + # + compile(pysource, "cffi_init", "exec") + # + self._embedding = pysource + + def def_extern(self, *args, **kwds): + raise ValueError("ffi.def_extern() is only available on API-mode FFI " + "objects") + + def list_types(self): + """Returns the user type names known to this FFI instance. + This returns a tuple containing three lists of names: + (typedef_names, names_of_structs, names_of_unions) + """ + typedefs = [] + structs = [] + unions = [] + for key in self._parser._declarations: + if key.startswith('typedef '): + typedefs.append(key[8:]) + elif key.startswith('struct '): + structs.append(key[7:]) + elif key.startswith('union '): + unions.append(key[6:]) + typedefs.sort() + structs.sort() + unions.sort() + return (typedefs, structs, unions) + + +def _load_backend_lib(backend, name, flags): + import os + if name is None: + if sys.platform != "win32": + return backend.load_library(None, flags) + name = "c" # Windows: load_library(None) fails, but this works + # on Python 2 (backward compatibility hack only) + first_error = None + if '.' in name or '/' in name or os.sep in name: + try: + return backend.load_library(name, flags) + except OSError as e: + first_error = e + import ctypes.util + path = ctypes.util.find_library(name) + if path is None: + if name == "c" and sys.platform == "win32" and sys.version_info >= (3,): + raise OSError("dlopen(None) cannot work on Windows for Python 3 " + "(see http://bugs.python.org/issue23606)") + msg = ("ctypes.util.find_library() did not manage " + "to locate a library called %r" % (name,)) + if first_error is not None: + msg = "%s. Additionally, %s" % (first_error, msg) + raise OSError(msg) + return backend.load_library(path, flags) + +def _make_ffi_library(ffi, libname, flags): + backend = ffi._backend + backendlib = _load_backend_lib(backend, libname, flags) + # + def accessor_function(name): + key = 'function ' + name + tp, _ = ffi._parser._declarations[key] + BType = ffi._get_cached_btype(tp) + value = backendlib.load_function(BType, name) + library.__dict__[name] = value + # + def accessor_variable(name): + key = 'variable ' + name + tp, _ = ffi._parser._declarations[key] + BType = ffi._get_cached_btype(tp) + read_variable = backendlib.read_variable + write_variable = backendlib.write_variable + setattr(FFILibrary, name, property( + lambda self: read_variable(BType, name), + lambda self, value: write_variable(BType, name, value))) + # + def addressof_var(name): + try: + return addr_variables[name] + except KeyError: + with ffi._lock: + if name not in addr_variables: + key = 'variable ' + name + tp, _ = ffi._parser._declarations[key] + BType = ffi._get_cached_btype(tp) + if BType.kind != 'array': + BType = model.pointer_cache(ffi, BType) + p = backendlib.load_function(BType, name) + addr_variables[name] = p + return addr_variables[name] + # + def accessor_constant(name): + raise NotImplementedError("non-integer constant '%s' cannot be " + "accessed from a dlopen() library" % (name,)) + # + def accessor_int_constant(name): + library.__dict__[name] = ffi._parser._int_constants[name] + # + accessors = {} + accessors_version = [False] + addr_variables = {} + # + def update_accessors(): + if accessors_version[0] is ffi._cdef_version: + return + # + for key, (tp, _) in ffi._parser._declarations.items(): + if not isinstance(tp, model.EnumType): + tag, name = key.split(' ', 1) + if tag == 'function': + accessors[name] = accessor_function + elif tag == 'variable': + accessors[name] = accessor_variable + elif tag == 'constant': + accessors[name] = accessor_constant + else: + for i, enumname in enumerate(tp.enumerators): + def accessor_enum(name, tp=tp, i=i): + tp.check_not_partial() + library.__dict__[name] = tp.enumvalues[i] + accessors[enumname] = accessor_enum + for name in ffi._parser._int_constants: + accessors.setdefault(name, accessor_int_constant) + accessors_version[0] = ffi._cdef_version + # + def make_accessor(name): + with ffi._lock: + if name in library.__dict__ or name in FFILibrary.__dict__: + return # added by another thread while waiting for the lock + if name not in accessors: + update_accessors() + if name not in accessors: + raise AttributeError(name) + accessors[name](name) + # + class FFILibrary(object): + def __getattr__(self, name): + make_accessor(name) + return getattr(self, name) + def __setattr__(self, name, value): + try: + property = getattr(self.__class__, name) + except AttributeError: + make_accessor(name) + setattr(self, name, value) + else: + property.__set__(self, value) + def __dir__(self): + with ffi._lock: + update_accessors() + return accessors.keys() + def __addressof__(self, name): + if name in library.__dict__: + return library.__dict__[name] + if name in FFILibrary.__dict__: + return addressof_var(name) + make_accessor(name) + if name in library.__dict__: + return library.__dict__[name] + if name in FFILibrary.__dict__: + return addressof_var(name) + raise AttributeError("cffi library has no function or " + "global variable named '%s'" % (name,)) + def __cffi_close__(self): + backendlib.close_lib() + self.__dict__.clear() + # + if libname is not None: + try: + if not isinstance(libname, str): # unicode, on Python 2 + libname = libname.encode('utf-8') + FFILibrary.__name__ = 'FFILibrary_%s' % libname + except UnicodeError: + pass + library = FFILibrary() + return library, library.__dict__ + +def _builtin_function_type(func): + # a hack to make at least ffi.typeof(builtin_function) work, + # if the builtin function was obtained by 'vengine_cpy'. + import sys + try: + module = sys.modules[func.__module__] + ffi = module._cffi_original_ffi + types_of_builtin_funcs = module._cffi_types_of_builtin_funcs + tp = types_of_builtin_funcs[func] + except (KeyError, AttributeError, TypeError): + return None + else: + with ffi._lock: + return ffi._get_cached_btype(tp) diff --git a/server/www/packages/packages-linux/x64/cffi/backend_ctypes.py b/server/www/packages/packages-linux/x64/cffi/backend_ctypes.py new file mode 100644 index 0000000..e7956a7 --- /dev/null +++ b/server/www/packages/packages-linux/x64/cffi/backend_ctypes.py @@ -0,0 +1,1121 @@ +import ctypes, ctypes.util, operator, sys +from . import model + +if sys.version_info < (3,): + bytechr = chr +else: + unicode = str + long = int + xrange = range + bytechr = lambda num: bytes([num]) + +class CTypesType(type): + pass + +class CTypesData(object): + __metaclass__ = CTypesType + __slots__ = ['__weakref__'] + __name__ = '' + + def __init__(self, *args): + raise TypeError("cannot instantiate %r" % (self.__class__,)) + + @classmethod + def _newp(cls, init): + raise TypeError("expected a pointer or array ctype, got '%s'" + % (cls._get_c_name(),)) + + @staticmethod + def _to_ctypes(value): + raise TypeError + + @classmethod + def _arg_to_ctypes(cls, *value): + try: + ctype = cls._ctype + except AttributeError: + raise TypeError("cannot create an instance of %r" % (cls,)) + if value: + res = cls._to_ctypes(*value) + if not isinstance(res, ctype): + res = cls._ctype(res) + else: + res = cls._ctype() + return res + + @classmethod + def _create_ctype_obj(cls, init): + if init is None: + return cls._arg_to_ctypes() + else: + return cls._arg_to_ctypes(init) + + @staticmethod + def _from_ctypes(ctypes_value): + raise TypeError + + @classmethod + def _get_c_name(cls, replace_with=''): + return cls._reftypename.replace(' &', replace_with) + + @classmethod + def _fix_class(cls): + cls.__name__ = 'CData<%s>' % (cls._get_c_name(),) + cls.__qualname__ = 'CData<%s>' % (cls._get_c_name(),) + cls.__module__ = 'ffi' + + def _get_own_repr(self): + raise NotImplementedError + + def _addr_repr(self, address): + if address == 0: + return 'NULL' + else: + if address < 0: + address += 1 << (8*ctypes.sizeof(ctypes.c_void_p)) + return '0x%x' % address + + def __repr__(self, c_name=None): + own = self._get_own_repr() + return '' % (c_name or self._get_c_name(), own) + + def _convert_to_address(self, BClass): + if BClass is None: + raise TypeError("cannot convert %r to an address" % ( + self._get_c_name(),)) + else: + raise TypeError("cannot convert %r to %r" % ( + self._get_c_name(), BClass._get_c_name())) + + @classmethod + def _get_size(cls): + return ctypes.sizeof(cls._ctype) + + def _get_size_of_instance(self): + return ctypes.sizeof(self._ctype) + + @classmethod + def _cast_from(cls, source): + raise TypeError("cannot cast to %r" % (cls._get_c_name(),)) + + def _cast_to_integer(self): + return self._convert_to_address(None) + + @classmethod + def _alignment(cls): + return ctypes.alignment(cls._ctype) + + def __iter__(self): + raise TypeError("cdata %r does not support iteration" % ( + self._get_c_name()),) + + def _make_cmp(name): + cmpfunc = getattr(operator, name) + def cmp(self, other): + v_is_ptr = not isinstance(self, CTypesGenericPrimitive) + w_is_ptr = (isinstance(other, CTypesData) and + not isinstance(other, CTypesGenericPrimitive)) + if v_is_ptr and w_is_ptr: + return cmpfunc(self._convert_to_address(None), + other._convert_to_address(None)) + elif v_is_ptr or w_is_ptr: + return NotImplemented + else: + if isinstance(self, CTypesGenericPrimitive): + self = self._value + if isinstance(other, CTypesGenericPrimitive): + other = other._value + return cmpfunc(self, other) + cmp.func_name = name + return cmp + + __eq__ = _make_cmp('__eq__') + __ne__ = _make_cmp('__ne__') + __lt__ = _make_cmp('__lt__') + __le__ = _make_cmp('__le__') + __gt__ = _make_cmp('__gt__') + __ge__ = _make_cmp('__ge__') + + def __hash__(self): + return hash(self._convert_to_address(None)) + + def _to_string(self, maxlen): + raise TypeError("string(): %r" % (self,)) + + +class CTypesGenericPrimitive(CTypesData): + __slots__ = [] + + def __hash__(self): + return hash(self._value) + + def _get_own_repr(self): + return repr(self._from_ctypes(self._value)) + + +class CTypesGenericArray(CTypesData): + __slots__ = [] + + @classmethod + def _newp(cls, init): + return cls(init) + + def __iter__(self): + for i in xrange(len(self)): + yield self[i] + + def _get_own_repr(self): + return self._addr_repr(ctypes.addressof(self._blob)) + + +class CTypesGenericPtr(CTypesData): + __slots__ = ['_address', '_as_ctype_ptr'] + _automatic_casts = False + kind = "pointer" + + @classmethod + def _newp(cls, init): + return cls(init) + + @classmethod + def _cast_from(cls, source): + if source is None: + address = 0 + elif isinstance(source, CTypesData): + address = source._cast_to_integer() + elif isinstance(source, (int, long)): + address = source + else: + raise TypeError("bad type for cast to %r: %r" % + (cls, type(source).__name__)) + return cls._new_pointer_at(address) + + @classmethod + def _new_pointer_at(cls, address): + self = cls.__new__(cls) + self._address = address + self._as_ctype_ptr = ctypes.cast(address, cls._ctype) + return self + + def _get_own_repr(self): + try: + return self._addr_repr(self._address) + except AttributeError: + return '???' + + def _cast_to_integer(self): + return self._address + + def __nonzero__(self): + return bool(self._address) + __bool__ = __nonzero__ + + @classmethod + def _to_ctypes(cls, value): + if not isinstance(value, CTypesData): + raise TypeError("unexpected %s object" % type(value).__name__) + address = value._convert_to_address(cls) + return ctypes.cast(address, cls._ctype) + + @classmethod + def _from_ctypes(cls, ctypes_ptr): + address = ctypes.cast(ctypes_ptr, ctypes.c_void_p).value or 0 + return cls._new_pointer_at(address) + + @classmethod + def _initialize(cls, ctypes_ptr, value): + if value: + ctypes_ptr.contents = cls._to_ctypes(value).contents + + def _convert_to_address(self, BClass): + if (BClass in (self.__class__, None) or BClass._automatic_casts + or self._automatic_casts): + return self._address + else: + return CTypesData._convert_to_address(self, BClass) + + +class CTypesBaseStructOrUnion(CTypesData): + __slots__ = ['_blob'] + + @classmethod + def _create_ctype_obj(cls, init): + # may be overridden + raise TypeError("cannot instantiate opaque type %s" % (cls,)) + + def _get_own_repr(self): + return self._addr_repr(ctypes.addressof(self._blob)) + + @classmethod + def _offsetof(cls, fieldname): + return getattr(cls._ctype, fieldname).offset + + def _convert_to_address(self, BClass): + if getattr(BClass, '_BItem', None) is self.__class__: + return ctypes.addressof(self._blob) + else: + return CTypesData._convert_to_address(self, BClass) + + @classmethod + def _from_ctypes(cls, ctypes_struct_or_union): + self = cls.__new__(cls) + self._blob = ctypes_struct_or_union + return self + + @classmethod + def _to_ctypes(cls, value): + return value._blob + + def __repr__(self, c_name=None): + return CTypesData.__repr__(self, c_name or self._get_c_name(' &')) + + +class CTypesBackend(object): + + PRIMITIVE_TYPES = { + 'char': ctypes.c_char, + 'short': ctypes.c_short, + 'int': ctypes.c_int, + 'long': ctypes.c_long, + 'long long': ctypes.c_longlong, + 'signed char': ctypes.c_byte, + 'unsigned char': ctypes.c_ubyte, + 'unsigned short': ctypes.c_ushort, + 'unsigned int': ctypes.c_uint, + 'unsigned long': ctypes.c_ulong, + 'unsigned long long': ctypes.c_ulonglong, + 'float': ctypes.c_float, + 'double': ctypes.c_double, + '_Bool': ctypes.c_bool, + } + + for _name in ['unsigned long long', 'unsigned long', + 'unsigned int', 'unsigned short', 'unsigned char']: + _size = ctypes.sizeof(PRIMITIVE_TYPES[_name]) + PRIMITIVE_TYPES['uint%d_t' % (8*_size)] = PRIMITIVE_TYPES[_name] + if _size == ctypes.sizeof(ctypes.c_void_p): + PRIMITIVE_TYPES['uintptr_t'] = PRIMITIVE_TYPES[_name] + if _size == ctypes.sizeof(ctypes.c_size_t): + PRIMITIVE_TYPES['size_t'] = PRIMITIVE_TYPES[_name] + + for _name in ['long long', 'long', 'int', 'short', 'signed char']: + _size = ctypes.sizeof(PRIMITIVE_TYPES[_name]) + PRIMITIVE_TYPES['int%d_t' % (8*_size)] = PRIMITIVE_TYPES[_name] + if _size == ctypes.sizeof(ctypes.c_void_p): + PRIMITIVE_TYPES['intptr_t'] = PRIMITIVE_TYPES[_name] + PRIMITIVE_TYPES['ptrdiff_t'] = PRIMITIVE_TYPES[_name] + if _size == ctypes.sizeof(ctypes.c_size_t): + PRIMITIVE_TYPES['ssize_t'] = PRIMITIVE_TYPES[_name] + + + def __init__(self): + self.RTLD_LAZY = 0 # not supported anyway by ctypes + self.RTLD_NOW = 0 + self.RTLD_GLOBAL = ctypes.RTLD_GLOBAL + self.RTLD_LOCAL = ctypes.RTLD_LOCAL + + def set_ffi(self, ffi): + self.ffi = ffi + + def _get_types(self): + return CTypesData, CTypesType + + def load_library(self, path, flags=0): + cdll = ctypes.CDLL(path, flags) + return CTypesLibrary(self, cdll) + + def new_void_type(self): + class CTypesVoid(CTypesData): + __slots__ = [] + _reftypename = 'void &' + @staticmethod + def _from_ctypes(novalue): + return None + @staticmethod + def _to_ctypes(novalue): + if novalue is not None: + raise TypeError("None expected, got %s object" % + (type(novalue).__name__,)) + return None + CTypesVoid._fix_class() + return CTypesVoid + + def new_primitive_type(self, name): + if name == 'wchar_t': + raise NotImplementedError(name) + ctype = self.PRIMITIVE_TYPES[name] + if name == 'char': + kind = 'char' + elif name in ('float', 'double'): + kind = 'float' + else: + if name in ('signed char', 'unsigned char'): + kind = 'byte' + elif name == '_Bool': + kind = 'bool' + else: + kind = 'int' + is_signed = (ctype(-1).value == -1) + # + def _cast_source_to_int(source): + if isinstance(source, (int, long, float)): + source = int(source) + elif isinstance(source, CTypesData): + source = source._cast_to_integer() + elif isinstance(source, bytes): + source = ord(source) + elif source is None: + source = 0 + else: + raise TypeError("bad type for cast to %r: %r" % + (CTypesPrimitive, type(source).__name__)) + return source + # + kind1 = kind + class CTypesPrimitive(CTypesGenericPrimitive): + __slots__ = ['_value'] + _ctype = ctype + _reftypename = '%s &' % name + kind = kind1 + + def __init__(self, value): + self._value = value + + @staticmethod + def _create_ctype_obj(init): + if init is None: + return ctype() + return ctype(CTypesPrimitive._to_ctypes(init)) + + if kind == 'int' or kind == 'byte': + @classmethod + def _cast_from(cls, source): + source = _cast_source_to_int(source) + source = ctype(source).value # cast within range + return cls(source) + def __int__(self): + return self._value + + if kind == 'bool': + @classmethod + def _cast_from(cls, source): + if not isinstance(source, (int, long, float)): + source = _cast_source_to_int(source) + return cls(bool(source)) + def __int__(self): + return int(self._value) + + if kind == 'char': + @classmethod + def _cast_from(cls, source): + source = _cast_source_to_int(source) + source = bytechr(source & 0xFF) + return cls(source) + def __int__(self): + return ord(self._value) + + if kind == 'float': + @classmethod + def _cast_from(cls, source): + if isinstance(source, float): + pass + elif isinstance(source, CTypesGenericPrimitive): + if hasattr(source, '__float__'): + source = float(source) + else: + source = int(source) + else: + source = _cast_source_to_int(source) + source = ctype(source).value # fix precision + return cls(source) + def __int__(self): + return int(self._value) + def __float__(self): + return self._value + + _cast_to_integer = __int__ + + if kind == 'int' or kind == 'byte' or kind == 'bool': + @staticmethod + def _to_ctypes(x): + if not isinstance(x, (int, long)): + if isinstance(x, CTypesData): + x = int(x) + else: + raise TypeError("integer expected, got %s" % + type(x).__name__) + if ctype(x).value != x: + if not is_signed and x < 0: + raise OverflowError("%s: negative integer" % name) + else: + raise OverflowError("%s: integer out of bounds" + % name) + return x + + if kind == 'char': + @staticmethod + def _to_ctypes(x): + if isinstance(x, bytes) and len(x) == 1: + return x + if isinstance(x, CTypesPrimitive): # > + return x._value + raise TypeError("character expected, got %s" % + type(x).__name__) + def __nonzero__(self): + return ord(self._value) != 0 + else: + def __nonzero__(self): + return self._value != 0 + __bool__ = __nonzero__ + + if kind == 'float': + @staticmethod + def _to_ctypes(x): + if not isinstance(x, (int, long, float, CTypesData)): + raise TypeError("float expected, got %s" % + type(x).__name__) + return ctype(x).value + + @staticmethod + def _from_ctypes(value): + return getattr(value, 'value', value) + + @staticmethod + def _initialize(blob, init): + blob.value = CTypesPrimitive._to_ctypes(init) + + if kind == 'char': + def _to_string(self, maxlen): + return self._value + if kind == 'byte': + def _to_string(self, maxlen): + return chr(self._value & 0xff) + # + CTypesPrimitive._fix_class() + return CTypesPrimitive + + def new_pointer_type(self, BItem): + getbtype = self.ffi._get_cached_btype + if BItem is getbtype(model.PrimitiveType('char')): + kind = 'charp' + elif BItem in (getbtype(model.PrimitiveType('signed char')), + getbtype(model.PrimitiveType('unsigned char'))): + kind = 'bytep' + elif BItem is getbtype(model.void_type): + kind = 'voidp' + else: + kind = 'generic' + # + class CTypesPtr(CTypesGenericPtr): + __slots__ = ['_own'] + if kind == 'charp': + __slots__ += ['__as_strbuf'] + _BItem = BItem + if hasattr(BItem, '_ctype'): + _ctype = ctypes.POINTER(BItem._ctype) + _bitem_size = ctypes.sizeof(BItem._ctype) + else: + _ctype = ctypes.c_void_p + if issubclass(BItem, CTypesGenericArray): + _reftypename = BItem._get_c_name('(* &)') + else: + _reftypename = BItem._get_c_name(' * &') + + def __init__(self, init): + ctypeobj = BItem._create_ctype_obj(init) + if kind == 'charp': + self.__as_strbuf = ctypes.create_string_buffer( + ctypeobj.value + b'\x00') + self._as_ctype_ptr = ctypes.cast( + self.__as_strbuf, self._ctype) + else: + self._as_ctype_ptr = ctypes.pointer(ctypeobj) + self._address = ctypes.cast(self._as_ctype_ptr, + ctypes.c_void_p).value + self._own = True + + def __add__(self, other): + if isinstance(other, (int, long)): + return self._new_pointer_at(self._address + + other * self._bitem_size) + else: + return NotImplemented + + def __sub__(self, other): + if isinstance(other, (int, long)): + return self._new_pointer_at(self._address - + other * self._bitem_size) + elif type(self) is type(other): + return (self._address - other._address) // self._bitem_size + else: + return NotImplemented + + def __getitem__(self, index): + if getattr(self, '_own', False) and index != 0: + raise IndexError + return BItem._from_ctypes(self._as_ctype_ptr[index]) + + def __setitem__(self, index, value): + self._as_ctype_ptr[index] = BItem._to_ctypes(value) + + if kind == 'charp' or kind == 'voidp': + @classmethod + def _arg_to_ctypes(cls, *value): + if value and isinstance(value[0], bytes): + return ctypes.c_char_p(value[0]) + else: + return super(CTypesPtr, cls)._arg_to_ctypes(*value) + + if kind == 'charp' or kind == 'bytep': + def _to_string(self, maxlen): + if maxlen < 0: + maxlen = sys.maxsize + p = ctypes.cast(self._as_ctype_ptr, + ctypes.POINTER(ctypes.c_char)) + n = 0 + while n < maxlen and p[n] != b'\x00': + n += 1 + return b''.join([p[i] for i in range(n)]) + + def _get_own_repr(self): + if getattr(self, '_own', False): + return 'owning %d bytes' % ( + ctypes.sizeof(self._as_ctype_ptr.contents),) + return super(CTypesPtr, self)._get_own_repr() + # + if (BItem is self.ffi._get_cached_btype(model.void_type) or + BItem is self.ffi._get_cached_btype(model.PrimitiveType('char'))): + CTypesPtr._automatic_casts = True + # + CTypesPtr._fix_class() + return CTypesPtr + + def new_array_type(self, CTypesPtr, length): + if length is None: + brackets = ' &[]' + else: + brackets = ' &[%d]' % length + BItem = CTypesPtr._BItem + getbtype = self.ffi._get_cached_btype + if BItem is getbtype(model.PrimitiveType('char')): + kind = 'char' + elif BItem in (getbtype(model.PrimitiveType('signed char')), + getbtype(model.PrimitiveType('unsigned char'))): + kind = 'byte' + else: + kind = 'generic' + # + class CTypesArray(CTypesGenericArray): + __slots__ = ['_blob', '_own'] + if length is not None: + _ctype = BItem._ctype * length + else: + __slots__.append('_ctype') + _reftypename = BItem._get_c_name(brackets) + _declared_length = length + _CTPtr = CTypesPtr + + def __init__(self, init): + if length is None: + if isinstance(init, (int, long)): + len1 = init + init = None + elif kind == 'char' and isinstance(init, bytes): + len1 = len(init) + 1 # extra null + else: + init = tuple(init) + len1 = len(init) + self._ctype = BItem._ctype * len1 + self._blob = self._ctype() + self._own = True + if init is not None: + self._initialize(self._blob, init) + + @staticmethod + def _initialize(blob, init): + if isinstance(init, bytes): + init = [init[i:i+1] for i in range(len(init))] + else: + if isinstance(init, CTypesGenericArray): + if (len(init) != len(blob) or + not isinstance(init, CTypesArray)): + raise TypeError("length/type mismatch: %s" % (init,)) + init = tuple(init) + if len(init) > len(blob): + raise IndexError("too many initializers") + addr = ctypes.cast(blob, ctypes.c_void_p).value + PTR = ctypes.POINTER(BItem._ctype) + itemsize = ctypes.sizeof(BItem._ctype) + for i, value in enumerate(init): + p = ctypes.cast(addr + i * itemsize, PTR) + BItem._initialize(p.contents, value) + + def __len__(self): + return len(self._blob) + + def __getitem__(self, index): + if not (0 <= index < len(self._blob)): + raise IndexError + return BItem._from_ctypes(self._blob[index]) + + def __setitem__(self, index, value): + if not (0 <= index < len(self._blob)): + raise IndexError + self._blob[index] = BItem._to_ctypes(value) + + if kind == 'char' or kind == 'byte': + def _to_string(self, maxlen): + if maxlen < 0: + maxlen = len(self._blob) + p = ctypes.cast(self._blob, + ctypes.POINTER(ctypes.c_char)) + n = 0 + while n < maxlen and p[n] != b'\x00': + n += 1 + return b''.join([p[i] for i in range(n)]) + + def _get_own_repr(self): + if getattr(self, '_own', False): + return 'owning %d bytes' % (ctypes.sizeof(self._blob),) + return super(CTypesArray, self)._get_own_repr() + + def _convert_to_address(self, BClass): + if BClass in (CTypesPtr, None) or BClass._automatic_casts: + return ctypes.addressof(self._blob) + else: + return CTypesData._convert_to_address(self, BClass) + + @staticmethod + def _from_ctypes(ctypes_array): + self = CTypesArray.__new__(CTypesArray) + self._blob = ctypes_array + return self + + @staticmethod + def _arg_to_ctypes(value): + return CTypesPtr._arg_to_ctypes(value) + + def __add__(self, other): + if isinstance(other, (int, long)): + return CTypesPtr._new_pointer_at( + ctypes.addressof(self._blob) + + other * ctypes.sizeof(BItem._ctype)) + else: + return NotImplemented + + @classmethod + def _cast_from(cls, source): + raise NotImplementedError("casting to %r" % ( + cls._get_c_name(),)) + # + CTypesArray._fix_class() + return CTypesArray + + def _new_struct_or_union(self, kind, name, base_ctypes_class): + # + class struct_or_union(base_ctypes_class): + pass + struct_or_union.__name__ = '%s_%s' % (kind, name) + kind1 = kind + # + class CTypesStructOrUnion(CTypesBaseStructOrUnion): + __slots__ = ['_blob'] + _ctype = struct_or_union + _reftypename = '%s &' % (name,) + _kind = kind = kind1 + # + CTypesStructOrUnion._fix_class() + return CTypesStructOrUnion + + def new_struct_type(self, name): + return self._new_struct_or_union('struct', name, ctypes.Structure) + + def new_union_type(self, name): + return self._new_struct_or_union('union', name, ctypes.Union) + + def complete_struct_or_union(self, CTypesStructOrUnion, fields, tp, + totalsize=-1, totalalignment=-1, sflags=0, + pack=0): + if totalsize >= 0 or totalalignment >= 0: + raise NotImplementedError("the ctypes backend of CFFI does not support " + "structures completed by verify(); please " + "compile and install the _cffi_backend module.") + struct_or_union = CTypesStructOrUnion._ctype + fnames = [fname for (fname, BField, bitsize) in fields] + btypes = [BField for (fname, BField, bitsize) in fields] + bitfields = [bitsize for (fname, BField, bitsize) in fields] + # + bfield_types = {} + cfields = [] + for (fname, BField, bitsize) in fields: + if bitsize < 0: + cfields.append((fname, BField._ctype)) + bfield_types[fname] = BField + else: + cfields.append((fname, BField._ctype, bitsize)) + bfield_types[fname] = Ellipsis + if sflags & 8: + struct_or_union._pack_ = 1 + elif pack: + struct_or_union._pack_ = pack + struct_or_union._fields_ = cfields + CTypesStructOrUnion._bfield_types = bfield_types + # + @staticmethod + def _create_ctype_obj(init): + result = struct_or_union() + if init is not None: + initialize(result, init) + return result + CTypesStructOrUnion._create_ctype_obj = _create_ctype_obj + # + def initialize(blob, init): + if is_union: + if len(init) > 1: + raise ValueError("union initializer: %d items given, but " + "only one supported (use a dict if needed)" + % (len(init),)) + if not isinstance(init, dict): + if isinstance(init, (bytes, unicode)): + raise TypeError("union initializer: got a str") + init = tuple(init) + if len(init) > len(fnames): + raise ValueError("too many values for %s initializer" % + CTypesStructOrUnion._get_c_name()) + init = dict(zip(fnames, init)) + addr = ctypes.addressof(blob) + for fname, value in init.items(): + BField, bitsize = name2fieldtype[fname] + assert bitsize < 0, \ + "not implemented: initializer with bit fields" + offset = CTypesStructOrUnion._offsetof(fname) + PTR = ctypes.POINTER(BField._ctype) + p = ctypes.cast(addr + offset, PTR) + BField._initialize(p.contents, value) + is_union = CTypesStructOrUnion._kind == 'union' + name2fieldtype = dict(zip(fnames, zip(btypes, bitfields))) + # + for fname, BField, bitsize in fields: + if fname == '': + raise NotImplementedError("nested anonymous structs/unions") + if hasattr(CTypesStructOrUnion, fname): + raise ValueError("the field name %r conflicts in " + "the ctypes backend" % fname) + if bitsize < 0: + def getter(self, fname=fname, BField=BField, + offset=CTypesStructOrUnion._offsetof(fname), + PTR=ctypes.POINTER(BField._ctype)): + addr = ctypes.addressof(self._blob) + p = ctypes.cast(addr + offset, PTR) + return BField._from_ctypes(p.contents) + def setter(self, value, fname=fname, BField=BField): + setattr(self._blob, fname, BField._to_ctypes(value)) + # + if issubclass(BField, CTypesGenericArray): + setter = None + if BField._declared_length == 0: + def getter(self, fname=fname, BFieldPtr=BField._CTPtr, + offset=CTypesStructOrUnion._offsetof(fname), + PTR=ctypes.POINTER(BField._ctype)): + addr = ctypes.addressof(self._blob) + p = ctypes.cast(addr + offset, PTR) + return BFieldPtr._from_ctypes(p) + # + else: + def getter(self, fname=fname, BField=BField): + return BField._from_ctypes(getattr(self._blob, fname)) + def setter(self, value, fname=fname, BField=BField): + # xxx obscure workaround + value = BField._to_ctypes(value) + oldvalue = getattr(self._blob, fname) + setattr(self._blob, fname, value) + if value != getattr(self._blob, fname): + setattr(self._blob, fname, oldvalue) + raise OverflowError("value too large for bitfield") + setattr(CTypesStructOrUnion, fname, property(getter, setter)) + # + CTypesPtr = self.ffi._get_cached_btype(model.PointerType(tp)) + for fname in fnames: + if hasattr(CTypesPtr, fname): + raise ValueError("the field name %r conflicts in " + "the ctypes backend" % fname) + def getter(self, fname=fname): + return getattr(self[0], fname) + def setter(self, value, fname=fname): + setattr(self[0], fname, value) + setattr(CTypesPtr, fname, property(getter, setter)) + + def new_function_type(self, BArgs, BResult, has_varargs): + nameargs = [BArg._get_c_name() for BArg in BArgs] + if has_varargs: + nameargs.append('...') + nameargs = ', '.join(nameargs) + # + class CTypesFunctionPtr(CTypesGenericPtr): + __slots__ = ['_own_callback', '_name'] + _ctype = ctypes.CFUNCTYPE(getattr(BResult, '_ctype', None), + *[BArg._ctype for BArg in BArgs], + use_errno=True) + _reftypename = BResult._get_c_name('(* &)(%s)' % (nameargs,)) + + def __init__(self, init, error=None): + # create a callback to the Python callable init() + import traceback + assert not has_varargs, "varargs not supported for callbacks" + if getattr(BResult, '_ctype', None) is not None: + error = BResult._from_ctypes( + BResult._create_ctype_obj(error)) + else: + error = None + def callback(*args): + args2 = [] + for arg, BArg in zip(args, BArgs): + args2.append(BArg._from_ctypes(arg)) + try: + res2 = init(*args2) + res2 = BResult._to_ctypes(res2) + except: + traceback.print_exc() + res2 = error + if issubclass(BResult, CTypesGenericPtr): + if res2: + res2 = ctypes.cast(res2, ctypes.c_void_p).value + # .value: http://bugs.python.org/issue1574593 + else: + res2 = None + #print repr(res2) + return res2 + if issubclass(BResult, CTypesGenericPtr): + # The only pointers callbacks can return are void*s: + # http://bugs.python.org/issue5710 + callback_ctype = ctypes.CFUNCTYPE( + ctypes.c_void_p, + *[BArg._ctype for BArg in BArgs], + use_errno=True) + else: + callback_ctype = CTypesFunctionPtr._ctype + self._as_ctype_ptr = callback_ctype(callback) + self._address = ctypes.cast(self._as_ctype_ptr, + ctypes.c_void_p).value + self._own_callback = init + + @staticmethod + def _initialize(ctypes_ptr, value): + if value: + raise NotImplementedError("ctypes backend: not supported: " + "initializers for function pointers") + + def __repr__(self): + c_name = getattr(self, '_name', None) + if c_name: + i = self._reftypename.index('(* &)') + if self._reftypename[i-1] not in ' )*': + c_name = ' ' + c_name + c_name = self._reftypename.replace('(* &)', c_name) + return CTypesData.__repr__(self, c_name) + + def _get_own_repr(self): + if getattr(self, '_own_callback', None) is not None: + return 'calling %r' % (self._own_callback,) + return super(CTypesFunctionPtr, self)._get_own_repr() + + def __call__(self, *args): + if has_varargs: + assert len(args) >= len(BArgs) + extraargs = args[len(BArgs):] + args = args[:len(BArgs)] + else: + assert len(args) == len(BArgs) + ctypes_args = [] + for arg, BArg in zip(args, BArgs): + ctypes_args.append(BArg._arg_to_ctypes(arg)) + if has_varargs: + for i, arg in enumerate(extraargs): + if arg is None: + ctypes_args.append(ctypes.c_void_p(0)) # NULL + continue + if not isinstance(arg, CTypesData): + raise TypeError( + "argument %d passed in the variadic part " + "needs to be a cdata object (got %s)" % + (1 + len(BArgs) + i, type(arg).__name__)) + ctypes_args.append(arg._arg_to_ctypes(arg)) + result = self._as_ctype_ptr(*ctypes_args) + return BResult._from_ctypes(result) + # + CTypesFunctionPtr._fix_class() + return CTypesFunctionPtr + + def new_enum_type(self, name, enumerators, enumvalues, CTypesInt): + assert isinstance(name, str) + reverse_mapping = dict(zip(reversed(enumvalues), + reversed(enumerators))) + # + class CTypesEnum(CTypesInt): + __slots__ = [] + _reftypename = '%s &' % name + + def _get_own_repr(self): + value = self._value + try: + return '%d: %s' % (value, reverse_mapping[value]) + except KeyError: + return str(value) + + def _to_string(self, maxlen): + value = self._value + try: + return reverse_mapping[value] + except KeyError: + return str(value) + # + CTypesEnum._fix_class() + return CTypesEnum + + def get_errno(self): + return ctypes.get_errno() + + def set_errno(self, value): + ctypes.set_errno(value) + + def string(self, b, maxlen=-1): + return b._to_string(maxlen) + + def buffer(self, bptr, size=-1): + raise NotImplementedError("buffer() with ctypes backend") + + def sizeof(self, cdata_or_BType): + if isinstance(cdata_or_BType, CTypesData): + return cdata_or_BType._get_size_of_instance() + else: + assert issubclass(cdata_or_BType, CTypesData) + return cdata_or_BType._get_size() + + def alignof(self, BType): + assert issubclass(BType, CTypesData) + return BType._alignment() + + def newp(self, BType, source): + if not issubclass(BType, CTypesData): + raise TypeError + return BType._newp(source) + + def cast(self, BType, source): + return BType._cast_from(source) + + def callback(self, BType, source, error, onerror): + assert onerror is None # XXX not implemented + return BType(source, error) + + _weakref_cache_ref = None + + def gcp(self, cdata, destructor, size=0): + if self._weakref_cache_ref is None: + import weakref + class MyRef(weakref.ref): + def __eq__(self, other): + myref = self() + return self is other or ( + myref is not None and myref is other()) + def __ne__(self, other): + return not (self == other) + def __hash__(self): + try: + return self._hash + except AttributeError: + self._hash = hash(self()) + return self._hash + self._weakref_cache_ref = {}, MyRef + weak_cache, MyRef = self._weakref_cache_ref + + if destructor is None: + try: + del weak_cache[MyRef(cdata)] + except KeyError: + raise TypeError("Can remove destructor only on a object " + "previously returned by ffi.gc()") + return None + + def remove(k): + cdata, destructor = weak_cache.pop(k, (None, None)) + if destructor is not None: + destructor(cdata) + + new_cdata = self.cast(self.typeof(cdata), cdata) + assert new_cdata is not cdata + weak_cache[MyRef(new_cdata, remove)] = (cdata, destructor) + return new_cdata + + typeof = type + + def getcname(self, BType, replace_with): + return BType._get_c_name(replace_with) + + def typeoffsetof(self, BType, fieldname, num=0): + if isinstance(fieldname, str): + if num == 0 and issubclass(BType, CTypesGenericPtr): + BType = BType._BItem + if not issubclass(BType, CTypesBaseStructOrUnion): + raise TypeError("expected a struct or union ctype") + BField = BType._bfield_types[fieldname] + if BField is Ellipsis: + raise TypeError("not supported for bitfields") + return (BField, BType._offsetof(fieldname)) + elif isinstance(fieldname, (int, long)): + if issubclass(BType, CTypesGenericArray): + BType = BType._CTPtr + if not issubclass(BType, CTypesGenericPtr): + raise TypeError("expected an array or ptr ctype") + BItem = BType._BItem + offset = BItem._get_size() * fieldname + if offset > sys.maxsize: + raise OverflowError + return (BItem, offset) + else: + raise TypeError(type(fieldname)) + + def rawaddressof(self, BTypePtr, cdata, offset=None): + if isinstance(cdata, CTypesBaseStructOrUnion): + ptr = ctypes.pointer(type(cdata)._to_ctypes(cdata)) + elif isinstance(cdata, CTypesGenericPtr): + if offset is None or not issubclass(type(cdata)._BItem, + CTypesBaseStructOrUnion): + raise TypeError("unexpected cdata type") + ptr = type(cdata)._to_ctypes(cdata) + elif isinstance(cdata, CTypesGenericArray): + ptr = type(cdata)._to_ctypes(cdata) + else: + raise TypeError("expected a ") + if offset: + ptr = ctypes.cast( + ctypes.c_void_p( + ctypes.cast(ptr, ctypes.c_void_p).value + offset), + type(ptr)) + return BTypePtr._from_ctypes(ptr) + + +class CTypesLibrary(object): + + def __init__(self, backend, cdll): + self.backend = backend + self.cdll = cdll + + def load_function(self, BType, name): + c_func = getattr(self.cdll, name) + funcobj = BType._from_ctypes(c_func) + funcobj._name = name + return funcobj + + def read_variable(self, BType, name): + try: + ctypes_obj = BType._ctype.in_dll(self.cdll, name) + except AttributeError as e: + raise NotImplementedError(e) + return BType._from_ctypes(ctypes_obj) + + def write_variable(self, BType, name, value): + new_ctypes_obj = BType._to_ctypes(value) + ctypes_obj = BType._ctype.in_dll(self.cdll, name) + ctypes.memmove(ctypes.addressof(ctypes_obj), + ctypes.addressof(new_ctypes_obj), + ctypes.sizeof(BType._ctype)) diff --git a/server/www/packages/packages-linux/x64/cffi/cffi_opcode.py b/server/www/packages/packages-linux/x64/cffi/cffi_opcode.py new file mode 100644 index 0000000..a0df98d --- /dev/null +++ b/server/www/packages/packages-linux/x64/cffi/cffi_opcode.py @@ -0,0 +1,187 @@ +from .error import VerificationError + +class CffiOp(object): + def __init__(self, op, arg): + self.op = op + self.arg = arg + + def as_c_expr(self): + if self.op is None: + assert isinstance(self.arg, str) + return '(_cffi_opcode_t)(%s)' % (self.arg,) + classname = CLASS_NAME[self.op] + return '_CFFI_OP(_CFFI_OP_%s, %s)' % (classname, self.arg) + + def as_python_bytes(self): + if self.op is None and self.arg.isdigit(): + value = int(self.arg) # non-negative: '-' not in self.arg + if value >= 2**31: + raise OverflowError("cannot emit %r: limited to 2**31-1" + % (self.arg,)) + return format_four_bytes(value) + if isinstance(self.arg, str): + raise VerificationError("cannot emit to Python: %r" % (self.arg,)) + return format_four_bytes((self.arg << 8) | self.op) + + def __str__(self): + classname = CLASS_NAME.get(self.op, self.op) + return '(%s %s)' % (classname, self.arg) + +def format_four_bytes(num): + return '\\x%02X\\x%02X\\x%02X\\x%02X' % ( + (num >> 24) & 0xFF, + (num >> 16) & 0xFF, + (num >> 8) & 0xFF, + (num ) & 0xFF) + +OP_PRIMITIVE = 1 +OP_POINTER = 3 +OP_ARRAY = 5 +OP_OPEN_ARRAY = 7 +OP_STRUCT_UNION = 9 +OP_ENUM = 11 +OP_FUNCTION = 13 +OP_FUNCTION_END = 15 +OP_NOOP = 17 +OP_BITFIELD = 19 +OP_TYPENAME = 21 +OP_CPYTHON_BLTN_V = 23 # varargs +OP_CPYTHON_BLTN_N = 25 # noargs +OP_CPYTHON_BLTN_O = 27 # O (i.e. a single arg) +OP_CONSTANT = 29 +OP_CONSTANT_INT = 31 +OP_GLOBAL_VAR = 33 +OP_DLOPEN_FUNC = 35 +OP_DLOPEN_CONST = 37 +OP_GLOBAL_VAR_F = 39 +OP_EXTERN_PYTHON = 41 + +PRIM_VOID = 0 +PRIM_BOOL = 1 +PRIM_CHAR = 2 +PRIM_SCHAR = 3 +PRIM_UCHAR = 4 +PRIM_SHORT = 5 +PRIM_USHORT = 6 +PRIM_INT = 7 +PRIM_UINT = 8 +PRIM_LONG = 9 +PRIM_ULONG = 10 +PRIM_LONGLONG = 11 +PRIM_ULONGLONG = 12 +PRIM_FLOAT = 13 +PRIM_DOUBLE = 14 +PRIM_LONGDOUBLE = 15 + +PRIM_WCHAR = 16 +PRIM_INT8 = 17 +PRIM_UINT8 = 18 +PRIM_INT16 = 19 +PRIM_UINT16 = 20 +PRIM_INT32 = 21 +PRIM_UINT32 = 22 +PRIM_INT64 = 23 +PRIM_UINT64 = 24 +PRIM_INTPTR = 25 +PRIM_UINTPTR = 26 +PRIM_PTRDIFF = 27 +PRIM_SIZE = 28 +PRIM_SSIZE = 29 +PRIM_INT_LEAST8 = 30 +PRIM_UINT_LEAST8 = 31 +PRIM_INT_LEAST16 = 32 +PRIM_UINT_LEAST16 = 33 +PRIM_INT_LEAST32 = 34 +PRIM_UINT_LEAST32 = 35 +PRIM_INT_LEAST64 = 36 +PRIM_UINT_LEAST64 = 37 +PRIM_INT_FAST8 = 38 +PRIM_UINT_FAST8 = 39 +PRIM_INT_FAST16 = 40 +PRIM_UINT_FAST16 = 41 +PRIM_INT_FAST32 = 42 +PRIM_UINT_FAST32 = 43 +PRIM_INT_FAST64 = 44 +PRIM_UINT_FAST64 = 45 +PRIM_INTMAX = 46 +PRIM_UINTMAX = 47 +PRIM_FLOATCOMPLEX = 48 +PRIM_DOUBLECOMPLEX = 49 +PRIM_CHAR16 = 50 +PRIM_CHAR32 = 51 + +_NUM_PRIM = 52 +_UNKNOWN_PRIM = -1 +_UNKNOWN_FLOAT_PRIM = -2 +_UNKNOWN_LONG_DOUBLE = -3 + +_IO_FILE_STRUCT = -1 + +PRIMITIVE_TO_INDEX = { + 'char': PRIM_CHAR, + 'short': PRIM_SHORT, + 'int': PRIM_INT, + 'long': PRIM_LONG, + 'long long': PRIM_LONGLONG, + 'signed char': PRIM_SCHAR, + 'unsigned char': PRIM_UCHAR, + 'unsigned short': PRIM_USHORT, + 'unsigned int': PRIM_UINT, + 'unsigned long': PRIM_ULONG, + 'unsigned long long': PRIM_ULONGLONG, + 'float': PRIM_FLOAT, + 'double': PRIM_DOUBLE, + 'long double': PRIM_LONGDOUBLE, + 'float _Complex': PRIM_FLOATCOMPLEX, + 'double _Complex': PRIM_DOUBLECOMPLEX, + '_Bool': PRIM_BOOL, + 'wchar_t': PRIM_WCHAR, + 'char16_t': PRIM_CHAR16, + 'char32_t': PRIM_CHAR32, + 'int8_t': PRIM_INT8, + 'uint8_t': PRIM_UINT8, + 'int16_t': PRIM_INT16, + 'uint16_t': PRIM_UINT16, + 'int32_t': PRIM_INT32, + 'uint32_t': PRIM_UINT32, + 'int64_t': PRIM_INT64, + 'uint64_t': PRIM_UINT64, + 'intptr_t': PRIM_INTPTR, + 'uintptr_t': PRIM_UINTPTR, + 'ptrdiff_t': PRIM_PTRDIFF, + 'size_t': PRIM_SIZE, + 'ssize_t': PRIM_SSIZE, + 'int_least8_t': PRIM_INT_LEAST8, + 'uint_least8_t': PRIM_UINT_LEAST8, + 'int_least16_t': PRIM_INT_LEAST16, + 'uint_least16_t': PRIM_UINT_LEAST16, + 'int_least32_t': PRIM_INT_LEAST32, + 'uint_least32_t': PRIM_UINT_LEAST32, + 'int_least64_t': PRIM_INT_LEAST64, + 'uint_least64_t': PRIM_UINT_LEAST64, + 'int_fast8_t': PRIM_INT_FAST8, + 'uint_fast8_t': PRIM_UINT_FAST8, + 'int_fast16_t': PRIM_INT_FAST16, + 'uint_fast16_t': PRIM_UINT_FAST16, + 'int_fast32_t': PRIM_INT_FAST32, + 'uint_fast32_t': PRIM_UINT_FAST32, + 'int_fast64_t': PRIM_INT_FAST64, + 'uint_fast64_t': PRIM_UINT_FAST64, + 'intmax_t': PRIM_INTMAX, + 'uintmax_t': PRIM_UINTMAX, + } + +F_UNION = 0x01 +F_CHECK_FIELDS = 0x02 +F_PACKED = 0x04 +F_EXTERNAL = 0x08 +F_OPAQUE = 0x10 + +G_FLAGS = dict([('_CFFI_' + _key, globals()[_key]) + for _key in ['F_UNION', 'F_CHECK_FIELDS', 'F_PACKED', + 'F_EXTERNAL', 'F_OPAQUE']]) + +CLASS_NAME = {} +for _name, _value in list(globals().items()): + if _name.startswith('OP_') and isinstance(_value, int): + CLASS_NAME[_value] = _name[3:] diff --git a/server/www/packages/packages-linux/x64/cffi/commontypes.py b/server/www/packages/packages-linux/x64/cffi/commontypes.py new file mode 100644 index 0000000..8ec97c7 --- /dev/null +++ b/server/www/packages/packages-linux/x64/cffi/commontypes.py @@ -0,0 +1,80 @@ +import sys +from . import model +from .error import FFIError + + +COMMON_TYPES = {} + +try: + # fetch "bool" and all simple Windows types + from _cffi_backend import _get_common_types + _get_common_types(COMMON_TYPES) +except ImportError: + pass + +COMMON_TYPES['FILE'] = model.unknown_type('FILE', '_IO_FILE') +COMMON_TYPES['bool'] = '_Bool' # in case we got ImportError above + +for _type in model.PrimitiveType.ALL_PRIMITIVE_TYPES: + if _type.endswith('_t'): + COMMON_TYPES[_type] = _type +del _type + +_CACHE = {} + +def resolve_common_type(parser, commontype): + try: + return _CACHE[commontype] + except KeyError: + cdecl = COMMON_TYPES.get(commontype, commontype) + if not isinstance(cdecl, str): + result, quals = cdecl, 0 # cdecl is already a BaseType + elif cdecl in model.PrimitiveType.ALL_PRIMITIVE_TYPES: + result, quals = model.PrimitiveType(cdecl), 0 + elif cdecl == 'set-unicode-needed': + raise FFIError("The Windows type %r is only available after " + "you call ffi.set_unicode()" % (commontype,)) + else: + if commontype == cdecl: + raise FFIError( + "Unsupported type: %r. Please look at " + "http://cffi.readthedocs.io/en/latest/cdef.html#ffi-cdef-limitations " + "and file an issue if you think this type should really " + "be supported." % (commontype,)) + result, quals = parser.parse_type_and_quals(cdecl) # recursive + + assert isinstance(result, model.BaseTypeByIdentity) + _CACHE[commontype] = result, quals + return result, quals + + +# ____________________________________________________________ +# extra types for Windows (most of them are in commontypes.c) + + +def win_common_types(): + return { + "UNICODE_STRING": model.StructType( + "_UNICODE_STRING", + ["Length", + "MaximumLength", + "Buffer"], + [model.PrimitiveType("unsigned short"), + model.PrimitiveType("unsigned short"), + model.PointerType(model.PrimitiveType("wchar_t"))], + [-1, -1, -1]), + "PUNICODE_STRING": "UNICODE_STRING *", + "PCUNICODE_STRING": "const UNICODE_STRING *", + + "TBYTE": "set-unicode-needed", + "TCHAR": "set-unicode-needed", + "LPCTSTR": "set-unicode-needed", + "PCTSTR": "set-unicode-needed", + "LPTSTR": "set-unicode-needed", + "PTSTR": "set-unicode-needed", + "PTBYTE": "set-unicode-needed", + "PTCHAR": "set-unicode-needed", + } + +if sys.platform == 'win32': + COMMON_TYPES.update(win_common_types()) diff --git a/server/www/packages/packages-linux/x64/cffi/cparser.py b/server/www/packages/packages-linux/x64/cffi/cparser.py new file mode 100644 index 0000000..ea27c48 --- /dev/null +++ b/server/www/packages/packages-linux/x64/cffi/cparser.py @@ -0,0 +1,963 @@ +from . import model +from .commontypes import COMMON_TYPES, resolve_common_type +from .error import FFIError, CDefError +try: + from . import _pycparser as pycparser +except ImportError: + import pycparser +import weakref, re, sys + +try: + if sys.version_info < (3,): + import thread as _thread + else: + import _thread + lock = _thread.allocate_lock() +except ImportError: + lock = None + +def _workaround_for_static_import_finders(): + # Issue #392: packaging tools like cx_Freeze can not find these + # because pycparser uses exec dynamic import. This is an obscure + # workaround. This function is never called. + import pycparser.yacctab + import pycparser.lextab + +CDEF_SOURCE_STRING = "" +_r_comment = re.compile(r"/\*.*?\*/|//([^\n\\]|\\.)*?$", + re.DOTALL | re.MULTILINE) +_r_define = re.compile(r"^\s*#\s*define\s+([A-Za-z_][A-Za-z_0-9]*)" + r"\b((?:[^\n\\]|\\.)*?)$", + re.DOTALL | re.MULTILINE) +_r_partial_enum = re.compile(r"=\s*\.\.\.\s*[,}]|\.\.\.\s*\}") +_r_enum_dotdotdot = re.compile(r"__dotdotdot\d+__$") +_r_partial_array = re.compile(r"\[\s*\.\.\.\s*\]") +_r_words = re.compile(r"\w+|\S") +_parser_cache = None +_r_int_literal = re.compile(r"-?0?x?[0-9a-f]+[lu]*$", re.IGNORECASE) +_r_stdcall1 = re.compile(r"\b(__stdcall|WINAPI)\b") +_r_stdcall2 = re.compile(r"[(]\s*(__stdcall|WINAPI)\b") +_r_cdecl = re.compile(r"\b__cdecl\b") +_r_extern_python = re.compile(r'\bextern\s*"' + r'(Python|Python\s*\+\s*C|C\s*\+\s*Python)"\s*.') +_r_star_const_space = re.compile( # matches "* const " + r"[*]\s*((const|volatile|restrict)\b\s*)+") +_r_int_dotdotdot = re.compile(r"(\b(int|long|short|signed|unsigned|char)\s*)+" + r"\.\.\.") +_r_float_dotdotdot = re.compile(r"\b(double|float)\s*\.\.\.") + +def _get_parser(): + global _parser_cache + if _parser_cache is None: + _parser_cache = pycparser.CParser() + return _parser_cache + +def _workaround_for_old_pycparser(csource): + # Workaround for a pycparser issue (fixed between pycparser 2.10 and + # 2.14): "char*const***" gives us a wrong syntax tree, the same as + # for "char***(*const)". This means we can't tell the difference + # afterwards. But "char(*const(***))" gives us the right syntax + # tree. The issue only occurs if there are several stars in + # sequence with no parenthesis inbetween, just possibly qualifiers. + # Attempt to fix it by adding some parentheses in the source: each + # time we see "* const" or "* const *", we add an opening + # parenthesis before each star---the hard part is figuring out where + # to close them. + parts = [] + while True: + match = _r_star_const_space.search(csource) + if not match: + break + #print repr(''.join(parts)+csource), '=>', + parts.append(csource[:match.start()]) + parts.append('('); closing = ')' + parts.append(match.group()) # e.g. "* const " + endpos = match.end() + if csource.startswith('*', endpos): + parts.append('('); closing += ')' + level = 0 + i = endpos + while i < len(csource): + c = csource[i] + if c == '(': + level += 1 + elif c == ')': + if level == 0: + break + level -= 1 + elif c in ',;=': + if level == 0: + break + i += 1 + csource = csource[endpos:i] + closing + csource[i:] + #print repr(''.join(parts)+csource) + parts.append(csource) + return ''.join(parts) + +def _preprocess_extern_python(csource): + # input: `extern "Python" int foo(int);` or + # `extern "Python" { int foo(int); }` + # output: + # void __cffi_extern_python_start; + # int foo(int); + # void __cffi_extern_python_stop; + # + # input: `extern "Python+C" int foo(int);` + # output: + # void __cffi_extern_python_plus_c_start; + # int foo(int); + # void __cffi_extern_python_stop; + parts = [] + while True: + match = _r_extern_python.search(csource) + if not match: + break + endpos = match.end() - 1 + #print + #print ''.join(parts)+csource + #print '=>' + parts.append(csource[:match.start()]) + if 'C' in match.group(1): + parts.append('void __cffi_extern_python_plus_c_start; ') + else: + parts.append('void __cffi_extern_python_start; ') + if csource[endpos] == '{': + # grouping variant + closing = csource.find('}', endpos) + if closing < 0: + raise CDefError("'extern \"Python\" {': no '}' found") + if csource.find('{', endpos + 1, closing) >= 0: + raise NotImplementedError("cannot use { } inside a block " + "'extern \"Python\" { ... }'") + parts.append(csource[endpos+1:closing]) + csource = csource[closing+1:] + else: + # non-grouping variant + semicolon = csource.find(';', endpos) + if semicolon < 0: + raise CDefError("'extern \"Python\": no ';' found") + parts.append(csource[endpos:semicolon+1]) + csource = csource[semicolon+1:] + parts.append(' void __cffi_extern_python_stop;') + #print ''.join(parts)+csource + #print + parts.append(csource) + return ''.join(parts) + +def _warn_for_string_literal(csource): + if '"' not in csource: + return + for line in csource.splitlines(): + if '"' in line and not line.lstrip().startswith('#'): + import warnings + warnings.warn("String literal found in cdef() or type source. " + "String literals are ignored here, but you should " + "remove them anyway because some character sequences " + "confuse pre-parsing.") + break + +def _warn_for_non_extern_non_static_global_variable(decl): + if not decl.storage: + import warnings + warnings.warn("Global variable '%s' in cdef(): for consistency " + "with C it should have a storage class specifier " + "(usually 'extern')" % (decl.name,)) + +def _preprocess(csource): + # Remove comments. NOTE: this only work because the cdef() section + # should not contain any string literal! + csource = _r_comment.sub(' ', csource) + # Remove the "#define FOO x" lines + macros = {} + for match in _r_define.finditer(csource): + macroname, macrovalue = match.groups() + macrovalue = macrovalue.replace('\\\n', '').strip() + macros[macroname] = macrovalue + csource = _r_define.sub('', csource) + # + if pycparser.__version__ < '2.14': + csource = _workaround_for_old_pycparser(csource) + # + # BIG HACK: replace WINAPI or __stdcall with "volatile const". + # It doesn't make sense for the return type of a function to be + # "volatile volatile const", so we abuse it to detect __stdcall... + # Hack number 2 is that "int(volatile *fptr)();" is not valid C + # syntax, so we place the "volatile" before the opening parenthesis. + csource = _r_stdcall2.sub(' volatile volatile const(', csource) + csource = _r_stdcall1.sub(' volatile volatile const ', csource) + csource = _r_cdecl.sub(' ', csource) + # + # Replace `extern "Python"` with start/end markers + csource = _preprocess_extern_python(csource) + # + # Now there should not be any string literal left; warn if we get one + _warn_for_string_literal(csource) + # + # Replace "[...]" with "[__dotdotdotarray__]" + csource = _r_partial_array.sub('[__dotdotdotarray__]', csource) + # + # Replace "...}" with "__dotdotdotNUM__}". This construction should + # occur only at the end of enums; at the end of structs we have "...;}" + # and at the end of vararg functions "...);". Also replace "=...[,}]" + # with ",__dotdotdotNUM__[,}]": this occurs in the enums too, when + # giving an unknown value. + matches = list(_r_partial_enum.finditer(csource)) + for number, match in enumerate(reversed(matches)): + p = match.start() + if csource[p] == '=': + p2 = csource.find('...', p, match.end()) + assert p2 > p + csource = '%s,__dotdotdot%d__ %s' % (csource[:p], number, + csource[p2+3:]) + else: + assert csource[p:p+3] == '...' + csource = '%s __dotdotdot%d__ %s' % (csource[:p], number, + csource[p+3:]) + # Replace "int ..." or "unsigned long int..." with "__dotdotdotint__" + csource = _r_int_dotdotdot.sub(' __dotdotdotint__ ', csource) + # Replace "float ..." or "double..." with "__dotdotdotfloat__" + csource = _r_float_dotdotdot.sub(' __dotdotdotfloat__ ', csource) + # Replace all remaining "..." with the same name, "__dotdotdot__", + # which is declared with a typedef for the purpose of C parsing. + return csource.replace('...', ' __dotdotdot__ '), macros + +def _common_type_names(csource): + # Look in the source for what looks like usages of types from the + # list of common types. A "usage" is approximated here as the + # appearance of the word, minus a "definition" of the type, which + # is the last word in a "typedef" statement. Approximative only + # but should be fine for all the common types. + look_for_words = set(COMMON_TYPES) + look_for_words.add(';') + look_for_words.add(',') + look_for_words.add('(') + look_for_words.add(')') + look_for_words.add('typedef') + words_used = set() + is_typedef = False + paren = 0 + previous_word = '' + for word in _r_words.findall(csource): + if word in look_for_words: + if word == ';': + if is_typedef: + words_used.discard(previous_word) + look_for_words.discard(previous_word) + is_typedef = False + elif word == 'typedef': + is_typedef = True + paren = 0 + elif word == '(': + paren += 1 + elif word == ')': + paren -= 1 + elif word == ',': + if is_typedef and paren == 0: + words_used.discard(previous_word) + look_for_words.discard(previous_word) + else: # word in COMMON_TYPES + words_used.add(word) + previous_word = word + return words_used + + +class Parser(object): + + def __init__(self): + self._declarations = {} + self._included_declarations = set() + self._anonymous_counter = 0 + self._structnode2type = weakref.WeakKeyDictionary() + self._options = {} + self._int_constants = {} + self._recomplete = [] + self._uses_new_feature = None + + def _parse(self, csource): + csource, macros = _preprocess(csource) + # XXX: for more efficiency we would need to poke into the + # internals of CParser... the following registers the + # typedefs, because their presence or absence influences the + # parsing itself (but what they are typedef'ed to plays no role) + ctn = _common_type_names(csource) + typenames = [] + for name in sorted(self._declarations): + if name.startswith('typedef '): + name = name[8:] + typenames.append(name) + ctn.discard(name) + typenames += sorted(ctn) + # + csourcelines = [] + csourcelines.append('# 1 ""') + for typename in typenames: + csourcelines.append('typedef int %s;' % typename) + csourcelines.append('typedef int __dotdotdotint__, __dotdotdotfloat__,' + ' __dotdotdot__;') + # this forces pycparser to consider the following in the file + # called from line 1 + csourcelines.append('# 1 "%s"' % (CDEF_SOURCE_STRING,)) + csourcelines.append(csource) + fullcsource = '\n'.join(csourcelines) + if lock is not None: + lock.acquire() # pycparser is not thread-safe... + try: + ast = _get_parser().parse(fullcsource) + except pycparser.c_parser.ParseError as e: + self.convert_pycparser_error(e, csource) + finally: + if lock is not None: + lock.release() + # csource will be used to find buggy source text + return ast, macros, csource + + def _convert_pycparser_error(self, e, csource): + # xxx look for ":NUM:" at the start of str(e) + # and interpret that as a line number. This will not work if + # the user gives explicit ``# NUM "FILE"`` directives. + line = None + msg = str(e) + match = re.match(r"%s:(\d+):" % (CDEF_SOURCE_STRING,), msg) + if match: + linenum = int(match.group(1), 10) + csourcelines = csource.splitlines() + if 1 <= linenum <= len(csourcelines): + line = csourcelines[linenum-1] + return line + + def convert_pycparser_error(self, e, csource): + line = self._convert_pycparser_error(e, csource) + + msg = str(e) + if line: + msg = 'cannot parse "%s"\n%s' % (line.strip(), msg) + else: + msg = 'parse error\n%s' % (msg,) + raise CDefError(msg) + + def parse(self, csource, override=False, packed=False, pack=None, + dllexport=False): + if packed: + if packed != True: + raise ValueError("'packed' should be False or True; use " + "'pack' to give another value") + if pack: + raise ValueError("cannot give both 'pack' and 'packed'") + pack = 1 + elif pack: + if pack & (pack - 1): + raise ValueError("'pack' must be a power of two, not %r" % + (pack,)) + else: + pack = 0 + prev_options = self._options + try: + self._options = {'override': override, + 'packed': pack, + 'dllexport': dllexport} + self._internal_parse(csource) + finally: + self._options = prev_options + + def _internal_parse(self, csource): + ast, macros, csource = self._parse(csource) + # add the macros + self._process_macros(macros) + # find the first "__dotdotdot__" and use that as a separator + # between the repeated typedefs and the real csource + iterator = iter(ast.ext) + for decl in iterator: + if decl.name == '__dotdotdot__': + break + else: + assert 0 + current_decl = None + # + try: + self._inside_extern_python = '__cffi_extern_python_stop' + for decl in iterator: + current_decl = decl + if isinstance(decl, pycparser.c_ast.Decl): + self._parse_decl(decl) + elif isinstance(decl, pycparser.c_ast.Typedef): + if not decl.name: + raise CDefError("typedef does not declare any name", + decl) + quals = 0 + if (isinstance(decl.type.type, pycparser.c_ast.IdentifierType) and + decl.type.type.names[-1].startswith('__dotdotdot')): + realtype = self._get_unknown_type(decl) + elif (isinstance(decl.type, pycparser.c_ast.PtrDecl) and + isinstance(decl.type.type, pycparser.c_ast.TypeDecl) and + isinstance(decl.type.type.type, + pycparser.c_ast.IdentifierType) and + decl.type.type.type.names[-1].startswith('__dotdotdot')): + realtype = self._get_unknown_ptr_type(decl) + else: + realtype, quals = self._get_type_and_quals( + decl.type, name=decl.name, partial_length_ok=True) + self._declare('typedef ' + decl.name, realtype, quals=quals) + elif decl.__class__.__name__ == 'Pragma': + pass # skip pragma, only in pycparser 2.15 + else: + raise CDefError("unexpected <%s>: this construct is valid " + "C but not valid in cdef()" % + decl.__class__.__name__, decl) + except CDefError as e: + if len(e.args) == 1: + e.args = e.args + (current_decl,) + raise + except FFIError as e: + msg = self._convert_pycparser_error(e, csource) + if msg: + e.args = (e.args[0] + "\n *** Err: %s" % msg,) + raise + + def _add_constants(self, key, val): + if key in self._int_constants: + if self._int_constants[key] == val: + return # ignore identical double declarations + raise FFIError( + "multiple declarations of constant: %s" % (key,)) + self._int_constants[key] = val + + def _add_integer_constant(self, name, int_str): + int_str = int_str.lower().rstrip("ul") + neg = int_str.startswith('-') + if neg: + int_str = int_str[1:] + # "010" is not valid oct in py3 + if (int_str.startswith("0") and int_str != '0' + and not int_str.startswith("0x")): + int_str = "0o" + int_str[1:] + pyvalue = int(int_str, 0) + if neg: + pyvalue = -pyvalue + self._add_constants(name, pyvalue) + self._declare('macro ' + name, pyvalue) + + def _process_macros(self, macros): + for key, value in macros.items(): + value = value.strip() + if _r_int_literal.match(value): + self._add_integer_constant(key, value) + elif value == '...': + self._declare('macro ' + key, value) + else: + raise CDefError( + 'only supports one of the following syntax:\n' + ' #define %s ... (literally dot-dot-dot)\n' + ' #define %s NUMBER (with NUMBER an integer' + ' constant, decimal/hex/octal)\n' + 'got:\n' + ' #define %s %s' + % (key, key, key, value)) + + def _declare_function(self, tp, quals, decl): + tp = self._get_type_pointer(tp, quals) + if self._options.get('dllexport'): + tag = 'dllexport_python ' + elif self._inside_extern_python == '__cffi_extern_python_start': + tag = 'extern_python ' + elif self._inside_extern_python == '__cffi_extern_python_plus_c_start': + tag = 'extern_python_plus_c ' + else: + tag = 'function ' + self._declare(tag + decl.name, tp) + + def _parse_decl(self, decl): + node = decl.type + if isinstance(node, pycparser.c_ast.FuncDecl): + tp, quals = self._get_type_and_quals(node, name=decl.name) + assert isinstance(tp, model.RawFunctionType) + self._declare_function(tp, quals, decl) + else: + if isinstance(node, pycparser.c_ast.Struct): + self._get_struct_union_enum_type('struct', node) + elif isinstance(node, pycparser.c_ast.Union): + self._get_struct_union_enum_type('union', node) + elif isinstance(node, pycparser.c_ast.Enum): + self._get_struct_union_enum_type('enum', node) + elif not decl.name: + raise CDefError("construct does not declare any variable", + decl) + # + if decl.name: + tp, quals = self._get_type_and_quals(node, + partial_length_ok=True) + if tp.is_raw_function: + self._declare_function(tp, quals, decl) + elif (tp.is_integer_type() and + hasattr(decl, 'init') and + hasattr(decl.init, 'value') and + _r_int_literal.match(decl.init.value)): + self._add_integer_constant(decl.name, decl.init.value) + elif (tp.is_integer_type() and + isinstance(decl.init, pycparser.c_ast.UnaryOp) and + decl.init.op == '-' and + hasattr(decl.init.expr, 'value') and + _r_int_literal.match(decl.init.expr.value)): + self._add_integer_constant(decl.name, + '-' + decl.init.expr.value) + elif (tp is model.void_type and + decl.name.startswith('__cffi_extern_python_')): + # hack: `extern "Python"` in the C source is replaced + # with "void __cffi_extern_python_start;" and + # "void __cffi_extern_python_stop;" + self._inside_extern_python = decl.name + else: + if self._inside_extern_python !='__cffi_extern_python_stop': + raise CDefError( + "cannot declare constants or " + "variables with 'extern \"Python\"'") + if (quals & model.Q_CONST) and not tp.is_array_type: + self._declare('constant ' + decl.name, tp, quals=quals) + else: + _warn_for_non_extern_non_static_global_variable(decl) + self._declare('variable ' + decl.name, tp, quals=quals) + + def parse_type(self, cdecl): + return self.parse_type_and_quals(cdecl)[0] + + def parse_type_and_quals(self, cdecl): + ast, macros = self._parse('void __dummy(\n%s\n);' % cdecl)[:2] + assert not macros + exprnode = ast.ext[-1].type.args.params[0] + if isinstance(exprnode, pycparser.c_ast.ID): + raise CDefError("unknown identifier '%s'" % (exprnode.name,)) + return self._get_type_and_quals(exprnode.type) + + def _declare(self, name, obj, included=False, quals=0): + if name in self._declarations: + prevobj, prevquals = self._declarations[name] + if prevobj is obj and prevquals == quals: + return + if not self._options.get('override'): + raise FFIError( + "multiple declarations of %s (for interactive usage, " + "try cdef(xx, override=True))" % (name,)) + assert '__dotdotdot__' not in name.split() + self._declarations[name] = (obj, quals) + if included: + self._included_declarations.add(obj) + + def _extract_quals(self, type): + quals = 0 + if isinstance(type, (pycparser.c_ast.TypeDecl, + pycparser.c_ast.PtrDecl)): + if 'const' in type.quals: + quals |= model.Q_CONST + if 'volatile' in type.quals: + quals |= model.Q_VOLATILE + if 'restrict' in type.quals: + quals |= model.Q_RESTRICT + return quals + + def _get_type_pointer(self, type, quals, declname=None): + if isinstance(type, model.RawFunctionType): + return type.as_function_pointer() + if (isinstance(type, model.StructOrUnionOrEnum) and + type.name.startswith('$') and type.name[1:].isdigit() and + type.forcename is None and declname is not None): + return model.NamedPointerType(type, declname, quals) + return model.PointerType(type, quals) + + def _get_type_and_quals(self, typenode, name=None, partial_length_ok=False): + # first, dereference typedefs, if we have it already parsed, we're good + if (isinstance(typenode, pycparser.c_ast.TypeDecl) and + isinstance(typenode.type, pycparser.c_ast.IdentifierType) and + len(typenode.type.names) == 1 and + ('typedef ' + typenode.type.names[0]) in self._declarations): + tp, quals = self._declarations['typedef ' + typenode.type.names[0]] + quals |= self._extract_quals(typenode) + return tp, quals + # + if isinstance(typenode, pycparser.c_ast.ArrayDecl): + # array type + if typenode.dim is None: + length = None + else: + length = self._parse_constant( + typenode.dim, partial_length_ok=partial_length_ok) + tp, quals = self._get_type_and_quals(typenode.type, + partial_length_ok=partial_length_ok) + return model.ArrayType(tp, length), quals + # + if isinstance(typenode, pycparser.c_ast.PtrDecl): + # pointer type + itemtype, itemquals = self._get_type_and_quals(typenode.type) + tp = self._get_type_pointer(itemtype, itemquals, declname=name) + quals = self._extract_quals(typenode) + return tp, quals + # + if isinstance(typenode, pycparser.c_ast.TypeDecl): + quals = self._extract_quals(typenode) + type = typenode.type + if isinstance(type, pycparser.c_ast.IdentifierType): + # assume a primitive type. get it from .names, but reduce + # synonyms to a single chosen combination + names = list(type.names) + if names != ['signed', 'char']: # keep this unmodified + prefixes = {} + while names: + name = names[0] + if name in ('short', 'long', 'signed', 'unsigned'): + prefixes[name] = prefixes.get(name, 0) + 1 + del names[0] + else: + break + # ignore the 'signed' prefix below, and reorder the others + newnames = [] + for prefix in ('unsigned', 'short', 'long'): + for i in range(prefixes.get(prefix, 0)): + newnames.append(prefix) + if not names: + names = ['int'] # implicitly + if names == ['int']: # but kill it if 'short' or 'long' + if 'short' in prefixes or 'long' in prefixes: + names = [] + names = newnames + names + ident = ' '.join(names) + if ident == 'void': + return model.void_type, quals + if ident == '__dotdotdot__': + raise FFIError(':%d: bad usage of "..."' % + typenode.coord.line) + tp0, quals0 = resolve_common_type(self, ident) + return tp0, (quals | quals0) + # + if isinstance(type, pycparser.c_ast.Struct): + # 'struct foobar' + tp = self._get_struct_union_enum_type('struct', type, name) + return tp, quals + # + if isinstance(type, pycparser.c_ast.Union): + # 'union foobar' + tp = self._get_struct_union_enum_type('union', type, name) + return tp, quals + # + if isinstance(type, pycparser.c_ast.Enum): + # 'enum foobar' + tp = self._get_struct_union_enum_type('enum', type, name) + return tp, quals + # + if isinstance(typenode, pycparser.c_ast.FuncDecl): + # a function type + return self._parse_function_type(typenode, name), 0 + # + # nested anonymous structs or unions end up here + if isinstance(typenode, pycparser.c_ast.Struct): + return self._get_struct_union_enum_type('struct', typenode, name, + nested=True), 0 + if isinstance(typenode, pycparser.c_ast.Union): + return self._get_struct_union_enum_type('union', typenode, name, + nested=True), 0 + # + raise FFIError(":%d: bad or unsupported type declaration" % + typenode.coord.line) + + def _parse_function_type(self, typenode, funcname=None): + params = list(getattr(typenode.args, 'params', [])) + for i, arg in enumerate(params): + if not hasattr(arg, 'type'): + raise CDefError("%s arg %d: unknown type '%s'" + " (if you meant to use the old C syntax of giving" + " untyped arguments, it is not supported)" + % (funcname or 'in expression', i + 1, + getattr(arg, 'name', '?'))) + ellipsis = ( + len(params) > 0 and + isinstance(params[-1].type, pycparser.c_ast.TypeDecl) and + isinstance(params[-1].type.type, + pycparser.c_ast.IdentifierType) and + params[-1].type.type.names == ['__dotdotdot__']) + if ellipsis: + params.pop() + if not params: + raise CDefError( + "%s: a function with only '(...)' as argument" + " is not correct C" % (funcname or 'in expression')) + args = [self._as_func_arg(*self._get_type_and_quals(argdeclnode.type)) + for argdeclnode in params] + if not ellipsis and args == [model.void_type]: + args = [] + result, quals = self._get_type_and_quals(typenode.type) + # the 'quals' on the result type are ignored. HACK: we absure them + # to detect __stdcall functions: we textually replace "__stdcall" + # with "volatile volatile const" above. + abi = None + if hasattr(typenode.type, 'quals'): # else, probable syntax error anyway + if typenode.type.quals[-3:] == ['volatile', 'volatile', 'const']: + abi = '__stdcall' + return model.RawFunctionType(tuple(args), result, ellipsis, abi) + + def _as_func_arg(self, type, quals): + if isinstance(type, model.ArrayType): + return model.PointerType(type.item, quals) + elif isinstance(type, model.RawFunctionType): + return type.as_function_pointer() + else: + return type + + def _get_struct_union_enum_type(self, kind, type, name=None, nested=False): + # First, a level of caching on the exact 'type' node of the AST. + # This is obscure, but needed because pycparser "unrolls" declarations + # such as "typedef struct { } foo_t, *foo_p" and we end up with + # an AST that is not a tree, but a DAG, with the "type" node of the + # two branches foo_t and foo_p of the trees being the same node. + # It's a bit silly but detecting "DAG-ness" in the AST tree seems + # to be the only way to distinguish this case from two independent + # structs. See test_struct_with_two_usages. + try: + return self._structnode2type[type] + except KeyError: + pass + # + # Note that this must handle parsing "struct foo" any number of + # times and always return the same StructType object. Additionally, + # one of these times (not necessarily the first), the fields of + # the struct can be specified with "struct foo { ...fields... }". + # If no name is given, then we have to create a new anonymous struct + # with no caching; in this case, the fields are either specified + # right now or never. + # + force_name = name + name = type.name + # + # get the type or create it if needed + if name is None: + # 'force_name' is used to guess a more readable name for + # anonymous structs, for the common case "typedef struct { } foo". + if force_name is not None: + explicit_name = '$%s' % force_name + else: + self._anonymous_counter += 1 + explicit_name = '$%d' % self._anonymous_counter + tp = None + else: + explicit_name = name + key = '%s %s' % (kind, name) + tp, _ = self._declarations.get(key, (None, None)) + # + if tp is None: + if kind == 'struct': + tp = model.StructType(explicit_name, None, None, None) + elif kind == 'union': + tp = model.UnionType(explicit_name, None, None, None) + elif kind == 'enum': + if explicit_name == '__dotdotdot__': + raise CDefError("Enums cannot be declared with ...") + tp = self._build_enum_type(explicit_name, type.values) + else: + raise AssertionError("kind = %r" % (kind,)) + if name is not None: + self._declare(key, tp) + else: + if kind == 'enum' and type.values is not None: + raise NotImplementedError( + "enum %s: the '{}' declaration should appear on the first " + "time the enum is mentioned, not later" % explicit_name) + if not tp.forcename: + tp.force_the_name(force_name) + if tp.forcename and '$' in tp.name: + self._declare('anonymous %s' % tp.forcename, tp) + # + self._structnode2type[type] = tp + # + # enums: done here + if kind == 'enum': + return tp + # + # is there a 'type.decls'? If yes, then this is the place in the + # C sources that declare the fields. If no, then just return the + # existing type, possibly still incomplete. + if type.decls is None: + return tp + # + if tp.fldnames is not None: + raise CDefError("duplicate declaration of struct %s" % name) + fldnames = [] + fldtypes = [] + fldbitsize = [] + fldquals = [] + for decl in type.decls: + if (isinstance(decl.type, pycparser.c_ast.IdentifierType) and + ''.join(decl.type.names) == '__dotdotdot__'): + # XXX pycparser is inconsistent: 'names' should be a list + # of strings, but is sometimes just one string. Use + # str.join() as a way to cope with both. + self._make_partial(tp, nested) + continue + if decl.bitsize is None: + bitsize = -1 + else: + bitsize = self._parse_constant(decl.bitsize) + self._partial_length = False + type, fqual = self._get_type_and_quals(decl.type, + partial_length_ok=True) + if self._partial_length: + self._make_partial(tp, nested) + if isinstance(type, model.StructType) and type.partial: + self._make_partial(tp, nested) + fldnames.append(decl.name or '') + fldtypes.append(type) + fldbitsize.append(bitsize) + fldquals.append(fqual) + tp.fldnames = tuple(fldnames) + tp.fldtypes = tuple(fldtypes) + tp.fldbitsize = tuple(fldbitsize) + tp.fldquals = tuple(fldquals) + if fldbitsize != [-1] * len(fldbitsize): + if isinstance(tp, model.StructType) and tp.partial: + raise NotImplementedError("%s: using both bitfields and '...;'" + % (tp,)) + tp.packed = self._options.get('packed') + if tp.completed: # must be re-completed: it is not opaque any more + tp.completed = 0 + self._recomplete.append(tp) + return tp + + def _make_partial(self, tp, nested): + if not isinstance(tp, model.StructOrUnion): + raise CDefError("%s cannot be partial" % (tp,)) + if not tp.has_c_name() and not nested: + raise NotImplementedError("%s is partial but has no C name" %(tp,)) + tp.partial = True + + def _parse_constant(self, exprnode, partial_length_ok=False): + # for now, limited to expressions that are an immediate number + # or positive/negative number + if isinstance(exprnode, pycparser.c_ast.Constant): + s = exprnode.value + if '0' <= s[0] <= '9': + s = s.rstrip('uUlL') + try: + if s.startswith('0'): + return int(s, 8) + else: + return int(s, 10) + except ValueError: + if len(s) > 1: + if s.lower()[0:2] == '0x': + return int(s, 16) + elif s.lower()[0:2] == '0b': + return int(s, 2) + raise CDefError("invalid constant %r" % (s,)) + elif s[0] == "'" and s[-1] == "'" and ( + len(s) == 3 or (len(s) == 4 and s[1] == "\\")): + return ord(s[-2]) + else: + raise CDefError("invalid constant %r" % (s,)) + # + if (isinstance(exprnode, pycparser.c_ast.UnaryOp) and + exprnode.op == '+'): + return self._parse_constant(exprnode.expr) + # + if (isinstance(exprnode, pycparser.c_ast.UnaryOp) and + exprnode.op == '-'): + return -self._parse_constant(exprnode.expr) + # load previously defined int constant + if (isinstance(exprnode, pycparser.c_ast.ID) and + exprnode.name in self._int_constants): + return self._int_constants[exprnode.name] + # + if (isinstance(exprnode, pycparser.c_ast.ID) and + exprnode.name == '__dotdotdotarray__'): + if partial_length_ok: + self._partial_length = True + return '...' + raise FFIError(":%d: unsupported '[...]' here, cannot derive " + "the actual array length in this context" + % exprnode.coord.line) + # + if isinstance(exprnode, pycparser.c_ast.BinaryOp): + left = self._parse_constant(exprnode.left) + right = self._parse_constant(exprnode.right) + if exprnode.op == '+': + return left + right + elif exprnode.op == '-': + return left - right + elif exprnode.op == '*': + return left * right + elif exprnode.op == '/': + return self._c_div(left, right) + elif exprnode.op == '%': + return left - self._c_div(left, right) * right + elif exprnode.op == '<<': + return left << right + elif exprnode.op == '>>': + return left >> right + elif exprnode.op == '&': + return left & right + elif exprnode.op == '|': + return left | right + elif exprnode.op == '^': + return left ^ right + # + raise FFIError(":%d: unsupported expression: expected a " + "simple numeric constant" % exprnode.coord.line) + + def _c_div(self, a, b): + result = a // b + if ((a < 0) ^ (b < 0)) and (a % b) != 0: + result += 1 + return result + + def _build_enum_type(self, explicit_name, decls): + if decls is not None: + partial = False + enumerators = [] + enumvalues = [] + nextenumvalue = 0 + for enum in decls.enumerators: + if _r_enum_dotdotdot.match(enum.name): + partial = True + continue + if enum.value is not None: + nextenumvalue = self._parse_constant(enum.value) + enumerators.append(enum.name) + enumvalues.append(nextenumvalue) + self._add_constants(enum.name, nextenumvalue) + nextenumvalue += 1 + enumerators = tuple(enumerators) + enumvalues = tuple(enumvalues) + tp = model.EnumType(explicit_name, enumerators, enumvalues) + tp.partial = partial + else: # opaque enum + tp = model.EnumType(explicit_name, (), ()) + return tp + + def include(self, other): + for name, (tp, quals) in other._declarations.items(): + if name.startswith('anonymous $enum_$'): + continue # fix for test_anonymous_enum_include + kind = name.split(' ', 1)[0] + if kind in ('struct', 'union', 'enum', 'anonymous', 'typedef'): + self._declare(name, tp, included=True, quals=quals) + for k, v in other._int_constants.items(): + self._add_constants(k, v) + + def _get_unknown_type(self, decl): + typenames = decl.type.type.names + if typenames == ['__dotdotdot__']: + return model.unknown_type(decl.name) + + if typenames == ['__dotdotdotint__']: + if self._uses_new_feature is None: + self._uses_new_feature = "'typedef int... %s'" % decl.name + return model.UnknownIntegerType(decl.name) + + if typenames == ['__dotdotdotfloat__']: + # note: not for 'long double' so far + if self._uses_new_feature is None: + self._uses_new_feature = "'typedef float... %s'" % decl.name + return model.UnknownFloatType(decl.name) + + raise FFIError(':%d: unsupported usage of "..." in typedef' + % decl.coord.line) + + def _get_unknown_ptr_type(self, decl): + if decl.type.type.type.names == ['__dotdotdot__']: + return model.unknown_ptr_type(decl.name) + raise FFIError(':%d: unsupported usage of "..." in typedef' + % decl.coord.line) diff --git a/server/www/packages/packages-linux/x64/cffi/error.py b/server/www/packages/packages-linux/x64/cffi/error.py new file mode 100644 index 0000000..0a27247 --- /dev/null +++ b/server/www/packages/packages-linux/x64/cffi/error.py @@ -0,0 +1,31 @@ + +class FFIError(Exception): + __module__ = 'cffi' + +class CDefError(Exception): + __module__ = 'cffi' + def __str__(self): + try: + current_decl = self.args[1] + filename = current_decl.coord.file + linenum = current_decl.coord.line + prefix = '%s:%d: ' % (filename, linenum) + except (AttributeError, TypeError, IndexError): + prefix = '' + return '%s%s' % (prefix, self.args[0]) + +class VerificationError(Exception): + """ An error raised when verification fails + """ + __module__ = 'cffi' + +class VerificationMissing(Exception): + """ An error raised when incomplete structures are passed into + cdef, but no verification has been done + """ + __module__ = 'cffi' + +class PkgConfigError(Exception): + """ An error raised for missing modules in pkg-config + """ + __module__ = 'cffi' diff --git a/server/www/packages/packages-linux/x64/cffi/ffiplatform.py b/server/www/packages/packages-linux/x64/cffi/ffiplatform.py new file mode 100644 index 0000000..8531346 --- /dev/null +++ b/server/www/packages/packages-linux/x64/cffi/ffiplatform.py @@ -0,0 +1,127 @@ +import sys, os +from .error import VerificationError + + +LIST_OF_FILE_NAMES = ['sources', 'include_dirs', 'library_dirs', + 'extra_objects', 'depends'] + +def get_extension(srcfilename, modname, sources=(), **kwds): + _hack_at_distutils() + from distutils.core import Extension + allsources = [srcfilename] + for src in sources: + allsources.append(os.path.normpath(src)) + return Extension(name=modname, sources=allsources, **kwds) + +def compile(tmpdir, ext, compiler_verbose=0, debug=None): + """Compile a C extension module using distutils.""" + + _hack_at_distutils() + saved_environ = os.environ.copy() + try: + outputfilename = _build(tmpdir, ext, compiler_verbose, debug) + outputfilename = os.path.abspath(outputfilename) + finally: + # workaround for a distutils bugs where some env vars can + # become longer and longer every time it is used + for key, value in saved_environ.items(): + if os.environ.get(key) != value: + os.environ[key] = value + return outputfilename + +def _build(tmpdir, ext, compiler_verbose=0, debug=None): + # XXX compact but horrible :-( + from distutils.core import Distribution + import distutils.errors, distutils.log + # + dist = Distribution({'ext_modules': [ext]}) + dist.parse_config_files() + options = dist.get_option_dict('build_ext') + if debug is None: + debug = sys.flags.debug + options['debug'] = ('ffiplatform', debug) + options['force'] = ('ffiplatform', True) + options['build_lib'] = ('ffiplatform', tmpdir) + options['build_temp'] = ('ffiplatform', tmpdir) + # + try: + old_level = distutils.log.set_threshold(0) or 0 + try: + distutils.log.set_verbosity(compiler_verbose) + dist.run_command('build_ext') + cmd_obj = dist.get_command_obj('build_ext') + [soname] = cmd_obj.get_outputs() + finally: + distutils.log.set_threshold(old_level) + except (distutils.errors.CompileError, + distutils.errors.LinkError) as e: + raise VerificationError('%s: %s' % (e.__class__.__name__, e)) + # + return soname + +try: + from os.path import samefile +except ImportError: + def samefile(f1, f2): + return os.path.abspath(f1) == os.path.abspath(f2) + +def maybe_relative_path(path): + if not os.path.isabs(path): + return path # already relative + dir = path + names = [] + while True: + prevdir = dir + dir, name = os.path.split(prevdir) + if dir == prevdir or not dir: + return path # failed to make it relative + names.append(name) + try: + if samefile(dir, os.curdir): + names.reverse() + return os.path.join(*names) + except OSError: + pass + +# ____________________________________________________________ + +try: + int_or_long = (int, long) + import cStringIO +except NameError: + int_or_long = int # Python 3 + import io as cStringIO + +def _flatten(x, f): + if isinstance(x, str): + f.write('%ds%s' % (len(x), x)) + elif isinstance(x, dict): + keys = sorted(x.keys()) + f.write('%dd' % len(keys)) + for key in keys: + _flatten(key, f) + _flatten(x[key], f) + elif isinstance(x, (list, tuple)): + f.write('%dl' % len(x)) + for value in x: + _flatten(value, f) + elif isinstance(x, int_or_long): + f.write('%di' % (x,)) + else: + raise TypeError( + "the keywords to verify() contains unsupported object %r" % (x,)) + +def flatten(x): + f = cStringIO.StringIO() + _flatten(x, f) + return f.getvalue() + +def _hack_at_distutils(): + # Windows-only workaround for some configurations: see + # https://bugs.python.org/issue23246 (Python 2.7 with + # a specific MS compiler suite download) + if sys.platform == "win32": + try: + import setuptools # for side-effects, patches distutils + except ImportError: + pass diff --git a/server/www/packages/packages-linux/x64/cffi/lock.py b/server/www/packages/packages-linux/x64/cffi/lock.py new file mode 100644 index 0000000..db91b71 --- /dev/null +++ b/server/www/packages/packages-linux/x64/cffi/lock.py @@ -0,0 +1,30 @@ +import sys + +if sys.version_info < (3,): + try: + from thread import allocate_lock + except ImportError: + from dummy_thread import allocate_lock +else: + try: + from _thread import allocate_lock + except ImportError: + from _dummy_thread import allocate_lock + + +##import sys +##l1 = allocate_lock + +##class allocate_lock(object): +## def __init__(self): +## self._real = l1() +## def __enter__(self): +## for i in range(4, 0, -1): +## print sys._getframe(i).f_code +## print +## return self._real.__enter__() +## def __exit__(self, *args): +## return self._real.__exit__(*args) +## def acquire(self, f): +## assert f is False +## return self._real.acquire(f) diff --git a/server/www/packages/packages-linux/x64/cffi/model.py b/server/www/packages/packages-linux/x64/cffi/model.py new file mode 100644 index 0000000..5f1b0d2 --- /dev/null +++ b/server/www/packages/packages-linux/x64/cffi/model.py @@ -0,0 +1,614 @@ +import types +import weakref + +from .lock import allocate_lock +from .error import CDefError, VerificationError, VerificationMissing + +# type qualifiers +Q_CONST = 0x01 +Q_RESTRICT = 0x02 +Q_VOLATILE = 0x04 + +def qualify(quals, replace_with): + if quals & Q_CONST: + replace_with = ' const ' + replace_with.lstrip() + if quals & Q_VOLATILE: + replace_with = ' volatile ' + replace_with.lstrip() + if quals & Q_RESTRICT: + # It seems that __restrict is supported by gcc and msvc. + # If you hit some different compiler, add a #define in + # _cffi_include.h for it (and in its copies, documented there) + replace_with = ' __restrict ' + replace_with.lstrip() + return replace_with + + +class BaseTypeByIdentity(object): + is_array_type = False + is_raw_function = False + + def get_c_name(self, replace_with='', context='a C file', quals=0): + result = self.c_name_with_marker + assert result.count('&') == 1 + # some logic duplication with ffi.getctype()... :-( + replace_with = replace_with.strip() + if replace_with: + if replace_with.startswith('*') and '&[' in result: + replace_with = '(%s)' % replace_with + elif not replace_with[0] in '[(': + replace_with = ' ' + replace_with + replace_with = qualify(quals, replace_with) + result = result.replace('&', replace_with) + if '$' in result: + raise VerificationError( + "cannot generate '%s' in %s: unknown type name" + % (self._get_c_name(), context)) + return result + + def _get_c_name(self): + return self.c_name_with_marker.replace('&', '') + + def has_c_name(self): + return '$' not in self._get_c_name() + + def is_integer_type(self): + return False + + def get_cached_btype(self, ffi, finishlist, can_delay=False): + try: + BType = ffi._cached_btypes[self] + except KeyError: + BType = self.build_backend_type(ffi, finishlist) + BType2 = ffi._cached_btypes.setdefault(self, BType) + assert BType2 is BType + return BType + + def __repr__(self): + return '<%s>' % (self._get_c_name(),) + + def _get_items(self): + return [(name, getattr(self, name)) for name in self._attrs_] + + +class BaseType(BaseTypeByIdentity): + + def __eq__(self, other): + return (self.__class__ == other.__class__ and + self._get_items() == other._get_items()) + + def __ne__(self, other): + return not self == other + + def __hash__(self): + return hash((self.__class__, tuple(self._get_items()))) + + +class VoidType(BaseType): + _attrs_ = () + + def __init__(self): + self.c_name_with_marker = 'void&' + + def build_backend_type(self, ffi, finishlist): + return global_cache(self, ffi, 'new_void_type') + +void_type = VoidType() + + +class BasePrimitiveType(BaseType): + def is_complex_type(self): + return False + + +class PrimitiveType(BasePrimitiveType): + _attrs_ = ('name',) + + ALL_PRIMITIVE_TYPES = { + 'char': 'c', + 'short': 'i', + 'int': 'i', + 'long': 'i', + 'long long': 'i', + 'signed char': 'i', + 'unsigned char': 'i', + 'unsigned short': 'i', + 'unsigned int': 'i', + 'unsigned long': 'i', + 'unsigned long long': 'i', + 'float': 'f', + 'double': 'f', + 'long double': 'f', + 'float _Complex': 'j', + 'double _Complex': 'j', + '_Bool': 'i', + # the following types are not primitive in the C sense + 'wchar_t': 'c', + 'char16_t': 'c', + 'char32_t': 'c', + 'int8_t': 'i', + 'uint8_t': 'i', + 'int16_t': 'i', + 'uint16_t': 'i', + 'int32_t': 'i', + 'uint32_t': 'i', + 'int64_t': 'i', + 'uint64_t': 'i', + 'int_least8_t': 'i', + 'uint_least8_t': 'i', + 'int_least16_t': 'i', + 'uint_least16_t': 'i', + 'int_least32_t': 'i', + 'uint_least32_t': 'i', + 'int_least64_t': 'i', + 'uint_least64_t': 'i', + 'int_fast8_t': 'i', + 'uint_fast8_t': 'i', + 'int_fast16_t': 'i', + 'uint_fast16_t': 'i', + 'int_fast32_t': 'i', + 'uint_fast32_t': 'i', + 'int_fast64_t': 'i', + 'uint_fast64_t': 'i', + 'intptr_t': 'i', + 'uintptr_t': 'i', + 'intmax_t': 'i', + 'uintmax_t': 'i', + 'ptrdiff_t': 'i', + 'size_t': 'i', + 'ssize_t': 'i', + } + + def __init__(self, name): + assert name in self.ALL_PRIMITIVE_TYPES + self.name = name + self.c_name_with_marker = name + '&' + + def is_char_type(self): + return self.ALL_PRIMITIVE_TYPES[self.name] == 'c' + def is_integer_type(self): + return self.ALL_PRIMITIVE_TYPES[self.name] == 'i' + def is_float_type(self): + return self.ALL_PRIMITIVE_TYPES[self.name] == 'f' + def is_complex_type(self): + return self.ALL_PRIMITIVE_TYPES[self.name] == 'j' + + def build_backend_type(self, ffi, finishlist): + return global_cache(self, ffi, 'new_primitive_type', self.name) + + +class UnknownIntegerType(BasePrimitiveType): + _attrs_ = ('name',) + + def __init__(self, name): + self.name = name + self.c_name_with_marker = name + '&' + + def is_integer_type(self): + return True + + def build_backend_type(self, ffi, finishlist): + raise NotImplementedError("integer type '%s' can only be used after " + "compilation" % self.name) + +class UnknownFloatType(BasePrimitiveType): + _attrs_ = ('name', ) + + def __init__(self, name): + self.name = name + self.c_name_with_marker = name + '&' + + def build_backend_type(self, ffi, finishlist): + raise NotImplementedError("float type '%s' can only be used after " + "compilation" % self.name) + + +class BaseFunctionType(BaseType): + _attrs_ = ('args', 'result', 'ellipsis', 'abi') + + def __init__(self, args, result, ellipsis, abi=None): + self.args = args + self.result = result + self.ellipsis = ellipsis + self.abi = abi + # + reprargs = [arg._get_c_name() for arg in self.args] + if self.ellipsis: + reprargs.append('...') + reprargs = reprargs or ['void'] + replace_with = self._base_pattern % (', '.join(reprargs),) + if abi is not None: + replace_with = replace_with[:1] + abi + ' ' + replace_with[1:] + self.c_name_with_marker = ( + self.result.c_name_with_marker.replace('&', replace_with)) + + +class RawFunctionType(BaseFunctionType): + # Corresponds to a C type like 'int(int)', which is the C type of + # a function, but not a pointer-to-function. The backend has no + # notion of such a type; it's used temporarily by parsing. + _base_pattern = '(&)(%s)' + is_raw_function = True + + def build_backend_type(self, ffi, finishlist): + raise CDefError("cannot render the type %r: it is a function " + "type, not a pointer-to-function type" % (self,)) + + def as_function_pointer(self): + return FunctionPtrType(self.args, self.result, self.ellipsis, self.abi) + + +class FunctionPtrType(BaseFunctionType): + _base_pattern = '(*&)(%s)' + + def build_backend_type(self, ffi, finishlist): + result = self.result.get_cached_btype(ffi, finishlist) + args = [] + for tp in self.args: + args.append(tp.get_cached_btype(ffi, finishlist)) + abi_args = () + if self.abi == "__stdcall": + if not self.ellipsis: # __stdcall ignored for variadic funcs + try: + abi_args = (ffi._backend.FFI_STDCALL,) + except AttributeError: + pass + return global_cache(self, ffi, 'new_function_type', + tuple(args), result, self.ellipsis, *abi_args) + + def as_raw_function(self): + return RawFunctionType(self.args, self.result, self.ellipsis, self.abi) + + +class PointerType(BaseType): + _attrs_ = ('totype', 'quals') + + def __init__(self, totype, quals=0): + self.totype = totype + self.quals = quals + extra = qualify(quals, " *&") + if totype.is_array_type: + extra = "(%s)" % (extra.lstrip(),) + self.c_name_with_marker = totype.c_name_with_marker.replace('&', extra) + + def build_backend_type(self, ffi, finishlist): + BItem = self.totype.get_cached_btype(ffi, finishlist, can_delay=True) + return global_cache(self, ffi, 'new_pointer_type', BItem) + +voidp_type = PointerType(void_type) + +def ConstPointerType(totype): + return PointerType(totype, Q_CONST) + +const_voidp_type = ConstPointerType(void_type) + + +class NamedPointerType(PointerType): + _attrs_ = ('totype', 'name') + + def __init__(self, totype, name, quals=0): + PointerType.__init__(self, totype, quals) + self.name = name + self.c_name_with_marker = name + '&' + + +class ArrayType(BaseType): + _attrs_ = ('item', 'length') + is_array_type = True + + def __init__(self, item, length): + self.item = item + self.length = length + # + if length is None: + brackets = '&[]' + elif length == '...': + brackets = '&[/*...*/]' + else: + brackets = '&[%s]' % length + self.c_name_with_marker = ( + self.item.c_name_with_marker.replace('&', brackets)) + + def resolve_length(self, newlength): + return ArrayType(self.item, newlength) + + def build_backend_type(self, ffi, finishlist): + if self.length == '...': + raise CDefError("cannot render the type %r: unknown length" % + (self,)) + self.item.get_cached_btype(ffi, finishlist) # force the item BType + BPtrItem = PointerType(self.item).get_cached_btype(ffi, finishlist) + return global_cache(self, ffi, 'new_array_type', BPtrItem, self.length) + +char_array_type = ArrayType(PrimitiveType('char'), None) + + +class StructOrUnionOrEnum(BaseTypeByIdentity): + _attrs_ = ('name',) + forcename = None + + def build_c_name_with_marker(self): + name = self.forcename or '%s %s' % (self.kind, self.name) + self.c_name_with_marker = name + '&' + + def force_the_name(self, forcename): + self.forcename = forcename + self.build_c_name_with_marker() + + def get_official_name(self): + assert self.c_name_with_marker.endswith('&') + return self.c_name_with_marker[:-1] + + +class StructOrUnion(StructOrUnionOrEnum): + fixedlayout = None + completed = 0 + partial = False + packed = 0 + + def __init__(self, name, fldnames, fldtypes, fldbitsize, fldquals=None): + self.name = name + self.fldnames = fldnames + self.fldtypes = fldtypes + self.fldbitsize = fldbitsize + self.fldquals = fldquals + self.build_c_name_with_marker() + + def anonymous_struct_fields(self): + if self.fldtypes is not None: + for name, type in zip(self.fldnames, self.fldtypes): + if name == '' and isinstance(type, StructOrUnion): + yield type + + def enumfields(self, expand_anonymous_struct_union=True): + fldquals = self.fldquals + if fldquals is None: + fldquals = (0,) * len(self.fldnames) + for name, type, bitsize, quals in zip(self.fldnames, self.fldtypes, + self.fldbitsize, fldquals): + if (name == '' and isinstance(type, StructOrUnion) + and expand_anonymous_struct_union): + # nested anonymous struct/union + for result in type.enumfields(): + yield result + else: + yield (name, type, bitsize, quals) + + def force_flatten(self): + # force the struct or union to have a declaration that lists + # directly all fields returned by enumfields(), flattening + # nested anonymous structs/unions. + names = [] + types = [] + bitsizes = [] + fldquals = [] + for name, type, bitsize, quals in self.enumfields(): + names.append(name) + types.append(type) + bitsizes.append(bitsize) + fldquals.append(quals) + self.fldnames = tuple(names) + self.fldtypes = tuple(types) + self.fldbitsize = tuple(bitsizes) + self.fldquals = tuple(fldquals) + + def get_cached_btype(self, ffi, finishlist, can_delay=False): + BType = StructOrUnionOrEnum.get_cached_btype(self, ffi, finishlist, + can_delay) + if not can_delay: + self.finish_backend_type(ffi, finishlist) + return BType + + def finish_backend_type(self, ffi, finishlist): + if self.completed: + if self.completed != 2: + raise NotImplementedError("recursive structure declaration " + "for '%s'" % (self.name,)) + return + BType = ffi._cached_btypes[self] + # + self.completed = 1 + # + if self.fldtypes is None: + pass # not completing it: it's an opaque struct + # + elif self.fixedlayout is None: + fldtypes = [tp.get_cached_btype(ffi, finishlist) + for tp in self.fldtypes] + lst = list(zip(self.fldnames, fldtypes, self.fldbitsize)) + extra_flags = () + if self.packed: + if self.packed == 1: + extra_flags = (8,) # SF_PACKED + else: + extra_flags = (0, self.packed) + ffi._backend.complete_struct_or_union(BType, lst, self, + -1, -1, *extra_flags) + # + else: + fldtypes = [] + fieldofs, fieldsize, totalsize, totalalignment = self.fixedlayout + for i in range(len(self.fldnames)): + fsize = fieldsize[i] + ftype = self.fldtypes[i] + # + if isinstance(ftype, ArrayType) and ftype.length == '...': + # fix the length to match the total size + BItemType = ftype.item.get_cached_btype(ffi, finishlist) + nlen, nrest = divmod(fsize, ffi.sizeof(BItemType)) + if nrest != 0: + self._verification_error( + "field '%s.%s' has a bogus size?" % ( + self.name, self.fldnames[i] or '{}')) + ftype = ftype.resolve_length(nlen) + self.fldtypes = (self.fldtypes[:i] + (ftype,) + + self.fldtypes[i+1:]) + # + BFieldType = ftype.get_cached_btype(ffi, finishlist) + if isinstance(ftype, ArrayType) and ftype.length is None: + assert fsize == 0 + else: + bitemsize = ffi.sizeof(BFieldType) + if bitemsize != fsize: + self._verification_error( + "field '%s.%s' is declared as %d bytes, but is " + "really %d bytes" % (self.name, + self.fldnames[i] or '{}', + bitemsize, fsize)) + fldtypes.append(BFieldType) + # + lst = list(zip(self.fldnames, fldtypes, self.fldbitsize, fieldofs)) + ffi._backend.complete_struct_or_union(BType, lst, self, + totalsize, totalalignment) + self.completed = 2 + + def _verification_error(self, msg): + raise VerificationError(msg) + + def check_not_partial(self): + if self.partial and self.fixedlayout is None: + raise VerificationMissing(self._get_c_name()) + + def build_backend_type(self, ffi, finishlist): + self.check_not_partial() + finishlist.append(self) + # + return global_cache(self, ffi, 'new_%s_type' % self.kind, + self.get_official_name(), key=self) + + +class StructType(StructOrUnion): + kind = 'struct' + + +class UnionType(StructOrUnion): + kind = 'union' + + +class EnumType(StructOrUnionOrEnum): + kind = 'enum' + partial = False + partial_resolved = False + + def __init__(self, name, enumerators, enumvalues, baseinttype=None): + self.name = name + self.enumerators = enumerators + self.enumvalues = enumvalues + self.baseinttype = baseinttype + self.build_c_name_with_marker() + + def force_the_name(self, forcename): + StructOrUnionOrEnum.force_the_name(self, forcename) + if self.forcename is None: + name = self.get_official_name() + self.forcename = '$' + name.replace(' ', '_') + + def check_not_partial(self): + if self.partial and not self.partial_resolved: + raise VerificationMissing(self._get_c_name()) + + def build_backend_type(self, ffi, finishlist): + self.check_not_partial() + base_btype = self.build_baseinttype(ffi, finishlist) + return global_cache(self, ffi, 'new_enum_type', + self.get_official_name(), + self.enumerators, self.enumvalues, + base_btype, key=self) + + def build_baseinttype(self, ffi, finishlist): + if self.baseinttype is not None: + return self.baseinttype.get_cached_btype(ffi, finishlist) + # + if self.enumvalues: + smallest_value = min(self.enumvalues) + largest_value = max(self.enumvalues) + else: + import warnings + try: + # XXX! The goal is to ensure that the warnings.warn() + # will not suppress the warning. We want to get it + # several times if we reach this point several times. + __warningregistry__.clear() + except NameError: + pass + warnings.warn("%r has no values explicitly defined; " + "guessing that it is equivalent to 'unsigned int'" + % self._get_c_name()) + smallest_value = largest_value = 0 + if smallest_value < 0: # needs a signed type + sign = 1 + candidate1 = PrimitiveType("int") + candidate2 = PrimitiveType("long") + else: + sign = 0 + candidate1 = PrimitiveType("unsigned int") + candidate2 = PrimitiveType("unsigned long") + btype1 = candidate1.get_cached_btype(ffi, finishlist) + btype2 = candidate2.get_cached_btype(ffi, finishlist) + size1 = ffi.sizeof(btype1) + size2 = ffi.sizeof(btype2) + if (smallest_value >= ((-1) << (8*size1-1)) and + largest_value < (1 << (8*size1-sign))): + return btype1 + if (smallest_value >= ((-1) << (8*size2-1)) and + largest_value < (1 << (8*size2-sign))): + return btype2 + raise CDefError("%s values don't all fit into either 'long' " + "or 'unsigned long'" % self._get_c_name()) + +def unknown_type(name, structname=None): + if structname is None: + structname = '$%s' % name + tp = StructType(structname, None, None, None) + tp.force_the_name(name) + tp.origin = "unknown_type" + return tp + +def unknown_ptr_type(name, structname=None): + if structname is None: + structname = '$$%s' % name + tp = StructType(structname, None, None, None) + return NamedPointerType(tp, name) + + +global_lock = allocate_lock() +_typecache_cffi_backend = weakref.WeakValueDictionary() + +def get_typecache(backend): + # returns _typecache_cffi_backend if backend is the _cffi_backend + # module, or type(backend).__typecache if backend is an instance of + # CTypesBackend (or some FakeBackend class during tests) + if isinstance(backend, types.ModuleType): + return _typecache_cffi_backend + with global_lock: + if not hasattr(type(backend), '__typecache'): + type(backend).__typecache = weakref.WeakValueDictionary() + return type(backend).__typecache + +def global_cache(srctype, ffi, funcname, *args, **kwds): + key = kwds.pop('key', (funcname, args)) + assert not kwds + try: + return ffi._typecache[key] + except KeyError: + pass + try: + res = getattr(ffi._backend, funcname)(*args) + except NotImplementedError as e: + raise NotImplementedError("%s: %r: %s" % (funcname, srctype, e)) + # note that setdefault() on WeakValueDictionary is not atomic + # and contains a rare bug (http://bugs.python.org/issue19542); + # we have to use a lock and do it ourselves + cache = ffi._typecache + with global_lock: + res1 = cache.get(key) + if res1 is None: + cache[key] = res + return res + else: + return res1 + +def pointer_cache(ffi, BType): + return global_cache('?', ffi, 'new_pointer_type', BType) + +def attach_exception_info(e, name): + if e.args and type(e.args[0]) is str: + e.args = ('%s: %s' % (name, e.args[0]),) + e.args[1:] diff --git a/server/www/packages/packages-linux/x64/cffi/parse_c_type.h b/server/www/packages/packages-linux/x64/cffi/parse_c_type.h new file mode 100644 index 0000000..84e4ef8 --- /dev/null +++ b/server/www/packages/packages-linux/x64/cffi/parse_c_type.h @@ -0,0 +1,181 @@ + +/* This part is from file 'cffi/parse_c_type.h'. It is copied at the + beginning of C sources generated by CFFI's ffi.set_source(). */ + +typedef void *_cffi_opcode_t; + +#define _CFFI_OP(opcode, arg) (_cffi_opcode_t)(opcode | (((uintptr_t)(arg)) << 8)) +#define _CFFI_GETOP(cffi_opcode) ((unsigned char)(uintptr_t)cffi_opcode) +#define _CFFI_GETARG(cffi_opcode) (((intptr_t)cffi_opcode) >> 8) + +#define _CFFI_OP_PRIMITIVE 1 +#define _CFFI_OP_POINTER 3 +#define _CFFI_OP_ARRAY 5 +#define _CFFI_OP_OPEN_ARRAY 7 +#define _CFFI_OP_STRUCT_UNION 9 +#define _CFFI_OP_ENUM 11 +#define _CFFI_OP_FUNCTION 13 +#define _CFFI_OP_FUNCTION_END 15 +#define _CFFI_OP_NOOP 17 +#define _CFFI_OP_BITFIELD 19 +#define _CFFI_OP_TYPENAME 21 +#define _CFFI_OP_CPYTHON_BLTN_V 23 // varargs +#define _CFFI_OP_CPYTHON_BLTN_N 25 // noargs +#define _CFFI_OP_CPYTHON_BLTN_O 27 // O (i.e. a single arg) +#define _CFFI_OP_CONSTANT 29 +#define _CFFI_OP_CONSTANT_INT 31 +#define _CFFI_OP_GLOBAL_VAR 33 +#define _CFFI_OP_DLOPEN_FUNC 35 +#define _CFFI_OP_DLOPEN_CONST 37 +#define _CFFI_OP_GLOBAL_VAR_F 39 +#define _CFFI_OP_EXTERN_PYTHON 41 + +#define _CFFI_PRIM_VOID 0 +#define _CFFI_PRIM_BOOL 1 +#define _CFFI_PRIM_CHAR 2 +#define _CFFI_PRIM_SCHAR 3 +#define _CFFI_PRIM_UCHAR 4 +#define _CFFI_PRIM_SHORT 5 +#define _CFFI_PRIM_USHORT 6 +#define _CFFI_PRIM_INT 7 +#define _CFFI_PRIM_UINT 8 +#define _CFFI_PRIM_LONG 9 +#define _CFFI_PRIM_ULONG 10 +#define _CFFI_PRIM_LONGLONG 11 +#define _CFFI_PRIM_ULONGLONG 12 +#define _CFFI_PRIM_FLOAT 13 +#define _CFFI_PRIM_DOUBLE 14 +#define _CFFI_PRIM_LONGDOUBLE 15 + +#define _CFFI_PRIM_WCHAR 16 +#define _CFFI_PRIM_INT8 17 +#define _CFFI_PRIM_UINT8 18 +#define _CFFI_PRIM_INT16 19 +#define _CFFI_PRIM_UINT16 20 +#define _CFFI_PRIM_INT32 21 +#define _CFFI_PRIM_UINT32 22 +#define _CFFI_PRIM_INT64 23 +#define _CFFI_PRIM_UINT64 24 +#define _CFFI_PRIM_INTPTR 25 +#define _CFFI_PRIM_UINTPTR 26 +#define _CFFI_PRIM_PTRDIFF 27 +#define _CFFI_PRIM_SIZE 28 +#define _CFFI_PRIM_SSIZE 29 +#define _CFFI_PRIM_INT_LEAST8 30 +#define _CFFI_PRIM_UINT_LEAST8 31 +#define _CFFI_PRIM_INT_LEAST16 32 +#define _CFFI_PRIM_UINT_LEAST16 33 +#define _CFFI_PRIM_INT_LEAST32 34 +#define _CFFI_PRIM_UINT_LEAST32 35 +#define _CFFI_PRIM_INT_LEAST64 36 +#define _CFFI_PRIM_UINT_LEAST64 37 +#define _CFFI_PRIM_INT_FAST8 38 +#define _CFFI_PRIM_UINT_FAST8 39 +#define _CFFI_PRIM_INT_FAST16 40 +#define _CFFI_PRIM_UINT_FAST16 41 +#define _CFFI_PRIM_INT_FAST32 42 +#define _CFFI_PRIM_UINT_FAST32 43 +#define _CFFI_PRIM_INT_FAST64 44 +#define _CFFI_PRIM_UINT_FAST64 45 +#define _CFFI_PRIM_INTMAX 46 +#define _CFFI_PRIM_UINTMAX 47 +#define _CFFI_PRIM_FLOATCOMPLEX 48 +#define _CFFI_PRIM_DOUBLECOMPLEX 49 +#define _CFFI_PRIM_CHAR16 50 +#define _CFFI_PRIM_CHAR32 51 + +#define _CFFI__NUM_PRIM 52 +#define _CFFI__UNKNOWN_PRIM (-1) +#define _CFFI__UNKNOWN_FLOAT_PRIM (-2) +#define _CFFI__UNKNOWN_LONG_DOUBLE (-3) + +#define _CFFI__IO_FILE_STRUCT (-1) + + +struct _cffi_global_s { + const char *name; + void *address; + _cffi_opcode_t type_op; + void *size_or_direct_fn; // OP_GLOBAL_VAR: size, or 0 if unknown + // OP_CPYTHON_BLTN_*: addr of direct function +}; + +struct _cffi_getconst_s { + unsigned long long value; + const struct _cffi_type_context_s *ctx; + int gindex; +}; + +struct _cffi_struct_union_s { + const char *name; + int type_index; // -> _cffi_types, on a OP_STRUCT_UNION + int flags; // _CFFI_F_* flags below + size_t size; + int alignment; + int first_field_index; // -> _cffi_fields array + int num_fields; +}; +#define _CFFI_F_UNION 0x01 // is a union, not a struct +#define _CFFI_F_CHECK_FIELDS 0x02 // complain if fields are not in the + // "standard layout" or if some are missing +#define _CFFI_F_PACKED 0x04 // for CHECK_FIELDS, assume a packed struct +#define _CFFI_F_EXTERNAL 0x08 // in some other ffi.include() +#define _CFFI_F_OPAQUE 0x10 // opaque + +struct _cffi_field_s { + const char *name; + size_t field_offset; + size_t field_size; + _cffi_opcode_t field_type_op; +}; + +struct _cffi_enum_s { + const char *name; + int type_index; // -> _cffi_types, on a OP_ENUM + int type_prim; // _CFFI_PRIM_xxx + const char *enumerators; // comma-delimited string +}; + +struct _cffi_typename_s { + const char *name; + int type_index; /* if opaque, points to a possibly artificial + OP_STRUCT which is itself opaque */ +}; + +struct _cffi_type_context_s { + _cffi_opcode_t *types; + const struct _cffi_global_s *globals; + const struct _cffi_field_s *fields; + const struct _cffi_struct_union_s *struct_unions; + const struct _cffi_enum_s *enums; + const struct _cffi_typename_s *typenames; + int num_globals; + int num_struct_unions; + int num_enums; + int num_typenames; + const char *const *includes; + int num_types; + int flags; /* future extension */ +}; + +struct _cffi_parse_info_s { + const struct _cffi_type_context_s *ctx; + _cffi_opcode_t *output; + unsigned int output_size; + size_t error_location; + const char *error_message; +}; + +struct _cffi_externpy_s { + const char *name; + size_t size_of_result; + void *reserved1, *reserved2; +}; + +#ifdef _CFFI_INTERNAL +static int parse_c_type(struct _cffi_parse_info_s *info, const char *input); +static int search_in_globals(const struct _cffi_type_context_s *ctx, + const char *search, size_t search_len); +static int search_in_struct_unions(const struct _cffi_type_context_s *ctx, + const char *search, size_t search_len); +#endif diff --git a/server/www/packages/packages-linux/x64/cffi/pkgconfig.py b/server/www/packages/packages-linux/x64/cffi/pkgconfig.py new file mode 100644 index 0000000..5c93f15 --- /dev/null +++ b/server/www/packages/packages-linux/x64/cffi/pkgconfig.py @@ -0,0 +1,121 @@ +# pkg-config, https://www.freedesktop.org/wiki/Software/pkg-config/ integration for cffi +import sys, os, subprocess + +from .error import PkgConfigError + + +def merge_flags(cfg1, cfg2): + """Merge values from cffi config flags cfg2 to cf1 + + Example: + merge_flags({"libraries": ["one"]}, {"libraries": ["two"]}) + {"libraries": ["one", "two"]} + """ + for key, value in cfg2.items(): + if key not in cfg1: + cfg1[key] = value + else: + if not isinstance(cfg1[key], list): + raise TypeError("cfg1[%r] should be a list of strings" % (key,)) + if not isinstance(value, list): + raise TypeError("cfg2[%r] should be a list of strings" % (key,)) + cfg1[key].extend(value) + return cfg1 + + +def call(libname, flag, encoding=sys.getfilesystemencoding()): + """Calls pkg-config and returns the output if found + """ + a = ["pkg-config", "--print-errors"] + a.append(flag) + a.append(libname) + try: + pc = subprocess.Popen(a, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + except EnvironmentError as e: + raise PkgConfigError("cannot run pkg-config: %s" % (str(e).strip(),)) + + bout, berr = pc.communicate() + if pc.returncode != 0: + try: + berr = berr.decode(encoding) + except Exception: + pass + raise PkgConfigError(berr.strip()) + + if sys.version_info >= (3,) and not isinstance(bout, str): # Python 3.x + try: + bout = bout.decode(encoding) + except UnicodeDecodeError: + raise PkgConfigError("pkg-config %s %s returned bytes that cannot " + "be decoded with encoding %r:\n%r" % + (flag, libname, encoding, bout)) + + if os.altsep != '\\' and '\\' in bout: + raise PkgConfigError("pkg-config %s %s returned an unsupported " + "backslash-escaped output:\n%r" % + (flag, libname, bout)) + return bout + + +def flags_from_pkgconfig(libs): + r"""Return compiler line flags for FFI.set_source based on pkg-config output + + Usage + ... + ffibuilder.set_source("_foo", pkgconfig = ["libfoo", "libbar >= 1.8.3"]) + + If pkg-config is installed on build machine, then arguments include_dirs, + library_dirs, libraries, define_macros, extra_compile_args and + extra_link_args are extended with an output of pkg-config for libfoo and + libbar. + + Raises PkgConfigError in case the pkg-config call fails. + """ + + def get_include_dirs(string): + return [x[2:] for x in string.split() if x.startswith("-I")] + + def get_library_dirs(string): + return [x[2:] for x in string.split() if x.startswith("-L")] + + def get_libraries(string): + return [x[2:] for x in string.split() if x.startswith("-l")] + + # convert -Dfoo=bar to list of tuples [("foo", "bar")] expected by distutils + def get_macros(string): + def _macro(x): + x = x[2:] # drop "-D" + if '=' in x: + return tuple(x.split("=", 1)) # "-Dfoo=bar" => ("foo", "bar") + else: + return (x, None) # "-Dfoo" => ("foo", None) + return [_macro(x) for x in string.split() if x.startswith("-D")] + + def get_other_cflags(string): + return [x for x in string.split() if not x.startswith("-I") and + not x.startswith("-D")] + + def get_other_libs(string): + return [x for x in string.split() if not x.startswith("-L") and + not x.startswith("-l")] + + # return kwargs for given libname + def kwargs(libname): + fse = sys.getfilesystemencoding() + all_cflags = call(libname, "--cflags") + all_libs = call(libname, "--libs") + return { + "include_dirs": get_include_dirs(all_cflags), + "library_dirs": get_library_dirs(all_libs), + "libraries": get_libraries(all_libs), + "define_macros": get_macros(all_cflags), + "extra_compile_args": get_other_cflags(all_cflags), + "extra_link_args": get_other_libs(all_libs), + } + + # merge all arguments together + ret = {} + for libname in libs: + lib_flags = kwargs(libname) + merge_flags(ret, lib_flags) + return ret diff --git a/server/www/packages/packages-linux/x64/cffi/recompiler.py b/server/www/packages/packages-linux/x64/cffi/recompiler.py new file mode 100644 index 0000000..d6530e5 --- /dev/null +++ b/server/www/packages/packages-linux/x64/cffi/recompiler.py @@ -0,0 +1,1543 @@ +import os, sys, io +from . import ffiplatform, model +from .error import VerificationError +from .cffi_opcode import * + +VERSION_BASE = 0x2601 +VERSION_EMBEDDED = 0x2701 +VERSION_CHAR16CHAR32 = 0x2801 + + +class GlobalExpr: + def __init__(self, name, address, type_op, size=0, check_value=0): + self.name = name + self.address = address + self.type_op = type_op + self.size = size + self.check_value = check_value + + def as_c_expr(self): + return ' { "%s", (void *)%s, %s, (void *)%s },' % ( + self.name, self.address, self.type_op.as_c_expr(), self.size) + + def as_python_expr(self): + return "b'%s%s',%d" % (self.type_op.as_python_bytes(), self.name, + self.check_value) + +class FieldExpr: + def __init__(self, name, field_offset, field_size, fbitsize, field_type_op): + self.name = name + self.field_offset = field_offset + self.field_size = field_size + self.fbitsize = fbitsize + self.field_type_op = field_type_op + + def as_c_expr(self): + spaces = " " * len(self.name) + return (' { "%s", %s,\n' % (self.name, self.field_offset) + + ' %s %s,\n' % (spaces, self.field_size) + + ' %s %s },' % (spaces, self.field_type_op.as_c_expr())) + + def as_python_expr(self): + raise NotImplementedError + + def as_field_python_expr(self): + if self.field_type_op.op == OP_NOOP: + size_expr = '' + elif self.field_type_op.op == OP_BITFIELD: + size_expr = format_four_bytes(self.fbitsize) + else: + raise NotImplementedError + return "b'%s%s%s'" % (self.field_type_op.as_python_bytes(), + size_expr, + self.name) + +class StructUnionExpr: + def __init__(self, name, type_index, flags, size, alignment, comment, + first_field_index, c_fields): + self.name = name + self.type_index = type_index + self.flags = flags + self.size = size + self.alignment = alignment + self.comment = comment + self.first_field_index = first_field_index + self.c_fields = c_fields + + def as_c_expr(self): + return (' { "%s", %d, %s,' % (self.name, self.type_index, self.flags) + + '\n %s, %s, ' % (self.size, self.alignment) + + '%d, %d ' % (self.first_field_index, len(self.c_fields)) + + ('/* %s */ ' % self.comment if self.comment else '') + + '},') + + def as_python_expr(self): + flags = eval(self.flags, G_FLAGS) + fields_expr = [c_field.as_field_python_expr() + for c_field in self.c_fields] + return "(b'%s%s%s',%s)" % ( + format_four_bytes(self.type_index), + format_four_bytes(flags), + self.name, + ','.join(fields_expr)) + +class EnumExpr: + def __init__(self, name, type_index, size, signed, allenums): + self.name = name + self.type_index = type_index + self.size = size + self.signed = signed + self.allenums = allenums + + def as_c_expr(self): + return (' { "%s", %d, _cffi_prim_int(%s, %s),\n' + ' "%s" },' % (self.name, self.type_index, + self.size, self.signed, self.allenums)) + + def as_python_expr(self): + prim_index = { + (1, 0): PRIM_UINT8, (1, 1): PRIM_INT8, + (2, 0): PRIM_UINT16, (2, 1): PRIM_INT16, + (4, 0): PRIM_UINT32, (4, 1): PRIM_INT32, + (8, 0): PRIM_UINT64, (8, 1): PRIM_INT64, + }[self.size, self.signed] + return "b'%s%s%s\\x00%s'" % (format_four_bytes(self.type_index), + format_four_bytes(prim_index), + self.name, self.allenums) + +class TypenameExpr: + def __init__(self, name, type_index): + self.name = name + self.type_index = type_index + + def as_c_expr(self): + return ' { "%s", %d },' % (self.name, self.type_index) + + def as_python_expr(self): + return "b'%s%s'" % (format_four_bytes(self.type_index), self.name) + + +# ____________________________________________________________ + + +class Recompiler: + _num_externpy = 0 + + def __init__(self, ffi, module_name, target_is_python=False): + self.ffi = ffi + self.module_name = module_name + self.target_is_python = target_is_python + self._version = VERSION_BASE + + def needs_version(self, ver): + self._version = max(self._version, ver) + + def collect_type_table(self): + self._typesdict = {} + self._generate("collecttype") + # + all_decls = sorted(self._typesdict, key=str) + # + # prepare all FUNCTION bytecode sequences first + self.cffi_types = [] + for tp in all_decls: + if tp.is_raw_function: + assert self._typesdict[tp] is None + self._typesdict[tp] = len(self.cffi_types) + self.cffi_types.append(tp) # placeholder + for tp1 in tp.args: + assert isinstance(tp1, (model.VoidType, + model.BasePrimitiveType, + model.PointerType, + model.StructOrUnionOrEnum, + model.FunctionPtrType)) + if self._typesdict[tp1] is None: + self._typesdict[tp1] = len(self.cffi_types) + self.cffi_types.append(tp1) # placeholder + self.cffi_types.append('END') # placeholder + # + # prepare all OTHER bytecode sequences + for tp in all_decls: + if not tp.is_raw_function and self._typesdict[tp] is None: + self._typesdict[tp] = len(self.cffi_types) + self.cffi_types.append(tp) # placeholder + if tp.is_array_type and tp.length is not None: + self.cffi_types.append('LEN') # placeholder + assert None not in self._typesdict.values() + # + # collect all structs and unions and enums + self._struct_unions = {} + self._enums = {} + for tp in all_decls: + if isinstance(tp, model.StructOrUnion): + self._struct_unions[tp] = None + elif isinstance(tp, model.EnumType): + self._enums[tp] = None + for i, tp in enumerate(sorted(self._struct_unions, + key=lambda tp: tp.name)): + self._struct_unions[tp] = i + for i, tp in enumerate(sorted(self._enums, + key=lambda tp: tp.name)): + self._enums[tp] = i + # + # emit all bytecode sequences now + for tp in all_decls: + method = getattr(self, '_emit_bytecode_' + tp.__class__.__name__) + method(tp, self._typesdict[tp]) + # + # consistency check + for op in self.cffi_types: + assert isinstance(op, CffiOp) + self.cffi_types = tuple(self.cffi_types) # don't change any more + + def _do_collect_type(self, tp): + if not isinstance(tp, model.BaseTypeByIdentity): + if isinstance(tp, tuple): + for x in tp: + self._do_collect_type(x) + return + if tp not in self._typesdict: + self._typesdict[tp] = None + if isinstance(tp, model.FunctionPtrType): + self._do_collect_type(tp.as_raw_function()) + elif isinstance(tp, model.StructOrUnion): + if tp.fldtypes is not None and ( + tp not in self.ffi._parser._included_declarations): + for name1, tp1, _, _ in tp.enumfields(): + self._do_collect_type(self._field_type(tp, name1, tp1)) + else: + for _, x in tp._get_items(): + self._do_collect_type(x) + + def _generate(self, step_name): + lst = self.ffi._parser._declarations.items() + for name, (tp, quals) in sorted(lst): + kind, realname = name.split(' ', 1) + try: + method = getattr(self, '_generate_cpy_%s_%s' % (kind, + step_name)) + except AttributeError: + raise VerificationError( + "not implemented in recompile(): %r" % name) + try: + self._current_quals = quals + method(tp, realname) + except Exception as e: + model.attach_exception_info(e, name) + raise + + # ---------- + + ALL_STEPS = ["global", "field", "struct_union", "enum", "typename"] + + def collect_step_tables(self): + # collect the declarations for '_cffi_globals', '_cffi_typenames', etc. + self._lsts = {} + for step_name in self.ALL_STEPS: + self._lsts[step_name] = [] + self._seen_struct_unions = set() + self._generate("ctx") + self._add_missing_struct_unions() + # + for step_name in self.ALL_STEPS: + lst = self._lsts[step_name] + if step_name != "field": + lst.sort(key=lambda entry: entry.name) + self._lsts[step_name] = tuple(lst) # don't change any more + # + # check for a possible internal inconsistency: _cffi_struct_unions + # should have been generated with exactly self._struct_unions + lst = self._lsts["struct_union"] + for tp, i in self._struct_unions.items(): + assert i < len(lst) + assert lst[i].name == tp.name + assert len(lst) == len(self._struct_unions) + # same with enums + lst = self._lsts["enum"] + for tp, i in self._enums.items(): + assert i < len(lst) + assert lst[i].name == tp.name + assert len(lst) == len(self._enums) + + # ---------- + + def _prnt(self, what=''): + self._f.write(what + '\n') + + def write_source_to_f(self, f, preamble): + if self.target_is_python: + assert preamble is None + self.write_py_source_to_f(f) + else: + assert preamble is not None + self.write_c_source_to_f(f, preamble) + + def _rel_readlines(self, filename): + g = open(os.path.join(os.path.dirname(__file__), filename), 'r') + lines = g.readlines() + g.close() + return lines + + def write_c_source_to_f(self, f, preamble): + self._f = f + prnt = self._prnt + if self.ffi._embedding is not None: + prnt('#define _CFFI_USE_EMBEDDING') + # + # first the '#include' (actually done by inlining the file's content) + lines = self._rel_readlines('_cffi_include.h') + i = lines.index('#include "parse_c_type.h"\n') + lines[i:i+1] = self._rel_readlines('parse_c_type.h') + prnt(''.join(lines)) + # + # if we have ffi._embedding != None, we give it here as a macro + # and include an extra file + base_module_name = self.module_name.split('.')[-1] + if self.ffi._embedding is not None: + prnt('#define _CFFI_MODULE_NAME "%s"' % (self.module_name,)) + prnt('static const char _CFFI_PYTHON_STARTUP_CODE[] = {') + self._print_string_literal_in_array(self.ffi._embedding) + prnt('0 };') + prnt('#ifdef PYPY_VERSION') + prnt('# define _CFFI_PYTHON_STARTUP_FUNC _cffi_pypyinit_%s' % ( + base_module_name,)) + prnt('#elif PY_MAJOR_VERSION >= 3') + prnt('# define _CFFI_PYTHON_STARTUP_FUNC PyInit_%s' % ( + base_module_name,)) + prnt('#else') + prnt('# define _CFFI_PYTHON_STARTUP_FUNC init%s' % ( + base_module_name,)) + prnt('#endif') + lines = self._rel_readlines('_embedding.h') + i = lines.index('#include "_cffi_errors.h"\n') + lines[i:i+1] = self._rel_readlines('_cffi_errors.h') + prnt(''.join(lines)) + self.needs_version(VERSION_EMBEDDED) + # + # then paste the C source given by the user, verbatim. + prnt('/************************************************************/') + prnt() + prnt(preamble) + prnt() + prnt('/************************************************************/') + prnt() + # + # the declaration of '_cffi_types' + prnt('static void *_cffi_types[] = {') + typeindex2type = dict([(i, tp) for (tp, i) in self._typesdict.items()]) + for i, op in enumerate(self.cffi_types): + comment = '' + if i in typeindex2type: + comment = ' // ' + typeindex2type[i]._get_c_name() + prnt('/* %2d */ %s,%s' % (i, op.as_c_expr(), comment)) + if not self.cffi_types: + prnt(' 0') + prnt('};') + prnt() + # + # call generate_cpy_xxx_decl(), for every xxx found from + # ffi._parser._declarations. This generates all the functions. + self._seen_constants = set() + self._generate("decl") + # + # the declaration of '_cffi_globals' and '_cffi_typenames' + nums = {} + for step_name in self.ALL_STEPS: + lst = self._lsts[step_name] + nums[step_name] = len(lst) + if nums[step_name] > 0: + prnt('static const struct _cffi_%s_s _cffi_%ss[] = {' % ( + step_name, step_name)) + for entry in lst: + prnt(entry.as_c_expr()) + prnt('};') + prnt() + # + # the declaration of '_cffi_includes' + if self.ffi._included_ffis: + prnt('static const char * const _cffi_includes[] = {') + for ffi_to_include in self.ffi._included_ffis: + try: + included_module_name, included_source = ( + ffi_to_include._assigned_source[:2]) + except AttributeError: + raise VerificationError( + "ffi object %r includes %r, but the latter has not " + "been prepared with set_source()" % ( + self.ffi, ffi_to_include,)) + if included_source is None: + raise VerificationError( + "not implemented yet: ffi.include() of a Python-based " + "ffi inside a C-based ffi") + prnt(' "%s",' % (included_module_name,)) + prnt(' NULL') + prnt('};') + prnt() + # + # the declaration of '_cffi_type_context' + prnt('static const struct _cffi_type_context_s _cffi_type_context = {') + prnt(' _cffi_types,') + for step_name in self.ALL_STEPS: + if nums[step_name] > 0: + prnt(' _cffi_%ss,' % step_name) + else: + prnt(' NULL, /* no %ss */' % step_name) + for step_name in self.ALL_STEPS: + if step_name != "field": + prnt(' %d, /* num_%ss */' % (nums[step_name], step_name)) + if self.ffi._included_ffis: + prnt(' _cffi_includes,') + else: + prnt(' NULL, /* no includes */') + prnt(' %d, /* num_types */' % (len(self.cffi_types),)) + flags = 0 + if self._num_externpy: + flags |= 1 # set to mean that we use extern "Python" + prnt(' %d, /* flags */' % flags) + prnt('};') + prnt() + # + # the init function + prnt('#ifdef __GNUC__') + prnt('# pragma GCC visibility push(default) /* for -fvisibility= */') + prnt('#endif') + prnt() + prnt('#ifdef PYPY_VERSION') + prnt('PyMODINIT_FUNC') + prnt('_cffi_pypyinit_%s(const void *p[])' % (base_module_name,)) + prnt('{') + if self._num_externpy: + prnt(' if (((intptr_t)p[0]) >= 0x0A03) {') + prnt(' _cffi_call_python_org = ' + '(void(*)(struct _cffi_externpy_s *, char *))p[1];') + prnt(' }') + prnt(' p[0] = (const void *)0x%x;' % self._version) + prnt(' p[1] = &_cffi_type_context;') + prnt('#if PY_MAJOR_VERSION >= 3') + prnt(' return NULL;') + prnt('#endif') + prnt('}') + # on Windows, distutils insists on putting init_cffi_xyz in + # 'export_symbols', so instead of fighting it, just give up and + # give it one + prnt('# ifdef _MSC_VER') + prnt(' PyMODINIT_FUNC') + prnt('# if PY_MAJOR_VERSION >= 3') + prnt(' PyInit_%s(void) { return NULL; }' % (base_module_name,)) + prnt('# else') + prnt(' init%s(void) { }' % (base_module_name,)) + prnt('# endif') + prnt('# endif') + prnt('#elif PY_MAJOR_VERSION >= 3') + prnt('PyMODINIT_FUNC') + prnt('PyInit_%s(void)' % (base_module_name,)) + prnt('{') + prnt(' return _cffi_init("%s", 0x%x, &_cffi_type_context);' % ( + self.module_name, self._version)) + prnt('}') + prnt('#else') + prnt('PyMODINIT_FUNC') + prnt('init%s(void)' % (base_module_name,)) + prnt('{') + prnt(' _cffi_init("%s", 0x%x, &_cffi_type_context);' % ( + self.module_name, self._version)) + prnt('}') + prnt('#endif') + prnt() + prnt('#ifdef __GNUC__') + prnt('# pragma GCC visibility pop') + prnt('#endif') + self._version = None + + def _to_py(self, x): + if isinstance(x, str): + return "b'%s'" % (x,) + if isinstance(x, (list, tuple)): + rep = [self._to_py(item) for item in x] + if len(rep) == 1: + rep.append('') + return "(%s)" % (','.join(rep),) + return x.as_python_expr() # Py2: unicode unexpected; Py3: bytes unexp. + + def write_py_source_to_f(self, f): + self._f = f + prnt = self._prnt + # + # header + prnt("# auto-generated file") + prnt("import _cffi_backend") + # + # the 'import' of the included ffis + num_includes = len(self.ffi._included_ffis or ()) + for i in range(num_includes): + ffi_to_include = self.ffi._included_ffis[i] + try: + included_module_name, included_source = ( + ffi_to_include._assigned_source[:2]) + except AttributeError: + raise VerificationError( + "ffi object %r includes %r, but the latter has not " + "been prepared with set_source()" % ( + self.ffi, ffi_to_include,)) + if included_source is not None: + raise VerificationError( + "not implemented yet: ffi.include() of a C-based " + "ffi inside a Python-based ffi") + prnt('from %s import ffi as _ffi%d' % (included_module_name, i)) + prnt() + prnt("ffi = _cffi_backend.FFI('%s'," % (self.module_name,)) + prnt(" _version = 0x%x," % (self._version,)) + self._version = None + # + # the '_types' keyword argument + self.cffi_types = tuple(self.cffi_types) # don't change any more + types_lst = [op.as_python_bytes() for op in self.cffi_types] + prnt(' _types = %s,' % (self._to_py(''.join(types_lst)),)) + typeindex2type = dict([(i, tp) for (tp, i) in self._typesdict.items()]) + # + # the keyword arguments from ALL_STEPS + for step_name in self.ALL_STEPS: + lst = self._lsts[step_name] + if len(lst) > 0 and step_name != "field": + prnt(' _%ss = %s,' % (step_name, self._to_py(lst))) + # + # the '_includes' keyword argument + if num_includes > 0: + prnt(' _includes = (%s,),' % ( + ', '.join(['_ffi%d' % i for i in range(num_includes)]),)) + # + # the footer + prnt(')') + + # ---------- + + def _gettypenum(self, type): + # a KeyError here is a bug. please report it! :-) + return self._typesdict[type] + + def _convert_funcarg_to_c(self, tp, fromvar, tovar, errcode): + extraarg = '' + if isinstance(tp, model.BasePrimitiveType) and not tp.is_complex_type(): + if tp.is_integer_type() and tp.name != '_Bool': + converter = '_cffi_to_c_int' + extraarg = ', %s' % tp.name + elif isinstance(tp, model.UnknownFloatType): + # don't check with is_float_type(): it may be a 'long + # double' here, and _cffi_to_c_double would loose precision + converter = '(%s)_cffi_to_c_double' % (tp.get_c_name(''),) + else: + cname = tp.get_c_name('') + converter = '(%s)_cffi_to_c_%s' % (cname, + tp.name.replace(' ', '_')) + if cname in ('char16_t', 'char32_t'): + self.needs_version(VERSION_CHAR16CHAR32) + errvalue = '-1' + # + elif isinstance(tp, model.PointerType): + self._convert_funcarg_to_c_ptr_or_array(tp, fromvar, + tovar, errcode) + return + # + elif (isinstance(tp, model.StructOrUnionOrEnum) or + isinstance(tp, model.BasePrimitiveType)): + # a struct (not a struct pointer) as a function argument; + # or, a complex (the same code works) + self._prnt(' if (_cffi_to_c((char *)&%s, _cffi_type(%d), %s) < 0)' + % (tovar, self._gettypenum(tp), fromvar)) + self._prnt(' %s;' % errcode) + return + # + elif isinstance(tp, model.FunctionPtrType): + converter = '(%s)_cffi_to_c_pointer' % tp.get_c_name('') + extraarg = ', _cffi_type(%d)' % self._gettypenum(tp) + errvalue = 'NULL' + # + else: + raise NotImplementedError(tp) + # + self._prnt(' %s = %s(%s%s);' % (tovar, converter, fromvar, extraarg)) + self._prnt(' if (%s == (%s)%s && PyErr_Occurred())' % ( + tovar, tp.get_c_name(''), errvalue)) + self._prnt(' %s;' % errcode) + + def _extra_local_variables(self, tp, localvars): + if isinstance(tp, model.PointerType): + localvars.add('Py_ssize_t datasize') + + def _convert_funcarg_to_c_ptr_or_array(self, tp, fromvar, tovar, errcode): + self._prnt(' datasize = _cffi_prepare_pointer_call_argument(') + self._prnt(' _cffi_type(%d), %s, (char **)&%s);' % ( + self._gettypenum(tp), fromvar, tovar)) + self._prnt(' if (datasize != 0) {') + self._prnt(' if (datasize < 0)') + self._prnt(' %s;' % errcode) + self._prnt(' %s = (%s)alloca((size_t)datasize);' % ( + tovar, tp.get_c_name(''))) + self._prnt(' memset((void *)%s, 0, (size_t)datasize);' % (tovar,)) + self._prnt(' if (_cffi_convert_array_from_object(' + '(char *)%s, _cffi_type(%d), %s) < 0)' % ( + tovar, self._gettypenum(tp), fromvar)) + self._prnt(' %s;' % errcode) + self._prnt(' }') + + def _convert_expr_from_c(self, tp, var, context): + if isinstance(tp, model.BasePrimitiveType): + if tp.is_integer_type() and tp.name != '_Bool': + return '_cffi_from_c_int(%s, %s)' % (var, tp.name) + elif isinstance(tp, model.UnknownFloatType): + return '_cffi_from_c_double(%s)' % (var,) + elif tp.name != 'long double' and not tp.is_complex_type(): + cname = tp.name.replace(' ', '_') + if cname in ('char16_t', 'char32_t'): + self.needs_version(VERSION_CHAR16CHAR32) + return '_cffi_from_c_%s(%s)' % (cname, var) + else: + return '_cffi_from_c_deref((char *)&%s, _cffi_type(%d))' % ( + var, self._gettypenum(tp)) + elif isinstance(tp, (model.PointerType, model.FunctionPtrType)): + return '_cffi_from_c_pointer((char *)%s, _cffi_type(%d))' % ( + var, self._gettypenum(tp)) + elif isinstance(tp, model.ArrayType): + return '_cffi_from_c_pointer((char *)%s, _cffi_type(%d))' % ( + var, self._gettypenum(model.PointerType(tp.item))) + elif isinstance(tp, model.StructOrUnion): + if tp.fldnames is None: + raise TypeError("'%s' is used as %s, but is opaque" % ( + tp._get_c_name(), context)) + return '_cffi_from_c_struct((char *)&%s, _cffi_type(%d))' % ( + var, self._gettypenum(tp)) + elif isinstance(tp, model.EnumType): + return '_cffi_from_c_deref((char *)&%s, _cffi_type(%d))' % ( + var, self._gettypenum(tp)) + else: + raise NotImplementedError(tp) + + # ---------- + # typedefs + + def _typedef_type(self, tp, name): + return self._global_type(tp, "(*(%s *)0)" % (name,)) + + def _generate_cpy_typedef_collecttype(self, tp, name): + self._do_collect_type(self._typedef_type(tp, name)) + + def _generate_cpy_typedef_decl(self, tp, name): + pass + + def _typedef_ctx(self, tp, name): + type_index = self._typesdict[tp] + self._lsts["typename"].append(TypenameExpr(name, type_index)) + + def _generate_cpy_typedef_ctx(self, tp, name): + tp = self._typedef_type(tp, name) + self._typedef_ctx(tp, name) + if getattr(tp, "origin", None) == "unknown_type": + self._struct_ctx(tp, tp.name, approxname=None) + elif isinstance(tp, model.NamedPointerType): + self._struct_ctx(tp.totype, tp.totype.name, approxname=tp.name, + named_ptr=tp) + + # ---------- + # function declarations + + def _generate_cpy_function_collecttype(self, tp, name): + self._do_collect_type(tp.as_raw_function()) + if tp.ellipsis and not self.target_is_python: + self._do_collect_type(tp) + + def _generate_cpy_function_decl(self, tp, name): + assert not self.target_is_python + assert isinstance(tp, model.FunctionPtrType) + if tp.ellipsis: + # cannot support vararg functions better than this: check for its + # exact type (including the fixed arguments), and build it as a + # constant function pointer (no CPython wrapper) + self._generate_cpy_constant_decl(tp, name) + return + prnt = self._prnt + numargs = len(tp.args) + if numargs == 0: + argname = 'noarg' + elif numargs == 1: + argname = 'arg0' + else: + argname = 'args' + # + # ------------------------------ + # the 'd' version of the function, only for addressof(lib, 'func') + arguments = [] + call_arguments = [] + context = 'argument of %s' % name + for i, type in enumerate(tp.args): + arguments.append(type.get_c_name(' x%d' % i, context)) + call_arguments.append('x%d' % i) + repr_arguments = ', '.join(arguments) + repr_arguments = repr_arguments or 'void' + if tp.abi: + abi = tp.abi + ' ' + else: + abi = '' + name_and_arguments = '%s_cffi_d_%s(%s)' % (abi, name, repr_arguments) + prnt('static %s' % (tp.result.get_c_name(name_and_arguments),)) + prnt('{') + call_arguments = ', '.join(call_arguments) + result_code = 'return ' + if isinstance(tp.result, model.VoidType): + result_code = '' + prnt(' %s%s(%s);' % (result_code, name, call_arguments)) + prnt('}') + # + prnt('#ifndef PYPY_VERSION') # ------------------------------ + # + prnt('static PyObject *') + prnt('_cffi_f_%s(PyObject *self, PyObject *%s)' % (name, argname)) + prnt('{') + # + context = 'argument of %s' % name + for i, type in enumerate(tp.args): + arg = type.get_c_name(' x%d' % i, context) + prnt(' %s;' % arg) + # + localvars = set() + for type in tp.args: + self._extra_local_variables(type, localvars) + for decl in localvars: + prnt(' %s;' % (decl,)) + # + if not isinstance(tp.result, model.VoidType): + result_code = 'result = ' + context = 'result of %s' % name + result_decl = ' %s;' % tp.result.get_c_name(' result', context) + prnt(result_decl) + else: + result_decl = None + result_code = '' + # + if len(tp.args) > 1: + rng = range(len(tp.args)) + for i in rng: + prnt(' PyObject *arg%d;' % i) + prnt() + prnt(' if (!PyArg_UnpackTuple(args, "%s", %d, %d, %s))' % ( + name, len(rng), len(rng), + ', '.join(['&arg%d' % i for i in rng]))) + prnt(' return NULL;') + prnt() + # + for i, type in enumerate(tp.args): + self._convert_funcarg_to_c(type, 'arg%d' % i, 'x%d' % i, + 'return NULL') + prnt() + # + prnt(' Py_BEGIN_ALLOW_THREADS') + prnt(' _cffi_restore_errno();') + call_arguments = ['x%d' % i for i in range(len(tp.args))] + call_arguments = ', '.join(call_arguments) + prnt(' { %s%s(%s); }' % (result_code, name, call_arguments)) + prnt(' _cffi_save_errno();') + prnt(' Py_END_ALLOW_THREADS') + prnt() + # + prnt(' (void)self; /* unused */') + if numargs == 0: + prnt(' (void)noarg; /* unused */') + if result_code: + prnt(' return %s;' % + self._convert_expr_from_c(tp.result, 'result', 'result type')) + else: + prnt(' Py_INCREF(Py_None);') + prnt(' return Py_None;') + prnt('}') + # + prnt('#else') # ------------------------------ + # + # the PyPy version: need to replace struct/union arguments with + # pointers, and if the result is a struct/union, insert a first + # arg that is a pointer to the result. We also do that for + # complex args and return type. + def need_indirection(type): + return (isinstance(type, model.StructOrUnion) or + (isinstance(type, model.PrimitiveType) and + type.is_complex_type())) + difference = False + arguments = [] + call_arguments = [] + context = 'argument of %s' % name + for i, type in enumerate(tp.args): + indirection = '' + if need_indirection(type): + indirection = '*' + difference = True + arg = type.get_c_name(' %sx%d' % (indirection, i), context) + arguments.append(arg) + call_arguments.append('%sx%d' % (indirection, i)) + tp_result = tp.result + if need_indirection(tp_result): + context = 'result of %s' % name + arg = tp_result.get_c_name(' *result', context) + arguments.insert(0, arg) + tp_result = model.void_type + result_decl = None + result_code = '*result = ' + difference = True + if difference: + repr_arguments = ', '.join(arguments) + repr_arguments = repr_arguments or 'void' + name_and_arguments = '%s_cffi_f_%s(%s)' % (abi, name, + repr_arguments) + prnt('static %s' % (tp_result.get_c_name(name_and_arguments),)) + prnt('{') + if result_decl: + prnt(result_decl) + call_arguments = ', '.join(call_arguments) + prnt(' { %s%s(%s); }' % (result_code, name, call_arguments)) + if result_decl: + prnt(' return result;') + prnt('}') + else: + prnt('# define _cffi_f_%s _cffi_d_%s' % (name, name)) + # + prnt('#endif') # ------------------------------ + prnt() + + def _generate_cpy_function_ctx(self, tp, name): + if tp.ellipsis and not self.target_is_python: + self._generate_cpy_constant_ctx(tp, name) + return + type_index = self._typesdict[tp.as_raw_function()] + numargs = len(tp.args) + if self.target_is_python: + meth_kind = OP_DLOPEN_FUNC + elif numargs == 0: + meth_kind = OP_CPYTHON_BLTN_N # 'METH_NOARGS' + elif numargs == 1: + meth_kind = OP_CPYTHON_BLTN_O # 'METH_O' + else: + meth_kind = OP_CPYTHON_BLTN_V # 'METH_VARARGS' + self._lsts["global"].append( + GlobalExpr(name, '_cffi_f_%s' % name, + CffiOp(meth_kind, type_index), + size='_cffi_d_%s' % name)) + + # ---------- + # named structs or unions + + def _field_type(self, tp_struct, field_name, tp_field): + if isinstance(tp_field, model.ArrayType): + actual_length = tp_field.length + if actual_length == '...': + ptr_struct_name = tp_struct.get_c_name('*') + actual_length = '_cffi_array_len(((%s)0)->%s)' % ( + ptr_struct_name, field_name) + tp_item = self._field_type(tp_struct, '%s[0]' % field_name, + tp_field.item) + tp_field = model.ArrayType(tp_item, actual_length) + return tp_field + + def _struct_collecttype(self, tp): + self._do_collect_type(tp) + if self.target_is_python: + # also requires nested anon struct/unions in ABI mode, recursively + for fldtype in tp.anonymous_struct_fields(): + self._struct_collecttype(fldtype) + + def _struct_decl(self, tp, cname, approxname): + if tp.fldtypes is None: + return + prnt = self._prnt + checkfuncname = '_cffi_checkfld_%s' % (approxname,) + prnt('_CFFI_UNUSED_FN') + prnt('static void %s(%s *p)' % (checkfuncname, cname)) + prnt('{') + prnt(' /* only to generate compile-time warnings or errors */') + prnt(' (void)p;') + for fname, ftype, fbitsize, fqual in tp.enumfields(): + try: + if ftype.is_integer_type() or fbitsize >= 0: + # accept all integers, but complain on float or double + if fname != '': + prnt(" (void)((p->%s) | 0); /* check that '%s.%s' is " + "an integer */" % (fname, cname, fname)) + continue + # only accept exactly the type declared, except that '[]' + # is interpreted as a '*' and so will match any array length. + # (It would also match '*', but that's harder to detect...) + while (isinstance(ftype, model.ArrayType) + and (ftype.length is None or ftype.length == '...')): + ftype = ftype.item + fname = fname + '[0]' + prnt(' { %s = &p->%s; (void)tmp; }' % ( + ftype.get_c_name('*tmp', 'field %r'%fname, quals=fqual), + fname)) + except VerificationError as e: + prnt(' /* %s */' % str(e)) # cannot verify it, ignore + prnt('}') + prnt('struct _cffi_align_%s { char x; %s y; };' % (approxname, cname)) + prnt() + + def _struct_ctx(self, tp, cname, approxname, named_ptr=None): + type_index = self._typesdict[tp] + reason_for_not_expanding = None + flags = [] + if isinstance(tp, model.UnionType): + flags.append("_CFFI_F_UNION") + if tp.fldtypes is None: + flags.append("_CFFI_F_OPAQUE") + reason_for_not_expanding = "opaque" + if (tp not in self.ffi._parser._included_declarations and + (named_ptr is None or + named_ptr not in self.ffi._parser._included_declarations)): + if tp.fldtypes is None: + pass # opaque + elif tp.partial or any(tp.anonymous_struct_fields()): + pass # field layout obtained silently from the C compiler + else: + flags.append("_CFFI_F_CHECK_FIELDS") + if tp.packed: + if tp.packed > 1: + raise NotImplementedError( + "%r is declared with 'pack=%r'; only 0 or 1 are " + "supported in API mode (try to use \"...;\", which " + "does not require a 'pack' declaration)" % + (tp, tp.packed)) + flags.append("_CFFI_F_PACKED") + else: + flags.append("_CFFI_F_EXTERNAL") + reason_for_not_expanding = "external" + flags = '|'.join(flags) or '0' + c_fields = [] + if reason_for_not_expanding is None: + expand_anonymous_struct_union = not self.target_is_python + enumfields = list(tp.enumfields(expand_anonymous_struct_union)) + for fldname, fldtype, fbitsize, fqual in enumfields: + fldtype = self._field_type(tp, fldname, fldtype) + self._check_not_opaque(fldtype, + "field '%s.%s'" % (tp.name, fldname)) + # cname is None for _add_missing_struct_unions() only + op = OP_NOOP + if fbitsize >= 0: + op = OP_BITFIELD + size = '%d /* bits */' % fbitsize + elif cname is None or ( + isinstance(fldtype, model.ArrayType) and + fldtype.length is None): + size = '(size_t)-1' + else: + size = 'sizeof(((%s)0)->%s)' % ( + tp.get_c_name('*') if named_ptr is None + else named_ptr.name, + fldname) + if cname is None or fbitsize >= 0: + offset = '(size_t)-1' + elif named_ptr is not None: + offset = '((char *)&((%s)0)->%s) - (char *)0' % ( + named_ptr.name, fldname) + else: + offset = 'offsetof(%s, %s)' % (tp.get_c_name(''), fldname) + c_fields.append( + FieldExpr(fldname, offset, size, fbitsize, + CffiOp(op, self._typesdict[fldtype]))) + first_field_index = len(self._lsts["field"]) + self._lsts["field"].extend(c_fields) + # + if cname is None: # unknown name, for _add_missing_struct_unions + size = '(size_t)-2' + align = -2 + comment = "unnamed" + else: + if named_ptr is not None: + size = 'sizeof(*(%s)0)' % (named_ptr.name,) + align = '-1 /* unknown alignment */' + else: + size = 'sizeof(%s)' % (cname,) + align = 'offsetof(struct _cffi_align_%s, y)' % (approxname,) + comment = None + else: + size = '(size_t)-1' + align = -1 + first_field_index = -1 + comment = reason_for_not_expanding + self._lsts["struct_union"].append( + StructUnionExpr(tp.name, type_index, flags, size, align, comment, + first_field_index, c_fields)) + self._seen_struct_unions.add(tp) + + def _check_not_opaque(self, tp, location): + while isinstance(tp, model.ArrayType): + tp = tp.item + if isinstance(tp, model.StructOrUnion) and tp.fldtypes is None: + raise TypeError( + "%s is of an opaque type (not declared in cdef())" % location) + + def _add_missing_struct_unions(self): + # not very nice, but some struct declarations might be missing + # because they don't have any known C name. Check that they are + # not partial (we can't complete or verify them!) and emit them + # anonymously. + lst = list(self._struct_unions.items()) + lst.sort(key=lambda tp_order: tp_order[1]) + for tp, order in lst: + if tp not in self._seen_struct_unions: + if tp.partial: + raise NotImplementedError("internal inconsistency: %r is " + "partial but was not seen at " + "this point" % (tp,)) + if tp.name.startswith('$') and tp.name[1:].isdigit(): + approxname = tp.name[1:] + elif tp.name == '_IO_FILE' and tp.forcename == 'FILE': + approxname = 'FILE' + self._typedef_ctx(tp, 'FILE') + else: + raise NotImplementedError("internal inconsistency: %r" % + (tp,)) + self._struct_ctx(tp, None, approxname) + + def _generate_cpy_struct_collecttype(self, tp, name): + self._struct_collecttype(tp) + _generate_cpy_union_collecttype = _generate_cpy_struct_collecttype + + def _struct_names(self, tp): + cname = tp.get_c_name('') + if ' ' in cname: + return cname, cname.replace(' ', '_') + else: + return cname, '_' + cname + + def _generate_cpy_struct_decl(self, tp, name): + self._struct_decl(tp, *self._struct_names(tp)) + _generate_cpy_union_decl = _generate_cpy_struct_decl + + def _generate_cpy_struct_ctx(self, tp, name): + self._struct_ctx(tp, *self._struct_names(tp)) + _generate_cpy_union_ctx = _generate_cpy_struct_ctx + + # ---------- + # 'anonymous' declarations. These are produced for anonymous structs + # or unions; the 'name' is obtained by a typedef. + + def _generate_cpy_anonymous_collecttype(self, tp, name): + if isinstance(tp, model.EnumType): + self._generate_cpy_enum_collecttype(tp, name) + else: + self._struct_collecttype(tp) + + def _generate_cpy_anonymous_decl(self, tp, name): + if isinstance(tp, model.EnumType): + self._generate_cpy_enum_decl(tp) + else: + self._struct_decl(tp, name, 'typedef_' + name) + + def _generate_cpy_anonymous_ctx(self, tp, name): + if isinstance(tp, model.EnumType): + self._enum_ctx(tp, name) + else: + self._struct_ctx(tp, name, 'typedef_' + name) + + # ---------- + # constants, declared with "static const ..." + + def _generate_cpy_const(self, is_int, name, tp=None, category='const', + check_value=None): + if (category, name) in self._seen_constants: + raise VerificationError( + "duplicate declaration of %s '%s'" % (category, name)) + self._seen_constants.add((category, name)) + # + prnt = self._prnt + funcname = '_cffi_%s_%s' % (category, name) + if is_int: + prnt('static int %s(unsigned long long *o)' % funcname) + prnt('{') + prnt(' int n = (%s) <= 0;' % (name,)) + prnt(' *o = (unsigned long long)((%s) | 0);' + ' /* check that %s is an integer */' % (name, name)) + if check_value is not None: + if check_value > 0: + check_value = '%dU' % (check_value,) + prnt(' if (!_cffi_check_int(*o, n, %s))' % (check_value,)) + prnt(' n |= 2;') + prnt(' return n;') + prnt('}') + else: + assert check_value is None + prnt('static void %s(char *o)' % funcname) + prnt('{') + prnt(' *(%s)o = %s;' % (tp.get_c_name('*'), name)) + prnt('}') + prnt() + + def _generate_cpy_constant_collecttype(self, tp, name): + is_int = tp.is_integer_type() + if not is_int or self.target_is_python: + self._do_collect_type(tp) + + def _generate_cpy_constant_decl(self, tp, name): + is_int = tp.is_integer_type() + self._generate_cpy_const(is_int, name, tp) + + def _generate_cpy_constant_ctx(self, tp, name): + if not self.target_is_python and tp.is_integer_type(): + type_op = CffiOp(OP_CONSTANT_INT, -1) + else: + if self.target_is_python: + const_kind = OP_DLOPEN_CONST + else: + const_kind = OP_CONSTANT + type_index = self._typesdict[tp] + type_op = CffiOp(const_kind, type_index) + self._lsts["global"].append( + GlobalExpr(name, '_cffi_const_%s' % name, type_op)) + + # ---------- + # enums + + def _generate_cpy_enum_collecttype(self, tp, name): + self._do_collect_type(tp) + + def _generate_cpy_enum_decl(self, tp, name=None): + for enumerator in tp.enumerators: + self._generate_cpy_const(True, enumerator) + + def _enum_ctx(self, tp, cname): + type_index = self._typesdict[tp] + type_op = CffiOp(OP_ENUM, -1) + if self.target_is_python: + tp.check_not_partial() + for enumerator, enumvalue in zip(tp.enumerators, tp.enumvalues): + self._lsts["global"].append( + GlobalExpr(enumerator, '_cffi_const_%s' % enumerator, type_op, + check_value=enumvalue)) + # + if cname is not None and '$' not in cname and not self.target_is_python: + size = "sizeof(%s)" % cname + signed = "((%s)-1) <= 0" % cname + else: + basetp = tp.build_baseinttype(self.ffi, []) + size = self.ffi.sizeof(basetp) + signed = int(int(self.ffi.cast(basetp, -1)) < 0) + allenums = ",".join(tp.enumerators) + self._lsts["enum"].append( + EnumExpr(tp.name, type_index, size, signed, allenums)) + + def _generate_cpy_enum_ctx(self, tp, name): + self._enum_ctx(tp, tp._get_c_name()) + + # ---------- + # macros: for now only for integers + + def _generate_cpy_macro_collecttype(self, tp, name): + pass + + def _generate_cpy_macro_decl(self, tp, name): + if tp == '...': + check_value = None + else: + check_value = tp # an integer + self._generate_cpy_const(True, name, check_value=check_value) + + def _generate_cpy_macro_ctx(self, tp, name): + if tp == '...': + if self.target_is_python: + raise VerificationError( + "cannot use the syntax '...' in '#define %s ...' when " + "using the ABI mode" % (name,)) + check_value = None + else: + check_value = tp # an integer + type_op = CffiOp(OP_CONSTANT_INT, -1) + self._lsts["global"].append( + GlobalExpr(name, '_cffi_const_%s' % name, type_op, + check_value=check_value)) + + # ---------- + # global variables + + def _global_type(self, tp, global_name): + if isinstance(tp, model.ArrayType): + actual_length = tp.length + if actual_length == '...': + actual_length = '_cffi_array_len(%s)' % (global_name,) + tp_item = self._global_type(tp.item, '%s[0]' % global_name) + tp = model.ArrayType(tp_item, actual_length) + return tp + + def _generate_cpy_variable_collecttype(self, tp, name): + self._do_collect_type(self._global_type(tp, name)) + + def _generate_cpy_variable_decl(self, tp, name): + prnt = self._prnt + tp = self._global_type(tp, name) + if isinstance(tp, model.ArrayType) and tp.length is None: + tp = tp.item + ampersand = '' + else: + ampersand = '&' + # This code assumes that casts from "tp *" to "void *" is a + # no-op, i.e. a function that returns a "tp *" can be called + # as if it returned a "void *". This should be generally true + # on any modern machine. The only exception to that rule (on + # uncommon architectures, and as far as I can tell) might be + # if 'tp' were a function type, but that is not possible here. + # (If 'tp' is a function _pointer_ type, then casts from "fn_t + # **" to "void *" are again no-ops, as far as I can tell.) + decl = '*_cffi_var_%s(void)' % (name,) + prnt('static ' + tp.get_c_name(decl, quals=self._current_quals)) + prnt('{') + prnt(' return %s(%s);' % (ampersand, name)) + prnt('}') + prnt() + + def _generate_cpy_variable_ctx(self, tp, name): + tp = self._global_type(tp, name) + type_index = self._typesdict[tp] + if self.target_is_python: + op = OP_GLOBAL_VAR + else: + op = OP_GLOBAL_VAR_F + self._lsts["global"].append( + GlobalExpr(name, '_cffi_var_%s' % name, CffiOp(op, type_index))) + + # ---------- + # extern "Python" + + def _generate_cpy_extern_python_collecttype(self, tp, name): + assert isinstance(tp, model.FunctionPtrType) + self._do_collect_type(tp) + _generate_cpy_dllexport_python_collecttype = \ + _generate_cpy_extern_python_plus_c_collecttype = \ + _generate_cpy_extern_python_collecttype + + def _extern_python_decl(self, tp, name, tag_and_space): + prnt = self._prnt + if isinstance(tp.result, model.VoidType): + size_of_result = '0' + else: + context = 'result of %s' % name + size_of_result = '(int)sizeof(%s)' % ( + tp.result.get_c_name('', context),) + prnt('static struct _cffi_externpy_s _cffi_externpy__%s =' % name) + prnt(' { "%s.%s", %s };' % (self.module_name, name, size_of_result)) + prnt() + # + arguments = [] + context = 'argument of %s' % name + for i, type in enumerate(tp.args): + arg = type.get_c_name(' a%d' % i, context) + arguments.append(arg) + # + repr_arguments = ', '.join(arguments) + repr_arguments = repr_arguments or 'void' + name_and_arguments = '%s(%s)' % (name, repr_arguments) + if tp.abi == "__stdcall": + name_and_arguments = '_cffi_stdcall ' + name_and_arguments + # + def may_need_128_bits(tp): + return (isinstance(tp, model.PrimitiveType) and + tp.name == 'long double') + # + size_of_a = max(len(tp.args)*8, 8) + if may_need_128_bits(tp.result): + size_of_a = max(size_of_a, 16) + if isinstance(tp.result, model.StructOrUnion): + size_of_a = 'sizeof(%s) > %d ? sizeof(%s) : %d' % ( + tp.result.get_c_name(''), size_of_a, + tp.result.get_c_name(''), size_of_a) + prnt('%s%s' % (tag_and_space, tp.result.get_c_name(name_and_arguments))) + prnt('{') + prnt(' char a[%s];' % size_of_a) + prnt(' char *p = a;') + for i, type in enumerate(tp.args): + arg = 'a%d' % i + if (isinstance(type, model.StructOrUnion) or + may_need_128_bits(type)): + arg = '&' + arg + type = model.PointerType(type) + prnt(' *(%s)(p + %d) = %s;' % (type.get_c_name('*'), i*8, arg)) + prnt(' _cffi_call_python(&_cffi_externpy__%s, p);' % name) + if not isinstance(tp.result, model.VoidType): + prnt(' return *(%s)p;' % (tp.result.get_c_name('*'),)) + prnt('}') + prnt() + self._num_externpy += 1 + + def _generate_cpy_extern_python_decl(self, tp, name): + self._extern_python_decl(tp, name, 'static ') + + def _generate_cpy_dllexport_python_decl(self, tp, name): + self._extern_python_decl(tp, name, 'CFFI_DLLEXPORT ') + + def _generate_cpy_extern_python_plus_c_decl(self, tp, name): + self._extern_python_decl(tp, name, '') + + def _generate_cpy_extern_python_ctx(self, tp, name): + if self.target_is_python: + raise VerificationError( + "cannot use 'extern \"Python\"' in the ABI mode") + if tp.ellipsis: + raise NotImplementedError("a vararg function is extern \"Python\"") + type_index = self._typesdict[tp] + type_op = CffiOp(OP_EXTERN_PYTHON, type_index) + self._lsts["global"].append( + GlobalExpr(name, '&_cffi_externpy__%s' % name, type_op, name)) + + _generate_cpy_dllexport_python_ctx = \ + _generate_cpy_extern_python_plus_c_ctx = \ + _generate_cpy_extern_python_ctx + + def _print_string_literal_in_array(self, s): + prnt = self._prnt + prnt('// # NB. this is not a string because of a size limit in MSVC') + for line in s.splitlines(True): + prnt(('// ' + line).rstrip()) + printed_line = '' + for c in line: + if len(printed_line) >= 76: + prnt(printed_line) + printed_line = '' + printed_line += '%d,' % (ord(c),) + prnt(printed_line) + + # ---------- + # emitting the opcodes for individual types + + def _emit_bytecode_VoidType(self, tp, index): + self.cffi_types[index] = CffiOp(OP_PRIMITIVE, PRIM_VOID) + + def _emit_bytecode_PrimitiveType(self, tp, index): + prim_index = PRIMITIVE_TO_INDEX[tp.name] + self.cffi_types[index] = CffiOp(OP_PRIMITIVE, prim_index) + + def _emit_bytecode_UnknownIntegerType(self, tp, index): + s = ('_cffi_prim_int(sizeof(%s), (\n' + ' ((%s)-1) | 0 /* check that %s is an integer type */\n' + ' ) <= 0)' % (tp.name, tp.name, tp.name)) + self.cffi_types[index] = CffiOp(OP_PRIMITIVE, s) + + def _emit_bytecode_UnknownFloatType(self, tp, index): + s = ('_cffi_prim_float(sizeof(%s) *\n' + ' (((%s)1) / 2) * 2 /* integer => 0, float => 1 */\n' + ' )' % (tp.name, tp.name)) + self.cffi_types[index] = CffiOp(OP_PRIMITIVE, s) + + def _emit_bytecode_RawFunctionType(self, tp, index): + self.cffi_types[index] = CffiOp(OP_FUNCTION, self._typesdict[tp.result]) + index += 1 + for tp1 in tp.args: + realindex = self._typesdict[tp1] + if index != realindex: + if isinstance(tp1, model.PrimitiveType): + self._emit_bytecode_PrimitiveType(tp1, index) + else: + self.cffi_types[index] = CffiOp(OP_NOOP, realindex) + index += 1 + flags = int(tp.ellipsis) + if tp.abi is not None: + if tp.abi == '__stdcall': + flags |= 2 + else: + raise NotImplementedError("abi=%r" % (tp.abi,)) + self.cffi_types[index] = CffiOp(OP_FUNCTION_END, flags) + + def _emit_bytecode_PointerType(self, tp, index): + self.cffi_types[index] = CffiOp(OP_POINTER, self._typesdict[tp.totype]) + + _emit_bytecode_ConstPointerType = _emit_bytecode_PointerType + _emit_bytecode_NamedPointerType = _emit_bytecode_PointerType + + def _emit_bytecode_FunctionPtrType(self, tp, index): + raw = tp.as_raw_function() + self.cffi_types[index] = CffiOp(OP_POINTER, self._typesdict[raw]) + + def _emit_bytecode_ArrayType(self, tp, index): + item_index = self._typesdict[tp.item] + if tp.length is None: + self.cffi_types[index] = CffiOp(OP_OPEN_ARRAY, item_index) + elif tp.length == '...': + raise VerificationError( + "type %s badly placed: the '...' array length can only be " + "used on global arrays or on fields of structures" % ( + str(tp).replace('/*...*/', '...'),)) + else: + assert self.cffi_types[index + 1] == 'LEN' + self.cffi_types[index] = CffiOp(OP_ARRAY, item_index) + self.cffi_types[index + 1] = CffiOp(None, str(tp.length)) + + def _emit_bytecode_StructType(self, tp, index): + struct_index = self._struct_unions[tp] + self.cffi_types[index] = CffiOp(OP_STRUCT_UNION, struct_index) + _emit_bytecode_UnionType = _emit_bytecode_StructType + + def _emit_bytecode_EnumType(self, tp, index): + enum_index = self._enums[tp] + self.cffi_types[index] = CffiOp(OP_ENUM, enum_index) + + +if sys.version_info >= (3,): + NativeIO = io.StringIO +else: + class NativeIO(io.BytesIO): + def write(self, s): + if isinstance(s, unicode): + s = s.encode('ascii') + super(NativeIO, self).write(s) + +def _make_c_or_py_source(ffi, module_name, preamble, target_file, verbose): + if verbose: + print("generating %s" % (target_file,)) + recompiler = Recompiler(ffi, module_name, + target_is_python=(preamble is None)) + recompiler.collect_type_table() + recompiler.collect_step_tables() + f = NativeIO() + recompiler.write_source_to_f(f, preamble) + output = f.getvalue() + try: + with open(target_file, 'r') as f1: + if f1.read(len(output) + 1) != output: + raise IOError + if verbose: + print("(already up-to-date)") + return False # already up-to-date + except IOError: + tmp_file = '%s.~%d' % (target_file, os.getpid()) + with open(tmp_file, 'w') as f1: + f1.write(output) + try: + os.rename(tmp_file, target_file) + except OSError: + os.unlink(target_file) + os.rename(tmp_file, target_file) + return True + +def make_c_source(ffi, module_name, preamble, target_c_file, verbose=False): + assert preamble is not None + return _make_c_or_py_source(ffi, module_name, preamble, target_c_file, + verbose) + +def make_py_source(ffi, module_name, target_py_file, verbose=False): + return _make_c_or_py_source(ffi, module_name, None, target_py_file, + verbose) + +def _modname_to_file(outputdir, modname, extension): + parts = modname.split('.') + try: + os.makedirs(os.path.join(outputdir, *parts[:-1])) + except OSError: + pass + parts[-1] += extension + return os.path.join(outputdir, *parts), parts + + +# Aaargh. Distutils is not tested at all for the purpose of compiling +# DLLs that are not extension modules. Here are some hacks to work +# around that, in the _patch_for_*() functions... + +def _patch_meth(patchlist, cls, name, new_meth): + old = getattr(cls, name) + patchlist.append((cls, name, old)) + setattr(cls, name, new_meth) + return old + +def _unpatch_meths(patchlist): + for cls, name, old_meth in reversed(patchlist): + setattr(cls, name, old_meth) + +def _patch_for_embedding(patchlist): + if sys.platform == 'win32': + # we must not remove the manifest when building for embedding! + from distutils.msvc9compiler import MSVCCompiler + _patch_meth(patchlist, MSVCCompiler, '_remove_visual_c_ref', + lambda self, manifest_file: manifest_file) + + if sys.platform == 'darwin': + # we must not make a '-bundle', but a '-dynamiclib' instead + from distutils.ccompiler import CCompiler + def my_link_shared_object(self, *args, **kwds): + if '-bundle' in self.linker_so: + self.linker_so = list(self.linker_so) + i = self.linker_so.index('-bundle') + self.linker_so[i] = '-dynamiclib' + return old_link_shared_object(self, *args, **kwds) + old_link_shared_object = _patch_meth(patchlist, CCompiler, + 'link_shared_object', + my_link_shared_object) + +def _patch_for_target(patchlist, target): + from distutils.command.build_ext import build_ext + # if 'target' is different from '*', we need to patch some internal + # method to just return this 'target' value, instead of having it + # built from module_name + if target.endswith('.*'): + target = target[:-2] + if sys.platform == 'win32': + target += '.dll' + elif sys.platform == 'darwin': + target += '.dylib' + else: + target += '.so' + _patch_meth(patchlist, build_ext, 'get_ext_filename', + lambda self, ext_name: target) + + +def recompile(ffi, module_name, preamble, tmpdir='.', call_c_compiler=True, + c_file=None, source_extension='.c', extradir=None, + compiler_verbose=1, target=None, debug=None, **kwds): + if not isinstance(module_name, str): + module_name = module_name.encode('ascii') + if ffi._windows_unicode: + ffi._apply_windows_unicode(kwds) + if preamble is not None: + embedding = (ffi._embedding is not None) + if embedding: + ffi._apply_embedding_fix(kwds) + if c_file is None: + c_file, parts = _modname_to_file(tmpdir, module_name, + source_extension) + if extradir: + parts = [extradir] + parts + ext_c_file = os.path.join(*parts) + else: + ext_c_file = c_file + # + if target is None: + if embedding: + target = '%s.*' % module_name + else: + target = '*' + # + ext = ffiplatform.get_extension(ext_c_file, module_name, **kwds) + updated = make_c_source(ffi, module_name, preamble, c_file, + verbose=compiler_verbose) + if call_c_compiler: + patchlist = [] + cwd = os.getcwd() + try: + if embedding: + _patch_for_embedding(patchlist) + if target != '*': + _patch_for_target(patchlist, target) + if compiler_verbose: + if tmpdir == '.': + msg = 'the current directory is' + else: + msg = 'setting the current directory to' + print('%s %r' % (msg, os.path.abspath(tmpdir))) + os.chdir(tmpdir) + outputfilename = ffiplatform.compile('.', ext, + compiler_verbose, debug) + finally: + os.chdir(cwd) + _unpatch_meths(patchlist) + return outputfilename + else: + return ext, updated + else: + if c_file is None: + c_file, _ = _modname_to_file(tmpdir, module_name, '.py') + updated = make_py_source(ffi, module_name, c_file, + verbose=compiler_verbose) + if call_c_compiler: + return c_file + else: + return None, updated + diff --git a/server/www/packages/packages-linux/x64/cffi/setuptools_ext.py b/server/www/packages/packages-linux/x64/cffi/setuptools_ext.py new file mode 100644 index 0000000..df5a518 --- /dev/null +++ b/server/www/packages/packages-linux/x64/cffi/setuptools_ext.py @@ -0,0 +1,217 @@ +import os +import sys + +try: + basestring +except NameError: + # Python 3.x + basestring = str + +def error(msg): + from distutils.errors import DistutilsSetupError + raise DistutilsSetupError(msg) + + +def execfile(filename, glob): + # We use execfile() (here rewritten for Python 3) instead of + # __import__() to load the build script. The problem with + # a normal import is that in some packages, the intermediate + # __init__.py files may already try to import the file that + # we are generating. + with open(filename) as f: + src = f.read() + src += '\n' # Python 2.6 compatibility + code = compile(src, filename, 'exec') + exec(code, glob, glob) + + +def add_cffi_module(dist, mod_spec): + from cffi.api import FFI + + if not isinstance(mod_spec, basestring): + error("argument to 'cffi_modules=...' must be a str or a list of str," + " not %r" % (type(mod_spec).__name__,)) + mod_spec = str(mod_spec) + try: + build_file_name, ffi_var_name = mod_spec.split(':') + except ValueError: + error("%r must be of the form 'path/build.py:ffi_variable'" % + (mod_spec,)) + if not os.path.exists(build_file_name): + ext = '' + rewritten = build_file_name.replace('.', '/') + '.py' + if os.path.exists(rewritten): + ext = ' (rewrite cffi_modules to [%r])' % ( + rewritten + ':' + ffi_var_name,) + error("%r does not name an existing file%s" % (build_file_name, ext)) + + mod_vars = {'__name__': '__cffi__', '__file__': build_file_name} + execfile(build_file_name, mod_vars) + + try: + ffi = mod_vars[ffi_var_name] + except KeyError: + error("%r: object %r not found in module" % (mod_spec, + ffi_var_name)) + if not isinstance(ffi, FFI): + ffi = ffi() # maybe it's a function instead of directly an ffi + if not isinstance(ffi, FFI): + error("%r is not an FFI instance (got %r)" % (mod_spec, + type(ffi).__name__)) + if not hasattr(ffi, '_assigned_source'): + error("%r: the set_source() method was not called" % (mod_spec,)) + module_name, source, source_extension, kwds = ffi._assigned_source + if ffi._windows_unicode: + kwds = kwds.copy() + ffi._apply_windows_unicode(kwds) + + if source is None: + _add_py_module(dist, ffi, module_name) + else: + _add_c_module(dist, ffi, module_name, source, source_extension, kwds) + +def _set_py_limited_api(Extension, kwds): + """ + Add py_limited_api to kwds if setuptools >= 26 is in use. + Do not alter the setting if it already exists. + Setuptools takes care of ignoring the flag on Python 2 and PyPy. + + CPython itself should ignore the flag in a debugging version + (by not listing .abi3.so in the extensions it supports), but + it doesn't so far, creating troubles. That's why we check + for "not hasattr(sys, 'gettotalrefcount')" (the 2.7 compatible equivalent + of 'd' not in sys.abiflags). (http://bugs.python.org/issue28401) + + On Windows, with CPython <= 3.4, it's better not to use py_limited_api + because virtualenv *still* doesn't copy PYTHON3.DLL on these versions. + For now we'll skip py_limited_api on all Windows versions to avoid an + inconsistent mess. + """ + if ('py_limited_api' not in kwds and not hasattr(sys, 'gettotalrefcount') + and sys.platform != 'win32'): + import setuptools + try: + setuptools_major_version = int(setuptools.__version__.partition('.')[0]) + if setuptools_major_version >= 26: + kwds['py_limited_api'] = True + except ValueError: # certain development versions of setuptools + # If we don't know the version number of setuptools, we + # try to set 'py_limited_api' anyway. At worst, we get a + # warning. + kwds['py_limited_api'] = True + return kwds + +def _add_c_module(dist, ffi, module_name, source, source_extension, kwds): + from distutils.core import Extension + # We are a setuptools extension. Need this build_ext for py_limited_api. + from setuptools.command.build_ext import build_ext + from distutils.dir_util import mkpath + from distutils import log + from cffi import recompiler + + allsources = ['$PLACEHOLDER'] + allsources.extend(kwds.pop('sources', [])) + kwds = _set_py_limited_api(Extension, kwds) + ext = Extension(name=module_name, sources=allsources, **kwds) + + def make_mod(tmpdir, pre_run=None): + c_file = os.path.join(tmpdir, module_name + source_extension) + log.info("generating cffi module %r" % c_file) + mkpath(tmpdir) + # a setuptools-only, API-only hook: called with the "ext" and "ffi" + # arguments just before we turn the ffi into C code. To use it, + # subclass the 'distutils.command.build_ext.build_ext' class and + # add a method 'def pre_run(self, ext, ffi)'. + if pre_run is not None: + pre_run(ext, ffi) + updated = recompiler.make_c_source(ffi, module_name, source, c_file) + if not updated: + log.info("already up-to-date") + return c_file + + if dist.ext_modules is None: + dist.ext_modules = [] + dist.ext_modules.append(ext) + + base_class = dist.cmdclass.get('build_ext', build_ext) + class build_ext_make_mod(base_class): + def run(self): + if ext.sources[0] == '$PLACEHOLDER': + pre_run = getattr(self, 'pre_run', None) + ext.sources[0] = make_mod(self.build_temp, pre_run) + base_class.run(self) + dist.cmdclass['build_ext'] = build_ext_make_mod + # NB. multiple runs here will create multiple 'build_ext_make_mod' + # classes. Even in this case the 'build_ext' command should be + # run once; but just in case, the logic above does nothing if + # called again. + + +def _add_py_module(dist, ffi, module_name): + from distutils.dir_util import mkpath + from setuptools.command.build_py import build_py + from setuptools.command.build_ext import build_ext + from distutils import log + from cffi import recompiler + + def generate_mod(py_file): + log.info("generating cffi module %r" % py_file) + mkpath(os.path.dirname(py_file)) + updated = recompiler.make_py_source(ffi, module_name, py_file) + if not updated: + log.info("already up-to-date") + + base_class = dist.cmdclass.get('build_py', build_py) + class build_py_make_mod(base_class): + def run(self): + base_class.run(self) + module_path = module_name.split('.') + module_path[-1] += '.py' + generate_mod(os.path.join(self.build_lib, *module_path)) + def get_source_files(self): + # This is called from 'setup.py sdist' only. Exclude + # the generate .py module in this case. + saved_py_modules = self.py_modules + try: + if saved_py_modules: + self.py_modules = [m for m in saved_py_modules + if m != module_name] + return base_class.get_source_files(self) + finally: + self.py_modules = saved_py_modules + dist.cmdclass['build_py'] = build_py_make_mod + + # distutils and setuptools have no notion I could find of a + # generated python module. If we don't add module_name to + # dist.py_modules, then things mostly work but there are some + # combination of options (--root and --record) that will miss + # the module. So we add it here, which gives a few apparently + # harmless warnings about not finding the file outside the + # build directory. + # Then we need to hack more in get_source_files(); see above. + if dist.py_modules is None: + dist.py_modules = [] + dist.py_modules.append(module_name) + + # the following is only for "build_ext -i" + base_class_2 = dist.cmdclass.get('build_ext', build_ext) + class build_ext_make_mod(base_class_2): + def run(self): + base_class_2.run(self) + if self.inplace: + # from get_ext_fullpath() in distutils/command/build_ext.py + module_path = module_name.split('.') + package = '.'.join(module_path[:-1]) + build_py = self.get_finalized_command('build_py') + package_dir = build_py.get_package_dir(package) + file_name = module_path[-1] + '.py' + generate_mod(os.path.join(package_dir, file_name)) + dist.cmdclass['build_ext'] = build_ext_make_mod + +def cffi_modules(dist, attr, value): + assert attr == 'cffi_modules' + if isinstance(value, basestring): + value = [value] + + for cffi_module in value: + add_cffi_module(dist, cffi_module) diff --git a/server/www/packages/packages-linux/x64/cffi/vengine_cpy.py b/server/www/packages/packages-linux/x64/cffi/vengine_cpy.py new file mode 100644 index 0000000..536f11f --- /dev/null +++ b/server/www/packages/packages-linux/x64/cffi/vengine_cpy.py @@ -0,0 +1,1015 @@ +# +# DEPRECATED: implementation for ffi.verify() +# +import sys, imp +from . import model +from .error import VerificationError + + +class VCPythonEngine(object): + _class_key = 'x' + _gen_python_module = True + + def __init__(self, verifier): + self.verifier = verifier + self.ffi = verifier.ffi + self._struct_pending_verification = {} + self._types_of_builtin_functions = {} + + def patch_extension_kwds(self, kwds): + pass + + def find_module(self, module_name, path, so_suffixes): + try: + f, filename, descr = imp.find_module(module_name, path) + except ImportError: + return None + if f is not None: + f.close() + # Note that after a setuptools installation, there are both .py + # and .so files with the same basename. The code here relies on + # imp.find_module() locating the .so in priority. + if descr[0] not in so_suffixes: + return None + return filename + + def collect_types(self): + self._typesdict = {} + self._generate("collecttype") + + def _prnt(self, what=''): + self._f.write(what + '\n') + + def _gettypenum(self, type): + # a KeyError here is a bug. please report it! :-) + return self._typesdict[type] + + def _do_collect_type(self, tp): + if ((not isinstance(tp, model.PrimitiveType) + or tp.name == 'long double') + and tp not in self._typesdict): + num = len(self._typesdict) + self._typesdict[tp] = num + + def write_source_to_f(self): + self.collect_types() + # + # The new module will have a _cffi_setup() function that receives + # objects from the ffi world, and that calls some setup code in + # the module. This setup code is split in several independent + # functions, e.g. one per constant. The functions are "chained" + # by ending in a tail call to each other. + # + # This is further split in two chained lists, depending on if we + # can do it at import-time or if we must wait for _cffi_setup() to + # provide us with the objects. This is needed because we + # need the values of the enum constants in order to build the + # that we may have to pass to _cffi_setup(). + # + # The following two 'chained_list_constants' items contains + # the head of these two chained lists, as a string that gives the + # call to do, if any. + self._chained_list_constants = ['((void)lib,0)', '((void)lib,0)'] + # + prnt = self._prnt + # first paste some standard set of lines that are mostly '#define' + prnt(cffimod_header) + prnt() + # then paste the C source given by the user, verbatim. + prnt(self.verifier.preamble) + prnt() + # + # call generate_cpy_xxx_decl(), for every xxx found from + # ffi._parser._declarations. This generates all the functions. + self._generate("decl") + # + # implement the function _cffi_setup_custom() as calling the + # head of the chained list. + self._generate_setup_custom() + prnt() + # + # produce the method table, including the entries for the + # generated Python->C function wrappers, which are done + # by generate_cpy_function_method(). + prnt('static PyMethodDef _cffi_methods[] = {') + self._generate("method") + prnt(' {"_cffi_setup", _cffi_setup, METH_VARARGS, NULL},') + prnt(' {NULL, NULL, 0, NULL} /* Sentinel */') + prnt('};') + prnt() + # + # standard init. + modname = self.verifier.get_module_name() + constants = self._chained_list_constants[False] + prnt('#if PY_MAJOR_VERSION >= 3') + prnt() + prnt('static struct PyModuleDef _cffi_module_def = {') + prnt(' PyModuleDef_HEAD_INIT,') + prnt(' "%s",' % modname) + prnt(' NULL,') + prnt(' -1,') + prnt(' _cffi_methods,') + prnt(' NULL, NULL, NULL, NULL') + prnt('};') + prnt() + prnt('PyMODINIT_FUNC') + prnt('PyInit_%s(void)' % modname) + prnt('{') + prnt(' PyObject *lib;') + prnt(' lib = PyModule_Create(&_cffi_module_def);') + prnt(' if (lib == NULL)') + prnt(' return NULL;') + prnt(' if (%s < 0 || _cffi_init() < 0) {' % (constants,)) + prnt(' Py_DECREF(lib);') + prnt(' return NULL;') + prnt(' }') + prnt(' return lib;') + prnt('}') + prnt() + prnt('#else') + prnt() + prnt('PyMODINIT_FUNC') + prnt('init%s(void)' % modname) + prnt('{') + prnt(' PyObject *lib;') + prnt(' lib = Py_InitModule("%s", _cffi_methods);' % modname) + prnt(' if (lib == NULL)') + prnt(' return;') + prnt(' if (%s < 0 || _cffi_init() < 0)' % (constants,)) + prnt(' return;') + prnt(' return;') + prnt('}') + prnt() + prnt('#endif') + + def load_library(self, flags=None): + # XXX review all usages of 'self' here! + # import it as a new extension module + imp.acquire_lock() + try: + if hasattr(sys, "getdlopenflags"): + previous_flags = sys.getdlopenflags() + try: + if hasattr(sys, "setdlopenflags") and flags is not None: + sys.setdlopenflags(flags) + module = imp.load_dynamic(self.verifier.get_module_name(), + self.verifier.modulefilename) + except ImportError as e: + error = "importing %r: %s" % (self.verifier.modulefilename, e) + raise VerificationError(error) + finally: + if hasattr(sys, "setdlopenflags"): + sys.setdlopenflags(previous_flags) + finally: + imp.release_lock() + # + # call loading_cpy_struct() to get the struct layout inferred by + # the C compiler + self._load(module, 'loading') + # + # the C code will need the objects. Collect them in + # order in a list. + revmapping = dict([(value, key) + for (key, value) in self._typesdict.items()]) + lst = [revmapping[i] for i in range(len(revmapping))] + lst = list(map(self.ffi._get_cached_btype, lst)) + # + # build the FFILibrary class and instance and call _cffi_setup(). + # this will set up some fields like '_cffi_types', and only then + # it will invoke the chained list of functions that will really + # build (notably) the constant objects, as if they are + # pointers, and store them as attributes on the 'library' object. + class FFILibrary(object): + _cffi_python_module = module + _cffi_ffi = self.ffi + _cffi_dir = [] + def __dir__(self): + return FFILibrary._cffi_dir + list(self.__dict__) + library = FFILibrary() + if module._cffi_setup(lst, VerificationError, library): + import warnings + warnings.warn("reimporting %r might overwrite older definitions" + % (self.verifier.get_module_name())) + # + # finally, call the loaded_cpy_xxx() functions. This will perform + # the final adjustments, like copying the Python->C wrapper + # functions from the module to the 'library' object, and setting + # up the FFILibrary class with properties for the global C variables. + self._load(module, 'loaded', library=library) + module._cffi_original_ffi = self.ffi + module._cffi_types_of_builtin_funcs = self._types_of_builtin_functions + return library + + def _get_declarations(self): + lst = [(key, tp) for (key, (tp, qual)) in + self.ffi._parser._declarations.items()] + lst.sort() + return lst + + def _generate(self, step_name): + for name, tp in self._get_declarations(): + kind, realname = name.split(' ', 1) + try: + method = getattr(self, '_generate_cpy_%s_%s' % (kind, + step_name)) + except AttributeError: + raise VerificationError( + "not implemented in verify(): %r" % name) + try: + method(tp, realname) + except Exception as e: + model.attach_exception_info(e, name) + raise + + def _load(self, module, step_name, **kwds): + for name, tp in self._get_declarations(): + kind, realname = name.split(' ', 1) + method = getattr(self, '_%s_cpy_%s' % (step_name, kind)) + try: + method(tp, realname, module, **kwds) + except Exception as e: + model.attach_exception_info(e, name) + raise + + def _generate_nothing(self, tp, name): + pass + + def _loaded_noop(self, tp, name, module, **kwds): + pass + + # ---------- + + def _convert_funcarg_to_c(self, tp, fromvar, tovar, errcode): + extraarg = '' + if isinstance(tp, model.PrimitiveType): + if tp.is_integer_type() and tp.name != '_Bool': + converter = '_cffi_to_c_int' + extraarg = ', %s' % tp.name + else: + converter = '(%s)_cffi_to_c_%s' % (tp.get_c_name(''), + tp.name.replace(' ', '_')) + errvalue = '-1' + # + elif isinstance(tp, model.PointerType): + self._convert_funcarg_to_c_ptr_or_array(tp, fromvar, + tovar, errcode) + return + # + elif isinstance(tp, (model.StructOrUnion, model.EnumType)): + # a struct (not a struct pointer) as a function argument + self._prnt(' if (_cffi_to_c((char *)&%s, _cffi_type(%d), %s) < 0)' + % (tovar, self._gettypenum(tp), fromvar)) + self._prnt(' %s;' % errcode) + return + # + elif isinstance(tp, model.FunctionPtrType): + converter = '(%s)_cffi_to_c_pointer' % tp.get_c_name('') + extraarg = ', _cffi_type(%d)' % self._gettypenum(tp) + errvalue = 'NULL' + # + else: + raise NotImplementedError(tp) + # + self._prnt(' %s = %s(%s%s);' % (tovar, converter, fromvar, extraarg)) + self._prnt(' if (%s == (%s)%s && PyErr_Occurred())' % ( + tovar, tp.get_c_name(''), errvalue)) + self._prnt(' %s;' % errcode) + + def _extra_local_variables(self, tp, localvars): + if isinstance(tp, model.PointerType): + localvars.add('Py_ssize_t datasize') + + def _convert_funcarg_to_c_ptr_or_array(self, tp, fromvar, tovar, errcode): + self._prnt(' datasize = _cffi_prepare_pointer_call_argument(') + self._prnt(' _cffi_type(%d), %s, (char **)&%s);' % ( + self._gettypenum(tp), fromvar, tovar)) + self._prnt(' if (datasize != 0) {') + self._prnt(' if (datasize < 0)') + self._prnt(' %s;' % errcode) + self._prnt(' %s = alloca((size_t)datasize);' % (tovar,)) + self._prnt(' memset((void *)%s, 0, (size_t)datasize);' % (tovar,)) + self._prnt(' if (_cffi_convert_array_from_object(' + '(char *)%s, _cffi_type(%d), %s) < 0)' % ( + tovar, self._gettypenum(tp), fromvar)) + self._prnt(' %s;' % errcode) + self._prnt(' }') + + def _convert_expr_from_c(self, tp, var, context): + if isinstance(tp, model.PrimitiveType): + if tp.is_integer_type() and tp.name != '_Bool': + return '_cffi_from_c_int(%s, %s)' % (var, tp.name) + elif tp.name != 'long double': + return '_cffi_from_c_%s(%s)' % (tp.name.replace(' ', '_'), var) + else: + return '_cffi_from_c_deref((char *)&%s, _cffi_type(%d))' % ( + var, self._gettypenum(tp)) + elif isinstance(tp, (model.PointerType, model.FunctionPtrType)): + return '_cffi_from_c_pointer((char *)%s, _cffi_type(%d))' % ( + var, self._gettypenum(tp)) + elif isinstance(tp, model.ArrayType): + return '_cffi_from_c_pointer((char *)%s, _cffi_type(%d))' % ( + var, self._gettypenum(model.PointerType(tp.item))) + elif isinstance(tp, model.StructOrUnion): + if tp.fldnames is None: + raise TypeError("'%s' is used as %s, but is opaque" % ( + tp._get_c_name(), context)) + return '_cffi_from_c_struct((char *)&%s, _cffi_type(%d))' % ( + var, self._gettypenum(tp)) + elif isinstance(tp, model.EnumType): + return '_cffi_from_c_deref((char *)&%s, _cffi_type(%d))' % ( + var, self._gettypenum(tp)) + else: + raise NotImplementedError(tp) + + # ---------- + # typedefs: generates no code so far + + _generate_cpy_typedef_collecttype = _generate_nothing + _generate_cpy_typedef_decl = _generate_nothing + _generate_cpy_typedef_method = _generate_nothing + _loading_cpy_typedef = _loaded_noop + _loaded_cpy_typedef = _loaded_noop + + # ---------- + # function declarations + + def _generate_cpy_function_collecttype(self, tp, name): + assert isinstance(tp, model.FunctionPtrType) + if tp.ellipsis: + self._do_collect_type(tp) + else: + # don't call _do_collect_type(tp) in this common case, + # otherwise test_autofilled_struct_as_argument fails + for type in tp.args: + self._do_collect_type(type) + self._do_collect_type(tp.result) + + def _generate_cpy_function_decl(self, tp, name): + assert isinstance(tp, model.FunctionPtrType) + if tp.ellipsis: + # cannot support vararg functions better than this: check for its + # exact type (including the fixed arguments), and build it as a + # constant function pointer (no CPython wrapper) + self._generate_cpy_const(False, name, tp) + return + prnt = self._prnt + numargs = len(tp.args) + if numargs == 0: + argname = 'noarg' + elif numargs == 1: + argname = 'arg0' + else: + argname = 'args' + prnt('static PyObject *') + prnt('_cffi_f_%s(PyObject *self, PyObject *%s)' % (name, argname)) + prnt('{') + # + context = 'argument of %s' % name + for i, type in enumerate(tp.args): + prnt(' %s;' % type.get_c_name(' x%d' % i, context)) + # + localvars = set() + for type in tp.args: + self._extra_local_variables(type, localvars) + for decl in localvars: + prnt(' %s;' % (decl,)) + # + if not isinstance(tp.result, model.VoidType): + result_code = 'result = ' + context = 'result of %s' % name + prnt(' %s;' % tp.result.get_c_name(' result', context)) + else: + result_code = '' + # + if len(tp.args) > 1: + rng = range(len(tp.args)) + for i in rng: + prnt(' PyObject *arg%d;' % i) + prnt() + prnt(' if (!PyArg_ParseTuple(args, "%s:%s", %s))' % ( + 'O' * numargs, name, ', '.join(['&arg%d' % i for i in rng]))) + prnt(' return NULL;') + prnt() + # + for i, type in enumerate(tp.args): + self._convert_funcarg_to_c(type, 'arg%d' % i, 'x%d' % i, + 'return NULL') + prnt() + # + prnt(' Py_BEGIN_ALLOW_THREADS') + prnt(' _cffi_restore_errno();') + prnt(' { %s%s(%s); }' % ( + result_code, name, + ', '.join(['x%d' % i for i in range(len(tp.args))]))) + prnt(' _cffi_save_errno();') + prnt(' Py_END_ALLOW_THREADS') + prnt() + # + prnt(' (void)self; /* unused */') + if numargs == 0: + prnt(' (void)noarg; /* unused */') + if result_code: + prnt(' return %s;' % + self._convert_expr_from_c(tp.result, 'result', 'result type')) + else: + prnt(' Py_INCREF(Py_None);') + prnt(' return Py_None;') + prnt('}') + prnt() + + def _generate_cpy_function_method(self, tp, name): + if tp.ellipsis: + return + numargs = len(tp.args) + if numargs == 0: + meth = 'METH_NOARGS' + elif numargs == 1: + meth = 'METH_O' + else: + meth = 'METH_VARARGS' + self._prnt(' {"%s", _cffi_f_%s, %s, NULL},' % (name, name, meth)) + + _loading_cpy_function = _loaded_noop + + def _loaded_cpy_function(self, tp, name, module, library): + if tp.ellipsis: + return + func = getattr(module, name) + setattr(library, name, func) + self._types_of_builtin_functions[func] = tp + + # ---------- + # named structs + + _generate_cpy_struct_collecttype = _generate_nothing + def _generate_cpy_struct_decl(self, tp, name): + assert name == tp.name + self._generate_struct_or_union_decl(tp, 'struct', name) + def _generate_cpy_struct_method(self, tp, name): + self._generate_struct_or_union_method(tp, 'struct', name) + def _loading_cpy_struct(self, tp, name, module): + self._loading_struct_or_union(tp, 'struct', name, module) + def _loaded_cpy_struct(self, tp, name, module, **kwds): + self._loaded_struct_or_union(tp) + + _generate_cpy_union_collecttype = _generate_nothing + def _generate_cpy_union_decl(self, tp, name): + assert name == tp.name + self._generate_struct_or_union_decl(tp, 'union', name) + def _generate_cpy_union_method(self, tp, name): + self._generate_struct_or_union_method(tp, 'union', name) + def _loading_cpy_union(self, tp, name, module): + self._loading_struct_or_union(tp, 'union', name, module) + def _loaded_cpy_union(self, tp, name, module, **kwds): + self._loaded_struct_or_union(tp) + + def _generate_struct_or_union_decl(self, tp, prefix, name): + if tp.fldnames is None: + return # nothing to do with opaque structs + checkfuncname = '_cffi_check_%s_%s' % (prefix, name) + layoutfuncname = '_cffi_layout_%s_%s' % (prefix, name) + cname = ('%s %s' % (prefix, name)).strip() + # + prnt = self._prnt + prnt('static void %s(%s *p)' % (checkfuncname, cname)) + prnt('{') + prnt(' /* only to generate compile-time warnings or errors */') + prnt(' (void)p;') + for fname, ftype, fbitsize, fqual in tp.enumfields(): + if (isinstance(ftype, model.PrimitiveType) + and ftype.is_integer_type()) or fbitsize >= 0: + # accept all integers, but complain on float or double + prnt(' (void)((p->%s) << 1);' % fname) + else: + # only accept exactly the type declared. + try: + prnt(' { %s = &p->%s; (void)tmp; }' % ( + ftype.get_c_name('*tmp', 'field %r'%fname, quals=fqual), + fname)) + except VerificationError as e: + prnt(' /* %s */' % str(e)) # cannot verify it, ignore + prnt('}') + prnt('static PyObject *') + prnt('%s(PyObject *self, PyObject *noarg)' % (layoutfuncname,)) + prnt('{') + prnt(' struct _cffi_aligncheck { char x; %s y; };' % cname) + prnt(' static Py_ssize_t nums[] = {') + prnt(' sizeof(%s),' % cname) + prnt(' offsetof(struct _cffi_aligncheck, y),') + for fname, ftype, fbitsize, fqual in tp.enumfields(): + if fbitsize >= 0: + continue # xxx ignore fbitsize for now + prnt(' offsetof(%s, %s),' % (cname, fname)) + if isinstance(ftype, model.ArrayType) and ftype.length is None: + prnt(' 0, /* %s */' % ftype._get_c_name()) + else: + prnt(' sizeof(((%s *)0)->%s),' % (cname, fname)) + prnt(' -1') + prnt(' };') + prnt(' (void)self; /* unused */') + prnt(' (void)noarg; /* unused */') + prnt(' return _cffi_get_struct_layout(nums);') + prnt(' /* the next line is not executed, but compiled */') + prnt(' %s(0);' % (checkfuncname,)) + prnt('}') + prnt() + + def _generate_struct_or_union_method(self, tp, prefix, name): + if tp.fldnames is None: + return # nothing to do with opaque structs + layoutfuncname = '_cffi_layout_%s_%s' % (prefix, name) + self._prnt(' {"%s", %s, METH_NOARGS, NULL},' % (layoutfuncname, + layoutfuncname)) + + def _loading_struct_or_union(self, tp, prefix, name, module): + if tp.fldnames is None: + return # nothing to do with opaque structs + layoutfuncname = '_cffi_layout_%s_%s' % (prefix, name) + # + function = getattr(module, layoutfuncname) + layout = function() + if isinstance(tp, model.StructOrUnion) and tp.partial: + # use the function()'s sizes and offsets to guide the + # layout of the struct + totalsize = layout[0] + totalalignment = layout[1] + fieldofs = layout[2::2] + fieldsize = layout[3::2] + tp.force_flatten() + assert len(fieldofs) == len(fieldsize) == len(tp.fldnames) + tp.fixedlayout = fieldofs, fieldsize, totalsize, totalalignment + else: + cname = ('%s %s' % (prefix, name)).strip() + self._struct_pending_verification[tp] = layout, cname + + def _loaded_struct_or_union(self, tp): + if tp.fldnames is None: + return # nothing to do with opaque structs + self.ffi._get_cached_btype(tp) # force 'fixedlayout' to be considered + + if tp in self._struct_pending_verification: + # check that the layout sizes and offsets match the real ones + def check(realvalue, expectedvalue, msg): + if realvalue != expectedvalue: + raise VerificationError( + "%s (we have %d, but C compiler says %d)" + % (msg, expectedvalue, realvalue)) + ffi = self.ffi + BStruct = ffi._get_cached_btype(tp) + layout, cname = self._struct_pending_verification.pop(tp) + check(layout[0], ffi.sizeof(BStruct), "wrong total size") + check(layout[1], ffi.alignof(BStruct), "wrong total alignment") + i = 2 + for fname, ftype, fbitsize, fqual in tp.enumfields(): + if fbitsize >= 0: + continue # xxx ignore fbitsize for now + check(layout[i], ffi.offsetof(BStruct, fname), + "wrong offset for field %r" % (fname,)) + if layout[i+1] != 0: + BField = ffi._get_cached_btype(ftype) + check(layout[i+1], ffi.sizeof(BField), + "wrong size for field %r" % (fname,)) + i += 2 + assert i == len(layout) + + # ---------- + # 'anonymous' declarations. These are produced for anonymous structs + # or unions; the 'name' is obtained by a typedef. + + _generate_cpy_anonymous_collecttype = _generate_nothing + + def _generate_cpy_anonymous_decl(self, tp, name): + if isinstance(tp, model.EnumType): + self._generate_cpy_enum_decl(tp, name, '') + else: + self._generate_struct_or_union_decl(tp, '', name) + + def _generate_cpy_anonymous_method(self, tp, name): + if not isinstance(tp, model.EnumType): + self._generate_struct_or_union_method(tp, '', name) + + def _loading_cpy_anonymous(self, tp, name, module): + if isinstance(tp, model.EnumType): + self._loading_cpy_enum(tp, name, module) + else: + self._loading_struct_or_union(tp, '', name, module) + + def _loaded_cpy_anonymous(self, tp, name, module, **kwds): + if isinstance(tp, model.EnumType): + self._loaded_cpy_enum(tp, name, module, **kwds) + else: + self._loaded_struct_or_union(tp) + + # ---------- + # constants, likely declared with '#define' + + def _generate_cpy_const(self, is_int, name, tp=None, category='const', + vartp=None, delayed=True, size_too=False, + check_value=None): + prnt = self._prnt + funcname = '_cffi_%s_%s' % (category, name) + prnt('static int %s(PyObject *lib)' % funcname) + prnt('{') + prnt(' PyObject *o;') + prnt(' int res;') + if not is_int: + prnt(' %s;' % (vartp or tp).get_c_name(' i', name)) + else: + assert category == 'const' + # + if check_value is not None: + self._check_int_constant_value(name, check_value) + # + if not is_int: + if category == 'var': + realexpr = '&' + name + else: + realexpr = name + prnt(' i = (%s);' % (realexpr,)) + prnt(' o = %s;' % (self._convert_expr_from_c(tp, 'i', + 'variable type'),)) + assert delayed + else: + prnt(' o = _cffi_from_c_int_const(%s);' % name) + prnt(' if (o == NULL)') + prnt(' return -1;') + if size_too: + prnt(' {') + prnt(' PyObject *o1 = o;') + prnt(' o = Py_BuildValue("On", o1, (Py_ssize_t)sizeof(%s));' + % (name,)) + prnt(' Py_DECREF(o1);') + prnt(' if (o == NULL)') + prnt(' return -1;') + prnt(' }') + prnt(' res = PyObject_SetAttrString(lib, "%s", o);' % name) + prnt(' Py_DECREF(o);') + prnt(' if (res < 0)') + prnt(' return -1;') + prnt(' return %s;' % self._chained_list_constants[delayed]) + self._chained_list_constants[delayed] = funcname + '(lib)' + prnt('}') + prnt() + + def _generate_cpy_constant_collecttype(self, tp, name): + is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type() + if not is_int: + self._do_collect_type(tp) + + def _generate_cpy_constant_decl(self, tp, name): + is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type() + self._generate_cpy_const(is_int, name, tp) + + _generate_cpy_constant_method = _generate_nothing + _loading_cpy_constant = _loaded_noop + _loaded_cpy_constant = _loaded_noop + + # ---------- + # enums + + def _check_int_constant_value(self, name, value, err_prefix=''): + prnt = self._prnt + if value <= 0: + prnt(' if ((%s) > 0 || (long)(%s) != %dL) {' % ( + name, name, value)) + else: + prnt(' if ((%s) <= 0 || (unsigned long)(%s) != %dUL) {' % ( + name, name, value)) + prnt(' char buf[64];') + prnt(' if ((%s) <= 0)' % name) + prnt(' snprintf(buf, 63, "%%ld", (long)(%s));' % name) + prnt(' else') + prnt(' snprintf(buf, 63, "%%lu", (unsigned long)(%s));' % + name) + prnt(' PyErr_Format(_cffi_VerificationError,') + prnt(' "%s%s has the real value %s, not %s",') + prnt(' "%s", "%s", buf, "%d");' % ( + err_prefix, name, value)) + prnt(' return -1;') + prnt(' }') + + def _enum_funcname(self, prefix, name): + # "$enum_$1" => "___D_enum____D_1" + name = name.replace('$', '___D_') + return '_cffi_e_%s_%s' % (prefix, name) + + def _generate_cpy_enum_decl(self, tp, name, prefix='enum'): + if tp.partial: + for enumerator in tp.enumerators: + self._generate_cpy_const(True, enumerator, delayed=False) + return + # + funcname = self._enum_funcname(prefix, name) + prnt = self._prnt + prnt('static int %s(PyObject *lib)' % funcname) + prnt('{') + for enumerator, enumvalue in zip(tp.enumerators, tp.enumvalues): + self._check_int_constant_value(enumerator, enumvalue, + "enum %s: " % name) + prnt(' return %s;' % self._chained_list_constants[True]) + self._chained_list_constants[True] = funcname + '(lib)' + prnt('}') + prnt() + + _generate_cpy_enum_collecttype = _generate_nothing + _generate_cpy_enum_method = _generate_nothing + + def _loading_cpy_enum(self, tp, name, module): + if tp.partial: + enumvalues = [getattr(module, enumerator) + for enumerator in tp.enumerators] + tp.enumvalues = tuple(enumvalues) + tp.partial_resolved = True + + def _loaded_cpy_enum(self, tp, name, module, library): + for enumerator, enumvalue in zip(tp.enumerators, tp.enumvalues): + setattr(library, enumerator, enumvalue) + + # ---------- + # macros: for now only for integers + + def _generate_cpy_macro_decl(self, tp, name): + if tp == '...': + check_value = None + else: + check_value = tp # an integer + self._generate_cpy_const(True, name, check_value=check_value) + + _generate_cpy_macro_collecttype = _generate_nothing + _generate_cpy_macro_method = _generate_nothing + _loading_cpy_macro = _loaded_noop + _loaded_cpy_macro = _loaded_noop + + # ---------- + # global variables + + def _generate_cpy_variable_collecttype(self, tp, name): + if isinstance(tp, model.ArrayType): + tp_ptr = model.PointerType(tp.item) + else: + tp_ptr = model.PointerType(tp) + self._do_collect_type(tp_ptr) + + def _generate_cpy_variable_decl(self, tp, name): + if isinstance(tp, model.ArrayType): + tp_ptr = model.PointerType(tp.item) + self._generate_cpy_const(False, name, tp, vartp=tp_ptr, + size_too = (tp.length == '...')) + else: + tp_ptr = model.PointerType(tp) + self._generate_cpy_const(False, name, tp_ptr, category='var') + + _generate_cpy_variable_method = _generate_nothing + _loading_cpy_variable = _loaded_noop + + def _loaded_cpy_variable(self, tp, name, module, library): + value = getattr(library, name) + if isinstance(tp, model.ArrayType): # int a[5] is "constant" in the + # sense that "a=..." is forbidden + if tp.length == '...': + assert isinstance(value, tuple) + (value, size) = value + BItemType = self.ffi._get_cached_btype(tp.item) + length, rest = divmod(size, self.ffi.sizeof(BItemType)) + if rest != 0: + raise VerificationError( + "bad size: %r does not seem to be an array of %s" % + (name, tp.item)) + tp = tp.resolve_length(length) + # 'value' is a which we have to replace with + # a if the N is actually known + if tp.length is not None: + BArray = self.ffi._get_cached_btype(tp) + value = self.ffi.cast(BArray, value) + setattr(library, name, value) + return + # remove ptr= from the library instance, and replace + # it by a property on the class, which reads/writes into ptr[0]. + ptr = value + delattr(library, name) + def getter(library): + return ptr[0] + def setter(library, value): + ptr[0] = value + setattr(type(library), name, property(getter, setter)) + type(library)._cffi_dir.append(name) + + # ---------- + + def _generate_setup_custom(self): + prnt = self._prnt + prnt('static int _cffi_setup_custom(PyObject *lib)') + prnt('{') + prnt(' return %s;' % self._chained_list_constants[True]) + prnt('}') + +cffimod_header = r''' +#include +#include + +/* this block of #ifs should be kept exactly identical between + c/_cffi_backend.c, cffi/vengine_cpy.py, cffi/vengine_gen.py + and cffi/_cffi_include.h */ +#if defined(_MSC_VER) +# include /* for alloca() */ +# if _MSC_VER < 1600 /* MSVC < 2010 */ + typedef __int8 int8_t; + typedef __int16 int16_t; + typedef __int32 int32_t; + typedef __int64 int64_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; + typedef unsigned __int64 uint64_t; + typedef __int8 int_least8_t; + typedef __int16 int_least16_t; + typedef __int32 int_least32_t; + typedef __int64 int_least64_t; + typedef unsigned __int8 uint_least8_t; + typedef unsigned __int16 uint_least16_t; + typedef unsigned __int32 uint_least32_t; + typedef unsigned __int64 uint_least64_t; + typedef __int8 int_fast8_t; + typedef __int16 int_fast16_t; + typedef __int32 int_fast32_t; + typedef __int64 int_fast64_t; + typedef unsigned __int8 uint_fast8_t; + typedef unsigned __int16 uint_fast16_t; + typedef unsigned __int32 uint_fast32_t; + typedef unsigned __int64 uint_fast64_t; + typedef __int64 intmax_t; + typedef unsigned __int64 uintmax_t; +# else +# include +# endif +# if _MSC_VER < 1800 /* MSVC < 2013 */ +# ifndef __cplusplus + typedef unsigned char _Bool; +# endif +# endif +#else +# include +# if (defined (__SVR4) && defined (__sun)) || defined(_AIX) || defined(__hpux) +# include +# endif +#endif + +#if PY_MAJOR_VERSION < 3 +# undef PyCapsule_CheckExact +# undef PyCapsule_GetPointer +# define PyCapsule_CheckExact(capsule) (PyCObject_Check(capsule)) +# define PyCapsule_GetPointer(capsule, name) \ + (PyCObject_AsVoidPtr(capsule)) +#endif + +#if PY_MAJOR_VERSION >= 3 +# define PyInt_FromLong PyLong_FromLong +#endif + +#define _cffi_from_c_double PyFloat_FromDouble +#define _cffi_from_c_float PyFloat_FromDouble +#define _cffi_from_c_long PyInt_FromLong +#define _cffi_from_c_ulong PyLong_FromUnsignedLong +#define _cffi_from_c_longlong PyLong_FromLongLong +#define _cffi_from_c_ulonglong PyLong_FromUnsignedLongLong +#define _cffi_from_c__Bool PyBool_FromLong + +#define _cffi_to_c_double PyFloat_AsDouble +#define _cffi_to_c_float PyFloat_AsDouble + +#define _cffi_from_c_int_const(x) \ + (((x) > 0) ? \ + ((unsigned long long)(x) <= (unsigned long long)LONG_MAX) ? \ + PyInt_FromLong((long)(x)) : \ + PyLong_FromUnsignedLongLong((unsigned long long)(x)) : \ + ((long long)(x) >= (long long)LONG_MIN) ? \ + PyInt_FromLong((long)(x)) : \ + PyLong_FromLongLong((long long)(x))) + +#define _cffi_from_c_int(x, type) \ + (((type)-1) > 0 ? /* unsigned */ \ + (sizeof(type) < sizeof(long) ? \ + PyInt_FromLong((long)x) : \ + sizeof(type) == sizeof(long) ? \ + PyLong_FromUnsignedLong((unsigned long)x) : \ + PyLong_FromUnsignedLongLong((unsigned long long)x)) : \ + (sizeof(type) <= sizeof(long) ? \ + PyInt_FromLong((long)x) : \ + PyLong_FromLongLong((long long)x))) + +#define _cffi_to_c_int(o, type) \ + ((type)( \ + sizeof(type) == 1 ? (((type)-1) > 0 ? (type)_cffi_to_c_u8(o) \ + : (type)_cffi_to_c_i8(o)) : \ + sizeof(type) == 2 ? (((type)-1) > 0 ? (type)_cffi_to_c_u16(o) \ + : (type)_cffi_to_c_i16(o)) : \ + sizeof(type) == 4 ? (((type)-1) > 0 ? (type)_cffi_to_c_u32(o) \ + : (type)_cffi_to_c_i32(o)) : \ + sizeof(type) == 8 ? (((type)-1) > 0 ? (type)_cffi_to_c_u64(o) \ + : (type)_cffi_to_c_i64(o)) : \ + (Py_FatalError("unsupported size for type " #type), (type)0))) + +#define _cffi_to_c_i8 \ + ((int(*)(PyObject *))_cffi_exports[1]) +#define _cffi_to_c_u8 \ + ((int(*)(PyObject *))_cffi_exports[2]) +#define _cffi_to_c_i16 \ + ((int(*)(PyObject *))_cffi_exports[3]) +#define _cffi_to_c_u16 \ + ((int(*)(PyObject *))_cffi_exports[4]) +#define _cffi_to_c_i32 \ + ((int(*)(PyObject *))_cffi_exports[5]) +#define _cffi_to_c_u32 \ + ((unsigned int(*)(PyObject *))_cffi_exports[6]) +#define _cffi_to_c_i64 \ + ((long long(*)(PyObject *))_cffi_exports[7]) +#define _cffi_to_c_u64 \ + ((unsigned long long(*)(PyObject *))_cffi_exports[8]) +#define _cffi_to_c_char \ + ((int(*)(PyObject *))_cffi_exports[9]) +#define _cffi_from_c_pointer \ + ((PyObject *(*)(char *, CTypeDescrObject *))_cffi_exports[10]) +#define _cffi_to_c_pointer \ + ((char *(*)(PyObject *, CTypeDescrObject *))_cffi_exports[11]) +#define _cffi_get_struct_layout \ + ((PyObject *(*)(Py_ssize_t[]))_cffi_exports[12]) +#define _cffi_restore_errno \ + ((void(*)(void))_cffi_exports[13]) +#define _cffi_save_errno \ + ((void(*)(void))_cffi_exports[14]) +#define _cffi_from_c_char \ + ((PyObject *(*)(char))_cffi_exports[15]) +#define _cffi_from_c_deref \ + ((PyObject *(*)(char *, CTypeDescrObject *))_cffi_exports[16]) +#define _cffi_to_c \ + ((int(*)(char *, CTypeDescrObject *, PyObject *))_cffi_exports[17]) +#define _cffi_from_c_struct \ + ((PyObject *(*)(char *, CTypeDescrObject *))_cffi_exports[18]) +#define _cffi_to_c_wchar_t \ + ((wchar_t(*)(PyObject *))_cffi_exports[19]) +#define _cffi_from_c_wchar_t \ + ((PyObject *(*)(wchar_t))_cffi_exports[20]) +#define _cffi_to_c_long_double \ + ((long double(*)(PyObject *))_cffi_exports[21]) +#define _cffi_to_c__Bool \ + ((_Bool(*)(PyObject *))_cffi_exports[22]) +#define _cffi_prepare_pointer_call_argument \ + ((Py_ssize_t(*)(CTypeDescrObject *, PyObject *, char **))_cffi_exports[23]) +#define _cffi_convert_array_from_object \ + ((int(*)(char *, CTypeDescrObject *, PyObject *))_cffi_exports[24]) +#define _CFFI_NUM_EXPORTS 25 + +typedef struct _ctypedescr CTypeDescrObject; + +static void *_cffi_exports[_CFFI_NUM_EXPORTS]; +static PyObject *_cffi_types, *_cffi_VerificationError; + +static int _cffi_setup_custom(PyObject *lib); /* forward */ + +static PyObject *_cffi_setup(PyObject *self, PyObject *args) +{ + PyObject *library; + int was_alive = (_cffi_types != NULL); + (void)self; /* unused */ + if (!PyArg_ParseTuple(args, "OOO", &_cffi_types, &_cffi_VerificationError, + &library)) + return NULL; + Py_INCREF(_cffi_types); + Py_INCREF(_cffi_VerificationError); + if (_cffi_setup_custom(library) < 0) + return NULL; + return PyBool_FromLong(was_alive); +} + +static int _cffi_init(void) +{ + PyObject *module, *c_api_object = NULL; + + module = PyImport_ImportModule("_cffi_backend"); + if (module == NULL) + goto failure; + + c_api_object = PyObject_GetAttrString(module, "_C_API"); + if (c_api_object == NULL) + goto failure; + if (!PyCapsule_CheckExact(c_api_object)) { + PyErr_SetNone(PyExc_ImportError); + goto failure; + } + memcpy(_cffi_exports, PyCapsule_GetPointer(c_api_object, "cffi"), + _CFFI_NUM_EXPORTS * sizeof(void *)); + + Py_DECREF(module); + Py_DECREF(c_api_object); + return 0; + + failure: + Py_XDECREF(module); + Py_XDECREF(c_api_object); + return -1; +} + +#define _cffi_type(num) ((CTypeDescrObject *)PyList_GET_ITEM(_cffi_types, num)) + +/**********/ +''' diff --git a/server/www/packages/packages-linux/x64/cffi/vengine_gen.py b/server/www/packages/packages-linux/x64/cffi/vengine_gen.py new file mode 100644 index 0000000..a64ff64 --- /dev/null +++ b/server/www/packages/packages-linux/x64/cffi/vengine_gen.py @@ -0,0 +1,675 @@ +# +# DEPRECATED: implementation for ffi.verify() +# +import sys, os +import types + +from . import model +from .error import VerificationError + + +class VGenericEngine(object): + _class_key = 'g' + _gen_python_module = False + + def __init__(self, verifier): + self.verifier = verifier + self.ffi = verifier.ffi + self.export_symbols = [] + self._struct_pending_verification = {} + + def patch_extension_kwds(self, kwds): + # add 'export_symbols' to the dictionary. Note that we add the + # list before filling it. When we fill it, it will thus also show + # up in kwds['export_symbols']. + kwds.setdefault('export_symbols', self.export_symbols) + + def find_module(self, module_name, path, so_suffixes): + for so_suffix in so_suffixes: + basename = module_name + so_suffix + if path is None: + path = sys.path + for dirname in path: + filename = os.path.join(dirname, basename) + if os.path.isfile(filename): + return filename + + def collect_types(self): + pass # not needed in the generic engine + + def _prnt(self, what=''): + self._f.write(what + '\n') + + def write_source_to_f(self): + prnt = self._prnt + # first paste some standard set of lines that are mostly '#include' + prnt(cffimod_header) + # then paste the C source given by the user, verbatim. + prnt(self.verifier.preamble) + # + # call generate_gen_xxx_decl(), for every xxx found from + # ffi._parser._declarations. This generates all the functions. + self._generate('decl') + # + # on Windows, distutils insists on putting init_cffi_xyz in + # 'export_symbols', so instead of fighting it, just give up and + # give it one + if sys.platform == 'win32': + if sys.version_info >= (3,): + prefix = 'PyInit_' + else: + prefix = 'init' + modname = self.verifier.get_module_name() + prnt("void %s%s(void) { }\n" % (prefix, modname)) + + def load_library(self, flags=0): + # import it with the CFFI backend + backend = self.ffi._backend + # needs to make a path that contains '/', on Posix + filename = os.path.join(os.curdir, self.verifier.modulefilename) + module = backend.load_library(filename, flags) + # + # call loading_gen_struct() to get the struct layout inferred by + # the C compiler + self._load(module, 'loading') + + # build the FFILibrary class and instance, this is a module subclass + # because modules are expected to have usually-constant-attributes and + # in PyPy this means the JIT is able to treat attributes as constant, + # which we want. + class FFILibrary(types.ModuleType): + _cffi_generic_module = module + _cffi_ffi = self.ffi + _cffi_dir = [] + def __dir__(self): + return FFILibrary._cffi_dir + library = FFILibrary("") + # + # finally, call the loaded_gen_xxx() functions. This will set + # up the 'library' object. + self._load(module, 'loaded', library=library) + return library + + def _get_declarations(self): + lst = [(key, tp) for (key, (tp, qual)) in + self.ffi._parser._declarations.items()] + lst.sort() + return lst + + def _generate(self, step_name): + for name, tp in self._get_declarations(): + kind, realname = name.split(' ', 1) + try: + method = getattr(self, '_generate_gen_%s_%s' % (kind, + step_name)) + except AttributeError: + raise VerificationError( + "not implemented in verify(): %r" % name) + try: + method(tp, realname) + except Exception as e: + model.attach_exception_info(e, name) + raise + + def _load(self, module, step_name, **kwds): + for name, tp in self._get_declarations(): + kind, realname = name.split(' ', 1) + method = getattr(self, '_%s_gen_%s' % (step_name, kind)) + try: + method(tp, realname, module, **kwds) + except Exception as e: + model.attach_exception_info(e, name) + raise + + def _generate_nothing(self, tp, name): + pass + + def _loaded_noop(self, tp, name, module, **kwds): + pass + + # ---------- + # typedefs: generates no code so far + + _generate_gen_typedef_decl = _generate_nothing + _loading_gen_typedef = _loaded_noop + _loaded_gen_typedef = _loaded_noop + + # ---------- + # function declarations + + def _generate_gen_function_decl(self, tp, name): + assert isinstance(tp, model.FunctionPtrType) + if tp.ellipsis: + # cannot support vararg functions better than this: check for its + # exact type (including the fixed arguments), and build it as a + # constant function pointer (no _cffi_f_%s wrapper) + self._generate_gen_const(False, name, tp) + return + prnt = self._prnt + numargs = len(tp.args) + argnames = [] + for i, type in enumerate(tp.args): + indirection = '' + if isinstance(type, model.StructOrUnion): + indirection = '*' + argnames.append('%sx%d' % (indirection, i)) + context = 'argument of %s' % name + arglist = [type.get_c_name(' %s' % arg, context) + for type, arg in zip(tp.args, argnames)] + tpresult = tp.result + if isinstance(tpresult, model.StructOrUnion): + arglist.insert(0, tpresult.get_c_name(' *r', context)) + tpresult = model.void_type + arglist = ', '.join(arglist) or 'void' + wrappername = '_cffi_f_%s' % name + self.export_symbols.append(wrappername) + if tp.abi: + abi = tp.abi + ' ' + else: + abi = '' + funcdecl = ' %s%s(%s)' % (abi, wrappername, arglist) + context = 'result of %s' % name + prnt(tpresult.get_c_name(funcdecl, context)) + prnt('{') + # + if isinstance(tp.result, model.StructOrUnion): + result_code = '*r = ' + elif not isinstance(tp.result, model.VoidType): + result_code = 'return ' + else: + result_code = '' + prnt(' %s%s(%s);' % (result_code, name, ', '.join(argnames))) + prnt('}') + prnt() + + _loading_gen_function = _loaded_noop + + def _loaded_gen_function(self, tp, name, module, library): + assert isinstance(tp, model.FunctionPtrType) + if tp.ellipsis: + newfunction = self._load_constant(False, tp, name, module) + else: + indirections = [] + base_tp = tp + if (any(isinstance(typ, model.StructOrUnion) for typ in tp.args) + or isinstance(tp.result, model.StructOrUnion)): + indirect_args = [] + for i, typ in enumerate(tp.args): + if isinstance(typ, model.StructOrUnion): + typ = model.PointerType(typ) + indirections.append((i, typ)) + indirect_args.append(typ) + indirect_result = tp.result + if isinstance(indirect_result, model.StructOrUnion): + if indirect_result.fldtypes is None: + raise TypeError("'%s' is used as result type, " + "but is opaque" % ( + indirect_result._get_c_name(),)) + indirect_result = model.PointerType(indirect_result) + indirect_args.insert(0, indirect_result) + indirections.insert(0, ("result", indirect_result)) + indirect_result = model.void_type + tp = model.FunctionPtrType(tuple(indirect_args), + indirect_result, tp.ellipsis) + BFunc = self.ffi._get_cached_btype(tp) + wrappername = '_cffi_f_%s' % name + newfunction = module.load_function(BFunc, wrappername) + for i, typ in indirections: + newfunction = self._make_struct_wrapper(newfunction, i, typ, + base_tp) + setattr(library, name, newfunction) + type(library)._cffi_dir.append(name) + + def _make_struct_wrapper(self, oldfunc, i, tp, base_tp): + backend = self.ffi._backend + BType = self.ffi._get_cached_btype(tp) + if i == "result": + ffi = self.ffi + def newfunc(*args): + res = ffi.new(BType) + oldfunc(res, *args) + return res[0] + else: + def newfunc(*args): + args = args[:i] + (backend.newp(BType, args[i]),) + args[i+1:] + return oldfunc(*args) + newfunc._cffi_base_type = base_tp + return newfunc + + # ---------- + # named structs + + def _generate_gen_struct_decl(self, tp, name): + assert name == tp.name + self._generate_struct_or_union_decl(tp, 'struct', name) + + def _loading_gen_struct(self, tp, name, module): + self._loading_struct_or_union(tp, 'struct', name, module) + + def _loaded_gen_struct(self, tp, name, module, **kwds): + self._loaded_struct_or_union(tp) + + def _generate_gen_union_decl(self, tp, name): + assert name == tp.name + self._generate_struct_or_union_decl(tp, 'union', name) + + def _loading_gen_union(self, tp, name, module): + self._loading_struct_or_union(tp, 'union', name, module) + + def _loaded_gen_union(self, tp, name, module, **kwds): + self._loaded_struct_or_union(tp) + + def _generate_struct_or_union_decl(self, tp, prefix, name): + if tp.fldnames is None: + return # nothing to do with opaque structs + checkfuncname = '_cffi_check_%s_%s' % (prefix, name) + layoutfuncname = '_cffi_layout_%s_%s' % (prefix, name) + cname = ('%s %s' % (prefix, name)).strip() + # + prnt = self._prnt + prnt('static void %s(%s *p)' % (checkfuncname, cname)) + prnt('{') + prnt(' /* only to generate compile-time warnings or errors */') + prnt(' (void)p;') + for fname, ftype, fbitsize, fqual in tp.enumfields(): + if (isinstance(ftype, model.PrimitiveType) + and ftype.is_integer_type()) or fbitsize >= 0: + # accept all integers, but complain on float or double + prnt(' (void)((p->%s) << 1);' % fname) + else: + # only accept exactly the type declared. + try: + prnt(' { %s = &p->%s; (void)tmp; }' % ( + ftype.get_c_name('*tmp', 'field %r'%fname, quals=fqual), + fname)) + except VerificationError as e: + prnt(' /* %s */' % str(e)) # cannot verify it, ignore + prnt('}') + self.export_symbols.append(layoutfuncname) + prnt('intptr_t %s(intptr_t i)' % (layoutfuncname,)) + prnt('{') + prnt(' struct _cffi_aligncheck { char x; %s y; };' % cname) + prnt(' static intptr_t nums[] = {') + prnt(' sizeof(%s),' % cname) + prnt(' offsetof(struct _cffi_aligncheck, y),') + for fname, ftype, fbitsize, fqual in tp.enumfields(): + if fbitsize >= 0: + continue # xxx ignore fbitsize for now + prnt(' offsetof(%s, %s),' % (cname, fname)) + if isinstance(ftype, model.ArrayType) and ftype.length is None: + prnt(' 0, /* %s */' % ftype._get_c_name()) + else: + prnt(' sizeof(((%s *)0)->%s),' % (cname, fname)) + prnt(' -1') + prnt(' };') + prnt(' return nums[i];') + prnt(' /* the next line is not executed, but compiled */') + prnt(' %s(0);' % (checkfuncname,)) + prnt('}') + prnt() + + def _loading_struct_or_union(self, tp, prefix, name, module): + if tp.fldnames is None: + return # nothing to do with opaque structs + layoutfuncname = '_cffi_layout_%s_%s' % (prefix, name) + # + BFunc = self.ffi._typeof_locked("intptr_t(*)(intptr_t)")[0] + function = module.load_function(BFunc, layoutfuncname) + layout = [] + num = 0 + while True: + x = function(num) + if x < 0: break + layout.append(x) + num += 1 + if isinstance(tp, model.StructOrUnion) and tp.partial: + # use the function()'s sizes and offsets to guide the + # layout of the struct + totalsize = layout[0] + totalalignment = layout[1] + fieldofs = layout[2::2] + fieldsize = layout[3::2] + tp.force_flatten() + assert len(fieldofs) == len(fieldsize) == len(tp.fldnames) + tp.fixedlayout = fieldofs, fieldsize, totalsize, totalalignment + else: + cname = ('%s %s' % (prefix, name)).strip() + self._struct_pending_verification[tp] = layout, cname + + def _loaded_struct_or_union(self, tp): + if tp.fldnames is None: + return # nothing to do with opaque structs + self.ffi._get_cached_btype(tp) # force 'fixedlayout' to be considered + + if tp in self._struct_pending_verification: + # check that the layout sizes and offsets match the real ones + def check(realvalue, expectedvalue, msg): + if realvalue != expectedvalue: + raise VerificationError( + "%s (we have %d, but C compiler says %d)" + % (msg, expectedvalue, realvalue)) + ffi = self.ffi + BStruct = ffi._get_cached_btype(tp) + layout, cname = self._struct_pending_verification.pop(tp) + check(layout[0], ffi.sizeof(BStruct), "wrong total size") + check(layout[1], ffi.alignof(BStruct), "wrong total alignment") + i = 2 + for fname, ftype, fbitsize, fqual in tp.enumfields(): + if fbitsize >= 0: + continue # xxx ignore fbitsize for now + check(layout[i], ffi.offsetof(BStruct, fname), + "wrong offset for field %r" % (fname,)) + if layout[i+1] != 0: + BField = ffi._get_cached_btype(ftype) + check(layout[i+1], ffi.sizeof(BField), + "wrong size for field %r" % (fname,)) + i += 2 + assert i == len(layout) + + # ---------- + # 'anonymous' declarations. These are produced for anonymous structs + # or unions; the 'name' is obtained by a typedef. + + def _generate_gen_anonymous_decl(self, tp, name): + if isinstance(tp, model.EnumType): + self._generate_gen_enum_decl(tp, name, '') + else: + self._generate_struct_or_union_decl(tp, '', name) + + def _loading_gen_anonymous(self, tp, name, module): + if isinstance(tp, model.EnumType): + self._loading_gen_enum(tp, name, module, '') + else: + self._loading_struct_or_union(tp, '', name, module) + + def _loaded_gen_anonymous(self, tp, name, module, **kwds): + if isinstance(tp, model.EnumType): + self._loaded_gen_enum(tp, name, module, **kwds) + else: + self._loaded_struct_or_union(tp) + + # ---------- + # constants, likely declared with '#define' + + def _generate_gen_const(self, is_int, name, tp=None, category='const', + check_value=None): + prnt = self._prnt + funcname = '_cffi_%s_%s' % (category, name) + self.export_symbols.append(funcname) + if check_value is not None: + assert is_int + assert category == 'const' + prnt('int %s(char *out_error)' % funcname) + prnt('{') + self._check_int_constant_value(name, check_value) + prnt(' return 0;') + prnt('}') + elif is_int: + assert category == 'const' + prnt('int %s(long long *out_value)' % funcname) + prnt('{') + prnt(' *out_value = (long long)(%s);' % (name,)) + prnt(' return (%s) <= 0;' % (name,)) + prnt('}') + else: + assert tp is not None + assert check_value is None + if category == 'var': + ampersand = '&' + else: + ampersand = '' + extra = '' + if category == 'const' and isinstance(tp, model.StructOrUnion): + extra = 'const *' + ampersand = '&' + prnt(tp.get_c_name(' %s%s(void)' % (extra, funcname), name)) + prnt('{') + prnt(' return (%s%s);' % (ampersand, name)) + prnt('}') + prnt() + + def _generate_gen_constant_decl(self, tp, name): + is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type() + self._generate_gen_const(is_int, name, tp) + + _loading_gen_constant = _loaded_noop + + def _load_constant(self, is_int, tp, name, module, check_value=None): + funcname = '_cffi_const_%s' % name + if check_value is not None: + assert is_int + self._load_known_int_constant(module, funcname) + value = check_value + elif is_int: + BType = self.ffi._typeof_locked("long long*")[0] + BFunc = self.ffi._typeof_locked("int(*)(long long*)")[0] + function = module.load_function(BFunc, funcname) + p = self.ffi.new(BType) + negative = function(p) + value = int(p[0]) + if value < 0 and not negative: + BLongLong = self.ffi._typeof_locked("long long")[0] + value += (1 << (8*self.ffi.sizeof(BLongLong))) + else: + assert check_value is None + fntypeextra = '(*)(void)' + if isinstance(tp, model.StructOrUnion): + fntypeextra = '*' + fntypeextra + BFunc = self.ffi._typeof_locked(tp.get_c_name(fntypeextra, name))[0] + function = module.load_function(BFunc, funcname) + value = function() + if isinstance(tp, model.StructOrUnion): + value = value[0] + return value + + def _loaded_gen_constant(self, tp, name, module, library): + is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type() + value = self._load_constant(is_int, tp, name, module) + setattr(library, name, value) + type(library)._cffi_dir.append(name) + + # ---------- + # enums + + def _check_int_constant_value(self, name, value): + prnt = self._prnt + if value <= 0: + prnt(' if ((%s) > 0 || (long)(%s) != %dL) {' % ( + name, name, value)) + else: + prnt(' if ((%s) <= 0 || (unsigned long)(%s) != %dUL) {' % ( + name, name, value)) + prnt(' char buf[64];') + prnt(' if ((%s) <= 0)' % name) + prnt(' sprintf(buf, "%%ld", (long)(%s));' % name) + prnt(' else') + prnt(' sprintf(buf, "%%lu", (unsigned long)(%s));' % + name) + prnt(' sprintf(out_error, "%s has the real value %s, not %s",') + prnt(' "%s", buf, "%d");' % (name[:100], value)) + prnt(' return -1;') + prnt(' }') + + def _load_known_int_constant(self, module, funcname): + BType = self.ffi._typeof_locked("char[]")[0] + BFunc = self.ffi._typeof_locked("int(*)(char*)")[0] + function = module.load_function(BFunc, funcname) + p = self.ffi.new(BType, 256) + if function(p) < 0: + error = self.ffi.string(p) + if sys.version_info >= (3,): + error = str(error, 'utf-8') + raise VerificationError(error) + + def _enum_funcname(self, prefix, name): + # "$enum_$1" => "___D_enum____D_1" + name = name.replace('$', '___D_') + return '_cffi_e_%s_%s' % (prefix, name) + + def _generate_gen_enum_decl(self, tp, name, prefix='enum'): + if tp.partial: + for enumerator in tp.enumerators: + self._generate_gen_const(True, enumerator) + return + # + funcname = self._enum_funcname(prefix, name) + self.export_symbols.append(funcname) + prnt = self._prnt + prnt('int %s(char *out_error)' % funcname) + prnt('{') + for enumerator, enumvalue in zip(tp.enumerators, tp.enumvalues): + self._check_int_constant_value(enumerator, enumvalue) + prnt(' return 0;') + prnt('}') + prnt() + + def _loading_gen_enum(self, tp, name, module, prefix='enum'): + if tp.partial: + enumvalues = [self._load_constant(True, tp, enumerator, module) + for enumerator in tp.enumerators] + tp.enumvalues = tuple(enumvalues) + tp.partial_resolved = True + else: + funcname = self._enum_funcname(prefix, name) + self._load_known_int_constant(module, funcname) + + def _loaded_gen_enum(self, tp, name, module, library): + for enumerator, enumvalue in zip(tp.enumerators, tp.enumvalues): + setattr(library, enumerator, enumvalue) + type(library)._cffi_dir.append(enumerator) + + # ---------- + # macros: for now only for integers + + def _generate_gen_macro_decl(self, tp, name): + if tp == '...': + check_value = None + else: + check_value = tp # an integer + self._generate_gen_const(True, name, check_value=check_value) + + _loading_gen_macro = _loaded_noop + + def _loaded_gen_macro(self, tp, name, module, library): + if tp == '...': + check_value = None + else: + check_value = tp # an integer + value = self._load_constant(True, tp, name, module, + check_value=check_value) + setattr(library, name, value) + type(library)._cffi_dir.append(name) + + # ---------- + # global variables + + def _generate_gen_variable_decl(self, tp, name): + if isinstance(tp, model.ArrayType): + if tp.length == '...': + prnt = self._prnt + funcname = '_cffi_sizeof_%s' % (name,) + self.export_symbols.append(funcname) + prnt("size_t %s(void)" % funcname) + prnt("{") + prnt(" return sizeof(%s);" % (name,)) + prnt("}") + tp_ptr = model.PointerType(tp.item) + self._generate_gen_const(False, name, tp_ptr) + else: + tp_ptr = model.PointerType(tp) + self._generate_gen_const(False, name, tp_ptr, category='var') + + _loading_gen_variable = _loaded_noop + + def _loaded_gen_variable(self, tp, name, module, library): + if isinstance(tp, model.ArrayType): # int a[5] is "constant" in the + # sense that "a=..." is forbidden + if tp.length == '...': + funcname = '_cffi_sizeof_%s' % (name,) + BFunc = self.ffi._typeof_locked('size_t(*)(void)')[0] + function = module.load_function(BFunc, funcname) + size = function() + BItemType = self.ffi._get_cached_btype(tp.item) + length, rest = divmod(size, self.ffi.sizeof(BItemType)) + if rest != 0: + raise VerificationError( + "bad size: %r does not seem to be an array of %s" % + (name, tp.item)) + tp = tp.resolve_length(length) + tp_ptr = model.PointerType(tp.item) + value = self._load_constant(False, tp_ptr, name, module) + # 'value' is a which we have to replace with + # a if the N is actually known + if tp.length is not None: + BArray = self.ffi._get_cached_btype(tp) + value = self.ffi.cast(BArray, value) + setattr(library, name, value) + type(library)._cffi_dir.append(name) + return + # remove ptr= from the library instance, and replace + # it by a property on the class, which reads/writes into ptr[0]. + funcname = '_cffi_var_%s' % name + BFunc = self.ffi._typeof_locked(tp.get_c_name('*(*)(void)', name))[0] + function = module.load_function(BFunc, funcname) + ptr = function() + def getter(library): + return ptr[0] + def setter(library, value): + ptr[0] = value + setattr(type(library), name, property(getter, setter)) + type(library)._cffi_dir.append(name) + +cffimod_header = r''' +#include +#include +#include +#include +#include /* XXX for ssize_t on some platforms */ + +/* this block of #ifs should be kept exactly identical between + c/_cffi_backend.c, cffi/vengine_cpy.py, cffi/vengine_gen.py + and cffi/_cffi_include.h */ +#if defined(_MSC_VER) +# include /* for alloca() */ +# if _MSC_VER < 1600 /* MSVC < 2010 */ + typedef __int8 int8_t; + typedef __int16 int16_t; + typedef __int32 int32_t; + typedef __int64 int64_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; + typedef unsigned __int64 uint64_t; + typedef __int8 int_least8_t; + typedef __int16 int_least16_t; + typedef __int32 int_least32_t; + typedef __int64 int_least64_t; + typedef unsigned __int8 uint_least8_t; + typedef unsigned __int16 uint_least16_t; + typedef unsigned __int32 uint_least32_t; + typedef unsigned __int64 uint_least64_t; + typedef __int8 int_fast8_t; + typedef __int16 int_fast16_t; + typedef __int32 int_fast32_t; + typedef __int64 int_fast64_t; + typedef unsigned __int8 uint_fast8_t; + typedef unsigned __int16 uint_fast16_t; + typedef unsigned __int32 uint_fast32_t; + typedef unsigned __int64 uint_fast64_t; + typedef __int64 intmax_t; + typedef unsigned __int64 uintmax_t; +# else +# include +# endif +# if _MSC_VER < 1800 /* MSVC < 2013 */ +# ifndef __cplusplus + typedef unsigned char _Bool; +# endif +# endif +#else +# include +# if (defined (__SVR4) && defined (__sun)) || defined(_AIX) || defined(__hpux) +# include +# endif +#endif +''' diff --git a/server/www/packages/packages-linux/x64/cffi/verifier.py b/server/www/packages/packages-linux/x64/cffi/verifier.py new file mode 100644 index 0000000..59b78c2 --- /dev/null +++ b/server/www/packages/packages-linux/x64/cffi/verifier.py @@ -0,0 +1,306 @@ +# +# DEPRECATED: implementation for ffi.verify() +# +import sys, os, binascii, shutil, io +from . import __version_verifier_modules__ +from . import ffiplatform +from .error import VerificationError + +if sys.version_info >= (3, 3): + import importlib.machinery + def _extension_suffixes(): + return importlib.machinery.EXTENSION_SUFFIXES[:] +else: + import imp + def _extension_suffixes(): + return [suffix for suffix, _, type in imp.get_suffixes() + if type == imp.C_EXTENSION] + + +if sys.version_info >= (3,): + NativeIO = io.StringIO +else: + class NativeIO(io.BytesIO): + def write(self, s): + if isinstance(s, unicode): + s = s.encode('ascii') + super(NativeIO, self).write(s) + + +class Verifier(object): + + def __init__(self, ffi, preamble, tmpdir=None, modulename=None, + ext_package=None, tag='', force_generic_engine=False, + source_extension='.c', flags=None, relative_to=None, **kwds): + if ffi._parser._uses_new_feature: + raise VerificationError( + "feature not supported with ffi.verify(), but only " + "with ffi.set_source(): %s" % (ffi._parser._uses_new_feature,)) + self.ffi = ffi + self.preamble = preamble + if not modulename: + flattened_kwds = ffiplatform.flatten(kwds) + vengine_class = _locate_engine_class(ffi, force_generic_engine) + self._vengine = vengine_class(self) + self._vengine.patch_extension_kwds(kwds) + self.flags = flags + self.kwds = self.make_relative_to(kwds, relative_to) + # + if modulename: + if tag: + raise TypeError("can't specify both 'modulename' and 'tag'") + else: + key = '\x00'.join([sys.version[:3], __version_verifier_modules__, + preamble, flattened_kwds] + + ffi._cdefsources) + if sys.version_info >= (3,): + key = key.encode('utf-8') + k1 = hex(binascii.crc32(key[0::2]) & 0xffffffff) + k1 = k1.lstrip('0x').rstrip('L') + k2 = hex(binascii.crc32(key[1::2]) & 0xffffffff) + k2 = k2.lstrip('0').rstrip('L') + modulename = '_cffi_%s_%s%s%s' % (tag, self._vengine._class_key, + k1, k2) + suffix = _get_so_suffixes()[0] + self.tmpdir = tmpdir or _caller_dir_pycache() + self.sourcefilename = os.path.join(self.tmpdir, modulename + source_extension) + self.modulefilename = os.path.join(self.tmpdir, modulename + suffix) + self.ext_package = ext_package + self._has_source = False + self._has_module = False + + def write_source(self, file=None): + """Write the C source code. It is produced in 'self.sourcefilename', + which can be tweaked beforehand.""" + with self.ffi._lock: + if self._has_source and file is None: + raise VerificationError( + "source code already written") + self._write_source(file) + + def compile_module(self): + """Write the C source code (if not done already) and compile it. + This produces a dynamic link library in 'self.modulefilename'.""" + with self.ffi._lock: + if self._has_module: + raise VerificationError("module already compiled") + if not self._has_source: + self._write_source() + self._compile_module() + + def load_library(self): + """Get a C module from this Verifier instance. + Returns an instance of a FFILibrary class that behaves like the + objects returned by ffi.dlopen(), but that delegates all + operations to the C module. If necessary, the C code is written + and compiled first. + """ + with self.ffi._lock: + if not self._has_module: + self._locate_module() + if not self._has_module: + if not self._has_source: + self._write_source() + self._compile_module() + return self._load_library() + + def get_module_name(self): + basename = os.path.basename(self.modulefilename) + # kill both the .so extension and the other .'s, as introduced + # by Python 3: 'basename.cpython-33m.so' + basename = basename.split('.', 1)[0] + # and the _d added in Python 2 debug builds --- but try to be + # conservative and not kill a legitimate _d + if basename.endswith('_d') and hasattr(sys, 'gettotalrefcount'): + basename = basename[:-2] + return basename + + def get_extension(self): + ffiplatform._hack_at_distutils() # backward compatibility hack + if not self._has_source: + with self.ffi._lock: + if not self._has_source: + self._write_source() + sourcename = ffiplatform.maybe_relative_path(self.sourcefilename) + modname = self.get_module_name() + return ffiplatform.get_extension(sourcename, modname, **self.kwds) + + def generates_python_module(self): + return self._vengine._gen_python_module + + def make_relative_to(self, kwds, relative_to): + if relative_to and os.path.dirname(relative_to): + dirname = os.path.dirname(relative_to) + kwds = kwds.copy() + for key in ffiplatform.LIST_OF_FILE_NAMES: + if key in kwds: + lst = kwds[key] + if not isinstance(lst, (list, tuple)): + raise TypeError("keyword '%s' should be a list or tuple" + % (key,)) + lst = [os.path.join(dirname, fn) for fn in lst] + kwds[key] = lst + return kwds + + # ---------- + + def _locate_module(self): + if not os.path.isfile(self.modulefilename): + if self.ext_package: + try: + pkg = __import__(self.ext_package, None, None, ['__doc__']) + except ImportError: + return # cannot import the package itself, give up + # (e.g. it might be called differently before installation) + path = pkg.__path__ + else: + path = None + filename = self._vengine.find_module(self.get_module_name(), path, + _get_so_suffixes()) + if filename is None: + return + self.modulefilename = filename + self._vengine.collect_types() + self._has_module = True + + def _write_source_to(self, file): + self._vengine._f = file + try: + self._vengine.write_source_to_f() + finally: + del self._vengine._f + + def _write_source(self, file=None): + if file is not None: + self._write_source_to(file) + else: + # Write our source file to an in memory file. + f = NativeIO() + self._write_source_to(f) + source_data = f.getvalue() + + # Determine if this matches the current file + if os.path.exists(self.sourcefilename): + with open(self.sourcefilename, "r") as fp: + needs_written = not (fp.read() == source_data) + else: + needs_written = True + + # Actually write the file out if it doesn't match + if needs_written: + _ensure_dir(self.sourcefilename) + with open(self.sourcefilename, "w") as fp: + fp.write(source_data) + + # Set this flag + self._has_source = True + + def _compile_module(self): + # compile this C source + tmpdir = os.path.dirname(self.sourcefilename) + outputfilename = ffiplatform.compile(tmpdir, self.get_extension()) + try: + same = ffiplatform.samefile(outputfilename, self.modulefilename) + except OSError: + same = False + if not same: + _ensure_dir(self.modulefilename) + shutil.move(outputfilename, self.modulefilename) + self._has_module = True + + def _load_library(self): + assert self._has_module + if self.flags is not None: + return self._vengine.load_library(self.flags) + else: + return self._vengine.load_library() + +# ____________________________________________________________ + +_FORCE_GENERIC_ENGINE = False # for tests + +def _locate_engine_class(ffi, force_generic_engine): + if _FORCE_GENERIC_ENGINE: + force_generic_engine = True + if not force_generic_engine: + if '__pypy__' in sys.builtin_module_names: + force_generic_engine = True + else: + try: + import _cffi_backend + except ImportError: + _cffi_backend = '?' + if ffi._backend is not _cffi_backend: + force_generic_engine = True + if force_generic_engine: + from . import vengine_gen + return vengine_gen.VGenericEngine + else: + from . import vengine_cpy + return vengine_cpy.VCPythonEngine + +# ____________________________________________________________ + +_TMPDIR = None + +def _caller_dir_pycache(): + if _TMPDIR: + return _TMPDIR + result = os.environ.get('CFFI_TMPDIR') + if result: + return result + filename = sys._getframe(2).f_code.co_filename + return os.path.abspath(os.path.join(os.path.dirname(filename), + '__pycache__')) + +def set_tmpdir(dirname): + """Set the temporary directory to use instead of __pycache__.""" + global _TMPDIR + _TMPDIR = dirname + +def cleanup_tmpdir(tmpdir=None, keep_so=False): + """Clean up the temporary directory by removing all files in it + called `_cffi_*.{c,so}` as well as the `build` subdirectory.""" + tmpdir = tmpdir or _caller_dir_pycache() + try: + filelist = os.listdir(tmpdir) + except OSError: + return + if keep_so: + suffix = '.c' # only remove .c files + else: + suffix = _get_so_suffixes()[0].lower() + for fn in filelist: + if fn.lower().startswith('_cffi_') and ( + fn.lower().endswith(suffix) or fn.lower().endswith('.c')): + try: + os.unlink(os.path.join(tmpdir, fn)) + except OSError: + pass + clean_dir = [os.path.join(tmpdir, 'build')] + for dir in clean_dir: + try: + for fn in os.listdir(dir): + fn = os.path.join(dir, fn) + if os.path.isdir(fn): + clean_dir.append(fn) + else: + os.unlink(fn) + except OSError: + pass + +def _get_so_suffixes(): + suffixes = _extension_suffixes() + if not suffixes: + # bah, no C_EXTENSION available. Occurs on pypy without cpyext + if sys.platform == 'win32': + suffixes = [".pyd"] + else: + suffixes = [".so"] + + return suffixes + +def _ensure_dir(filename): + dirname = os.path.dirname(filename) + if dirname and not os.path.isdir(dirname): + os.makedirs(dirname)