JFIFXX    $.' ",#(7),01444'9=82<.342  2!!22222222222222222222222222222222222222222222222222"4 ,PG"Z_4˷kjزZ,F+_z,© zh6٨icfu#ډb_N?wQ5-~I8TK<5oIv-k_U_~bMdӜUHh?]EwQk{_}qFW7HTՑYF?_'ϔ_Ջt=||I 6έ"D/[k9Y8ds|\Ҿp6Ҵ].6znopM[mei$[soᘨ˸ nɜG-ĨUycP3.DBli;hjx7Z^NhN3u{:jx힞#M&jL P@_ P&o89@Sz6t7#Oߋ s}YfTlmrZ)'Nk۞pw\Tȯ?8`Oi{wﭹW[r Q4F׊3m&L=h3z~#\l :F,j@ ʱwQT8"kJO6֚l}R>ډK]y&p}b;N1mr$|7>e@BTM*-iHgD) Em|ؘbҗaҾt4oG*oCNrPQ@z,|?W[0:n,jWiEW$~/hp\?{(0+Y8rΟ+>S-SVN;}s?. w9˟<Mq4Wv'{)01mBVW[8/< %wT^5b)iM pgN&ݝVO~qu9 !J27$O-! :%H ـyΠM=t{!S oK8txA& j0 vF Y|y ~6@c1vOpIg4lODL Rcj_uX63?nkWyf;^*B @~a`Eu+6L.ü>}y}_O6͐:YrGXkGl^w~㒶syIu! W XN7BVO!X2wvGRfT#t/?%8^WaTGcLMI(J1~8?aT ]ASE(*E} 2#I/׍qz^t̔bYz4xt){ OH+(EA&NXTo"XC')}Jzp ~5}^+6wcQ|LpdH}(.|kc4^"Z?ȕ a<L!039C EuCFEwç ;n?*oB8bʝ'#RqfM}7]s2tcS{\icTx;\7KPʇ Z O-~c>"?PEO8@8GQgaՎ󁶠䧘_%#r>1zaebqcPѵn#L =׀t L7`VA{C:ge@w1 Xp3c3ġpM"'-@n4fGB3DJ8[JoߐgK)ƛ$ 83+ 6ʻ SkI*KZlT _`?KQKdB`s}>`*>,*@JdoF*弝O}ks]yߘc1GV<=776qPTtXԀ!9*44Tހ3XΛex46YD  BdemDa\_l,G/֌7Y](xTt^%GE4}bTڹ;Y)BQu>J/J ⮶.XԄjݳ+Ed r5_D1 o Bx΢#<W8R6@gM. drD>(otU@x=~v2 ӣdoBd3eO6㣷ݜ66YQz`S{\P~z m5{J/L1xO\ZFu>ck#&:`$ai>2ΔloF[hlEܺΠk:)` $[69kOw\|8}ބ:񶐕IA1/=2[,!.}gN#ub ~݊}34qdELc$"[qU硬g^%B zrpJru%v\h1Yne`ǥ:gpQM~^Xi `S:V29.PV?Bk AEvw%_9CQwKekPؠ\;Io d{ ߞoc1eP\ `E=@KIRYK2NPlLɀ)&eB+ь( JTx_?EZ }@ 6U뙢طzdWIn` D噥[uV"G&Ú2g}&m?ċ"Om# {ON"SXNeysQ@FnVgdX~nj]J58up~.`r\O,ư0oS _Ml4kv\JSdxSW<AeIX$Iw:Sy›R9Q[,5;@]%u@ *rolbI  +%m:͇ZVủθau,RW33 dJeTYE.Mϧ-oj3+yy^cVO9NV\nd1 !͕_)av;թMlWR1)ElP;yوÏu 3k5Pr6<⒲l!˞*u־n!l:UNW %Chx8vL'X@*)̮ˍ D-M+JUkvK+x8cY?Ԡ~3mo|u@[XeYC\Kpx8oCC&N~3-H MXsu<`~"WL$8ξ3a)|:@m\^`@ҷ)5p+6p%i)P Mngc#0AruzRL+xSS?ʮ}()#tmˇ!0}}y$6Lt;$ʳ{^6{v6ķܰgVcnn ~zx«,2u?cE+ȘH؎%Za)X>uWTzNyosFQƤ$*&LLXL)1" LeOɟ9=:tZcŽY?ӭVwv~,Yrۗ|yGaFC.+ v1fήJ]STBn5sW}y$~z'c 8  ,! pVNSNNqy8z˱A4*'2n<s^ǧ˭PJޮɏUGLJ*#i}K%,)[z21z ?Nin1?TIR#m-1lA`fT5+ܐcq՝ʐ,3f2Uեmab#ŠdQy>\)SLYw#.ʑf ,"+w~N'cO3FN<)j&,- љ֊_zSTǦw>?nU仆Ve0$CdrP m׈eXmVu L.bֹ [Դaզ*\y8Է:Ez\0KqC b̘cөQ=0YsNS.3.Oo:#v7[#߫ 5܎LEr49nCOWlG^0k%;YߝZǓ:S#|}y,/kLd TA(AI$+I3;Y*Z}|ӧOdv..#:nf>>ȶITX 8y"dR|)0=n46ⲑ+ra ~]R̲c?6(q;5% |uj~z8R=XIV=|{vGj\gcqz؋%Mߍ1y#@f^^>N#x#۹6Y~?dfPO{P4Vu1E1J *|%JN`eWuzk M6q t[ gGvWIGu_ft5j"Y:Tɐ*; e54q$C2d} _SL#mYpO.C;cHi#֩%+) ӍƲVSYźg |tj38r|V1#;.SQA[S#`n+$$I P\[@s(EDzP])8G#0B[ىXIIq<9~[Z멜Z⊔IWU&A>P~#dp]9 "cP Md?٥Ifتuk/F9c*9Ǎ:ØFzn*@|Iށ9N3{'['ͬҲ4#}!V Fu,,mTIkv C7vB6kT91*l '~ƞFlU'M ][ΩũJ_{iIn$L jOdxkza۪#EClx˘oVɞljr)/,߬hL#^Lф,íMƁe̩NBLiLq}(q6IçJ$WE$:=#(KBzђ xlx?>Պ+>W,Ly!_DŌlQ![ SJ1ƐY}b,+Loxɓ)=yoh@꥟/Iѭ=Py9 ۍYӘe+pJnϱ?V\SO%(t =?MR[Șd/ nlB7j !;ӥ/[-A>dNsLj ,ɪv=1c.SQO3UƀܽE̻9GϷD7(}Ävӌ\y_0[w <΍>a_[0+LF.޺f>oNTq;y\bՃyjH<|q-eɏ_?_9+PHp$[uxK wMwNی'$Y2=qKBP~Yul:[<F12O5=d]Ysw:ϮEj,_QXz`H1,#II dwrP˂@ZJVy$\y{}^~[:NߌUOdؾe${p>G3cĖlʌ ת[`ϱ-WdgIig2 }s ؤ(%#sS@~3XnRG~\jc3vӍLM[JBTs3}jNʖW;7ç?=XF=-=qߚ#='c7ڑWI(O+=:uxqe2zi+kuGR0&eniT^J~\jyp'dtGsO39* b#Ɋ p[BwsT>d4ۧsnvnU_~,vƜJ1s QIz)(lv8MU=;56Gs#KMP=LvyGd}VwWBF'à ?MHUg2 !p7Qjڴ=ju JnA suMeƆҔ!)'8Ϣٔޝ(Vpצ֖d=ICJǠ{qkԭ߸i@Ku|p=..*+xz[Aqġ#s2aƊRR)*HRsi~a &fMP-KL@ZXy'x{}Zm+:)) IJ-iu ܒH'L(7yGӜq j 6ߌg1go,kرtY?W,pefOQS!K۟cҒA|սj>=⬒˧L[ ߿2JaB~Ru:Q] 0H~]7ƼI(}cq 'ήETq?fabӥvr )o-Q_'ᴎoK;Vo%~OK *bf:-ťIR`B5!RB@ï u ̯e\_U_ gES3QTaxU<~c?*#]MW,[8Oax]1bC|踤Plw5V%){t<d50iXSUm:Z┵i"1^B-PhJ&)O*DcWvM)}Pܗ-q\mmζZ-l@}aE6F@&Sg@ݚM ȹ 4#p\HdYDoH"\..RBHz_/5˘6KhJRPmƶim3,#ccoqa)*PtRmk7xDE\Y閣_X<~)c[[BP6YqS0%_;Àv~| VS؇ 'O0F0\U-d@7SJ*z3nyPOm~P3|Yʉr#CSN@ ƮRN)r"C:: #qbY. 6[2K2uǦHYRQMV G$Q+.>nNHq^ qmMVD+-#*U̒ p욳u:IBmPV@Or[b= 1UE_NmyKbNOU}the`|6֮P>\2PVIDiPO;9rmAHGWS]J*_G+kP2KaZH'KxWMZ%OYDRc+o?qGhmdSoh\D|:WUAQc yTq~^H/#pCZTI1ӏT4"ČZ}`w#*,ʹ 0i課Om*da^gJ݅{le9uF#Tֲ̲ٞC"qߍ ոޑo#XZTp@ o8(jdxw],f`~|,s^f1t|m򸄭/ctr5s79Q4H1꠲BB@l9@C+wpxu£Yc9?`@#omHs2)=2.ljg9$YS%*LRY7Z,*=䷘$armoϰUW.|rufIGwtZwo~5 YյhO+=8fF)W7L9lM̘·Y֘YLf큹pRF99.A "wz=E\Z'a 2Ǚ#;'}G*l^"q+2FQ hjkŦ${ޮ-T٭cf|3#~RJt$b(R(rdx >U b&9,>%E\ Άe$'q't*אެb-|dSBOO$R+H)܎K1m`;J2Y~9Og8=vqD`K[F)k[1m޼cn]skz$@)!I x՝"v9=ZA=`Ɠi :E)`7vI}dYI_ o:obo 3Q&D&2= Ά;>hy.*ⅥSӬ+q&j|UƧ}J0WW< ۋS)jQRjƯrN)Gű4Ѷ(S)Ǣ8iW52No˓ ۍ%5brOnL;n\G=^UdI8$&h'+(cȁ߫klS^cƗjԌEꭔgFȒ@}O*;evWVYJ\]X'5ղkFb 6Ro՜mi Ni>J?lPmU}>_Z&KKqrIDՉ~q3fL:Se>E-G{L6pe,8QIhaXaUA'ʂs+טIjP-y8ۈZ?J$WP Rs]|l(ԓsƊio(S0Y 8T97.WiLc~dxcE|2!XKƘਫ਼$((6~|d9u+qd^389Y6L.I?iIq9)O/뚅OXXVZF[یgQLK1RҖr@v#XlFНyS87kF!AsM^rkpjPDyS$Nqnxҍ!Uf!ehi2m`YI9r6 TFC}/y^Η5d'9A-J>{_l+`A['յϛ#w:݅%X}&PStQ"-\縵/$ƗhXb*yBS;Wջ_mcvt?2}1;qSdd~u:2k52R~z+|HE!)Ǟl7`0<,2*Hl-x^'_TVgZA'j ^2ΪN7t?w x1fIzC-ȖK^q;-WDvT78Z hK(P:Q- 8nZ܃e貾<1YT<,"6{/ ?͟|1:#gW>$dJdB=jf[%rE^il:BxSּ1հ,=*7 fcG#q eh?27,!7x6nLC4x},GeǝtC.vS F43zz\;QYC,6~;RYS/6|25vTimlv& nRh^ejRLGf? ۉҬܦƩ|Ȱ>3!viʯ>vオX3e_1zKȗ\qHS,EW[㺨uch⍸O}a>q6n6N6qN ! 1AQaq0@"2BRb#Pr3C`Scst$4D%Td ?Na3mCwxAmqmm$4n淿t'C"wzU=D\R+wp+YT&պ@ƃ3ޯ?AﶂaŘ@-Q=9Dռѻ@MVP܅G5fY6# ?0UQ,IX(6ڵ[DIMNލc&υj\XR|,4 jThAe^db#$]wOӪ1y%LYm뭛CUƃߜ}Cy1XνmF8jI]HۺиE@Ii;r8ӭVFՇ| &?3|xBMuSGe=Ӕ#BE5GY!z_eqр/W>|-Ci߇t1ޯќdR3ug=0 5[?#͏qcfH{ ?u=??ǯ}ZzhmΔBFTWPxs}G93 )gGR<>r h$'nchPBjJҧH -N1N?~}-q!=_2hcMlvY%UE@|vM2.Y[|y"EïKZF,ɯ?,q?vM 80jx";9vk+ ֧ ȺU?%vcVmA6Qg^MA}3nl QRNl8kkn'(M7m9وq%ޟ*h$Zk"$9: ?U8Sl,,|ɒxH(ѷGn/Q4PG%Ա8N! &7;eKM749R/%lc>x;>C:th?aKXbheᜋ^$Iհ hr7%F$EFdt5+(M6tÜUU|zW=aTsTgdqPQb'm1{|YXNb P~F^F:k6"j! Ir`1&-$Bevk:y#ywI0x=D4tUPZHڠ底taP6b>xaQ# WeFŮNjpJ* mQN*I-*ȩFg3 5Vʊɮa5FO@{NX?H]31Ri_uѕ 0 F~:60p͈SqX#a5>`o&+<2D: ڝ$nP*)N|yEjF5ټeihyZ >kbHavh-#!Po=@k̆IEN@}Ll?jO߭ʞQ|A07xwt!xfI2?Z<ץTcUj]陎Ltl }5ϓ$,Omˊ;@OjEj(ا,LXLOЦ90O .anA7j4 W_ٓzWjcBy՗+EM)dNg6y1_xp$Lv:9"zpʙ$^JԼ*ϭo=xLj6Ju82AH3$ٕ@=Vv]'qEz;I˼)=ɯx /W(Vp$ mu񶤑OqˎTr㠚xsrGCbypG1ߠw e8$⿄/M{*}W]˷.CK\ުx/$WPwr |i&}{X >$-l?-zglΆ(FhvS*b߲ڡn,|)mrH[a3ר[13o_U3TC$(=)0kgP u^=4 WYCҸ:vQרXàtkm,t*^,}D* "(I9R>``[~Q]#afi6l86:,ssN6j"A4IuQ6E,GnHzSHOuk5$I4ؤQ9@CwpBGv[]uOv0I4\yQѸ~>Z8Taqޣ;za/SI:ܫ_|>=Z8:SUIJ"IY8%b8H:QO6;7ISJҌAά3>cE+&jf$eC+z;V rʺmyeaQf&6ND.:NTvm<- uǝ\MvZYNNT-A>jr!SnO 13Ns%3D@`ܟ 1^c< aɽ̲Xë#w|ycW=9I*H8p^(4՗karOcWtO\ƍR8'KIQ?5>[}yUײ -h=% qThG2)"ו3]!kB*pFDlA,eEiHfPs5H:Փ~H0DتDIhF3c2E9H5zԑʚiX=:mxghd(v׊9iSOd@0ڽ:p5h-t&Xqӕ,ie|7A2O%PEhtjY1wЃ!  ࢽMy7\a@ţJ 4ȻF@o̒?4wx)]P~u57X 9^ܩU;Iꭆ 5 eK27({|Y׎ V\"Z1 Z}(Ǝ"1S_vE30>p; ΝD%xW?W?vo^Vidr[/&>~`9Why;R ;;ɮT?r$g1KACcKl:'3 cﳯ*"t8~l)m+U,z`(>yJ?h>]vЍG*{`;y]IT ;cNUfo¾h/$|NS1S"HVT4uhǜ]v;5͠x'C\SBplh}N ABx%ޭl/Twʽ]D=Kžr㻠l4SO?=k M: cCa#ha)ѐxcsgPiG{+xQI= zԫ+ 8"kñj=|c yCF/*9жh{ ?4o kmQNx;Y4膚aw?6>e]Qr:g,i"ԩA*M7qB?ӕFhV25r[7 Y }LR}*sg+xr2U=*'WSZDW]WǞ<叓{$9Ou4y90-1'*D`c^o?(9uݐ'PI& fJݮ:wSjfP1F:X H9dԯ˝[_54 }*;@ܨ ðynT?ןd#4rGͨH1|-#MrS3G3).᧏3vz֑r$G"`j 1tx0<ƆWh6y6,œGagAyb)hDß_mü gG;evݝnQ C-*oyaMI><]obD":GA-\%LT8c)+y76oQ#*{(F⽕y=rW\p۩cA^e6KʐcVf5$'->ՉN"F"UQ@fGb~#&M=8טJNu9D[̤so~ G9TtW^g5y$bY'سǴ=U-2 #MCt(i lj@Q 5̣i*OsxKf}\M{EV{υƇ);HIfeLȣr2>WIȂ6ik 5YOxȺ>Yf5'|H+98pjn.OyjY~iw'l;s2Y:'lgꥴ)o#'SaaKZ m}`169n"xI *+ }FP"l45'ZgE8?[X7(.Q-*ތL@̲v.5[=t\+CNܛ,gSQnH}*FG16&:t4ُ"Ạ$b |#rsaT ]ӽDP7ո0y)e$ٕvIh'QEAm*HRI=: 4牢) %_iNݧl] NtGHL ɱg<1V,J~ٹ"KQ 9HS9?@kr;we݁]I!{ @G["`J:n]{cAEVʆ#U96j#Ym\qe4hB7Cdv\MNgmAyQL4uLjj9#44tl^}LnR!t±]rh6ٍ>yҏNfU  Fm@8}/ujb9he:AyծwGpΧh5l}3p468)Udc;Us/֔YX1O2uqs`hwgr~{ RmhN؎*q 42*th>#E#HvOq}6e\,Wk#Xb>p}դ3T5†6[@Py*n|'f֧>lư΂̺SU'*qp_SM 'c6m ySʨ;MrƋmKxo,GmPAG:iw9}M(^V$ǒѽ9| aJSQarB;}ٻ֢2%Uc#gNaݕ'v[OY'3L3;,p]@S{lsX'cjwk'a.}}& dP*bK=ɍ!;3ngΊUߴmt'*{,=SzfD Ako~Gaoq_mi}#mPXhύmxǍ΂巿zfQc|kc?WY$_Lvl߶c`?ljݲˏ!V6UЂ(A4y)HpZ_x>eR$/`^'3qˏ-&Q=?CFVR DfV9{8gnh(P"6[D< E~0<@`G6Hгcc cK.5DdB`?XQ2ٿyqo&+1^ DW0ꊩG#QnL3c/x 11[yxპCWCcUĨ80me4.{muI=f0QRls9f9~fǨa"@8ȁQ#cicG$Gr/$W(WV"m7[mAmboD j۳ l^kh׽ # iXnveTka^Y4BNĕ0 !01@Q"2AaPq3BR?@4QT3,㺠W[=JKϞ2r^7vc:9 EߴwS#dIxu:Hp9E! V 2;73|F9Y*ʬFDu&y؟^EAA(ɩ^GV:ݜDy`Jr29ܾ㝉[E;FzxYGUeYC v-txIsםĘqEb+P\ :>iC';k|zرny]#ǿbQw(r|ӹs[D2v-%@;8<a[\o[ϧwI!*0krs)[J9^ʜp1) "/_>o<1AEy^C`x1'ܣnps`lfQ):lb>MejH^?kl3(z:1ŠK&?Q~{ٺhy/[V|6}KbXmn[-75q94dmc^h X5G-}دBޟ |rtMV+]c?-#ڛ^ǂ}LkrOu>-Dry D?:ޞUǜ7V?瓮"#rչģVR;n/_ ؉vݶe5db9/O009G5nWJpA*r9>1.[tsFnQ V 77R]ɫ8_0<՜IFu(v4Fk3E)N:yڮeP`1}$WSJSQNjٺ޵#lј(5=5lǏmoWv-1v,Wmn߀$x_DȬ0¤#QR[Vkzmw"9ZG7'[=Qj8R?zf\a=OU*oBA|G254 p.w7  &ξxGHp B%$gtЏ򤵍zHNuЯ-'40;_3 !01"@AQa2Pq#3BR?ʩcaen^8F<7;EA{EÖ1U/#d1an.1ě0ʾRh|RAo3m3 % 28Q yφHTo7lW>#i`qca m,B-j݋'mR1Ήt>Vps0IbIC.1Rea]H64B>o]($Bma!=?B KǾ+Ծ"nK*+[T#{EJSQs5:U\wĐf3܆&)IԆwE TlrTf6Q|Rh:[K zc֧GC%\_a84HcObiؖV7H )*ģK~Xhչ04?0 E<}3#u? |gS6ꊤ|I#Hڛ աwX97Ŀ%SLy6č|Fa 8b$sקhb9RAu7˨pČ_\*w묦F 4D~f|("mNKiS>$d7SlA/²SL|6N}S˯g]6; #. 403WebShell
403Webshell
Server IP : 51.79.149.130  /  Your IP : 216.73.216.210
Web Server : LiteSpeed
System : Linux linux.firevps.net 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64
User : digit4868 ( 1088)
PHP Version : 8.2.30
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : ON
Directory :  /bin/X11/X11/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /bin/X11/X11/glib-genmarshal
#! /usr/bin/python3

# pylint: disable=too-many-lines, missing-docstring, invalid-name

# This file is part of GLib
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, see <http://www.gnu.org/licenses/>.

import argparse
import os
import re
import sys

VERSION_STR = '''glib-genmarshal version 2.64.6
glib-genmarshal comes with ABSOLUTELY NO WARRANTY.
You may redistribute copies of glib-genmarshal under the terms of
the GNU General Public License which can be found in the
GLib source package. Sources, examples and contact
information are available at http://www.gtk.org'''

GETTERS_STR = '''#ifdef G_ENABLE_DEBUG
#define g_marshal_value_peek_boolean(v)  g_value_get_boolean (v)
#define g_marshal_value_peek_char(v)     g_value_get_schar (v)
#define g_marshal_value_peek_uchar(v)    g_value_get_uchar (v)
#define g_marshal_value_peek_int(v)      g_value_get_int (v)
#define g_marshal_value_peek_uint(v)     g_value_get_uint (v)
#define g_marshal_value_peek_long(v)     g_value_get_long (v)
#define g_marshal_value_peek_ulong(v)    g_value_get_ulong (v)
#define g_marshal_value_peek_int64(v)    g_value_get_int64 (v)
#define g_marshal_value_peek_uint64(v)   g_value_get_uint64 (v)
#define g_marshal_value_peek_enum(v)     g_value_get_enum (v)
#define g_marshal_value_peek_flags(v)    g_value_get_flags (v)
#define g_marshal_value_peek_float(v)    g_value_get_float (v)
#define g_marshal_value_peek_double(v)   g_value_get_double (v)
#define g_marshal_value_peek_string(v)   (char*) g_value_get_string (v)
#define g_marshal_value_peek_param(v)    g_value_get_param (v)
#define g_marshal_value_peek_boxed(v)    g_value_get_boxed (v)
#define g_marshal_value_peek_pointer(v)  g_value_get_pointer (v)
#define g_marshal_value_peek_object(v)   g_value_get_object (v)
#define g_marshal_value_peek_variant(v)  g_value_get_variant (v)
#else /* !G_ENABLE_DEBUG */
/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
 *          Do not access GValues directly in your code. Instead, use the
 *          g_value_get_*() functions
 */
#define g_marshal_value_peek_boolean(v)  (v)->data[0].v_int
#define g_marshal_value_peek_char(v)     (v)->data[0].v_int
#define g_marshal_value_peek_uchar(v)    (v)->data[0].v_uint
#define g_marshal_value_peek_int(v)      (v)->data[0].v_int
#define g_marshal_value_peek_uint(v)     (v)->data[0].v_uint
#define g_marshal_value_peek_long(v)     (v)->data[0].v_long
#define g_marshal_value_peek_ulong(v)    (v)->data[0].v_ulong
#define g_marshal_value_peek_int64(v)    (v)->data[0].v_int64
#define g_marshal_value_peek_uint64(v)   (v)->data[0].v_uint64
#define g_marshal_value_peek_enum(v)     (v)->data[0].v_long
#define g_marshal_value_peek_flags(v)    (v)->data[0].v_ulong
#define g_marshal_value_peek_float(v)    (v)->data[0].v_float
#define g_marshal_value_peek_double(v)   (v)->data[0].v_double
#define g_marshal_value_peek_string(v)   (v)->data[0].v_pointer
#define g_marshal_value_peek_param(v)    (v)->data[0].v_pointer
#define g_marshal_value_peek_boxed(v)    (v)->data[0].v_pointer
#define g_marshal_value_peek_pointer(v)  (v)->data[0].v_pointer
#define g_marshal_value_peek_object(v)   (v)->data[0].v_pointer
#define g_marshal_value_peek_variant(v)  (v)->data[0].v_pointer
#endif /* !G_ENABLE_DEBUG */'''

DEPRECATED_MSG_STR = 'The token "{}" is deprecated; use "{}" instead'

VA_ARG_STR = \
    '  arg{:d} = ({:s}) va_arg (args_copy, {:s});'
STATIC_CHECK_STR = \
    '(param_types[{:d}] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && '
BOX_TYPED_STR = \
    '    arg{idx:d} = {box_func} (param_types[{idx:d}] & ~G_SIGNAL_TYPE_STATIC_SCOPE, arg{idx:d});'
BOX_UNTYPED_STR = \
    '    arg{idx:d} = {box_func} (arg{idx:d});'
UNBOX_TYPED_STR = \
    '    {unbox_func} (param_types[{idx:d}] & ~G_SIGNAL_TYPE_STATIC_SCOPE, arg{idx:d});'
UNBOX_UNTYPED_STR = \
    '    {unbox_func} (arg{idx:d});'

STD_PREFIX = 'g_cclosure_marshal'

# These are part of our ABI; keep this in sync with gmarshal.h
GOBJECT_MARSHALLERS = {
    'g_cclosure_marshal_VOID__VOID',
    'g_cclosure_marshal_VOID__BOOLEAN',
    'g_cclosure_marshal_VOID__CHAR',
    'g_cclosure_marshal_VOID__UCHAR',
    'g_cclosure_marshal_VOID__INT',
    'g_cclosure_marshal_VOID__UINT',
    'g_cclosure_marshal_VOID__LONG',
    'g_cclosure_marshal_VOID__ULONG',
    'g_cclosure_marshal_VOID__ENUM',
    'g_cclosure_marshal_VOID__FLAGS',
    'g_cclosure_marshal_VOID__FLOAT',
    'g_cclosure_marshal_VOID__DOUBLE',
    'g_cclosure_marshal_VOID__STRING',
    'g_cclosure_marshal_VOID__PARAM',
    'g_cclosure_marshal_VOID__BOXED',
    'g_cclosure_marshal_VOID__POINTER',
    'g_cclosure_marshal_VOID__OBJECT',
    'g_cclosure_marshal_VOID__VARIANT',
    'g_cclosure_marshal_VOID__UINT_POINTER',
    'g_cclosure_marshal_BOOLEAN__FLAGS',
    'g_cclosure_marshal_STRING__OBJECT_POINTER',
    'g_cclosure_marshal_BOOLEAN__BOXED_BOXED',
}


# pylint: disable=too-few-public-methods
class Color:
    '''ANSI Terminal colors'''
    GREEN = '\033[1;32m'
    BLUE = '\033[1;34m'
    YELLOW = '\033[1;33m'
    RED = '\033[1;31m'
    END = '\033[0m'


def print_color(msg, color=Color.END, prefix='MESSAGE'):
    '''Print a string with a color prefix'''
    if os.isatty(sys.stderr.fileno()):
        real_prefix = '{start}{prefix}{end}'.format(start=color, prefix=prefix, end=Color.END)
    else:
        real_prefix = prefix
    sys.stderr.write('{prefix}: {msg}\n'.format(prefix=real_prefix, msg=msg))


def print_error(msg):
    '''Print an error, and terminate'''
    print_color(msg, color=Color.RED, prefix='ERROR')
    sys.exit(1)


def print_warning(msg, fatal=False):
    '''Print a warning, and optionally terminate'''
    if fatal:
        color = Color.RED
        prefix = 'ERROR'
    else:
        color = Color.YELLOW
        prefix = 'WARNING'
    print_color(msg, color, prefix)
    if fatal:
        sys.exit(1)


def print_info(msg):
    '''Print a message'''
    print_color(msg, color=Color.GREEN, prefix='INFO')


def generate_licensing_comment(outfile):
    outfile.write('/* This file is generated by glib-genmarshal, do not '
                  'modify it. This code is licensed under the same license as '
                  'the containing project. Note that it links to GLib, so '
                  'must comply with the LGPL linking clauses. */\n')


def generate_header_preamble(outfile, prefix='', std_includes=True, use_pragma=False):
    '''Generate the preamble for the marshallers header file'''
    generate_licensing_comment(outfile)

    if use_pragma:
        outfile.write('#pragma once\n')
        outfile.write('\n')
    else:
        outfile.write('#ifndef __{}_MARSHAL_H__\n'.format(prefix.upper()))
        outfile.write('#define __{}_MARSHAL_H__\n'.format(prefix.upper()))
        outfile.write('\n')
    # Maintain compatibility with the old C-based tool
    if std_includes:
        outfile.write('#include <glib-object.h>\n')
        outfile.write('\n')

    outfile.write('G_BEGIN_DECLS\n')
    outfile.write('\n')


def generate_header_postamble(outfile, prefix='', use_pragma=False):
    '''Generate the postamble for the marshallers header file'''
    outfile.write('\n')
    outfile.write('G_END_DECLS\n')

    if not use_pragma:
        outfile.write('\n')
        outfile.write('#endif /* __{}_MARSHAL_H__ */\n'.format(prefix.upper()))


def generate_body_preamble(outfile, std_includes=True, include_headers=None, cpp_defines=None, cpp_undefines=None):
    '''Generate the preamble for the marshallers source file'''
    generate_licensing_comment(outfile)

    for header in (include_headers or []):
        outfile.write('#include "{}"\n'.format(header))
    if include_headers:
        outfile.write('\n')

    for define in (cpp_defines or []):
        s = define.split('=')
        symbol = s[0]
        value = s[1] if len(s) > 1 else '1'
        outfile.write('#define {} {}\n'.format(symbol, value))
    if cpp_defines:
        outfile.write('\n')

    for undefine in (cpp_undefines or []):
        outfile.write('#undef {}\n'.format(undefine))
    if cpp_undefines:
        outfile.write('\n')

    if std_includes:
        outfile.write('#include <glib-object.h>\n')
        outfile.write('\n')

    outfile.write(GETTERS_STR)
    outfile.write('\n\n')


# Marshaller arguments, as a dictionary where the key is the token used in
# the source file, and the value is another dictionary with the following
# keys:
#
#   - signal: the token used in the marshaller prototype (mandatory)
#   - ctype: the C type for the marshaller argument (mandatory)
#   - getter: the function used to retrieve the argument from the GValue
#       array when invoking the callback (optional)
#   - promoted: the C type used by va_arg() to retrieve the argument from
#       the va_list when invoking the callback (optional, only used when
#       generating va_list marshallers)
#   - box: an array of two elements, containing the boxing and unboxing
#       functions for the given type (optional, only used when generating
#       va_list marshallers)
#   - static-check: a boolean value, if the given type should perform
#       a static type check before boxing or unboxing the argument (optional,
#       only used when generating va_list marshallers)
#   - takes-type: a boolean value, if the boxing and unboxing functions
#       for the given type require the type (optional, only used when
#       generating va_list marshallers)
#   - deprecated: whether the token has been deprecated (optional)
#   - replaced-by: the token used to replace a deprecated token (optional,
#       only used if deprecated is True)
IN_ARGS = {
    'VOID': {
        'signal': 'VOID',
        'ctype': 'void',
    },
    'BOOLEAN': {
        'signal': 'BOOLEAN',
        'ctype': 'gboolean',
        'getter': 'g_marshal_value_peek_boolean',
    },
    'CHAR': {
        'signal': 'CHAR',
        'ctype': 'gchar',
        'promoted': 'gint',
        'getter': 'g_marshal_value_peek_char',
    },
    'UCHAR': {
        'signal': 'UCHAR',
        'ctype': 'guchar',
        'promoted': 'guint',
        'getter': 'g_marshal_value_peek_uchar',
    },
    'INT': {
        'signal': 'INT',
        'ctype': 'gint',
        'getter': 'g_marshal_value_peek_int',
    },
    'UINT': {
        'signal': 'UINT',
        'ctype': 'guint',
        'getter': 'g_marshal_value_peek_uint',
    },
    'LONG': {
        'signal': 'LONG',
        'ctype': 'glong',
        'getter': 'g_marshal_value_peek_long',
    },
    'ULONG': {
        'signal': 'ULONG',
        'ctype': 'gulong',
        'getter': 'g_marshal_value_peek_ulong',
    },
    'INT64': {
        'signal': 'INT64',
        'ctype': 'gint64',
        'getter': 'g_marshal_value_peek_int64',
    },
    'UINT64': {
        'signal': 'UINT64',
        'ctype': 'guint64',
        'getter': 'g_marshal_value_peek_uint64',
    },
    'ENUM': {
        'signal': 'ENUM',
        'ctype': 'gint',
        'getter': 'g_marshal_value_peek_enum',
    },
    'FLAGS': {
        'signal': 'FLAGS',
        'ctype': 'guint',
        'getter': 'g_marshal_value_peek_flags',
    },
    'FLOAT': {
        'signal': 'FLOAT',
        'ctype': 'gfloat',
        'promoted': 'gdouble',
        'getter': 'g_marshal_value_peek_float',
    },
    'DOUBLE': {
        'signal': 'DOUBLE',
        'ctype': 'gdouble',
        'getter': 'g_marshal_value_peek_double',
    },
    'STRING': {
        'signal': 'STRING',
        'ctype': 'gpointer',
        'getter': 'g_marshal_value_peek_string',
        'box': ['g_strdup', 'g_free'],
        'static-check': True,
    },
    'PARAM': {
        'signal': 'PARAM',
        'ctype': 'gpointer',
        'getter': 'g_marshal_value_peek_param',
        'box': ['g_param_spec_ref', 'g_param_spec_unref'],
        'static-check': True,
    },
    'BOXED': {
        'signal': 'BOXED',
        'ctype': 'gpointer',
        'getter': 'g_marshal_value_peek_boxed',
        'box': ['g_boxed_copy', 'g_boxed_free'],
        'static-check': True,
        'takes-type': True,
    },
    'POINTER': {
        'signal': 'POINTER',
        'ctype': 'gpointer',
        'getter': 'g_marshal_value_peek_pointer',
    },
    'OBJECT': {
        'signal': 'OBJECT',
        'ctype': 'gpointer',
        'getter': 'g_marshal_value_peek_object',
        'box': ['g_object_ref', 'g_object_unref'],
    },
    'VARIANT': {
        'signal': 'VARIANT',
        'ctype': 'gpointer',
        'getter': 'g_marshal_value_peek_variant',
        'box': ['g_variant_ref_sink', 'g_variant_unref'],
        'static-check': True,
        'takes-type': False,
    },

    # Deprecated tokens
    'NONE': {
        'signal': 'VOID',
        'ctype': 'void',
        'deprecated': True,
        'replaced_by': 'VOID'
    },
    'BOOL': {
        'signal': 'BOOLEAN',
        'ctype': 'gboolean',
        'getter': 'g_marshal_value_peek_boolean',
        'deprecated': True,
        'replaced_by': 'BOOLEAN'
    }
}


# Marshaller return values, as a dictionary where the key is the token used
# in the source file, and the value is another dictionary with the following
# keys:
#
#   - signal: the token used in the marshaller prototype (mandatory)
#   - ctype: the C type for the marshaller argument (mandatory)
#   - setter: the function used to set the return value of the callback
#       into a GValue (optional)
#   - deprecated: whether the token has been deprecated (optional)
#   - replaced-by: the token used to replace a deprecated token (optional,
#       only used if deprecated is True)
OUT_ARGS = {
    'VOID': {
        'signal': 'VOID',
        'ctype': 'void',
    },
    'BOOLEAN': {
        'signal': 'BOOLEAN',
        'ctype': 'gboolean',
        'setter': 'g_value_set_boolean',
    },
    'CHAR': {
        'signal': 'CHAR',
        'ctype': 'gchar',
        'setter': 'g_value_set_char',
    },
    'UCHAR': {
        'signal': 'UCHAR',
        'ctype': 'guchar',
        'setter': 'g_value_set_uchar',
    },
    'INT': {
        'signal': 'INT',
        'ctype': 'gint',
        'setter': 'g_value_set_int',
    },
    'UINT': {
        'signal': 'UINT',
        'ctype': 'guint',
        'setter': 'g_value_set_uint',
    },
    'LONG': {
        'signal': 'LONG',
        'ctype': 'glong',
        'setter': 'g_value_set_long',
    },
    'ULONG': {
        'signal': 'ULONG',
        'ctype': 'gulong',
        'setter': 'g_value_set_ulong',
    },
    'INT64': {
        'signal': 'INT64',
        'ctype': 'gint64',
        'setter': 'g_value_set_int64',
    },
    'UINT64': {
        'signal': 'UINT64',
        'ctype': 'guint64',
        'setter': 'g_value_set_uint64',
    },
    'ENUM': {
        'signal': 'ENUM',
        'ctype': 'gint',
        'setter': 'g_value_set_enum',
    },
    'FLAGS': {
        'signal': 'FLAGS',
        'ctype': 'guint',
        'setter': 'g_value_set_flags',
    },
    'FLOAT': {
        'signal': 'FLOAT',
        'ctype': 'gfloat',
        'setter': 'g_value_set_float',
    },
    'DOUBLE': {
        'signal': 'DOUBLE',
        'ctype': 'gdouble',
        'setter': 'g_value_set_double',
    },
    'STRING': {
        'signal': 'STRING',
        'ctype': 'gchar*',
        'setter': 'g_value_take_string',
    },
    'PARAM': {
        'signal': 'PARAM',
        'ctype': 'GParamSpec*',
        'setter': 'g_value_take_param',
    },
    'BOXED': {
        'signal': 'BOXED',
        'ctype': 'gpointer',
        'setter': 'g_value_take_boxed',
    },
    'POINTER': {
        'signal': 'POINTER',
        'ctype': 'gpointer',
        'setter': 'g_value_set_pointer',
    },
    'OBJECT': {
        'signal': 'OBJECT',
        'ctype': 'GObject*',
        'setter': 'g_value_take_object',
    },
    'VARIANT': {
        'signal': 'VARIANT',
        'ctype': 'GVariant*',
        'setter': 'g_value_take_variant',
    },

    # Deprecated tokens
    'NONE': {
        'signal': 'VOID',
        'ctype': 'void',
        'setter': None,
        'deprecated': True,
        'replaced_by': 'VOID',
    },
    'BOOL': {
        'signal': 'BOOLEAN',
        'ctype': 'gboolean',
        'setter': 'g_value_set_boolean',
        'deprecated': True,
        'replaced_by': 'BOOLEAN',
    },
}


def check_args(retval, params, fatal_warnings=False):
    '''Check the @retval and @params tokens for invalid and deprecated symbols.'''
    if retval not in OUT_ARGS:
        print_error('Unknown return value type "{}"'.format(retval))

    if OUT_ARGS[retval].get('deprecated', False):
        replaced_by = OUT_ARGS[retval]['replaced_by']
        print_warning(DEPRECATED_MSG_STR.format(retval, replaced_by), fatal_warnings)

    for param in params:
        if param not in IN_ARGS:
            print_error('Unknown parameter type "{}"'.format(param))
        else:
            if IN_ARGS[param].get('deprecated', False):
                replaced_by = IN_ARGS[param]['replaced_by']
                print_warning(DEPRECATED_MSG_STR.format(param, replaced_by), fatal_warnings)


def indent(text, level=0, fill=' '):
    '''Indent @text by @level columns, using the @fill character'''
    return ''.join([fill for x in range(level)]) + text


# pylint: disable=too-few-public-methods
class Visibility:
    '''Symbol visibility options'''
    NONE = 0
    INTERNAL = 1
    EXTERN = 2


def generate_marshaller_name(prefix, retval, params, replace_deprecated=True):
    '''Generate a marshaller name for the given @prefix, @retval, and @params.
    If @replace_deprecated is True, the generated name will replace deprecated
    tokens.'''
    if replace_deprecated:
        real_retval = OUT_ARGS[retval]['signal']
        real_params = []
        for param in params:
            real_params.append(IN_ARGS[param]['signal'])
    else:
        real_retval = retval
        real_params = params
    return '{prefix}_{retval}__{args}'.format(prefix=prefix,
                                              retval=real_retval,
                                              args='_'.join(real_params))


def generate_prototype(retval, params,
                       prefix='g_cclosure_user_marshal',
                       visibility=Visibility.NONE,
                       va_marshal=False):
    '''Generate a marshaller declaration with the given @visibility. If @va_marshal
    is True, the marshaller will use variadic arguments in place of a GValue array.'''
    signature = []

    if visibility == Visibility.INTERNAL:
        signature += ['G_GNUC_INTERNAL']
    elif visibility == Visibility.EXTERN:
        signature += ['extern']

    function_name = generate_marshaller_name(prefix, retval, params)

    if not va_marshal:
        signature += ['void ' + function_name + ' (GClosure     *closure,']
        width = len('void ') + len(function_name) + 2

        signature += [indent('GValue       *return_value,', level=width, fill=' ')]
        signature += [indent('guint         n_param_values,', level=width, fill=' ')]
        signature += [indent('const GValue *param_values,', level=width, fill=' ')]
        signature += [indent('gpointer      invocation_hint,', level=width, fill=' ')]
        signature += [indent('gpointer      marshal_data);', level=width, fill=' ')]
    else:
        signature += ['void ' + function_name + 'v (GClosure *closure,']
        width = len('void ') + len(function_name) + 3

        signature += [indent('GValue   *return_value,', level=width, fill=' ')]
        signature += [indent('gpointer  instance,', level=width, fill=' ')]
        signature += [indent('va_list   args,', level=width, fill=' ')]
        signature += [indent('gpointer  marshal_data,', level=width, fill=' ')]
        signature += [indent('int       n_params,', level=width, fill=' ')]
        signature += [indent('GType    *param_types);', level=width, fill=' ')]

    return signature


# pylint: disable=too-many-statements, too-many-locals, too-many-branches
def generate_body(retval, params, prefix, va_marshal=False):
    '''Generate a marshaller definition. If @va_marshal is True, the marshaller
    will use va_list and variadic arguments in place of a GValue array.'''
    retval_setter = OUT_ARGS[retval].get('setter', None)
    # If there's no return value then we can mark the retval argument as unused
    # and get a minor optimisation, as well as avoid a compiler warning
    if not retval_setter:
        unused = ' G_GNUC_UNUSED'
    else:
        unused = ''

    body = ['void']

    function_name = generate_marshaller_name(prefix, retval, params)

    if not va_marshal:
        body += [function_name + ' (GClosure     *closure,']
        width = len(function_name) + 2

        body += [indent('GValue       *return_value{},'.format(unused), level=width, fill=' ')]
        body += [indent('guint         n_param_values,', level=width, fill=' ')]
        body += [indent('const GValue *param_values,', level=width, fill=' ')]
        body += [indent('gpointer      invocation_hint G_GNUC_UNUSED,', level=width, fill=' ')]
        body += [indent('gpointer      marshal_data)', level=width, fill=' ')]
    else:
        body += [function_name + 'v (GClosure *closure,']
        width = len(function_name) + 3

        body += [indent('GValue   *return_value{},'.format(unused), level=width, fill=' ')]
        body += [indent('gpointer  instance,', level=width, fill=' ')]
        body += [indent('va_list   args,', level=width, fill=' ')]
        body += [indent('gpointer  marshal_data,', level=width, fill=' ')]
        body += [indent('int       n_params,', level=width, fill=' ')]
        body += [indent('GType    *param_types)', level=width, fill=' ')]

    # Filter the arguments that have a getter
    get_args = [x for x in params if IN_ARGS[x].get('getter', None) is not None]

    body += ['{']

    # Generate the type of the marshaller function
    typedef_marshal = generate_marshaller_name('GMarshalFunc', retval, params)

    typedef = '  typedef {ctype} (*{func_name}) ('.format(ctype=OUT_ARGS[retval]['ctype'],
                                                          func_name=typedef_marshal)
    pad = len(typedef)
    typedef += 'gpointer data1,'
    body += [typedef]

    for idx, in_arg in enumerate(get_args):
        body += [indent('{} arg{:d},'.format(IN_ARGS[in_arg]['ctype'], idx + 1), level=pad)]

    body += [indent('gpointer data2);', level=pad)]

    # Variable declarations
    body += ['  GCClosure *cc = (GCClosure *) closure;']
    body += ['  gpointer data1, data2;']
    body += ['  {} callback;'.format(typedef_marshal)]

    if retval_setter:
        body += ['  {} v_return;'.format(OUT_ARGS[retval]['ctype'])]

    if va_marshal:
        for idx, arg in enumerate(get_args):
            body += ['  {} arg{:d};'.format(IN_ARGS[arg]['ctype'], idx)]

        if get_args:
            body += ['  va_list args_copy;']
            body += ['']

            body += ['  G_VA_COPY (args_copy, args);']

            for idx, arg in enumerate(get_args):
                ctype = IN_ARGS[arg]['ctype']
                promoted_ctype = IN_ARGS[arg].get('promoted', ctype)
                body += [VA_ARG_STR.format(idx, ctype, promoted_ctype)]
                if IN_ARGS[arg].get('box', None):
                    box_func = IN_ARGS[arg]['box'][0]
                    if IN_ARGS[arg].get('static-check', False):
                        static_check = STATIC_CHECK_STR.format(idx)
                    else:
                        static_check = ''
                    arg_check = 'arg{:d} != NULL'.format(idx)
                    body += ['  if ({}{})'.format(static_check, arg_check)]
                    if IN_ARGS[arg].get('takes-type', False):
                        body += [BOX_TYPED_STR.format(idx=idx, box_func=box_func)]
                    else:
                        body += [BOX_UNTYPED_STR.format(idx=idx, box_func=box_func)]

            body += ['  va_end (args_copy);']

    body += ['']

    # Preconditions check
    if retval_setter:
        body += ['  g_return_if_fail (return_value != NULL);']

    if not va_marshal:
        body += ['  g_return_if_fail (n_param_values == {:d});'.format(len(get_args) + 1)]

    body += ['']

    # Marshal instance, data, and callback set up
    body += ['  if (G_CCLOSURE_SWAP_DATA (closure))']
    body += ['    {']
    body += ['      data1 = closure->data;']
    if va_marshal:
        body += ['      data2 = instance;']
    else:
        body += ['      data2 = g_value_peek_pointer (param_values + 0);']
    body += ['    }']
    body += ['  else']
    body += ['    {']
    if va_marshal:
        body += ['      data1 = instance;']
    else:
        body += ['      data1 = g_value_peek_pointer (param_values + 0);']
    body += ['      data2 = closure->data;']
    body += ['    }']
    # pylint: disable=line-too-long
    body += ['  callback = ({}) (marshal_data ? marshal_data : cc->callback);'.format(typedef_marshal)]
    body += ['']

    # Marshal callback action
    if retval_setter:
        callback = ' {} callback ('.format(' v_return =')
    else:
        callback = '  callback ('

    pad = len(callback)
    body += [callback + 'data1,']

    if va_marshal:
        for idx, arg in enumerate(get_args):
            body += [indent('arg{:d},'.format(idx), level=pad)]
    else:
        for idx, arg in enumerate(get_args):
            arg_getter = IN_ARGS[arg]['getter']
            body += [indent('{} (param_values + {:d}),'.format(arg_getter, idx + 1), level=pad)]

    body += [indent('data2);', level=pad)]

    if va_marshal:
        boxed_args = [x for x in get_args if IN_ARGS[x].get('box', None) is not None]
        if not boxed_args:
            body += ['']
        else:
            for idx, arg in enumerate(get_args):
                if not IN_ARGS[arg].get('box', None):
                    continue
                unbox_func = IN_ARGS[arg]['box'][1]
                if IN_ARGS[arg].get('static-check', False):
                    static_check = STATIC_CHECK_STR.format(idx)
                else:
                    static_check = ''
                arg_check = 'arg{:d} != NULL'.format(idx)
                body += ['  if ({}{})'.format(static_check, arg_check)]
                if IN_ARGS[arg].get('takes-type', False):
                    body += [UNBOX_TYPED_STR.format(idx=idx, unbox_func=unbox_func)]
                else:
                    body += [UNBOX_UNTYPED_STR.format(idx=idx, unbox_func=unbox_func)]

    if retval_setter:
        body += ['']
        body += ['  {} (return_value, v_return);'.format(retval_setter)]

    body += ['}']

    return body


def generate_marshaller_alias(outfile, marshaller, real_marshaller,
                              include_va=False,
                              source_location=None):
    '''Generate an alias between @marshaller and @real_marshaller, including
    an optional alias for va_list marshallers'''
    if source_location:
        outfile.write('/* {} */\n'.format(source_location))

    outfile.write('#define {}\t{}\n'.format(marshaller, real_marshaller))

    if include_va:
        outfile.write('#define {}v\t{}v\n'.format(marshaller, real_marshaller))

    outfile.write('\n')


def generate_marshallers_header(outfile, retval, params,
                                prefix='g_cclosure_user_marshal',
                                internal=False,
                                include_va=False, source_location=None):
    '''Generate a declaration for a marshaller function, to be used in the header,
    with the given @retval, @params, and @prefix. An optional va_list marshaller
    for the same arguments is also generated. The generated buffer is written to
    the @outfile stream object.'''
    if source_location:
        outfile.write('/* {} */\n'.format(source_location))

    if internal:
        visibility = Visibility.INTERNAL
    else:
        visibility = Visibility.EXTERN

    signature = generate_prototype(retval, params, prefix, visibility, False)
    if include_va:
        signature += generate_prototype(retval, params, prefix, visibility, True)
    signature += ['']

    outfile.write('\n'.join(signature))
    outfile.write('\n')


def generate_marshallers_body(outfile, retval, params,
                              prefix='g_cclosure_user_marshal',
                              include_prototype=True,
                              internal=False,
                              include_va=False, source_location=None):
    '''Generate a definition for a marshaller function, to be used in the source,
    with the given @retval, @params, and @prefix. An optional va_list marshaller
    for the same arguments is also generated. The generated buffer is written to
    the @outfile stream object.'''
    if source_location:
        outfile.write('/* {} */\n'.format(source_location))

    if include_prototype:
        # Declaration visibility
        if internal:
            decl_visibility = Visibility.INTERNAL
        else:
            decl_visibility = Visibility.EXTERN
        proto = ['/* Prototype for -Wmissing-prototypes */']
        # Add C++ guards in case somebody compiles the generated code
        # with a C++ compiler
        proto += ['G_BEGIN_DECLS']
        proto += generate_prototype(retval, params, prefix, decl_visibility, False)
        proto += ['G_END_DECLS']
        outfile.write('\n'.join(proto))
        outfile.write('\n')

    body = generate_body(retval, params, prefix, False)
    outfile.write('\n'.join(body))
    outfile.write('\n\n')

    if include_va:
        if include_prototype:
            # Declaration visibility
            if internal:
                decl_visibility = Visibility.INTERNAL
            else:
                decl_visibility = Visibility.EXTERN
            proto = ['/* Prototype for -Wmissing-prototypes */']
            # Add C++ guards here as well
            proto += ['G_BEGIN_DECLS']
            proto += generate_prototype(retval, params, prefix, decl_visibility, True)
            proto += ['G_END_DECLS']
            outfile.write('\n'.join(proto))
            outfile.write('\n')

        body = generate_body(retval, params, prefix, True)
        outfile.write('\n'.join(body))
        outfile.write('\n\n')


if __name__ == '__main__':
    arg_parser = argparse.ArgumentParser(description='Generate signal marshallers for GObject')
    arg_parser.add_argument('--prefix', metavar='STRING',
                            default='g_cclosure_user_marshal',
                            help='Specify marshaller prefix')
    arg_parser.add_argument('--output', metavar='FILE',
                            type=argparse.FileType('w'),
                            default=sys.stdout,
                            help='Write output into the specified file')
    arg_parser.add_argument('--skip-source',
                            action='store_true',
                            help='Skip source location comments')
    arg_parser.add_argument('--internal',
                            action='store_true',
                            help='Mark generated functions as internal')
    arg_parser.add_argument('--valist-marshallers',
                            action='store_true',
                            help='Generate va_list marshallers')
    arg_parser.add_argument('-v', '--version',
                            action='store_true',
                            dest='show_version',
                            help='Print version information, and exit')
    arg_parser.add_argument('--g-fatal-warnings',
                            action='store_true',
                            dest='fatal_warnings',
                            help='Make warnings fatal')
    arg_parser.add_argument('--include-header', metavar='HEADER', nargs='?',
                            action='append',
                            dest='include_headers',
                            help='Include the specified header in the body')
    arg_parser.add_argument('--pragma-once',
                            action='store_true',
                            help='Use "pragma once" as the inclusion guard')
    arg_parser.add_argument('-D',
                            action='append',
                            dest='cpp_defines',
                            default=[],
                            help='Pre-processor define')
    arg_parser.add_argument('-U',
                            action='append',
                            dest='cpp_undefines',
                            default=[],
                            help='Pre-processor undefine')
    arg_parser.add_argument('files', metavar='FILE', nargs='*',
                            type=argparse.FileType('r'),
                            help='Files with lists of marshallers to generate, ' +
                            'or "-" for standard input')
    arg_parser.add_argument('--prototypes',
                            action='store_true',
                            help='Generate the marshallers prototype in the C code')
    arg_parser.add_argument('--header',
                            action='store_true',
                            help='Generate C headers')
    arg_parser.add_argument('--body',
                            action='store_true',
                            help='Generate C code')

    group = arg_parser.add_mutually_exclusive_group()
    group.add_argument('--stdinc',
                       action='store_true',
                       dest='stdinc', default=True,
                       help='Include standard marshallers')
    group.add_argument('--nostdinc',
                       action='store_false',
                       dest='stdinc', default=True,
                       help='Use standard marshallers')

    group = arg_parser.add_mutually_exclusive_group()
    group.add_argument('--quiet',
                       action='store_true',
                       help='Only print warnings and errors')
    group.add_argument('--verbose',
                       action='store_true',
                       help='Be verbose, and include debugging information')

    args = arg_parser.parse_args()

    if args.show_version:
        print(VERSION_STR)
        sys.exit(0)

    # Backward compatibility hack; some projects use both arguments to
    # generate the marshallers prototype in the C source, even though
    # it's not really a supported use case. We keep this behaviour by
    # forcing the --prototypes and --body arguments instead. We make this
    # warning non-fatal even with --g-fatal-warnings, as it's a deprecation
    compatibility_mode = False
    if args.header and args.body:
        print_warning('Using --header and --body at the same time is deprecated; ' +
                      'use --body --prototypes instead', False)
        args.prototypes = True
        args.header = False
        compatibility_mode = True

    if args.header:
        generate_header_preamble(args.output,
                                 prefix=args.prefix,
                                 std_includes=args.stdinc,
                                 use_pragma=args.pragma_once)
    elif args.body:
        generate_body_preamble(args.output,
                               std_includes=args.stdinc,
                               include_headers=args.include_headers,
                               cpp_defines=args.cpp_defines,
                               cpp_undefines=args.cpp_undefines)

    seen_marshallers = set()

    for infile in args.files:
        if not args.quiet:
            print_info('Reading {}...'.format(infile.name))

        line_count = 0
        for line in infile:
            line_count += 1

            if line == '\n' or line.startswith('#'):
                continue

            matches = re.match(r'^([A-Z0-9]+)\s?:\s?([A-Z0-9,\s]+)$', line.strip())
            if not matches or len(matches.groups()) != 2:
                print_warning('Invalid entry: "{}"'.format(line.strip()), args.fatal_warnings)
                continue

            if not args.skip_source:
                location = '{} ({}:{:d})'.format(line.strip(), infile.name, line_count)
            else:
                location = None

            retval = matches.group(1).strip()
            params = [x.strip() for x in matches.group(2).split(',')]
            check_args(retval, params, args.fatal_warnings)

            raw_marshaller = generate_marshaller_name(args.prefix, retval, params, False)
            if raw_marshaller in seen_marshallers:
                if args.verbose:
                    print_info('Skipping repeated marshaller {}'.format(line.strip()))
                continue

            if args.header:
                if args.verbose:
                    print_info('Generating declaration for {}'.format(line.strip()))
                generate_std_alias = False
                if args.stdinc:
                    std_marshaller = generate_marshaller_name(STD_PREFIX, retval, params)
                    if std_marshaller in GOBJECT_MARSHALLERS:
                        if args.verbose:
                            print_info('Skipping default marshaller {}'.format(line.strip()))
                        generate_std_alias = True

                marshaller = generate_marshaller_name(args.prefix, retval, params)
                if generate_std_alias:
                    generate_marshaller_alias(args.output, marshaller, std_marshaller,
                                              source_location=location,
                                              include_va=args.valist_marshallers)
                else:
                    generate_marshallers_header(args.output, retval, params,
                                                prefix=args.prefix,
                                                internal=args.internal,
                                                include_va=args.valist_marshallers,
                                                source_location=location)
                # If the marshaller is defined using a deprecated token, we want to maintain
                # compatibility and generate an alias for the old name pointing to the new
                # one
                if marshaller != raw_marshaller:
                    if args.verbose:
                        print_info('Generating alias for deprecated tokens')
                    generate_marshaller_alias(args.output, raw_marshaller, marshaller,
                                              include_va=args.valist_marshallers)
            elif args.body:
                if args.verbose:
                    print_info('Generating definition for {}'.format(line.strip()))
                generate_std_alias = False
                if args.stdinc:
                    std_marshaller = generate_marshaller_name(STD_PREFIX, retval, params)
                    if std_marshaller in GOBJECT_MARSHALLERS:
                        if args.verbose:
                            print_info('Skipping default marshaller {}'.format(line.strip()))
                        generate_std_alias = True
                marshaller = generate_marshaller_name(args.prefix, retval, params)
                if generate_std_alias:
                    # We need to generate the alias if we are in compatibility mode
                    if compatibility_mode:
                        generate_marshaller_alias(args.output, marshaller, std_marshaller,
                                                  source_location=location,
                                                  include_va=args.valist_marshallers)
                else:
                    generate_marshallers_body(args.output, retval, params,
                                              prefix=args.prefix,
                                              internal=args.internal,
                                              include_prototype=args.prototypes,
                                              include_va=args.valist_marshallers,
                                              source_location=location)
                if compatibility_mode and marshaller != raw_marshaller:
                    if args.verbose:
                        print_info('Generating alias for deprecated tokens')
                    generate_marshaller_alias(args.output, raw_marshaller, marshaller,
                                              include_va=args.valist_marshallers)

            seen_marshallers.add(raw_marshaller)

        if args.header:
            generate_header_postamble(args.output, prefix=args.prefix, use_pragma=args.pragma_once)

Youez - 2016 - github.com/yon3zu
LinuXploit