2
0

interfaceMakerPythonNative.cxx 176 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704
  1. // Filename: interfaceMakerPythonNative.cxx
  2. ////////////////////////////////////////////////////////////////////
  3. //
  4. // PANDA 3D SOFTWARE
  5. // Copyright (c) Carnegie Mellon University. All rights reserved.
  6. //
  7. // All use of this software is subject to the terms of the revised BSD
  8. // license. You should have received a copy of this license along
  9. // with this source code in a file named "LICENSE."
  10. //
  11. ////////////////////////////////////////////////////////////////////
  12. #include "interfaceMakerPythonNative.h"
  13. #include "interrogateBuilder.h"
  14. #include "interrogate.h"
  15. #include "functionRemap.h"
  16. #include "parameterRemapUnchanged.h"
  17. #include "typeManager.h"
  18. #include "interrogateDatabase.h"
  19. #include "interrogateType.h"
  20. #include "interrogateFunction.h"
  21. #include "cppFunctionType.h"
  22. #include "cppPointerType.h"
  23. #include "cppTypeDeclaration.h"
  24. #include "cppStructType.h"
  25. #include "vector"
  26. #include "cppParameterList.h"
  27. #include "algorithm"
  28. #include <set>
  29. #include <map>
  30. extern bool inside_python_native;
  31. extern InterrogateType dummy_type;
  32. extern std::string EXPORT_IMPORT_PREFIX;
  33. #define CLASS_PREFIX "Dtool_"
  34. #define INSTANCE_PREFIX "Dtool_"
  35. #define BASE_INSTANCE_NAME "Dtool_PyInstDef"
  36. /////////////////////////////////////////////////////////
  37. // Name Remapper...
  38. // Snagged from ffi py code....
  39. /////////////////////////////////////////////////////////
  40. struct RenameSet {
  41. const char *_from;
  42. const char *_to;
  43. int function_type;
  44. };
  45. struct FlagSet {
  46. const char *_to;
  47. int function_type;
  48. };
  49. ///////////////////////////////////////////////////////////////////////////////////////
  50. RenameSet methodRenameDictionary[] = {
  51. { "operator ==" , "__eq__", 0 },
  52. { "operator !=" , "__ne__", 0 },
  53. { "operator << " , "__lshift__", 0 },
  54. { "operator >>" , "__rshift__", 0 },
  55. { "operator <" , "__lt__", 0 },
  56. { "operator >" , "__gt__", 0 },
  57. { "operator <=" , "__le__", 0 },
  58. { "operator >=" , "__ge__", 0 },
  59. { "operator =" , "assign", 0 },
  60. { "operator ()" , "__call__", 0 },
  61. { "operator []" , "__getitem__", 0 },
  62. { "operator ++unary", "increment", 0 },
  63. { "operator ++" , "increment", 0 },
  64. { "operator --unary", "decrement", 0 },
  65. { "operator --" , "decrement", 0 },
  66. { "operator ^" , "__xor__", 0 },
  67. { "operator %" , "__mod__", 0 },
  68. { "operator !" , "logicalNot", 0 },
  69. { "operator ~unary", "__invert__", 0 },
  70. { "operator &" , "__and__", 0 },
  71. { "operator &&" , "logicalAnd", 0 },
  72. { "operator |" , "__or__", 0 },
  73. { "operator ||" , "logicalOr", 0 },
  74. { "operator +" , "__add__", 0 },
  75. { "operator -" , "__sub__", 0 },
  76. { "operator -unary", "__neg__", 0 },
  77. { "operator *" , "__mul__", 0 },
  78. { "operator /" , "__div__", 0 },
  79. { "operator +=" , "__iadd__", 1 },
  80. { "operator -=" , "__isub__", 1 },
  81. { "operator *=" , "__imul__", 1 },
  82. { "operator /=" , "__idiv__", 1 },
  83. { "operator ," , "concatenate", 0 },
  84. { "operator |=" , "__ior__", 1 },
  85. { "operator &=" , "__iand__", 1 },
  86. { "operator ^=" , "__ixor__", 1 },
  87. { "operator ~=" , "bitwiseNotEqual", 0 },
  88. { "operator ->" , "dereference", 0 },
  89. { "operator <<=" , "__ilshift__", 1 },
  90. { "operator >>=" , "__irshift__", 1 },
  91. { "operator typecast bool", "__nonzero__", 0 },
  92. { "__nonzero__" , "__nonzero__", 0 },
  93. { "__reduce__" , "__reduce__", 0 },
  94. { "__reduce_persist__", "__reduce_persist__", 0 },
  95. { "__copy__" , "__copy__", 0 },
  96. { "__deepcopy__" , "__deepcopy__", 0 },
  97. { "print" , "Cprint", 0 },
  98. { "CInterval.set_t", "_priv__cSetT", 0 },
  99. { "__bool__" , "__bool__", 0 },
  100. { "__bytes__" , "__bytes__", 0 },
  101. { "__iter__" , "__iter__", 0 },
  102. { "__getbuffer__" , "__getbuffer__", 0 },
  103. { "__releasebuffer__", "__releasebuffer__", 0 },
  104. { NULL, NULL, -1 }
  105. };
  106. const char *InPlaceSet[] = {
  107. "__iadd__",
  108. "__isub__",
  109. "__imul__",
  110. "__idiv__",
  111. "__ior__",
  112. "__iand__",
  113. "__ixor__",
  114. "__ilshift__",
  115. "__irshift__",
  116. "__itruediv__",
  117. "__ifloordiv__",
  118. "__imod__",
  119. "__ipow__",
  120. NULL,
  121. };
  122. ///////////////////////////////////////////////////////////////////////////////////////
  123. RenameSet classRenameDictionary[] = {
  124. // No longer used, now empty.
  125. { NULL, NULL, -1 }
  126. };
  127. ///////////////////////////////////////////////////////////////////////////////////////
  128. ///////////////////////////////////////////////////////////////////////////////////////
  129. const char *pythonKeywords[] = {
  130. "and",
  131. "as",
  132. "assert",
  133. "break",
  134. "class",
  135. "continue",
  136. "def",
  137. "del",
  138. "elif",
  139. "else",
  140. "except",
  141. "exec",
  142. "finally",
  143. "for",
  144. "from",
  145. "global",
  146. "if",
  147. "import",
  148. "in",
  149. "is",
  150. "lambda",
  151. "nonlocal",
  152. "not",
  153. "or",
  154. "pass",
  155. "print",
  156. "raise",
  157. "return",
  158. "try",
  159. "while",
  160. "with",
  161. "yield",
  162. NULL
  163. };
  164. ///////////////////////////////////////////////////////////////////////////////////////
  165. std::string
  166. checkKeyword(std::string &cppName) {
  167. for (int x = 0; pythonKeywords[x] != NULL; x++) {
  168. if (cppName == pythonKeywords[x]) {
  169. return std::string("_") + cppName;
  170. }
  171. }
  172. return cppName;
  173. }
  174. ///////////////////////////////////////////////////////////////////////////////////////
  175. ///////////////////////////////////////////////////////////////////////////////////////
  176. std::string
  177. classNameFromCppName(const std::string &cppName, bool mangle) {
  178. //# initialize to empty string
  179. std::string className = "";
  180. //# These are the characters we want to strip out of the name
  181. const std::string badChars("!@#$%^&*()<>,.-=+~{}? ");
  182. bool nextCap = false;
  183. bool firstChar = true && mangle;
  184. for (std::string::const_iterator chr = cppName.begin();
  185. chr != cppName.end();
  186. chr++) {
  187. if ((*chr == '_' || *chr == ' ') && mangle) {
  188. nextCap = true;
  189. } else if (badChars.find(*chr) != std::string::npos) {
  190. if (!mangle) {
  191. className += '_';
  192. }
  193. } else if (nextCap || firstChar) {
  194. className += toupper(*chr);
  195. nextCap = false;
  196. firstChar = false;
  197. } else {
  198. className += * chr;
  199. }
  200. }
  201. for (int x = 0; classRenameDictionary[x]._from != NULL; x++) {
  202. if (cppName == classRenameDictionary[x]._from) {
  203. className = classRenameDictionary[x]._to;
  204. }
  205. }
  206. if (className.empty()) {
  207. std::string text = "** ERROR ** Renaming class: " + cppName + " to empty string";
  208. printf("%s", text.c_str());
  209. }
  210. className = checkKeyword(className);
  211. //# FFIConstants.notify.debug('Renaming class: ' + cppName + ' to: ' + className)
  212. return className;
  213. }
  214. ///////////////////////////////////////////////////////////////////////////////////////
  215. ///////////////////////////////////////////////////////////////////////////////////////
  216. std::string
  217. methodNameFromCppName(const std::string &cppName, const std::string &className, bool mangle) {
  218. std::string origName = cppName;
  219. if (origName.substr(0, 6) == "__py__") {
  220. // By convention, a leading prefix of "__py__" is stripped. This
  221. // indicates a Python-specific variant of a particular method.
  222. origName = origName.substr(6);
  223. }
  224. std::string methodName;
  225. const std::string badChars("!@#$%^&*()<>,.-=+~{}? ");
  226. bool nextCap = false;
  227. for (std::string::const_iterator chr = origName.begin();
  228. chr != origName.end();
  229. chr++) {
  230. if ((*chr == '_' || *chr == ' ') && mangle) {
  231. nextCap = true;
  232. } else if (badChars.find(*chr) != std::string::npos) {
  233. if (!mangle) {
  234. methodName += '_';
  235. }
  236. } else if (nextCap) {
  237. methodName += toupper(*chr);
  238. nextCap = false;
  239. } else {
  240. methodName += *chr;
  241. }
  242. }
  243. for (int x = 0; methodRenameDictionary[x]._from != NULL; x++) {
  244. if (origName == methodRenameDictionary[x]._from) {
  245. methodName = methodRenameDictionary[x]._to;
  246. }
  247. }
  248. if (className.size() > 0) {
  249. string lookup_name = className + '.' + cppName;
  250. for (int x = 0; classRenameDictionary[x]._from != NULL; x++) {
  251. if (lookup_name == methodRenameDictionary[x]._from) {
  252. methodName = methodRenameDictionary[x]._to;
  253. }
  254. }
  255. }
  256. // # Mangle names that happen to be python keywords so they are not anymore
  257. methodName = checkKeyword(methodName);
  258. return methodName;
  259. }
  260. std::string methodNameFromCppName(InterfaceMaker::Function *func, const std::string &className, bool mangle) {
  261. std::string cppName = func->_ifunc.get_name();
  262. if (func->_ifunc.is_unary_op()) {
  263. cppName += "unary";
  264. }
  265. return methodNameFromCppName(cppName, className, mangle);
  266. }
  267. ///////////////////////////////////////////////////////////////////////////////////////
  268. ///////////////////////////////////////////////////////////////////////////////////////
  269. bool isInplaceFunction(InterfaceMaker::Function *func) {
  270. std::string wname = methodNameFromCppName(func, "", false);
  271. for (int x = 0; InPlaceSet[x] != NULL; x++) {
  272. if (InPlaceSet[x] == wname) {
  273. return true;
  274. }
  275. }
  276. return false;
  277. }
  278. ////////////////////////////////////////////////////////////////////
  279. // Function: InterfaceMakerPythonNative::get_slotted_function_def
  280. // Access: Private, Static
  281. // Description: Determines whether this method should be mapped to
  282. // one of Python's special slotted functions, those
  283. // hard-coded functions that are assigned to particular
  284. // function pointers within the object structure, for
  285. // special functions like __getitem__ and __len__.
  286. //
  287. // Returns true if it has such a mapping, false if it is
  288. // just a normal method. If it returns true, the
  289. // SlottedFunctionDef structure is filled in with the
  290. // important details.
  291. ////////////////////////////////////////////////////////////////////
  292. bool InterfaceMakerPythonNative::
  293. get_slotted_function_def(Object *obj, Function *func, SlottedFunctionDef &def) {
  294. def._answer_location = string();
  295. def._wrapper_type = WT_none;
  296. def._min_version = 0;
  297. string method_name = func->_ifunc.get_name();
  298. bool is_unary_op = func->_ifunc.is_unary_op();
  299. if (method_name == "operator +") {
  300. def._answer_location = "tp_as_number->nb_add";
  301. def._wrapper_type = WT_numeric_operator;
  302. return true;
  303. }
  304. if (method_name == "operator -" && is_unary_op) {
  305. def._answer_location = "tp_as_number->nb_negative";
  306. def._wrapper_type = WT_no_params;
  307. return true;
  308. }
  309. if (method_name == "operator -") {
  310. def._answer_location = "tp_as_number->nb_subtract";
  311. def._wrapper_type = WT_numeric_operator;
  312. return true;
  313. }
  314. if (method_name == "operator *") {
  315. def._answer_location = "tp_as_number->nb_multiply";
  316. def._wrapper_type = WT_numeric_operator;
  317. return true;
  318. }
  319. if (method_name == "operator /") {
  320. def._answer_location = "tp_as_number->nb_divide";
  321. def._wrapper_type = WT_numeric_operator;
  322. return true;
  323. }
  324. if (method_name == "operator %") {
  325. def._answer_location = "tp_as_number->nb_remainder";
  326. def._wrapper_type = WT_numeric_operator;
  327. return true;
  328. }
  329. if (method_name == "operator << ") {
  330. def._answer_location = "tp_as_number->nb_lshift";
  331. def._wrapper_type = WT_numeric_operator;
  332. return true;
  333. }
  334. if (method_name == "operator >>") {
  335. def._answer_location = "tp_as_number->nb_rshift";
  336. def._wrapper_type = WT_numeric_operator;
  337. return true;
  338. }
  339. if (method_name == "operator ^") {
  340. def._answer_location = "tp_as_number->nb_xor";
  341. def._wrapper_type = WT_numeric_operator;
  342. return true;
  343. }
  344. if (method_name == "operator ~" && is_unary_op) {
  345. def._answer_location = "tp_as_number->nb_invert";
  346. def._wrapper_type = WT_no_params;
  347. return true;
  348. }
  349. if (method_name == "operator &") {
  350. def._answer_location = "tp_as_number->nb_and";
  351. def._wrapper_type = WT_numeric_operator;
  352. return true;
  353. }
  354. if (method_name == "operator |") {
  355. def._answer_location = "tp_as_number->nb_or";
  356. def._wrapper_type = WT_numeric_operator;
  357. return true;
  358. }
  359. if (method_name == "__pow__") {
  360. def._answer_location = "tp_as_number->nb_power";
  361. def._wrapper_type = WT_ternary_operator;
  362. return true;
  363. }
  364. if (method_name == "operator +=") {
  365. def._answer_location = "tp_as_number->nb_inplace_add";
  366. def._wrapper_type = WT_one_param;
  367. def._min_version = 0x02000000;
  368. return true;
  369. }
  370. if (method_name == "operator -=") {
  371. def._answer_location = "tp_as_number->nb_inplace_subtract";
  372. def._wrapper_type = WT_one_param;
  373. def._min_version = 0x02000000;
  374. return true;
  375. }
  376. if (method_name == "operator *=") {
  377. def._answer_location = "tp_as_number->nb_inplace_multiply";
  378. def._wrapper_type = WT_one_param;
  379. def._min_version = 0x02000000;
  380. return true;
  381. }
  382. if (method_name == "operator /=") {
  383. def._answer_location = "tp_as_number->nb_inplace_divide";
  384. def._wrapper_type = WT_one_param;
  385. def._min_version = 0x02000000;
  386. return true;
  387. }
  388. if (method_name == "operator %=") {
  389. def._answer_location = ".tp_as_number->nb_inplace_remainder";
  390. def._wrapper_type = WT_one_param;
  391. def._min_version = 0x02000000;
  392. return true;
  393. }
  394. if (method_name == "operator <<=") {
  395. def._answer_location = "tp_as_number->nb_inplace_lshift";
  396. def._wrapper_type = WT_one_param;
  397. def._min_version = 0x02000000;
  398. return true;
  399. }
  400. if (method_name == "operator >>=") {
  401. def._answer_location = "tp_as_number->nb_inplace_rshift";
  402. def._wrapper_type = WT_one_param;
  403. def._min_version = 0x02000000;
  404. return true;
  405. }
  406. if (method_name == "operator &=") {
  407. def._answer_location = "tp_as_number->nb_inplace_and";
  408. def._wrapper_type = WT_one_param;
  409. def._min_version = 0x02000000;
  410. return true;
  411. }
  412. if (method_name == "operator ^=") {
  413. def._answer_location = "tp_as_number->nb_inplace_xor";
  414. def._wrapper_type = WT_one_param;
  415. def._min_version = 0x02000000;
  416. return true;
  417. }
  418. if (method_name == "__ipow__") {
  419. def._answer_location = "tp_as_number->nb_inplace_power";
  420. def._wrapper_type = WT_one_or_two_params;
  421. def._min_version = 0x02000000;
  422. return true;
  423. }
  424. if (obj->_protocol_types & Object::PT_sequence) {
  425. if (func->_flags & FunctionRemap::F_getitem_int) {
  426. def._answer_location = "tp_as_sequence->sq_item";
  427. def._wrapper_type = WT_sequence_getitem;
  428. return true;
  429. }
  430. if (func->_flags & FunctionRemap::F_setitem_int) {
  431. def._answer_location = "tp_as_sequence->sq_ass_item";
  432. def._wrapper_type = WT_sequence_setitem;
  433. return true;
  434. }
  435. if (func->_flags & FunctionRemap::F_size) {
  436. def._answer_location = "tp_as_sequence->sq_length";
  437. def._wrapper_type = WT_sequence_size;
  438. return true;
  439. }
  440. }
  441. if (obj->_protocol_types & Object::PT_mapping) {
  442. if (func->_flags & FunctionRemap::F_getitem) {
  443. def._answer_location = "tp_as_mapping->mp_subscript";
  444. def._wrapper_type = WT_one_param;
  445. return true;
  446. }
  447. if (func->_flags & FunctionRemap::F_setitem) {
  448. def._answer_location = "tp_as_mapping->mp_ass_subscript";
  449. def._wrapper_type = WT_mapping_setitem;
  450. return true;
  451. }
  452. }
  453. if (obj->_protocol_types & Object::PT_iter) {
  454. if (method_name == "__iter__") {
  455. def._answer_location = "tp_iter";
  456. def._wrapper_type = WT_no_params;
  457. return true;
  458. }
  459. if (method_name == "next" || method_name == "__next__") {
  460. def._answer_location = "tp_iternext";
  461. def._wrapper_type = WT_iter_next;
  462. return true;
  463. }
  464. }
  465. if (method_name == "operator ()") {
  466. def._answer_location = "tp_call";
  467. def._wrapper_type = WT_none;
  468. return true;
  469. }
  470. if (method_name == "__getattr__") {
  471. def._answer_location = "tp_getattro";
  472. def._wrapper_type = WT_getattr;
  473. return true;
  474. }
  475. if (method_name == "__setattr__") {
  476. def._answer_location = "tp_setattro";
  477. def._wrapper_type = WT_setattr;
  478. return true;
  479. }
  480. if (method_name == "__nonzero__") {
  481. // Python 2 style.
  482. def._answer_location = "tp_as_number->nb_nonzero";
  483. def._wrapper_type = WT_inquiry;
  484. return true;
  485. }
  486. if (method_name == "__bool__") {
  487. // Python 3 style.
  488. def._answer_location = "tp_as_number->nb_nonzero";
  489. def._wrapper_type = WT_inquiry;
  490. return true;
  491. }
  492. if (method_name == "__getbuffer__") {
  493. def._answer_location = "tp_as_buffer->bf_getbuffer";
  494. def._wrapper_type = WT_getbuffer;
  495. def._min_version = 0x02060000;
  496. return true;
  497. }
  498. if (method_name == "__releasebuffer__") {
  499. def._answer_location = "tp_as_buffer->bf_releasebuffer";
  500. def._wrapper_type = WT_releasebuffer;
  501. def._min_version = 0x02060000;
  502. return true;
  503. }
  504. if (func->_ifunc.is_operator_typecast()) {
  505. // A typecast operator. Check for a supported low-level typecast type.
  506. if (!func->_remaps.empty()) {
  507. if (TypeManager::is_bool(func->_remaps[0]->_return_type->get_orig_type())) {
  508. // If it's a bool type, then we wrap it with the __nonzero__
  509. // slot method.
  510. def._answer_location = "tp_as_number->nb_nonzero";
  511. def._wrapper_type = WT_inquiry;
  512. return true;
  513. } else if (TypeManager::is_integer(func->_remaps[0]->_return_type->get_orig_type())) {
  514. // An integer type.
  515. def._answer_location = "tp_as_number->nb_int";
  516. def._wrapper_type = WT_no_params;
  517. return true;
  518. } else if (TypeManager::is_float(func->_remaps[0]->_return_type->get_orig_type())) {
  519. // A floating-point (or double) type.
  520. def._answer_location = "tp_as_number->nb_float";
  521. def._wrapper_type = WT_no_params;
  522. return true;
  523. }
  524. }
  525. }
  526. return false;
  527. }
  528. ///////////////////////////////////////////////////////////////////////////////
  529. ///////////////////////////////////////////////////////////////////////////////
  530. void InterfaceMakerPythonNative::
  531. get_valid_child_classes(std::map<std::string, CastDetails> &answer, CPPStructType *inclass, const std::string &upcast_seed, bool can_downcast) {
  532. if (inclass == NULL) {
  533. return;
  534. }
  535. CPPStructType::Derivation::const_iterator bi;
  536. for (bi = inclass->_derivation.begin();
  537. bi != inclass->_derivation.end();
  538. ++bi) {
  539. const CPPStructType::Base &base = (*bi);
  540. // if (base._vis <= V_public)
  541. // can_downcast = false;
  542. CPPStructType *base_type = TypeManager::resolve_type(base._base)->as_struct_type();
  543. if (base_type != NULL) {
  544. std::string scoped_name = base_type->get_local_name(&parser);
  545. if (answer.find(scoped_name) == answer.end()) {
  546. answer[scoped_name]._can_downcast = can_downcast;
  547. answer[scoped_name]._to_class_name = scoped_name;
  548. answer[scoped_name]._structType = base_type;
  549. if (base._is_virtual) {
  550. answer[scoped_name]._can_downcast = false;
  551. }
  552. std::string local_upcast("(");
  553. local_upcast += scoped_name + " *)"+ upcast_seed +"";
  554. answer[scoped_name]._up_cast_string = local_upcast;
  555. answer[scoped_name]._is_legal_py_class = is_cpp_type_legal(base_type);
  556. } else {
  557. answer[scoped_name]._can_downcast = false;
  558. }
  559. get_valid_child_classes(answer, base_type, answer[scoped_name]._up_cast_string, answer[scoped_name]._can_downcast);
  560. }
  561. }
  562. }
  563. ///////////////////////////////////////////////////////////////////////////////
  564. // Function : write_python_instance
  565. //
  566. ///////////////////////////////////////////////////////////////////////////////
  567. void InterfaceMakerPythonNative::
  568. write_python_instance(ostream &out, int indent_level, const std::string &return_expr, const std::string &assign_to, std::string &owns_memory_flag, const std::string &class_name, CPPType *ctype, bool inplace, const std::string &const_flag) {
  569. string assign_stmt("return ");
  570. if (!assign_to.empty()) {
  571. assign_stmt = assign_to + " = ";
  572. }
  573. if (inplace) {
  574. indent(out, indent_level) << "Py_INCREF(self);\n";
  575. indent(out, indent_level) << assign_stmt << "self;\n";
  576. } else {
  577. indent(out, indent_level) << "if (" << return_expr << " == NULL) {\n";
  578. indent(out, indent_level) << " Py_INCREF(Py_None);\n";
  579. indent(out, indent_level+2) << assign_stmt << "Py_None;\n";
  580. indent(out, indent_level) << "} else {\n";
  581. if (IsPandaTypedObject(ctype->as_struct_type())) {
  582. std::string typestr = "(" + return_expr + ")->as_typed_object()->get_type_index()";
  583. indent(out, indent_level+2) << assign_stmt
  584. << "DTool_CreatePyInstanceTyped((void *)" << return_expr << ", " << CLASS_PREFIX << make_safe_name(class_name) << ", " << owns_memory_flag << ", " << const_flag << ", " << typestr << ");\n";
  585. } else {
  586. // indent(out, indent_level) << "if (" << return_expr << "!= NULL)\n";
  587. indent(out, indent_level+2) << assign_stmt
  588. << "DTool_CreatePyInstance((void *)" << return_expr << ", " << CLASS_PREFIX << make_safe_name(class_name) << ", " << owns_memory_flag << ", " << const_flag << ");\n";
  589. }
  590. indent(out, indent_level) << "}\n";
  591. }
  592. }
  593. ////////////////////////////////////////////////////////////////////
  594. // Function: InterfaceMakerPythonNative::Constructor
  595. // Access: Public
  596. // Description:
  597. ////////////////////////////////////////////////////////////////////
  598. InterfaceMakerPythonNative::
  599. InterfaceMakerPythonNative(InterrogateModuleDef *def) :
  600. InterfaceMakerPython(def)
  601. {
  602. }
  603. ////////////////////////////////////////////////////////////////////
  604. // Function: InterfaceMakerPythonNative::Destructor
  605. // Access: Public, Virtual
  606. // Description:
  607. ////////////////////////////////////////////////////////////////////
  608. InterfaceMakerPythonNative::
  609. ~InterfaceMakerPythonNative() {
  610. }
  611. ////////////////////////////////////////////////////////////////////
  612. // Function: InterfaceMakerPythonNative::write_prototypes
  613. // Access: Public, Virtual
  614. // Description: Generates the list of function prototypes
  615. // corresponding to the functions that will be output in
  616. // write_functions().
  617. ////////////////////////////////////////////////////////////////////
  618. void InterfaceMakerPythonNative::
  619. write_prototypes(ostream &out_code, ostream *out_h) {
  620. inside_python_native = true;
  621. Functions::iterator fi;
  622. if (out_h != NULL) {
  623. *out_h << "#include \"py_panda.h\"\n\n";
  624. }
  625. out_code << "//********************************************************************\n";
  626. out_code << "//*** prototypes for .. Global\n";
  627. out_code << "//********************************************************************\n";
  628. /*
  629. for (fi = _functions.begin(); fi != _functions.end(); ++fi)
  630. {
  631. Function *func = (*fi);
  632. if (!func->_itype.is_global() && is_function_legal(func))
  633. write_prototype_for (out_code, func);
  634. }
  635. */
  636. Objects::iterator oi;
  637. for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
  638. Object *object = (*oi).second;
  639. if (object->_itype.is_class() || object->_itype.is_struct()) {
  640. if (is_cpp_type_legal(object->_itype._cpptype)) {
  641. if (isExportThisRun(object->_itype._cpptype)) {
  642. write_prototypes_class(out_code, out_h, object);
  643. } else {
  644. //write_prototypes_class_external(out_code, object);
  645. _external_imports.insert(make_safe_name(object->_itype.get_scoped_name()));
  646. }
  647. }
  648. }
  649. }
  650. out_code << "//********************************************************************\n";
  651. out_code << "//*** prototypes for .. External Objects\n";
  652. out_code << "//********************************************************************\n";
  653. for (std::set<std::string>::iterator ii = _external_imports.begin(); ii != _external_imports.end(); ii++) {
  654. out_code << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" << *ii << ";\n";
  655. }
  656. inside_python_native = false;
  657. }
  658. /////////////////////////////////////////////////////////////////////////////////////////////
  659. // Function : write_prototypes_class_external
  660. //
  661. // Description : Output enough enformation to a declartion of a externally
  662. // generated dtool type object
  663. /////////////////////////////////////////////////////////////////////////////////////////////
  664. void InterfaceMakerPythonNative::
  665. write_prototypes_class_external(ostream &out, Object *obj) {
  666. std::string class_name = make_safe_name(obj->_itype.get_scoped_name());
  667. std::string c_class_name = obj->_itype.get_true_name();
  668. std::string preferred_name = obj->_itype.get_name();
  669. out << "//********************************************************************\n";
  670. out << "//*** prototypes for external.. " << class_name << "\n";
  671. out << "//********************************************************************\n";
  672. out << "typedef " << c_class_name << " " << class_name << "_localtype;\n";
  673. out << "Define_Module_Class_Forward(" << _def->module_name << ", " << class_name << ", " << class_name << "_localtype, " << classNameFromCppName(preferred_name, false) << ");\n";
  674. }
  675. ///////////////////////////////////////// ////////////////////////////////////////////////////
  676. // Function : write_prototypes_class
  677. //
  678. /////////////////////////////////////////////////////////////////////////////////////////////
  679. void InterfaceMakerPythonNative::
  680. write_prototypes_class(ostream &out_code, ostream *out_h, Object *obj) {
  681. std::string ClassName = make_safe_name(obj->_itype.get_scoped_name());
  682. Functions::iterator fi;
  683. out_code << "//********************************************************************\n";
  684. out_code << "//*** prototypes for .. " << ClassName << "\n";
  685. out_code << "//********************************************************************\n";
  686. /*
  687. for (fi = obj->_methods.begin(); fi != obj->_methods.end(); ++fi) {
  688. Function *func = (*fi);
  689. write_prototype_for(out_code, func);
  690. }
  691. */
  692. /*
  693. for (fi = obj->_constructors.begin(); fi != obj->_constructors.end(); ++fi) {
  694. Function *func = (*fi);
  695. std::string fname = "int Dtool_Init_" + ClassName + "(PyObject *self, PyObject *args, PyObject *kwds)";
  696. write_prototype_for_name(out_code, obj, func, fname);
  697. }
  698. */
  699. write_class_declarations(out_code, out_h, obj);
  700. }
  701. ////////////////////////////////////////////////////////////////////
  702. // Function: InterfaceMakerPythonNative::write_functions
  703. // Access: Public, Virtual
  704. // Description: Generates the list of functions that are appropriate
  705. // for this interface. This function is called *before*
  706. // write_prototypes(), above.
  707. ////////////////////////////////////////////////////////////////////
  708. void InterfaceMakerPythonNative::
  709. write_functions(ostream &out) {
  710. inside_python_native = true;
  711. out << "//********************************************************************\n";
  712. out << "//*** Functions for .. Global\n" ;
  713. out << "//********************************************************************\n";
  714. FunctionsByIndex::iterator fi;
  715. for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
  716. Function *func = (*fi).second;
  717. if (!func->_itype.is_global() && is_function_legal(func)) {
  718. write_function_for_top(out, NULL, func);
  719. }
  720. }
  721. Objects::iterator oi;
  722. for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
  723. Object *object = (*oi).second;
  724. if (object->_itype.is_class() || object->_itype.is_struct()) {
  725. if (is_cpp_type_legal(object->_itype._cpptype)) {
  726. if (isExportThisRun(object->_itype._cpptype)) {
  727. write_class_details(out, object);
  728. }
  729. }
  730. }
  731. }
  732. //Objects::iterator oi;
  733. for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
  734. Object *object = (*oi).second;
  735. if (!object->_itype.get_outer_class()) {
  736. if (object->_itype.is_class() || object->_itype.is_struct()) {
  737. if (is_cpp_type_legal(object->_itype._cpptype)) {
  738. if (isExportThisRun(object->_itype._cpptype)) {
  739. write_module_class(out, object);
  740. }
  741. }
  742. }
  743. }
  744. }
  745. inside_python_native = true;
  746. }
  747. ////////////////////////////////////////////////////////////
  748. // Function : write_class_details
  749. ////////////////////////////////////////////////////////////
  750. void InterfaceMakerPythonNative::
  751. write_class_details(ostream &out, Object *obj) {
  752. Functions::iterator fi;
  753. //std::string cClassName = obj->_itype.get_scoped_name();
  754. std::string ClassName = make_safe_name(obj->_itype.get_scoped_name());
  755. std::string cClassName = obj->_itype.get_true_name();
  756. out << "//********************************************************************\n";
  757. out << "//*** Functions for .. " << cClassName << "\n" ;
  758. out << "//********************************************************************\n";
  759. for (fi = obj->_methods.begin(); fi != obj->_methods.end(); ++fi) {
  760. Function *func = (*fi);
  761. if (func) {
  762. write_function_for_top(out, obj, func);
  763. }
  764. }
  765. Properties::const_iterator pit;
  766. for (pit = obj->_properties.begin(); pit != obj->_properties.end(); ++pit) {
  767. Property *property = (*pit);
  768. const InterrogateElement &ielem = property->_ielement;
  769. bool coercion_attempted = false;
  770. if (property->_getter != NULL) {
  771. std::string fname = "PyObject *Dtool_" + ClassName + "_" + ielem.get_name() + "_Getter(PyObject *self, void *)";
  772. write_function_for_name(out, obj, property->_getter, fname, true, coercion_attempted, AT_no_args, false, false);
  773. }
  774. if (property->_setter != NULL) {
  775. std::string fname = "int Dtool_" + ClassName + "_" + ielem.get_name() + "_Setter(PyObject *self, PyObject *arg, void *)";
  776. write_function_for_name(out, obj, property->_setter, fname, true, coercion_attempted, AT_single_arg, true, false);
  777. }
  778. }
  779. if (obj->_constructors.size() == 0) {
  780. out << "int Dtool_Init_" + ClassName + "(PyObject *self, PyObject *args, PyObject *kwds) {\n"
  781. << " PyErr_SetString(PyExc_TypeError, \"cannot init constant class (" << cClassName << ")\");\n"
  782. << " return -1;\n"
  783. << "}\n\n";
  784. out << "int Dtool_InitNoCoerce_" << ClassName << "(PyObject *self, PyObject *args) {\n"
  785. << " PyErr_SetString(PyExc_TypeError, \"cannot init constant class (" << cClassName << ")\");\n"
  786. << " return -1;\n"
  787. << "}\n\n";
  788. } else {
  789. bool coercion_attempted = false;
  790. for (fi = obj->_constructors.begin(); fi != obj->_constructors.end(); ++fi) {
  791. Function *func = (*fi);
  792. std::string fname = "int Dtool_Init_" + ClassName + "(PyObject *self, PyObject *args, PyObject *kwds)";
  793. write_function_for_name(out, obj, func, fname, true, coercion_attempted, AT_keyword_args, true, false);
  794. }
  795. if (coercion_attempted) {
  796. // If a coercion attempt was written into the above constructor,
  797. // then write a secondary constructor, that won't attempt any
  798. // coercion. We'll need this for nested coercion calls.
  799. for (fi = obj->_constructors.begin(); fi != obj->_constructors.end(); ++fi) {
  800. Function *func = (*fi);
  801. std::string fname = "int Dtool_InitNoCoerce_" + ClassName + "(PyObject *self, PyObject *args)";
  802. write_function_for_name(out, obj, func, fname, false, coercion_attempted, AT_varargs, true, false);
  803. }
  804. } else {
  805. // Otherwise, since the above constructor didn't involve any
  806. // coercion anyway, we can use the same function for both
  807. // purposes. Construct a trivial wrapper.
  808. out << "int Dtool_InitNoCoerce_" << ClassName << "(PyObject *self, PyObject *args) {\n"
  809. << " return Dtool_Init_" << ClassName << "(self, args, NULL);\n"
  810. << "}\n\n";
  811. }
  812. }
  813. MakeSeqs::iterator msi;
  814. for (msi = obj->_make_seqs.begin(); msi != obj->_make_seqs.end(); ++msi) {
  815. write_make_seq(out, obj, ClassName, *msi);
  816. }
  817. CPPType *cpptype = TypeManager::resolve_type(obj->_itype._cpptype);
  818. std::map<string, CastDetails> details;
  819. std::map<string, CastDetails>::iterator di;
  820. builder.get_type(TypeManager::unwrap(cpptype), false);
  821. get_valid_child_classes(details, cpptype->as_struct_type());
  822. for (di = details.begin(); di != details.end(); di++) {
  823. //InterrogateType ptype =idb->get_type(di->first);
  824. if (di->second._is_legal_py_class && !isExportThisRun(di->second._structType))
  825. _external_imports.insert(make_safe_name(di->second._to_class_name));
  826. //out << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" << make_safe_name(di->second._to_class_name) << ";\n";
  827. }
  828. { // the Cast Converter
  829. out << "inline void *Dtool_UpcastInterface_" << ClassName << "(PyObject *self, Dtool_PyTypedObject *requested_type) {\n";
  830. out << " Dtool_PyTypedObject *SelfType = ((Dtool_PyInstDef *)self)->_My_Type;\n";
  831. out << " if (SelfType != &Dtool_" << ClassName << ") {\n";
  832. out << " printf(\"" << ClassName << " ** Bad Source Type-- Requesting Conversion from %s to %s\\n\", ((Dtool_PyInstDef *)self)->_My_Type->_name, requested_type->_name); fflush(NULL);\n";;
  833. out << " return NULL;\n";
  834. out << " }\n";
  835. out << "\n";
  836. out << " " << cClassName << " *local_this = (" << cClassName << " *)((Dtool_PyInstDef *)self)->_ptr_to_object;\n";
  837. out << " if (requested_type == &Dtool_" << ClassName << ") {\n";
  838. out << " return local_this;\n";
  839. out << " }\n";
  840. for (di = details.begin(); di != details.end(); di++) {
  841. if (di->second._is_legal_py_class) {
  842. out << " if (requested_type == &Dtool_" << make_safe_name(di->second._to_class_name) << ") {\n";
  843. out << " return " << di->second._up_cast_string << " local_this;\n";
  844. out << " }\n";
  845. }
  846. }
  847. out << " return NULL;\n";
  848. out << "}\n\n";
  849. out << "inline void *Dtool_DowncastInterface_" << ClassName << "(void *from_this, Dtool_PyTypedObject *from_type) {\n";
  850. out << " if (from_this == NULL || from_type == NULL) {\n";
  851. out << " return NULL;\n";
  852. out << " }\n";
  853. out << " if (from_type == &Dtool_" << ClassName << ") {\n";
  854. out << " return from_this;\n";
  855. out << " }\n";
  856. for (di = details.begin(); di != details.end(); di++) {
  857. if (di->second._can_downcast && di->second._is_legal_py_class) {
  858. out << " if (from_type == &Dtool_" << make_safe_name(di->second._to_class_name) << ") {\n";
  859. out << " " << di->second._to_class_name << "* other_this = (" << di->second._to_class_name << "*)from_this;\n" ;
  860. out << " return (" << cClassName << "*)other_this;\n";
  861. out << " }\n";
  862. }
  863. }
  864. out << " return (void *) NULL;\n";
  865. out << "}\n\n";
  866. }
  867. }
  868. ////////////////////////////////////////////////////////////
  869. /// Function : write_class_declarations
  870. //
  871. //
  872. ////////////////////////////////////////////////////////////
  873. void InterfaceMakerPythonNative::
  874. write_class_declarations(ostream &out, ostream *out_h, Object *obj) {
  875. const InterrogateType &itype = obj->_itype;
  876. std::string class_name = make_safe_name(obj->_itype.get_scoped_name());
  877. std::string c_class_name = obj->_itype.get_true_name();
  878. std::string preferred_name = itype.get_name();
  879. std::string class_struct_name = std::string(CLASS_PREFIX) + class_name;
  880. out << "typedef " << c_class_name << " " << class_name << "_localtype;\n";
  881. if (obj->_itype.has_destructor() ||
  882. obj->_itype.destructor_is_inherited()) {
  883. if (TypeManager::is_reference_count(obj->_itype._cpptype)) {
  884. out << "Define_Module_ClassRef(" << _def->module_name << ", " << class_name << ", " << class_name << "_localtype, " << classNameFromCppName(preferred_name, false) << ");\n";
  885. } else {
  886. out << "Define_Module_Class(" << _def->module_name << ", " << class_name << ", " << class_name << "_localtype, " << classNameFromCppName(preferred_name, false) << ");\n";
  887. }
  888. } else {
  889. if (TypeManager::is_reference_count(obj->_itype._cpptype)) {
  890. out << "Define_Module_ClassRef_Private(" << _def->module_name << ", " << class_name << ", " << class_name << "_localtype, " << classNameFromCppName(preferred_name, false) << ");\n";
  891. } else {
  892. out << "Define_Module_Class_Private(" << _def->module_name << ", " << class_name << ", " << class_name << "_localtype, " << classNameFromCppName(preferred_name, false) << ");\n";
  893. }
  894. }
  895. out << "\n";
  896. if (out_h != NULL) {
  897. *out_h << "extern \"C\" " << EXPORT_IMPORT_PREFIX << " struct Dtool_PyTypedObject Dtool_" << class_name << ";\n";
  898. }
  899. }
  900. ////////////////////////////////////////////////////////////////////
  901. // Function: InterfaceMakerPythonNative::write_sub_module
  902. // Access: Public, Virtual
  903. // Description: Generates whatever additional code is required to
  904. // support a module file.
  905. ////////////////////////////////////////////////////////////////////
  906. void InterfaceMakerPythonNative::
  907. write_sub_module(ostream &out, Object *obj) {
  908. //Object * obj = _objects[_embeded_index] ;
  909. std::string class_name = make_safe_name(obj->_itype.get_scoped_name());
  910. out << " // Module init upcall for " << obj->_itype.get_scoped_name() << "\n";
  911. out << " Dtool_PyModuleClassInit_" << class_name << "(module);\n";
  912. }
  913. /////////////////////////////////////////////////////////////////////////////
  914. // Function : write_module_support
  915. /////////////////////////////////////////////////////////////////////////////
  916. void InterfaceMakerPythonNative::
  917. write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
  918. out << "//********************************************************************\n";
  919. out << "//*** Module Object Linker ..\n";
  920. out << "//********************************************************************\n";
  921. out << "static void BuildInstants(PyObject * module) {\n";
  922. Objects::iterator oi;
  923. for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
  924. Object *object = (*oi).second;
  925. if (!object->_itype.get_outer_class()) {
  926. if (object->_itype.is_enum()) {
  927. int enum_count = object->_itype.number_of_enum_values();
  928. if (enum_count > 0) {
  929. out << "//********************************************************************\n";
  930. out << "//*** Module Enums .." << object->_itype.get_scoped_name() << "\n";
  931. out << "//********************************************************************\n";
  932. }
  933. for (int xx = 0; xx< enum_count; xx++) {
  934. string name1 = classNameFromCppName(object->_itype.get_enum_value_name(xx), false);
  935. string name2 = classNameFromCppName(object->_itype.get_enum_value_name(xx), true);
  936. int enum_value = object->_itype.get_enum_value(xx);
  937. out << " PyModule_AddIntConstant(module, \"" << name1 << "\", " << enum_value << ");\n";
  938. if (name1 != name2) {
  939. // Also write the mangled name, for historical purposes.
  940. out << " PyModule_AddIntConstant(module, \"" << name2 << "\", " << enum_value << ");\n";
  941. }
  942. }
  943. }
  944. }
  945. }
  946. InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
  947. int num_manifests = idb->get_num_global_manifests();
  948. for (int mi = 0; mi < num_manifests; mi++) {
  949. ManifestIndex manifest_index = idb->get_global_manifest(mi);
  950. const InterrogateManifest &iman = idb->get_manifest(manifest_index);
  951. if (iman.has_getter()) {
  952. FunctionIndex func_index = iman.get_getter();
  953. record_function(dummy_type, func_index);
  954. }
  955. string name1 = classNameFromCppName(iman.get_name(), false);
  956. string name2 = classNameFromCppName(iman.get_name(), true);
  957. if (iman.has_int_value()) {
  958. int value = iman.get_int_value();
  959. out << " PyModule_AddIntConstant(module, \"" << name1 << "\", " << value << ");\n";
  960. if (name1 != name2) {
  961. // Also write the mangled name, for historical purposes.
  962. out << " PyModule_AddIntConstant(module, \"" << name2 << "\", " << value << ");\n";
  963. }
  964. } else {
  965. string value = iman.get_definition();
  966. out << " PyModule_AddStringConstant(module, \"" << name1 << "\", \"" << value << "\");\n";
  967. if (name1 != name2) {
  968. out << " PyModule_AddStringConstant(module, \"" << name2 << "\", \"" << value << "\");\n";
  969. }
  970. }
  971. }
  972. for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
  973. Object *object = (*oi).second;
  974. if (!object->_itype.get_outer_class()) {
  975. if (object->_itype.is_class() ||object->_itype.is_struct()) {
  976. if (is_cpp_type_legal(object->_itype._cpptype)) {
  977. if (isExportThisRun(object->_itype._cpptype)) {
  978. write_sub_module(out, object);
  979. }
  980. }
  981. }
  982. }
  983. }
  984. out << "//********************************************************************\n";
  985. out << "//*** Module Init Upcall .. Externally Defined Class\n";
  986. out << "//********************************************************************\n";
  987. // for (std::set< std::string >::iterator ii = _external_imports.begin(); ii != _external_imports.end(); ii++)
  988. // out << "Dtool_" <<*ii << "._Dtool_ClassInit(NULL);\n";
  989. out << "}\n\n";
  990. bool force_base_functions = true;
  991. out << "static PyMethodDef python_simple_funcs[] = {\n";
  992. FunctionsByIndex::iterator fi;
  993. for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
  994. Function *func = (*fi).second;
  995. if (!func->_itype.is_global() && is_function_legal(func)) {
  996. string name1 = methodNameFromCppName(func, "", false);
  997. string name2 = methodNameFromCppName(func, "", true);
  998. string flags;
  999. switch (func->_args_type) {
  1000. case AT_keyword_args:
  1001. flags = "METH_VARARGS | METH_KEYWORDS";
  1002. break;
  1003. case AT_varargs:
  1004. flags = "METH_VARARGS";
  1005. break;
  1006. case AT_single_arg:
  1007. flags = "METH_O";
  1008. break;
  1009. default:
  1010. flags = "METH_NOARGS";
  1011. break;
  1012. }
  1013. // Note: we shouldn't add METH_STATIC here, since both METH_STATIC
  1014. // and METH_CLASS are illegal for module-level functions.
  1015. out << " { \"" << name1 << "\", (PyCFunction) &"
  1016. << func->_name << ", " << flags << ", (const char *)" << func->_name << "_comment},\n";
  1017. if (name1 != name2) {
  1018. out << " { \"" << name2 << "\", (PyCFunction) &"
  1019. << func->_name << ", " << flags << ", (const char *)" << func->_name << "_comment},\n";
  1020. }
  1021. }
  1022. }
  1023. if (force_base_functions) {
  1024. out << " // Support Function For Dtool_types ... for now in each module ??\n";
  1025. out << " {\"Dtool_BorrowThisReference\", &Dtool_BorrowThisReference, METH_VARARGS, \"Used to borrow 'this' pointer (to, from)\\nAssumes no ownership.\"},\n";
  1026. out << " {\"Dtool_AddToDictionary\", &Dtool_AddToDictionary, METH_VARARGS, \"Used to add items into a tp_dict\"},\n";
  1027. }
  1028. out << " {NULL, NULL, 0, NULL}\n" << "};\n\n";
  1029. out << "EXPORT_THIS struct LibraryDef " << def->library_name << "_moddef = {python_simple_funcs, BuildInstants};\n";
  1030. if (out_h != NULL) {
  1031. *out_h << "extern struct LibraryDef " << def->library_name << "_moddef;\n";
  1032. }
  1033. }
  1034. /////////////////////////////////////////////////////////////////////////////
  1035. ///// Function : write_module
  1036. /////////////////////////////////////////////////////////////////////////////
  1037. void InterfaceMakerPythonNative::
  1038. write_module(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
  1039. InterfaceMakerPython::write_module(out, out_h, def);
  1040. Objects::iterator oi;
  1041. out << "//********************************************************************\n";
  1042. out << "//*** Py Init Code For .. GlobalScope\n" ;
  1043. out << "//********************************************************************\n";
  1044. out << "#if PY_MAJOR_VERSION >= 3\n"
  1045. << "static struct PyModuleDef python_native_module = {\n"
  1046. << " PyModuleDef_HEAD_INIT,\n"
  1047. << " \"" << def->module_name << "\",\n"
  1048. << " NULL,\n"
  1049. << " -1,\n"
  1050. << " NULL,\n"
  1051. << " NULL, NULL, NULL, NULL\n"
  1052. << "};\n"
  1053. << "\n"
  1054. << "#ifdef _WIN32\n"
  1055. << "extern \"C\" __declspec(dllexport) PyObject *PyInit_" << def->module_name << "();\n"
  1056. << "#else\n"
  1057. << "extern \"C\" PyObject *PyInit_" << def->module_name << "();\n"
  1058. << "#endif\n"
  1059. << "\n"
  1060. << "PyObject *PyInit_" << def->module_name << "() {\n"
  1061. << " LibraryDef *refs[] = {&" << def->library_name << "_moddef, NULL};\n"
  1062. << " return Dtool_PyModuleInitHelper(refs, &python_native_module);\n"
  1063. << "}\n"
  1064. << "\n"
  1065. << "#else // Python 2 case\n"
  1066. << "\n"
  1067. << "#ifdef _WIN32\n"
  1068. << "extern \"C\" __declspec(dllexport) void init" << def->module_name << "();\n"
  1069. << "#else\n"
  1070. << "extern \"C\" void init" << def->module_name << "();\n"
  1071. << "#endif\n"
  1072. << "\n"
  1073. << "void init" << def->module_name << "() {\n"
  1074. << " LibraryDef *refs[] = {&" << def->library_name << "_moddef, NULL};\n"
  1075. << " Dtool_PyModuleInitHelper(refs, \"" << def->module_name << "\");\n"
  1076. << "}\n"
  1077. << "\n"
  1078. << "#endif\n"
  1079. << "\n";
  1080. }
  1081. /////////////////////////////////////////////////////////////////////////////////////////////
  1082. // Function :write_module_class
  1083. /////////////////////////////////////////////////////////////////////////////////////////////
  1084. void InterfaceMakerPythonNative::
  1085. write_module_class(ostream &out, Object *obj) {
  1086. bool has_local_hash = false;
  1087. bool has_local_repr = false;
  1088. bool has_local_str = false;
  1089. bool has_local_richcompare = false;
  1090. bool has_local_getbuffer = false;
  1091. {
  1092. int num_nested = obj->_itype.number_of_nested_types();
  1093. for (int ni = 0; ni < num_nested; ni++) {
  1094. TypeIndex nested_index = obj->_itype.get_nested_type(ni);
  1095. Object * nested_obj = _objects[nested_index];
  1096. if (nested_obj->_itype.is_class() || nested_obj->_itype.is_struct()) {
  1097. write_module_class(out, nested_obj);
  1098. }
  1099. }
  1100. }
  1101. InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
  1102. std::string ClassName = make_safe_name(obj->_itype.get_scoped_name());
  1103. std::string cClassName = obj->_itype.get_true_name();
  1104. std::string export_class_name = classNameFromCppName(obj->_itype.get_name(), false);
  1105. std::string export_class_name2 = classNameFromCppName(obj->_itype.get_name(), true);
  1106. Functions::iterator fi;
  1107. out << "//********************************************************************\n";
  1108. out << "//*** Py Init Code For .. " << ClassName << " | " << export_class_name << "\n" ;
  1109. out << "//********************************************************************\n";
  1110. out << "PyMethodDef Dtool_Methods_" << ClassName << "[] = {\n";
  1111. std::map<Function *, SlottedFunctionDef> slotted_functions;
  1112. // function Table
  1113. bool got_copy = false;
  1114. bool got_deepcopy = false;
  1115. for (fi = obj->_methods.begin(); fi != obj->_methods.end(); ++fi) {
  1116. Function *func = (*fi);
  1117. if (func->_name == "__copy__") {
  1118. got_copy = true;
  1119. } else if (func->_name == "__deepcopy__") {
  1120. got_deepcopy = true;
  1121. }
  1122. string name1 = methodNameFromCppName(func, export_class_name, false);
  1123. string name2 = methodNameFromCppName(func, export_class_name, true);
  1124. string flags;
  1125. switch (func->_args_type) {
  1126. case AT_keyword_args:
  1127. flags = "METH_VARARGS | METH_KEYWORDS";
  1128. break;
  1129. case AT_varargs:
  1130. flags = "METH_VARARGS";
  1131. break;
  1132. case AT_single_arg:
  1133. flags = "METH_O";
  1134. break;
  1135. default:
  1136. flags = "METH_NOARGS";
  1137. break;
  1138. }
  1139. if (!func->_has_this) {
  1140. flags += " | METH_STATIC";
  1141. }
  1142. out << " { \"" << name1 << "\", (PyCFunction) &"
  1143. << func->_name << ", " << flags << ", (char *) " << func->_name << "_comment},\n";
  1144. if (name1 != name2) {
  1145. out << " { \"" << name2 << "\", (PyCFunction) &"
  1146. << func->_name << ", " << flags << ", (char *) " << func->_name << "_comment},\n";
  1147. }
  1148. SlottedFunctionDef slotted_def;
  1149. if (get_slotted_function_def(obj, func, slotted_def)) {
  1150. slotted_functions[func] = slotted_def;
  1151. }
  1152. }
  1153. if (obj->_protocol_types & Object::PT_make_copy) {
  1154. if (!got_copy) {
  1155. out << " { \"__copy__\", (PyCFunction) &copy_from_make_copy, METH_NOARGS, NULL},\n";
  1156. got_copy = true;
  1157. }
  1158. } else if (obj->_protocol_types & Object::PT_copy_constructor) {
  1159. if (!got_copy) {
  1160. out << " { \"__copy__\", (PyCFunction) &copy_from_copy_constructor, METH_NOARGS, NULL},\n";
  1161. got_copy = true;
  1162. }
  1163. }
  1164. if (got_copy && !got_deepcopy) {
  1165. out << " { \"__deepcopy__\", (PyCFunction) &map_deepcopy_to_copy, METH_VARARGS, NULL},\n";
  1166. }
  1167. MakeSeqs::iterator msi;
  1168. for (msi = obj->_make_seqs.begin(); msi != obj->_make_seqs.end(); ++msi) {
  1169. string flags = "METH_NOARGS";
  1170. if (obj->is_static_method((*msi)->_element_name)) {
  1171. flags += " | METH_CLASS";
  1172. }
  1173. string name1 = methodNameFromCppName((*msi)->_seq_name, export_class_name, false);
  1174. string name2 = methodNameFromCppName((*msi)->_seq_name, export_class_name, true);
  1175. out << " { \"" << name1
  1176. << "\", (PyCFunction) &" << (*msi)->_name << ", " << flags << ", NULL},\n";
  1177. if (name1 != name2) {
  1178. out << " { \"" << name2
  1179. << "\", (PyCFunction) &" << (*msi)->_name << ", " << flags << ", NULL},\n";
  1180. }
  1181. }
  1182. out << " { NULL, NULL }\n"
  1183. << "};\n\n";
  1184. int num_derivations = obj->_itype.number_of_derivations();
  1185. int di;
  1186. for (di = 0; di < num_derivations; di++) {
  1187. TypeIndex d_type_Index = obj->_itype.get_derivation(di);
  1188. if (!interrogate_type_is_unpublished(d_type_Index)) {
  1189. const InterrogateType &d_itype = idb->get_type(d_type_Index);
  1190. if (is_cpp_type_legal(d_itype._cpptype)) {
  1191. if (!isExportThisRun(d_itype._cpptype)) {
  1192. _external_imports.insert(make_safe_name(d_itype.get_scoped_name().c_str()));
  1193. //out << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" << make_safe_name(d_itype.get_scoped_name().c_str()) << ";\n";
  1194. }
  1195. }
  1196. }
  1197. }
  1198. std::vector<std::string> bases;
  1199. for (di = 0; di < num_derivations; di++) {
  1200. TypeIndex d_type_Index = obj->_itype.get_derivation(di);
  1201. if (!interrogate_type_is_unpublished(d_type_Index)) {
  1202. const InterrogateType &d_itype = idb->get_type(d_type_Index);
  1203. if (is_cpp_type_legal(d_itype._cpptype)) {
  1204. bases.push_back(make_safe_name(d_itype.get_scoped_name().c_str()));
  1205. }
  1206. }
  1207. }
  1208. if (bases.empty()) {
  1209. bases.push_back("DTOOL_SUPER_BASE");
  1210. }
  1211. {
  1212. std::map<Function *, SlottedFunctionDef>::iterator rfi; // slotted_functions;
  1213. for (rfi = slotted_functions.begin(); rfi != slotted_functions.end(); rfi++) {
  1214. Function *func = rfi->first;
  1215. bool func_varargs = true;
  1216. string call_func;
  1217. switch (func->_args_type) {
  1218. case AT_keyword_args:
  1219. call_func = func->_name + "(self, args, NULL)";
  1220. break;
  1221. case AT_varargs:
  1222. call_func = func->_name + "(self, args)";
  1223. break;
  1224. case AT_single_arg:
  1225. func_varargs = false;
  1226. call_func = func->_name + "(self, arg)";
  1227. break;
  1228. default:
  1229. func_varargs = false;
  1230. call_func = func->_name + "(self)";
  1231. }
  1232. switch (rfi->second._wrapper_type) {
  1233. case WT_no_params:
  1234. // PyObject *func(PyObject *self)
  1235. {
  1236. out << "//////////////////\n";
  1237. out << "// A wrapper function to satisfy Python's internal calling conventions.\n";
  1238. out << "// " << ClassName << " ..." << rfi->second._answer_location << " = " << methodNameFromCppName(func, export_class_name, false) << "\n";
  1239. out << "//////////////////\n";
  1240. out << "static PyObject *" << func->_name << methodNameFromCppName(func, export_class_name, false) << "(PyObject *self) {\n";
  1241. if (func_varargs) {
  1242. out << " PyObject *args = PyTuple_New(0);\n";
  1243. out << " PyObject *result = " << call_func << ";\n";
  1244. out << " Py_DECREF(args);\n";
  1245. out << " return result;\n";
  1246. } else {
  1247. out << " return " << call_func << ";\n";
  1248. }
  1249. out << "}\n\n";
  1250. }
  1251. break;
  1252. case WT_one_param:
  1253. case WT_numeric_operator:
  1254. // PyObject *func(PyObject *self, PyObject *one)
  1255. {
  1256. out << "//////////////////\n";
  1257. out << "// A wrapper function to satisfy Python's internal calling conventions.\n";
  1258. out << "// " << ClassName << " ..." << rfi->second._answer_location << " = " << methodNameFromCppName(func, export_class_name, false) << "\n";
  1259. out << "//////////////////\n";
  1260. out << "static PyObject *" << func->_name << methodNameFromCppName(func, export_class_name, false) << "(PyObject *self, PyObject *arg) {\n";
  1261. if (func_varargs) {
  1262. out << " PyObject *args = PyTuple_Pack(1, arg);\n";
  1263. out << " PyObject *result = " << call_func << ";\n";
  1264. out << " Py_DECREF(args);\n";
  1265. out << " return result;\n";
  1266. } else {
  1267. out << " return " << call_func << ";\n";
  1268. }
  1269. out << "}\n\n";
  1270. }
  1271. break;
  1272. case WT_setattr:
  1273. // int func(PyObject *self, PyObject *one, PyObject *two = NULL)
  1274. {
  1275. out << "//////////////////\n";
  1276. out << "// A wrapper function to satisfy Python's internal calling conventions.\n";
  1277. out << "// " << ClassName << " ..." << rfi->second._answer_location << " = " << methodNameFromCppName(func, export_class_name, false) << "\n";
  1278. out << "//////////////////\n";
  1279. out << "static int " << func->_name << methodNameFromCppName(func, export_class_name, false) << "(PyObject *self, PyObject *arg, PyObject *arg2) {\n";
  1280. if (func_varargs) {
  1281. out << " PyObject *args;\n";
  1282. out << " if (arg2 == NULL) {\n";
  1283. out << " args = PyTuple_Pack(1, arg);\n";
  1284. out << " } else {\n";
  1285. out << " args = PyTuple_Pack(2, arg, arg2);\n";
  1286. out << " }\n";
  1287. out << " PyObject *py_result = " << call_func << ";\n";
  1288. out << " Py_DECREF(args);\n";
  1289. } else {
  1290. out << " PyObject *py_result = " << call_func << ";\n";
  1291. }
  1292. out << " if (py_result == NULL) return -1;\n";
  1293. out << "#if PY_MAJOR_VERSION >= 3\n";
  1294. out << " int result = PyLong_AsLong(py_result);\n";
  1295. out << "#else\n";
  1296. out << " int result = PyInt_AsLong(py_result);\n";
  1297. out << "#endif\n";
  1298. out << " Py_DECREF(py_result);\n";
  1299. out << " return result;\n";
  1300. out << "}\n\n";
  1301. }
  1302. break;
  1303. case WT_getattr:
  1304. // PyObject *func(PyObject *self, PyObject *one)
  1305. // Specifically to implement __getattr__.
  1306. // With special handling to pass up to
  1307. // PyObject_GenericGetAttr() if it returns NULL.
  1308. {
  1309. out << "//////////////////\n";
  1310. out << "// A wrapper function to satisfy Python's internal calling conventions.\n";
  1311. out << "// " << ClassName << " ..." << rfi->second._answer_location << " = " << methodNameFromCppName(func, export_class_name, false) << "\n";
  1312. out << "//////////////////\n";
  1313. out << "static PyObject *" << func->_name << methodNameFromCppName(func, export_class_name, false) << "(PyObject *self, PyObject *arg) {\n";
  1314. if (func_varargs) {
  1315. out << " PyObject *args = PyTuple_Pack(1, arg);\n";
  1316. out << " PyObject *result = " << call_func << ";\n";
  1317. out << " Py_DECREF(args);\n";
  1318. } else {
  1319. out << " PyObject *result = " << call_func << ";\n";
  1320. }
  1321. out << " if (result == NULL) {\n";
  1322. out << " PyErr_Clear();\n";
  1323. out << " return PyObject_GenericGetAttr(self, arg);\n";
  1324. out << " }\n";
  1325. out << " return result;\n";
  1326. out << "}\n\n";
  1327. }
  1328. break;
  1329. case WT_sequence_getitem:
  1330. // PyObject *func(PyObject *self, Py_ssize_t index)
  1331. {
  1332. out << "//////////////////\n";
  1333. out << "// A wrapper function to satisfy Python's internal calling conventions.\n";
  1334. out << "// " << ClassName << " ..." << rfi->second._answer_location << " = " << methodNameFromCppName(func, export_class_name, false) << "\n";
  1335. out << "//////////////////\n";
  1336. out << "static PyObject *" << func->_name << methodNameFromCppName(func, export_class_name, false) << "(PyObject *self, Py_ssize_t index) {\n";
  1337. out << " " << cClassName << " *local_this = NULL;\n";
  1338. out << " DTOOL_Call_ExtractThisPointerForType(self, &Dtool_" << ClassName << ", (void **)&local_this);\n";
  1339. out << " if (local_this == NULL) {\n";
  1340. out << " PyErr_SetString(PyExc_AttributeError, \"C++ object is not yet constructed, or already destructed.\");\n";
  1341. out << " return NULL;\n";
  1342. out << " }\n\n";
  1343. // This is a getitem or setitem of a sequence type. This means we
  1344. // *need* to raise IndexError if we're out of bounds. We have to
  1345. // assume the bounds are 0 .. this->size() (this is the same
  1346. // assumption that Python makes).
  1347. out << " if (index < 0 || index >= (Py_ssize_t) local_this->size()) {\n";
  1348. out << " PyErr_SetString(PyExc_IndexError, \"" << ClassName << " index out of range\");\n";
  1349. out << " return NULL;\n";
  1350. out << " }\n";
  1351. // Gather the remaps with the F_getitem_int flag.
  1352. std::set<FunctionRemap*> remaps;
  1353. Function::Remaps::const_iterator ri;
  1354. for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
  1355. FunctionRemap *remap = (*ri);
  1356. if (is_remap_legal(remap) && (remap->_flags & FunctionRemap::F_getitem_int)) {
  1357. remaps.insert(remap);
  1358. }
  1359. }
  1360. string expected_params;
  1361. bool coercion_attempted = false;
  1362. write_function_forset(out, obj, func, remaps, expected_params, 2, false, false,
  1363. coercion_attempted, AT_no_args, false, "index");
  1364. out << " return NULL;\n";
  1365. out << "}\n\n";
  1366. }
  1367. break;
  1368. case WT_sequence_setitem:
  1369. // int_t func(PyObject *self, Py_ssize_t index, PyObject *value)
  1370. {
  1371. out << "//////////////////\n";
  1372. out << "// A wrapper function to satisfy Python's internal calling conventions.\n";
  1373. out << "// " << ClassName << " ..." << rfi->second._answer_location << " = " << methodNameFromCppName(func, export_class_name, false) << "\n";
  1374. out << "//////////////////\n";
  1375. out << "static int " << func->_name << methodNameFromCppName(func, export_class_name, false) << "(PyObject *self, Py_ssize_t index, PyObject *arg) {\n";
  1376. out << " " << cClassName << " *local_this = NULL;\n";
  1377. out << " DTOOL_Call_ExtractThisPointerForType(self, &Dtool_" << ClassName << ", (void **)&local_this);\n";
  1378. out << " if (local_this == NULL) {\n";
  1379. out << " PyErr_SetString(PyExc_AttributeError, \"C++ object is not yet constructed, or already destructed.\");\n";
  1380. out << " return -1;\n";
  1381. out << " }\n\n";
  1382. out << " if (index < 0 || index >= (Py_ssize_t) local_this->size()) {\n";
  1383. out << " PyErr_SetString(PyExc_IndexError, \"" << ClassName << " index out of range\");\n";
  1384. out << " return -1;\n";
  1385. out << " }\n";
  1386. // Gather the remaps with the F_getitem_int flag.
  1387. std::set<FunctionRemap*> remaps;
  1388. Function::Remaps::const_iterator ri;
  1389. for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
  1390. FunctionRemap *remap = (*ri);
  1391. if (is_remap_legal(remap) && (remap->_flags & FunctionRemap::F_setitem_int)) {
  1392. remaps.insert(remap);
  1393. }
  1394. }
  1395. // Note: we disallow parameter coercion for setitem. It's not clear if anybody
  1396. // uses it in this case, and since some people may need to call this function
  1397. // very often, it's probably best to disable it for performance.
  1398. string expected_params;
  1399. bool coercion_attempted = false;
  1400. write_function_forset(out, obj, func, remaps, expected_params, 2, false, false,
  1401. coercion_attempted, AT_single_arg, true, "index");
  1402. out << " if (!PyErr_Occurred()) {\n";
  1403. out << " PyErr_SetString(PyExc_TypeError,\n";
  1404. out << " \"Arguments must match:\\n\"\n";
  1405. output_quoted(out, 6, expected_params);
  1406. out << ");\n";
  1407. out << " }\n";
  1408. out << " return -1;\n";
  1409. out << "}\n\n";
  1410. }
  1411. break;
  1412. case WT_sequence_size:
  1413. // Py_ssize_t func(PyObject *self)
  1414. {
  1415. out << "//////////////////\n";
  1416. out << "// A wrapper function to satisfy Python's internal calling conventions.\n";
  1417. out << "// " << ClassName << " ..." << rfi->second._answer_location << " = " << methodNameFromCppName(func, export_class_name, false) << "\n";
  1418. out << "//////////////////\n";
  1419. out << "static Py_ssize_t " << func->_name << methodNameFromCppName(func, export_class_name, false) << "(PyObject *self) {\n";
  1420. out << " " << cClassName << " *local_this = NULL;\n";
  1421. out << " DTOOL_Call_ExtractThisPointerForType(self, &Dtool_" << ClassName << ", (void **)&local_this);\n";
  1422. out << " if (local_this == NULL) {\n";
  1423. out << " PyErr_SetString(PyExc_AttributeError, \"C++ object is not yet constructed, or already destructed.\");\n";
  1424. out << " return -1;\n";
  1425. out << " }\n\n";
  1426. // This is a cheap cheat around all of the overhead of calling the wrapper function.
  1427. out << " return (Py_ssize_t) local_this->" << func->_ifunc.get_name() << "();\n";
  1428. out << "}\n\n";
  1429. }
  1430. break;
  1431. case WT_mapping_setitem:
  1432. // int func(PyObject *self, PyObject *one, PyObject *two)
  1433. {
  1434. out << "//////////////////\n";
  1435. out << "// A wrapper function to satisfy Python's internal calling conventions.\n";
  1436. out << "// " << ClassName << " ..." << rfi->second._answer_location << " = " << methodNameFromCppName(func, export_class_name, false) << "\n";
  1437. out << "//////////////////\n";
  1438. out << "static int " << func->_name << methodNameFromCppName(func, export_class_name, false) << "(PyObject *self, PyObject *arg, PyObject *arg2) {\n";
  1439. if (func_varargs) {
  1440. out << " PyObject *args = PyTuple_Pack(2, arg, arg2);\n";
  1441. out << " PyObject *result = " << call_func << ";\n";
  1442. out << " Py_DECREF(args);\n";
  1443. } else {
  1444. out << " PyObject *result = " << call_func << ";\n";
  1445. }
  1446. out << " if (result == NULL) {\n";
  1447. out << " return -1;\n";
  1448. out << " }\n";
  1449. out << " Py_DECREF(result);\n";
  1450. out << " return 0;\n";
  1451. out << "}\n\n";
  1452. }
  1453. break;
  1454. case WT_inquiry:
  1455. // int func(PyObject *self)
  1456. {
  1457. out << "//////////////////\n";
  1458. out << "// A wrapper function to satisfy Python's internal calling conventions.\n";
  1459. out << "// " << ClassName << " ..." << rfi->second._answer_location << " = " << methodNameFromCppName(func, export_class_name, false) << "\n";
  1460. out << "//////////////////\n";
  1461. out << "static int " << func->_name << methodNameFromCppName(func, export_class_name, false) << "(PyObject *self) {\n";
  1462. if (func_varargs) {
  1463. out << " PyObject *args = PyTuple_New(0);\n";
  1464. out << " PyObject *result = " << call_func << ";\n";
  1465. out << " Py_DECREF(args);\n";
  1466. } else {
  1467. out << " PyObject *result = " << call_func << ";\n";
  1468. }
  1469. out << " if (result == NULL) {\n";
  1470. out << " return -1;\n";
  1471. out << " }\n";
  1472. out << "#if PY_MAJOR_VERSION >= 3\n";
  1473. out << " int iresult = PyLong_AsLong(result);\n";
  1474. out << "#else\n";
  1475. out << " int iresult = PyInt_AsLong(result);\n";
  1476. out << "#endif\n";
  1477. out << " Py_DECREF(result);\n";
  1478. out << " return iresult;\n";
  1479. out << "}\n\n";
  1480. }
  1481. break;
  1482. case WT_getbuffer:
  1483. // int __getbuffer__(PyObject *self, Py_buffer *buffer, int flags)
  1484. // We map this directly, and assume that the arguments match. The whole point
  1485. // of this is to be fast, and we don't want to negate that by first wrapping
  1486. // and then unwrapping the arguments again. We also want to guarantee const
  1487. // correctness, since that will determine whether a read-only buffer is given.
  1488. {
  1489. has_local_getbuffer = true;
  1490. out << "//////////////////\n";
  1491. out << "// A wrapper function to satisfy Python's internal calling conventions.\n";
  1492. out << "// " << ClassName << " ..." << rfi->second._answer_location << " = " << methodNameFromCppName(func, export_class_name, false) << "\n";
  1493. out << "//////////////////\n";
  1494. out << "static int " << func->_name << methodNameFromCppName(func, export_class_name, false) << "(PyObject *self, Py_buffer *buffer, int flags) {\n";
  1495. out << " " << cClassName << " *local_this = NULL;\n";
  1496. out << " DTOOL_Call_ExtractThisPointerForType(self, &Dtool_" << ClassName << ", (void **) &local_this);\n";
  1497. out << " if (local_this == NULL) {\n";
  1498. out << " PyErr_SetString(PyExc_AttributeError, \"C++ object is not yet constructed, or already destructed.\");\n";
  1499. out << " return -1;\n";
  1500. out << " }\n\n";
  1501. vector_string params_const(1);
  1502. vector_string params_nonconst(1);
  1503. FunctionRemap *remap_const = NULL;
  1504. FunctionRemap *remap_nonconst = NULL;
  1505. // Iterate through the remaps to find the one that matches our parameters.
  1506. Function::Remaps::const_iterator ri;
  1507. for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
  1508. FunctionRemap *remap = (*ri);
  1509. if (remap->_flags & FunctionRemap::F_getbuffer) {
  1510. if (remap->_const_method) {
  1511. if ((remap->_flags & FunctionRemap::F_explicit_self) == 0) {
  1512. params_const.push_back("self");
  1513. }
  1514. remap_const = remap;
  1515. } else {
  1516. if ((remap->_flags & FunctionRemap::F_explicit_self) == 0) {
  1517. params_nonconst.push_back("self");
  1518. }
  1519. remap_nonconst = remap;
  1520. }
  1521. }
  1522. }
  1523. params_const.push_back("buffer");
  1524. params_const.push_back("flags");
  1525. params_nonconst.push_back("buffer");
  1526. params_nonconst.push_back("flags");
  1527. // We have to distinguish properly between const and nonconst, because the function
  1528. // may depend on it to decide whether to provide a writable buffer or a readonly buffer.
  1529. const string const_this = "(const " + cClassName + " *)local_this";
  1530. if (remap_const != NULL && remap_nonconst != NULL) {
  1531. out << " if (!((Dtool_PyInstDef *)self)->_is_const) {\n";
  1532. out << " return " << remap_nonconst->call_function(out, 4, false, "local_this", params_nonconst) << ";\n";
  1533. out << " } else {\n";
  1534. out << " return " << remap_const->call_function(out, 4, false, const_this, params_const) << ";\n";
  1535. out << " }\n";
  1536. } else if (remap_nonconst != NULL) {
  1537. out << " if (!((Dtool_PyInstDef *)self)->_is_const) {\n";
  1538. out << " return " << remap_nonconst->call_function(out, 4, false, "local_this", params_nonconst) << ";\n";
  1539. out << " } else {\n";
  1540. out << " PyErr_SetString(PyExc_TypeError,\n";
  1541. out << " \"Cannot call " << ClassName << ".__getbuffer__() on a const object.\");\n";
  1542. out << " return -1;\n";
  1543. out << " }\n";
  1544. } else if (remap_const != NULL) {
  1545. out << " return " << remap_const->call_function(out, 4, false, const_this, params_const) << ";\n";
  1546. } else {
  1547. nout << ClassName << "::__getbuffer__ does not match the required signature.\n";
  1548. out << " return -1;\n";
  1549. }
  1550. out << "}\n\n";
  1551. }
  1552. break;
  1553. case WT_releasebuffer:
  1554. // void __releasebuffer__(PyObject *self, Py_buffer *buffer)
  1555. // Same story as __getbuffer__ above.
  1556. {
  1557. out << "//////////////////\n";
  1558. out << "// A wrapper function to satisfy Python's internal calling conventions.\n";
  1559. out << "// " << ClassName << " ..." << rfi->second._answer_location << " = " << methodNameFromCppName(func, export_class_name, false) << "\n";
  1560. out << "//////////////////\n";
  1561. out << "static void " << func->_name << methodNameFromCppName(func, export_class_name, false) << "(PyObject *self, Py_buffer *buffer) {\n";
  1562. out << " " << cClassName << " *local_this = NULL;\n";
  1563. out << " DTOOL_Call_ExtractThisPointerForType(self, &Dtool_" << ClassName << ", (void **) &local_this);\n";
  1564. out << " if (local_this == NULL) {\n";
  1565. out << " PyErr_SetString(PyExc_AttributeError, \"C++ object is not yet constructed, or already destructed.\");\n";
  1566. out << " return;\n";
  1567. out << " }\n\n";
  1568. vector_string params_const(1);
  1569. vector_string params_nonconst(1);
  1570. FunctionRemap *remap_const = NULL;
  1571. FunctionRemap *remap_nonconst = NULL;
  1572. // Iterate through the remaps to find the one that matches our parameters.
  1573. Function::Remaps::const_iterator ri;
  1574. for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
  1575. FunctionRemap *remap = (*ri);
  1576. if (remap->_flags & FunctionRemap::F_releasebuffer) {
  1577. if (remap->_const_method) {
  1578. if ((remap->_flags & FunctionRemap::F_explicit_self) == 0) {
  1579. params_const.push_back("self");
  1580. }
  1581. remap_const = remap;
  1582. } else {
  1583. if ((remap->_flags & FunctionRemap::F_explicit_self) == 0) {
  1584. params_nonconst.push_back("self");
  1585. }
  1586. remap_nonconst = remap;
  1587. }
  1588. }
  1589. }
  1590. params_const.push_back("buffer");
  1591. params_nonconst.push_back("buffer");
  1592. string return_expr;
  1593. const string const_this = "(const " + cClassName + " *)local_this";
  1594. if (remap_const != NULL && remap_nonconst != NULL) {
  1595. out << " if (!((Dtool_PyInstDef *)self)->_is_const) {\n";
  1596. return_expr = remap_nonconst->call_function(out, 4, false, "local_this", params_nonconst);
  1597. if (!return_expr.empty()) {
  1598. out << " " << return_expr << ";\n";
  1599. }
  1600. out << " } else {\n";
  1601. return_expr = remap_const->call_function(out, 4, false, const_this, params_const);
  1602. if (!return_expr.empty()) {
  1603. out << " " << return_expr << ";\n";
  1604. }
  1605. out << " }\n";
  1606. } else if (remap_nonconst != NULL) {
  1607. // Doesn't matter if there's no const version. We *have* to call it or else we could leak memory.
  1608. return_expr = remap_nonconst->call_function(out, 2, false, "local_this", params_nonconst);
  1609. if (!return_expr.empty()) {
  1610. out << " " << return_expr << ";\n";
  1611. }
  1612. } else if (remap_const != NULL) {
  1613. return_expr = remap_const->call_function(out, 2, false, const_this, params_const);
  1614. if (!return_expr.empty()) {
  1615. out << " " << return_expr << ";\n";
  1616. }
  1617. } else {
  1618. nout << ClassName << "::__releasebuffer__ does not match the required signature.\n";
  1619. out << " return;\n";
  1620. }
  1621. out << "}\n\n";
  1622. }
  1623. break;
  1624. case WT_iter_next:
  1625. // PyObject *func(PyObject *self)
  1626. // However, returns NULL instead of None
  1627. {
  1628. out << "//////////////////\n";
  1629. out << "// A wrapper function to satisfy Python's internal calling conventions.\n";
  1630. out << "// " << ClassName << " ..." << rfi->second._answer_location << " = " << methodNameFromCppName(func, export_class_name, false) << "\n";
  1631. out << "//////////////////\n";
  1632. out << "static PyObject *" << func->_name << methodNameFromCppName(func, export_class_name, false) << "(PyObject *self) {\n";
  1633. if (func_varargs) {
  1634. out << " PyObject *args = PyTuple_New(0);\n";
  1635. out << " PyObject *result = " << call_func << ";\n";
  1636. out << " Py_DECREF(args);\n";
  1637. } else {
  1638. out << " PyObject *result = " << call_func << ";\n";
  1639. }
  1640. out << " if (result == Py_None) {\n";
  1641. out << " Py_DECREF(Py_None);\n";
  1642. out << " return NULL;\n";
  1643. out << " } else {\n";
  1644. out << " return result;\n";
  1645. out << " }\n";
  1646. out << "}\n\n";
  1647. }
  1648. break;
  1649. case WT_one_or_two_params:
  1650. case WT_ternary_operator:
  1651. // PyObject *func(PyObject *self, PyObject *one, PyObject *two)
  1652. {
  1653. out << "//////////////////\n";
  1654. out << "// A wrapper function to satisfy Python's internal calling conventions.\n";
  1655. out << "// " << ClassName << " ..." << rfi->second._answer_location << " = " << methodNameFromCppName(func, export_class_name, false) << "\n";
  1656. out << "//////////////////\n";
  1657. out << "static PyObject *" << func->_name << methodNameFromCppName(func, export_class_name, false) << "(PyObject *self, PyObject *arg, PyObject *arg2) {\n";
  1658. if (func_varargs) {
  1659. out << " PyObject *args;\n";
  1660. out << " if (arg2 != Py_None) {\n";
  1661. out << " args = PyTuple_Pack(2, arg, arg2);\n";
  1662. out << " } else {\n";
  1663. out << " args = PyTuple_Pack(1, arg);\n";
  1664. out << " }\n\n";
  1665. out << " PyObject *result = " << call_func << ";\n";
  1666. out << " Py_DECREF(args);\n";
  1667. out << " return result;\n";
  1668. } else {
  1669. out << " return " << call_func << ";\n";
  1670. }
  1671. out << "}\n\n";
  1672. }
  1673. break;
  1674. case WT_none:
  1675. break;
  1676. }
  1677. }
  1678. string get_key = HasAGetKeyFunction(obj->_itype);
  1679. if (!get_key.empty()) {
  1680. out << "//////////////////\n";
  1681. out << "// A LocalHash(getKey) Function for this type\n";
  1682. out << "// " << ClassName << "\n";
  1683. out << "//////////////////\n";
  1684. out << "static Py_hash_t Dtool_HashKey_" << ClassName << "(PyObject *self) {\n";
  1685. out << " " << cClassName << " *local_this = NULL;\n";
  1686. out << " DTOOL_Call_ExtractThisPointerForType(self, &Dtool_" << ClassName << ", (void **) &local_this);\n";
  1687. out << " if (local_this == NULL) {\n";
  1688. out << " PyErr_SetString(PyExc_AttributeError, \"C++ object is not yet constructed, or already destructed.\");\n";
  1689. out << " return -1;\n";
  1690. out << " }\n";
  1691. out << " return local_this->" << get_key << "();\n";
  1692. out << "}\n\n";
  1693. has_local_hash = true;
  1694. } else {
  1695. if (bases.size() == 0) {
  1696. out << "//////////////////\n";
  1697. out << "// A LocalHash(This Pointer) Function for this type\n";
  1698. out << "// " << ClassName << "\n";
  1699. out << "//////////////////\n";
  1700. out << "static Py_hash_t Dtool_HashKey_" << ClassName << "(PyObject *self) {\n";
  1701. out << " " << cClassName << " *local_this = NULL;\n";
  1702. out << " DTOOL_Call_ExtractThisPointerForType(self, &Dtool_" << ClassName << ", (void **) &local_this);\n";
  1703. out << " if (local_this == NULL) {\n";
  1704. out << " PyErr_SetString(PyExc_AttributeError, \"C++ object is not yet constructed, or already destructed.\");\n";
  1705. out << " return -1;\n";
  1706. out << " }\n";
  1707. out << " return (Py_hash_t) local_this;\n";
  1708. out << "}\n\n";
  1709. has_local_hash = true;
  1710. }
  1711. }
  1712. int need_repr = NeedsAReprFunction(obj->_itype);
  1713. if (need_repr > 0) {
  1714. out << "//////////////////\n";
  1715. out << "// A __repr__ function\n";
  1716. out << "// " << ClassName << "\n";
  1717. out << "//////////////////\n";
  1718. out << "static PyObject *Dtool_Repr_" << ClassName << "(PyObject *self) {\n";
  1719. out << " " << cClassName << " *local_this = NULL;\n";
  1720. out << " DTOOL_Call_ExtractThisPointerForType(self, &Dtool_" << ClassName << ", (void **) &local_this);\n";
  1721. out << " if (local_this == NULL) {\n";
  1722. out << " PyErr_SetString(PyExc_AttributeError, \"C++ object is not yet constructed, or already destructed.\");\n";
  1723. out << " return NULL;\n";
  1724. out << " }\n";
  1725. out << " ostringstream os;\n";
  1726. if (need_repr == 3) {
  1727. out << " invoke_extension(local_this).python_repr(os, \""
  1728. << classNameFromCppName(ClassName, false) << "\");\n";
  1729. } else if (need_repr == 2) {
  1730. out << " local_this->output(os);\n";
  1731. } else {
  1732. out << " local_this->python_repr(os, \""
  1733. << classNameFromCppName(ClassName, false) << "\");\n";
  1734. }
  1735. out << " std::string ss = os.str();\n";
  1736. out << "#if PY_MAJOR_VERSION >= 3\n";
  1737. out << " return PyUnicode_FromStringAndSize(ss.data(), ss.length());\n";
  1738. out << "#else\n";
  1739. out << " return PyString_FromStringAndSize(ss.data(), ss.length());\n";
  1740. out << "#endif\n";
  1741. out << "}\n\n";
  1742. has_local_repr = true;
  1743. }
  1744. int need_str = NeedsAStrFunction(obj->_itype);
  1745. if (need_str > 0) {
  1746. out << "//////////////////\n";
  1747. out << "// A __str__ function\n";
  1748. out << "// " << ClassName << "\n";
  1749. out << "//////////////////\n";
  1750. out << "static PyObject *Dtool_Str_" << ClassName << "(PyObject *self) {\n";
  1751. out << " " << cClassName << " *local_this = NULL;\n";
  1752. out << " DTOOL_Call_ExtractThisPointerForType(self, &Dtool_" << ClassName << ", (void **)&local_this);\n";
  1753. out << " if (local_this == NULL) {\n";
  1754. out << " PyErr_SetString(PyExc_AttributeError, \"C++ object is not yet constructed, or already destructed.\");\n";
  1755. out << " return NULL;\n";
  1756. out << " }\n";
  1757. out << " ostringstream os;\n";
  1758. if (need_str == 2) {
  1759. out << " local_this->write(os, 0);\n";
  1760. } else {
  1761. out << " local_this->write(os);\n";
  1762. }
  1763. out << " std::string ss = os.str();\n";
  1764. out << "#if PY_MAJOR_VERSION >= 3\n";
  1765. out << " return PyUnicode_FromStringAndSize(ss.data(), ss.length());\n";
  1766. out << "#else\n";
  1767. out << " return PyString_FromStringAndSize(ss.data(), ss.length());\n";
  1768. out << "#endif\n";
  1769. out << "}\n\n";
  1770. has_local_str = true;
  1771. }
  1772. }
  1773. if (NeedsARichCompareFunction(obj->_itype)) {
  1774. out << "//////////////////\n";
  1775. out << "// A rich comparison function\n";
  1776. out << "// " << ClassName << "\n";
  1777. out << "//////////////////\n";
  1778. out << "static PyObject *Dtool_RichCompare_" << ClassName << "(PyObject *self, PyObject *arg, int op) {\n";
  1779. out << " " << cClassName << " *local_this = NULL;\n";
  1780. out << " DTOOL_Call_ExtractThisPointerForType(self, &Dtool_" << ClassName << ", (void **)&local_this);\n";
  1781. out << " if (local_this == NULL) {\n";
  1782. out << " PyErr_SetString(PyExc_AttributeError, \"C++ object is not yet constructed, or already destructed.\");\n";
  1783. out << " return NULL;\n";
  1784. out << " }\n\n";
  1785. out << " switch (op) {\n";
  1786. Function *compare_to_func = NULL;
  1787. for (fi = obj->_methods.begin(); fi != obj->_methods.end(); ++fi) {
  1788. std::set<FunctionRemap*> remaps;
  1789. Function *func = (*fi);
  1790. if (!func) {
  1791. continue;
  1792. }
  1793. // We only accept comparison operators that take one parameter (besides 'this').
  1794. Function::Remaps::const_iterator ri;
  1795. for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
  1796. FunctionRemap *remap = (*ri);
  1797. if (is_remap_legal(remap) && remap->_has_this && (remap->_args_type == AT_single_arg)) {
  1798. remaps.insert(remap);
  1799. }
  1800. }
  1801. const string &fname = func->_ifunc.get_name();
  1802. if (fname == "operator <") {
  1803. out << " case Py_LT: {\n";
  1804. } else if (fname == "operator <=") {
  1805. out << " case Py_LE: {\n";
  1806. } else if (fname == "operator ==") {
  1807. out << " case Py_EQ: {\n";
  1808. } else if (fname == "operator !=") {
  1809. out << " case Py_NE: {\n";
  1810. } else if (fname == "operator >") {
  1811. out << " case Py_GT: {\n";
  1812. } else if (fname == "operator >=") {
  1813. out << " case Py_GE: {\n";
  1814. } else if (fname == "compare_to") {
  1815. compare_to_func = func;
  1816. continue;
  1817. } else {
  1818. continue;
  1819. }
  1820. string expected_params;
  1821. bool coercion_attempted = false;
  1822. write_function_forset(out, obj, func, remaps, expected_params, 4, false, true,
  1823. coercion_attempted, AT_single_arg, false);
  1824. out << " if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_TypeError)) {\n";
  1825. out << " PyErr_Clear();\n";
  1826. out << " }\n";
  1827. out << " break;\n";
  1828. out << " }\n";
  1829. has_local_richcompare = true;
  1830. }
  1831. out << " }\n\n";
  1832. out << " if (PyErr_Occurred()) {\n";
  1833. out << " return (PyObject *)NULL;\n";
  1834. out << " }\n\n";
  1835. if (compare_to_func != NULL) {
  1836. out << "#if PY_MAJOR_VERSION >= 3\n";
  1837. out << " // All is not lost; we still have the compare_to function to fall back onto.\n";
  1838. out << " PyObject *result = " << compare_to_func->_name << "(self, arg);\n";
  1839. out << " if (result != NULL) {\n";
  1840. out << " if (PyLong_Check(result)) {;\n";
  1841. out << " long cmpval = PyLong_AsLong(result);\n";
  1842. out << " switch (op) {\n";
  1843. out << " case Py_LT:\n";
  1844. out << " return PyBool_FromLong(cmpval < 0);\n";
  1845. out << " case Py_LE:\n";
  1846. out << " return PyBool_FromLong(cmpval <= 0);\n";
  1847. out << " case Py_EQ:\n";
  1848. out << " return PyBool_FromLong(cmpval == 0);\n";
  1849. out << " case Py_NE:\n";
  1850. out << " return PyBool_FromLong(cmpval != 0);\n";
  1851. out << " case Py_GT:\n";
  1852. out << " return PyBool_FromLong(cmpval > 0);\n";
  1853. out << " case Py_GE:\n";
  1854. out << " return PyBool_FromLong(cmpval >= 0);\n";
  1855. out << " }\n";
  1856. out << " }\n";
  1857. out << " Py_DECREF(result);\n";
  1858. out << " }\n\n";
  1859. out << " if (PyErr_Occurred()) {\n";
  1860. out << " if (PyErr_ExceptionMatches(PyExc_TypeError)) {\n";
  1861. out << " PyErr_Clear();\n";
  1862. out << " } else {\n";
  1863. out << " return (PyObject *)NULL;\n";
  1864. out << " }\n";
  1865. out << " }\n";
  1866. out << "#endif\n\n";
  1867. }
  1868. out << " Py_INCREF(Py_NotImplemented);\n";
  1869. out << " return Py_NotImplemented;\n";
  1870. out << "}\n\n";
  1871. }
  1872. if (obj->_properties.size() > 0) {
  1873. // Write out the array of properties, telling Python which getter and setter
  1874. // to call when they are assigned or queried in Python code.
  1875. out << "PyGetSetDef Dtool_Properties_" << ClassName << "[] = {\n";
  1876. Properties::const_iterator pit;
  1877. for (pit = obj->_properties.begin(); pit != obj->_properties.end(); ++pit) {
  1878. Property *property = (*pit);
  1879. const InterrogateElement &ielem = property->_ielement;
  1880. if (property->_getter == NULL || !is_function_legal(property->_getter)) {
  1881. continue;
  1882. }
  1883. out << " {(char *)\"" << ielem.get_name() << "\","
  1884. << " &Dtool_" << ClassName << "_" << ielem.get_name() << "_Getter,";
  1885. if (property->_setter == NULL || !is_function_legal(property->_setter)) {
  1886. out << " NULL,";
  1887. } else {
  1888. out << " &Dtool_" << ClassName << "_" << ielem.get_name() << "_Setter,";
  1889. }
  1890. if (ielem.has_comment()) {
  1891. out << "(char *)\n";
  1892. output_quoted(out, 4, ielem.get_comment());
  1893. out << ",\n ";
  1894. } else {
  1895. out << " NULL, ";
  1896. }
  1897. // Extra void* argument; we don't make use of it.
  1898. out << "NULL},\n";
  1899. }
  1900. out << " {NULL},\n";
  1901. out << "};\n\n";
  1902. }
  1903. out << "void Dtool_PyModuleClassInit_" << ClassName << "(PyObject *module) {\n";
  1904. out << " static bool initdone = false;\n";
  1905. out << " if (!initdone) {\n";
  1906. out << " initdone = true;\n";
  1907. // out << " memset(Dtool_" << ClassName << ".As_PyTypeObject().tp_as_number,0,sizeof(PyNumberMethods));\n";
  1908. // out << " memset(Dtool_" << ClassName << ".As_PyTypeObject().tp_as_mapping,0,sizeof(PyMappingMethods));\n";
  1909. // out << " static Dtool_PyTypedObject *InheritsFrom[] = {";
  1910. // add doc string
  1911. if (obj->_itype.has_comment()) {
  1912. out << "#ifndef NDEBUG\n";
  1913. out << " // Class documentation string\n";
  1914. out << " Dtool_" << ClassName
  1915. << ".As_PyTypeObject().tp_doc =\n";
  1916. output_quoted(out, 6, obj->_itype.get_comment());
  1917. out << ";\n"
  1918. << "#endif\n";
  1919. }
  1920. // Add flags.
  1921. if (obj->_protocol_types & Object::PT_iter) {
  1922. out << "#if PY_VERSION_HEX < 0x03000000\n";
  1923. out << " Dtool_" << ClassName << ".As_PyTypeObject().tp_flags |= Py_TPFLAGS_HAVE_ITER;\n";
  1924. out << "#endif";
  1925. }
  1926. if (has_local_getbuffer) {
  1927. out << "#if PY_VERSION_HEX >= 0x02060000 && PY_VERSION_HEX < 0x03000000\n";
  1928. out << " Dtool_" << ClassName << ".As_PyTypeObject().tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;\n";
  1929. out << "#endif";
  1930. }
  1931. // add bases///
  1932. if (bases.size() > 0) {
  1933. out << " // Dependent objects\n";
  1934. string baseargs;
  1935. for (vector<string>::iterator bi = bases.begin(); bi != bases.end(); ++bi) {
  1936. baseargs += ", &Dtool_" + *bi + ".As_PyTypeObject()";
  1937. out << " Dtool_" << make_safe_name(*bi) << "._Dtool_ClassInit(NULL);\n";
  1938. }
  1939. out << " Dtool_" << ClassName << ".As_PyTypeObject().tp_bases = PyTuple_Pack(" << bases.size() << baseargs << ");\n";
  1940. }
  1941. // get dictionary
  1942. out << " Dtool_" << ClassName << ".As_PyTypeObject().tp_dict = PyDict_New();\n";
  1943. out << " PyDict_SetItemString(Dtool_" << ClassName << ".As_PyTypeObject().tp_dict, \"DtoolClassDict\", Dtool_" << ClassName << ".As_PyTypeObject().tp_dict);\n";
  1944. // Now assign the slotted function definitions.
  1945. map<Function *, SlottedFunctionDef>::const_iterator rfi;
  1946. int prev_min_version = 0;
  1947. for (rfi = slotted_functions.begin(); rfi != slotted_functions.end(); rfi++) {
  1948. Function *func = rfi->first;
  1949. const SlottedFunctionDef &def = rfi->second;
  1950. // Add an #ifdef if there is a specific version requirement on this function.
  1951. if (def._min_version != prev_min_version) {
  1952. if (prev_min_version > 0) {
  1953. out << "#endif\n";
  1954. }
  1955. prev_min_version = def._min_version;
  1956. if (def._min_version > 0) {
  1957. out << "#if PY_VERSION_HEX >= 0x" << hex << def._min_version << dec << "\n";
  1958. }
  1959. }
  1960. out << " // " << rfi->second._answer_location << " = " << methodNameFromCppName(func, export_class_name, false) << "\n";
  1961. if (def._wrapper_type == WT_none) {
  1962. // Bound directly, without wrapper.
  1963. out << " Dtool_" << ClassName << ".As_PyTypeObject()." << def._answer_location << " = &" << func->_name << ";\n";
  1964. } else {
  1965. // Assign to the wrapper method that was generated earlier.
  1966. out << " Dtool_" << ClassName << ".As_PyTypeObject()." << def._answer_location << " = &" << func->_name << methodNameFromCppName(func, export_class_name, false) << ";\n";
  1967. }
  1968. }
  1969. if (prev_min_version > 0) {
  1970. out << "#endif\n";
  1971. }
  1972. // compare and hash work together in PY inherit behavior hmm grrr
  1973. // __hash__
  1974. if (has_local_hash) {
  1975. out << " // __hash__\n";
  1976. out << " Dtool_" << ClassName << ".As_PyTypeObject().tp_hash = &Dtool_HashKey_" << ClassName << ";\n";
  1977. out << "#if PY_MAJOR_VERSION >= 3\n";
  1978. if (!has_local_richcompare) {
  1979. out << " Dtool_" << ClassName << ".As_PyTypeObject().tp_richcompare = &DTOOL_PyObject_RichCompare;\n";
  1980. }
  1981. out << "#else\n";
  1982. out << " Dtool_" << ClassName << ".As_PyTypeObject().tp_compare = &DTOOL_PyObject_Compare;\n";
  1983. out << "#endif\n";
  1984. }
  1985. if (has_local_richcompare) {
  1986. out << " Dtool_" << ClassName << ".As_PyTypeObject().tp_richcompare = &Dtool_RichCompare_" << ClassName << ";\n";
  1987. }
  1988. if (has_local_repr) {
  1989. out << " // __repr__\n";
  1990. out << " Dtool_" << ClassName << ".As_PyTypeObject().tp_repr = &Dtool_Repr_" << ClassName << ";\n";
  1991. }
  1992. if (has_local_str) {
  1993. out << " // __str__\n";
  1994. out << " Dtool_" << ClassName << ".As_PyTypeObject().tp_str = &Dtool_Str_" << ClassName << ";\n";
  1995. } else if (has_local_repr) {
  1996. out << " // __str__ Repr Proxy\n";
  1997. out << " Dtool_" << ClassName << ".As_PyTypeObject().tp_str = &Dtool_Repr_" << ClassName << ";\n";
  1998. }
  1999. if (obj->_properties.size() > 0) {
  2000. // GetSet descriptor slots.
  2001. out << " Dtool_" << ClassName << ".As_PyTypeObject().tp_getset = Dtool_Properties_" << ClassName << ";\n";
  2002. }
  2003. int num_nested = obj->_itype.number_of_nested_types();
  2004. for (int ni = 0; ni < num_nested; ni++) {
  2005. TypeIndex nested_index = obj->_itype.get_nested_type(ni);
  2006. Object * nested_obj = _objects[nested_index];
  2007. if (nested_obj->_itype.is_class() || nested_obj->_itype.is_struct()) {
  2008. std::string ClassName1 = make_safe_name(nested_obj->_itype.get_scoped_name());
  2009. std::string ClassName2 = make_safe_name(nested_obj->_itype.get_name());
  2010. out << " // Nested Object " << ClassName1 << ";\n";
  2011. out << " Dtool_" << ClassName1 << "._Dtool_ClassInit(NULL);\n";
  2012. string name1 = classNameFromCppName(ClassName2, false);
  2013. string name2 = classNameFromCppName(ClassName2, true);
  2014. out << " PyDict_SetItemString(Dtool_" << ClassName << ".As_PyTypeObject().tp_dict, \"" << name1 << "\", (PyObject *)&Dtool_" << ClassName1 << ".As_PyTypeObject());\n";
  2015. if (name1 != name2) {
  2016. out << " PyDict_SetItemString(Dtool_" << ClassName << ".As_PyTypeObject().tp_dict, \"" << name2 << "\", (PyObject *)&Dtool_" << ClassName1 << ".As_PyTypeObject());\n";
  2017. }
  2018. } else {
  2019. if (nested_obj->_itype.is_enum()) {
  2020. out << " // Enum " << nested_obj->_itype.get_scoped_name() << ";\n";
  2021. int enum_count = nested_obj->_itype.number_of_enum_values();
  2022. for (int xx = 0; xx < enum_count; xx++) {
  2023. string name1 = classNameFromCppName(nested_obj->_itype.get_enum_value_name(xx), false);
  2024. string name2;
  2025. if (nested_obj->_itype.has_true_name()) {
  2026. name2 = classNameFromCppName(nested_obj->_itype.get_enum_value_name(xx), true);
  2027. } else {
  2028. // Don't generate the alternative syntax for anonymous enums, since we added support
  2029. // for those after we started deprecating the alternative syntax.
  2030. name2 = name1;
  2031. }
  2032. int enum_value = nested_obj->_itype.get_enum_value(xx);
  2033. out << "#if PY_MAJOR_VERSION >= 3\n";
  2034. out << " PyDict_SetItemString(Dtool_" << ClassName << ".As_PyTypeObject().tp_dict, \"" << name1 << "\", PyLong_FromLong(" << enum_value << "));\n";
  2035. if (name1 != name2) {
  2036. out << " PyDict_SetItemString(Dtool_" << ClassName << ".As_PyTypeObject().tp_dict, \"" << name2 << "\", PyLong_FromLong(" << enum_value << "));\n";
  2037. }
  2038. out << "#else\n";
  2039. out << " PyDict_SetItemString(Dtool_" << ClassName << ".As_PyTypeObject().tp_dict, \"" << name1 << "\", PyInt_FromLong(" << enum_value << "));\n";
  2040. if (name1 != name2) {
  2041. out << " PyDict_SetItemString(Dtool_" << ClassName << ".As_PyTypeObject().tp_dict, \"" << name2 << "\", PyInt_FromLong(" << enum_value << "));\n";
  2042. }
  2043. out << "#endif\n";
  2044. }
  2045. }
  2046. }
  2047. }
  2048. out << " if (PyType_Ready(&Dtool_" << ClassName << ".As_PyTypeObject()) < 0) {\n";
  2049. out << " PyErr_SetString(PyExc_TypeError, \"PyType_Ready(" << ClassName << ")\");\n";
  2050. out << " printf(\"Error in PyType_Ready(" << ClassName << ")\");\n";
  2051. out << " return;\n";
  2052. out << " }\n";
  2053. out << " Py_INCREF(&Dtool_" << ClassName << ".As_PyTypeObject());\n";
  2054. // Why make the class a member of itself?
  2055. //out << " PyDict_SetItemString(Dtool_" <<ClassName << ".As_PyTypeObject().tp_dict,\"" <<export_class_name<< "\",&Dtool_" <<ClassName << ".As_PyObject());\n";
  2056. bool is_runtime_typed = IsPandaTypedObject(obj->_itype._cpptype->as_struct_type());
  2057. if (HasAGetClassTypeFunction(obj->_itype)) {
  2058. is_runtime_typed = true;
  2059. }
  2060. if (is_runtime_typed) {
  2061. out << " RegisterRuntimeClass(&Dtool_" << ClassName << ", " << cClassName << "::get_class_type().get_index());\n";
  2062. } else {
  2063. out << " RegisterRuntimeClass(&Dtool_" << ClassName << ", -1);\n";
  2064. }
  2065. out << " }\n";
  2066. out << " if (module != NULL) {\n";
  2067. out << " Py_INCREF(&Dtool_" << ClassName << ".As_PyTypeObject());\n";
  2068. out << " PyModule_AddObject(module, \"" << export_class_name << "\", (PyObject *)&Dtool_" << ClassName << ".As_PyTypeObject());\n";
  2069. if (export_class_name != export_class_name2) {
  2070. out << " PyModule_AddObject(module, \"" << export_class_name2 << "\", (PyObject *)&Dtool_" << ClassName << ".As_PyTypeObject());\n";
  2071. }
  2072. // Also write out the explicit alternate names.
  2073. int num_alt_names = obj->_itype.get_num_alt_names();
  2074. for (int i = 0; i < num_alt_names; ++i) {
  2075. string alt_name = make_safe_name(obj->_itype.get_alt_name(i));
  2076. if (export_class_name != alt_name) {
  2077. out << " PyModule_AddObject(module, \"" << alt_name << "\", (PyObject *)&Dtool_" << ClassName << ".As_PyTypeObject());\n";
  2078. }
  2079. }
  2080. out << " }\n";
  2081. out << "}\n\n";
  2082. }
  2083. ////////////////////////////////////////////////////////////////////
  2084. // Function: InterfaceMakerPythonNative::synthesize_this_parameter
  2085. // Access: Public, Virtual
  2086. // Description: This method should be overridden and redefined to
  2087. // return true for interfaces that require the implicit
  2088. // "this" parameter, if present, to be passed as the
  2089. // first parameter to any wrapper functions.
  2090. ////////////////////////////////////////////////////////////////////
  2091. bool InterfaceMakerPythonNative::
  2092. synthesize_this_parameter() {
  2093. return true;
  2094. }
  2095. ////////////////////////////////////////////////////////////////////
  2096. // Function: InterfaceMakerPythonNative::get_wrapper_prefix
  2097. // Access: Protected, Virtual
  2098. // Description: Returns the prefix string used to generate wrapper
  2099. // function names.
  2100. ////////////////////////////////////////////////////////////////////
  2101. string InterfaceMakerPythonNative::
  2102. get_wrapper_prefix() {
  2103. return "Dtool_";
  2104. }
  2105. ////////////////////////////////////////////////////////////////////
  2106. // Function: InterfaceMakerPythonNative::get_unique_prefix
  2107. // Access: Protected, Virtual
  2108. // Description: Returns the prefix string used to generate unique
  2109. // symbolic names, which are not necessarily C-callable
  2110. // function names.
  2111. ////////////////////////////////////////////////////////////////////
  2112. string InterfaceMakerPythonNative::
  2113. get_unique_prefix() {
  2114. return "Dtool_";
  2115. }
  2116. ////////////////////////////////////////////////////////////////////
  2117. // Function: InterfaceMakerPythonNative::record_function_wrapper
  2118. // Access: Protected, Virtual
  2119. // Description: Associates the function wrapper with its function in
  2120. // the appropriate structures in the database.
  2121. ////////////////////////////////////////////////////////////////////
  2122. void InterfaceMakerPythonNative::
  2123. record_function_wrapper(InterrogateFunction &ifunc, FunctionWrapperIndex wrapper_index) {
  2124. ifunc._python_wrappers.push_back(wrapper_index);
  2125. }
  2126. ////////////////////////////////////////////////////////////////////
  2127. // Function: InterfaceMakerPythonNative::write_prototype_for
  2128. // Access: Private
  2129. // Description: Writes the prototype for the indicated function.
  2130. ////////////////////////////////////////////////////////////////////
  2131. void InterfaceMakerPythonNative::
  2132. write_prototype_for(ostream &out, InterfaceMaker::Function *func) {
  2133. std::string fname = "PyObject *" + func->_name + "(PyObject *self, PyObject *args)";
  2134. write_prototype_for_name(out, func, fname);
  2135. }
  2136. ////////////////////////////////////////////////////////////////////
  2137. ////////////////////////////////////////////////////////////////////
  2138. ////////////////////////////////////////////////////////////////////
  2139. void InterfaceMakerPythonNative::
  2140. write_prototype_for_name(ostream &out, InterfaceMaker::Function *func, const std::string &function_namename) {
  2141. Function::Remaps::const_iterator ri;
  2142. // for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
  2143. // FunctionRemap *remap = (*ri);
  2144. if (!output_function_names) {
  2145. // If we're not saving the function names, don't export it from
  2146. // the library.
  2147. out << "static ";
  2148. } else {
  2149. out << "extern \"C\" ";
  2150. }
  2151. out << function_namename << ";\n";
  2152. // }
  2153. }
  2154. ////////////////////////////////////////////////////////////////////
  2155. // Function: InterfaceMakerPythonNative::write_function_for
  2156. // Access: Private
  2157. // Description: Writes the definition for a function that will call
  2158. // the indicated C++ function or method.
  2159. ////////////////////////////////////////////////////////////////////
  2160. void InterfaceMakerPythonNative::
  2161. write_function_for_top(ostream &out, InterfaceMaker::Object *obj, InterfaceMaker::Function *func) {
  2162. std::string fname;
  2163. if (func->_ifunc.is_unary_op()) {
  2164. assert(func->_args_type == AT_no_args);
  2165. }
  2166. fname = "static PyObject *" + func->_name + "(PyObject *";
  2167. // This will be NULL for static funcs, so prevent code from using it.
  2168. if (func->_has_this) {
  2169. fname += "self";
  2170. }
  2171. switch (func->_args_type) {
  2172. case AT_keyword_args:
  2173. fname += ", PyObject *args, PyObject *kwds";
  2174. break;
  2175. case AT_varargs:
  2176. fname += ", PyObject *args";
  2177. break;
  2178. case AT_single_arg:
  2179. fname += ", PyObject *arg";
  2180. break;
  2181. default:
  2182. break;
  2183. }
  2184. fname += ")";
  2185. bool coercion_attempted = false;
  2186. write_function_for_name(out, obj, func, fname, true, coercion_attempted, func->_args_type, false, true);
  2187. }
  2188. ////////////////////////////////////////////////////////////////////
  2189. /// Function : write_function_for_name
  2190. //
  2191. // Wrap a complete name override function for Py.....
  2192. ////////////////////////////////////////////////////////////////////
  2193. void InterfaceMakerPythonNative::
  2194. write_function_for_name(ostream &out1, InterfaceMaker::Object *obj, InterfaceMaker::Function *func,
  2195. const std::string &function_name,
  2196. bool coercion_allowed, bool &coercion_attempted,
  2197. ArgsType args_type, bool return_int, bool write_comment) {
  2198. ostringstream out;
  2199. std::map<int, std::set<FunctionRemap *> > MapSets;
  2200. std::map<int, std::set<FunctionRemap *> >::iterator mii;
  2201. std::set<FunctionRemap *>::iterator sii;
  2202. Function::Remaps::const_iterator ri;
  2203. out1 << "/******************************************************************\n" << " * Python type method wrapper for\n";
  2204. for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
  2205. FunctionRemap *remap = (*ri);
  2206. if (is_remap_legal(remap)) {
  2207. int parameter_size = remap->_parameters.size();
  2208. if (remap->_has_this && remap->_type != FunctionRemap::T_constructor) {
  2209. parameter_size --;
  2210. }
  2211. MapSets[parameter_size].insert(remap);
  2212. out1 << " * ";
  2213. remap->write_orig_prototype(out1, 0);
  2214. out1 << "\n";
  2215. } else {
  2216. out1 << " * Rejected Remap [";
  2217. remap->write_orig_prototype(out1, 0);
  2218. out1 << "]\n";
  2219. }
  2220. }
  2221. out1 << " *******************************************************************/\n";
  2222. out << function_name << " {\n";
  2223. if (func->_has_this) {
  2224. // Extract pointer from 'self' parameter.
  2225. std::string ClassName = make_safe_name(obj->_itype.get_scoped_name());
  2226. std::string cClassName = obj->_itype.get_true_name();
  2227. SlottedFunctionDef def;
  2228. get_slotted_function_def(obj, func, def);
  2229. out << " " << cClassName << " *local_this = NULL;\n";
  2230. out << " DTOOL_Call_ExtractThisPointerForType(self, &Dtool_" << ClassName << ", (void **)&local_this);\n";
  2231. out << " if (local_this == NULL) {\n";
  2232. if (def._wrapper_type == WT_numeric_operator || def._wrapper_type == WT_ternary_operator) {
  2233. // WT_numeric_operator means we must return NotImplemented, instead
  2234. // of raising an exception, if the this pointer doesn't
  2235. // match. This is for things like __sub__, which Python
  2236. // likes to call on the wrong-type objects.
  2237. out << " Py_INCREF(Py_NotImplemented);\n";
  2238. out << " return Py_NotImplemented;\n";
  2239. } else {
  2240. // Other functions should raise an exception if the this
  2241. // pointer isn't set or is the wrong type.
  2242. out << " PyErr_SetString(PyExc_AttributeError, \"C++ object is not yet constructed, or already destructed.\");\n";
  2243. if (return_int) {
  2244. out << " return -1;\n";
  2245. } else {
  2246. out << " return NULL;\n";
  2247. }
  2248. }
  2249. out << " }\n";
  2250. }
  2251. bool is_inplace = isInplaceFunction(func);
  2252. if (MapSets.empty()) {
  2253. return;
  2254. }
  2255. std::string FunctionComment = func->_ifunc._comment;
  2256. std::string FunctionComment1;
  2257. if (FunctionComment.size() > 2) {
  2258. FunctionComment += "\n";
  2259. }
  2260. if (MapSets.size() > 1) {
  2261. string expected_params;
  2262. switch (args_type) {
  2263. case AT_keyword_args:
  2264. indent(out, 2) << "int parameter_count = PyTuple_Size(args);\n";
  2265. indent(out, 2) << "if (kwds != NULL) {\n";
  2266. indent(out, 2) << " parameter_count += PyDict_Size(kwds);\n";
  2267. indent(out, 2) << "}\n";
  2268. break;
  2269. case AT_varargs:
  2270. indent(out, 2) << "int parameter_count = PyTuple_Size(args);\n";
  2271. break;
  2272. case AT_single_arg:
  2273. // It shouldn't get here, but we'll handle these cases nonetheless.
  2274. indent(out, 2) << "const int parameter_count = 1;\n";
  2275. break;
  2276. default:
  2277. indent(out, 2) << "const int parameter_count = 0;\n";
  2278. break;
  2279. }
  2280. indent(out, 2) << "switch (parameter_count) {\n";
  2281. for (mii = MapSets.begin(); mii != MapSets.end(); mii ++) {
  2282. indent(out, 2) << "case " << mii->first << ": {\n";
  2283. write_function_forset(out, obj, func, mii->second, expected_params, 4, is_inplace,
  2284. coercion_allowed, coercion_attempted, args_type, return_int);
  2285. indent(out, 4) << "break;\n";
  2286. indent(out, 2) << "}\n";
  2287. }
  2288. indent(out, 2) << "default:\n";
  2289. indent(out, 4)
  2290. << "PyErr_Format(PyExc_TypeError, \""
  2291. << methodNameFromCppName(func, "", false)
  2292. << "() takes ";
  2293. // We add one to the parameter count for "self", following the
  2294. // Python convention.
  2295. int add_self = func->_has_this ? 1 : 0;
  2296. size_t mic;
  2297. for (mic = 0, mii = MapSets.begin();
  2298. mii != MapSets.end();
  2299. ++mii, ++mic) {
  2300. if (mic == MapSets.size() - 1) {
  2301. if (mic == 1) {
  2302. out << " or ";
  2303. } else {
  2304. out << ", or ";
  2305. }
  2306. } else if (mic != 0) {
  2307. out << ", ";
  2308. }
  2309. out << mii->first + add_self;
  2310. }
  2311. out << " arguments (%d given)\", parameter_count + " << add_self << ");\n";
  2312. if (return_int) {
  2313. indent(out, 4) << "return -1;\n";
  2314. } else {
  2315. indent(out, 4) << "return (PyObject *) NULL;\n";
  2316. }
  2317. indent(out, 2) << "}\n";
  2318. out << " if (!PyErr_Occurred()) { // Let error pass on\n";
  2319. out << " PyErr_SetString(PyExc_TypeError,\n";
  2320. out << " \"Arguments must match one of:\\n\"\n";
  2321. output_quoted(out, 6, expected_params);
  2322. out << ");\n";
  2323. out << " }\n";
  2324. if (return_int) {
  2325. indent(out, 2) << "return -1;\n";
  2326. } else {
  2327. indent(out, 2) << "return (PyObject *) NULL;\n";
  2328. }
  2329. if (!expected_params.empty() && FunctionComment1.empty()) {
  2330. FunctionComment1 += "C++ Interface:\n";
  2331. }
  2332. FunctionComment1 += expected_params;
  2333. } else {
  2334. string expected_params = "";
  2335. mii = MapSets.begin();
  2336. // If no parameters are accepted, we do need to check that the argument
  2337. // count is indeed 0, since we won't check that in write_function_instance.
  2338. if (mii->first == 0 && args_type != AT_no_args) {
  2339. switch (args_type) {
  2340. case AT_keyword_args:
  2341. out << " if (PyTuple_Size(args) > 0 || (kwds != NULL && PyDict_Size(kwds) > 0)) {\n";
  2342. out << " int parameter_count = PyTuple_Size(args);\n";
  2343. out << " if (kwds != NULL) {\n";
  2344. out << " parameter_count += PyDict_Size(kwds);\n";
  2345. out << " }\n";
  2346. break;
  2347. case AT_varargs:
  2348. out << " if (PyTuple_Size(args) > 0) {\n";
  2349. out << " const int parameter_count = PyTuple_GET_SIZE(args);\n";
  2350. break;
  2351. case AT_single_arg:
  2352. default:
  2353. // Shouldn't happen, but let's handle this case nonetheless.
  2354. out << " {\n";
  2355. out << " const int parameter_count = 1;\n";
  2356. break;
  2357. }
  2358. out << " PyErr_Format(PyExc_TypeError,\n"
  2359. << " \"" << methodNameFromCppName(func, "", false)
  2360. << "() takes no arguments (%d given)\",\n"
  2361. << " parameter_count);\n";
  2362. if (return_int) {
  2363. out << " return -1;\n";
  2364. } else {
  2365. out << " return (PyObject *) NULL;\n";
  2366. }
  2367. out << " }\n";
  2368. }
  2369. write_function_forset(out, obj, func, mii->second, expected_params, 2, is_inplace,
  2370. coercion_allowed, coercion_attempted, args_type, return_int);
  2371. out << " if (!PyErr_Occurred()) {\n";
  2372. out << " PyErr_SetString(PyExc_TypeError,\n";
  2373. out << " \"Arguments must match:\\n\"\n";
  2374. output_quoted(out, 6, expected_params);
  2375. out << ");\n";
  2376. out << " }\n";
  2377. if (return_int) {
  2378. indent(out, 2) << "return -1;\n";
  2379. } else {
  2380. indent(out, 2) << "return (PyObject *) NULL;\n";
  2381. }
  2382. if (!expected_params.empty() && FunctionComment1.empty()) {
  2383. FunctionComment1 += "C++ Interface:\n";
  2384. }
  2385. FunctionComment1 += expected_params;
  2386. }
  2387. out << "}\n\n";
  2388. if (!FunctionComment1.empty()) {
  2389. FunctionComment = FunctionComment1 + "\n" + FunctionComment;
  2390. }
  2391. if (write_comment) {
  2392. // Write out the function doc string. We only do this if it is
  2393. // not a constructor, since we don't have a place to put the
  2394. // constructor doc string.
  2395. out << "#ifndef NDEBUG\n";
  2396. out << "static const char *" << func->_name << "_comment =\n";
  2397. output_quoted(out, 2, FunctionComment);
  2398. out << ";\n";
  2399. out << "#else\n";
  2400. out << "static const char *" << func->_name << "_comment = NULL;\n";
  2401. out << "#endif\n";
  2402. }
  2403. out << "\n";
  2404. out1 << out.str();
  2405. }
  2406. ////////////////////////////////////////////////////////
  2407. // Function : GetParnetDepth
  2408. //
  2409. // Support Function used to Sort the name based overrides.. For know must be complex to simple
  2410. ////////////////////////////////////////////////////////
  2411. int GetParnetDepth(CPPType *type) {
  2412. int answer = 0;
  2413. // printf(" %s\n",type->get_local_name().c_str());
  2414. if (TypeManager::is_basic_string_char(type)) {
  2415. } else if (TypeManager::is_basic_string_wchar(type)) {
  2416. } else if (TypeManager::is_bool(type)) {
  2417. } else if (TypeManager::is_unsigned_longlong(type)) {
  2418. } else if (TypeManager::is_longlong(type)) {
  2419. } else if (TypeManager::is_integer(type)) {
  2420. } else if (TypeManager::is_float(type)) {
  2421. } else if (TypeManager::is_char_pointer(type)) {
  2422. } else if (TypeManager::is_wchar_pointer(type)) {
  2423. } else if (TypeManager::is_pointer_to_PyObject(type)) {
  2424. } else if (TypeManager::is_pointer_to_Py_buffer(type)) {
  2425. } else if (TypeManager::is_pointer(type) ||
  2426. TypeManager::is_reference(type) ||
  2427. TypeManager::is_struct(type)) {
  2428. ++answer;
  2429. int deepest = 0;
  2430. TypeIndex type_index = builder.get_type(TypeManager::unwrap(TypeManager::resolve_type(type)), false);
  2431. InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
  2432. const InterrogateType &itype = idb->get_type(type_index);
  2433. if (itype.is_class() || itype.is_struct()) {
  2434. int num_derivations = itype.number_of_derivations();
  2435. for (int di = 0; di < num_derivations; di++) {
  2436. TypeIndex d_type_Index = itype.get_derivation(di);
  2437. const InterrogateType &d_itype = idb->get_type(d_type_Index);
  2438. int this_one = GetParnetDepth(d_itype._cpptype);
  2439. if (this_one > deepest) {
  2440. deepest = this_one;
  2441. }
  2442. }
  2443. }
  2444. answer += deepest;
  2445. // printf(" Class Name %s %d\n",itype.get_name().c_str(),answer);
  2446. }
  2447. // printf(" Class Name %s %d\n",itype.get_name().c_str(),answer);
  2448. return answer;
  2449. }
  2450. ////////////////////////////////////////////////////////
  2451. // The Core sort function for remap calling orders..
  2452. //////////////////////////////////////////////////////////
  2453. bool RemapCompareLess(FunctionRemap *in1, FunctionRemap *in2) {
  2454. assert(in1 != NULL);
  2455. assert(in2 != NULL);
  2456. if (in1->_parameters.size() != in2->_parameters.size()) {
  2457. return (in1->_parameters.size() > in2->_parameters.size());
  2458. }
  2459. int pcount = in1->_parameters.size();
  2460. for (int x = 0; x < pcount; x++) {
  2461. CPPType *orig_type1 = in1->_parameters[x]._remap->get_orig_type();
  2462. CPPType *orig_type2 = in2->_parameters[x]._remap->get_orig_type();
  2463. // Hack to make int sort before float and double. We do
  2464. // this by letting everything compare less than float types.
  2465. // But if there's a double variant, prefer it over the float variant.
  2466. if (TypeManager::is_float(orig_type1) &&
  2467. !TypeManager::is_double(orig_type1)) {
  2468. return false;
  2469. }
  2470. if (TypeManager::is_float(orig_type2) &&
  2471. !TypeManager::is_double(orig_type2)) {
  2472. return true;
  2473. }
  2474. if (TypeManager::is_float(orig_type1)) {
  2475. return false;
  2476. }
  2477. if (TypeManager::is_float(orig_type2)) {
  2478. return true;
  2479. }
  2480. int pd1 = GetParnetDepth(orig_type1);
  2481. int pd2 = GetParnetDepth(orig_type2);
  2482. if (pd1 != pd2) {
  2483. return (pd1 > pd2);
  2484. }
  2485. }
  2486. // ok maybe something to do with return strength..
  2487. return false;
  2488. }
  2489. ///////////////////////////////////////////////////////////
  2490. // Function : write_function_forset
  2491. //
  2492. // A set is defined as all remaps that have the same number of paramaters..
  2493. ///////////////////////////////////////////////////////////
  2494. void InterfaceMakerPythonNative::
  2495. write_function_forset(ostream &out, InterfaceMaker::Object *obj,
  2496. InterfaceMaker::Function *func,
  2497. std::set<FunctionRemap *> &remapsin,
  2498. string &expected_params, int indent_level,
  2499. bool is_inplace, bool coercion_allowed,
  2500. bool &coercion_attempted,
  2501. ArgsType args_type,
  2502. bool return_int, const string &first_pexpr) {
  2503. // Do we accept any parameters that are class objects? If so, we
  2504. // might need to check for parameter coercion.
  2505. bool coercion_possible = false;
  2506. if (coercion_allowed) {
  2507. std::set<FunctionRemap *>::const_iterator sii;
  2508. for (sii = remapsin.begin(); sii != remapsin.end() && !coercion_possible; ++sii) {
  2509. FunctionRemap *remap = (*sii);
  2510. int pn = 0;
  2511. if (remap->_has_this) {
  2512. // Skip the "this" parameter. It's never coercible.
  2513. ++pn;
  2514. }
  2515. while (pn < (int)remap->_parameters.size()) {
  2516. CPPType *type = remap->_parameters[pn]._remap->get_new_type();
  2517. if (TypeManager::is_char_pointer(type)) {
  2518. } else if (TypeManager::is_wchar_pointer(type)) {
  2519. } else if (TypeManager::is_pointer_to_PyObject(type)) {
  2520. } else if (TypeManager::is_pointer_to_Py_buffer(type)) {
  2521. } else if (TypeManager::is_pointer(type)) {
  2522. // This is a pointer to an object, so we
  2523. // might be able to coerce a parameter to it.
  2524. coercion_possible = true;
  2525. break;
  2526. }
  2527. ++pn;
  2528. }
  2529. }
  2530. }
  2531. if (coercion_possible) {
  2532. // These objects keep track of whether we have attempted automatic
  2533. // parameter coercion.
  2534. indent(out, indent_level)
  2535. << "{\n";
  2536. indent_level += 2;
  2537. indent(out, indent_level)
  2538. << "PyObject *coerced = NULL;\n";
  2539. indent(out, indent_level)
  2540. << "PyObject **coerced_ptr = NULL;\n";
  2541. indent(out, indent_level)
  2542. << "bool report_errors = false;\n";
  2543. indent(out, indent_level)
  2544. << "while (true) {\n";
  2545. indent_level += 2;
  2546. } else {
  2547. out << "\n";
  2548. }
  2549. if (remapsin.size() > 1) {
  2550. // There are multiple different overloads for this number of
  2551. // parameters. Sort them all into order from most-specific to
  2552. // least-specific, then try them one at a time.
  2553. std::vector<FunctionRemap *> remaps (remapsin.begin(), remapsin.end());
  2554. std::sort(remaps.begin(), remaps.end(), RemapCompareLess);
  2555. std::vector<FunctionRemap *>::iterator sii;
  2556. for (sii = remaps.begin(); sii != remaps.end(); sii ++) {
  2557. FunctionRemap *remap = (*sii);
  2558. if (remap->_has_this && !remap->_const_method) {
  2559. // If it's a non-const method, we only allow a
  2560. // non-const this.
  2561. indent(out, indent_level)
  2562. << "if (!((Dtool_PyInstDef *)self)->_is_const) {\n";
  2563. } else {
  2564. indent(out, indent_level)
  2565. << "{\n";
  2566. }
  2567. indent(out, indent_level) << "// -2 ";
  2568. remap->write_orig_prototype(out, 0); out << "\n";
  2569. write_function_instance(out, obj, func, remap, expected_params, indent_level + 2, is_inplace,
  2570. coercion_possible, coercion_attempted, args_type, return_int, first_pexpr);
  2571. indent(out, indent_level + 2) << "PyErr_Clear();\n";
  2572. indent(out, indent_level) << "}\n\n";
  2573. }
  2574. } else {
  2575. // There is only one possible overload with this number of
  2576. // parameters. Just call it.
  2577. std::set<FunctionRemap *>::iterator sii;
  2578. for (sii = remapsin.begin(); sii != remapsin.end(); sii ++) {
  2579. FunctionRemap *remap = (*sii);
  2580. if (remap->_has_this && !remap->_const_method) {
  2581. // If it's a non-const method, we only allow a
  2582. // non-const this.
  2583. indent(out, indent_level)
  2584. << "if (!((Dtool_PyInstDef *)self)->_is_const) {\n";
  2585. indent_level += 2;
  2586. }
  2587. indent(out, indent_level)
  2588. << "// 1-" ;
  2589. remap->write_orig_prototype(out, 0);
  2590. out << "\n" ;
  2591. write_function_instance(out, obj, func, remap, expected_params, indent_level, is_inplace,
  2592. coercion_possible, coercion_attempted, args_type, return_int, first_pexpr);
  2593. if (remap->_has_this && !remap->_const_method) {
  2594. indent(out, indent_level - 2)
  2595. << "} else {\n";
  2596. indent(out, indent_level)
  2597. << "PyErr_SetString(PyExc_TypeError,\n";
  2598. string class_name = remap->_cpptype->get_simple_name();
  2599. indent(out, indent_level)
  2600. << " \"Cannot call "
  2601. << classNameFromCppName(class_name, false)
  2602. << "." << methodNameFromCppName(func, class_name, false)
  2603. << "() on a const object.\");\n";
  2604. if (return_int) {
  2605. indent(out, indent_level)
  2606. << "return -1;\n";
  2607. } else {
  2608. indent(out, indent_level)
  2609. << "return (PyObject *) NULL;\n";
  2610. }
  2611. indent_level -= 2;
  2612. indent(out, indent_level)
  2613. << "}\n\n";
  2614. } else {
  2615. out << "\n";
  2616. }
  2617. }
  2618. }
  2619. // Now we've tried all of the possible overloads, and had no luck.
  2620. if (coercion_possible) {
  2621. // Try again, this time with coercion enabled.
  2622. indent(out, indent_level)
  2623. << "if (coerced_ptr == NULL && !report_errors) {\n";
  2624. indent(out, indent_level + 2)
  2625. << "coerced_ptr = &coerced;\n";
  2626. indent(out, indent_level + 2)
  2627. << "continue;\n";
  2628. indent(out, indent_level)
  2629. << "}\n";
  2630. // No dice. Go back one more time, and this time get the error
  2631. // message.
  2632. indent(out, indent_level)
  2633. << "if (!report_errors) {\n";
  2634. indent(out, indent_level + 2)
  2635. << "report_errors = true;\n";
  2636. indent(out, indent_level + 2)
  2637. << "continue;\n";
  2638. indent(out, indent_level)
  2639. << "}\n";
  2640. // We've been through three times. We're done.
  2641. indent(out, indent_level)
  2642. << "break;\n";
  2643. indent_level -= 2;
  2644. indent(out, indent_level)
  2645. << "}\n";
  2646. indent(out, indent_level)
  2647. << "Py_XDECREF(coerced);\n";
  2648. indent_level -= 2;
  2649. indent(out, indent_level)
  2650. << "}\n";
  2651. }
  2652. }
  2653. ////////////////////////////////////////////////////////////////////
  2654. // Function: InterfaceMakerPythonNative::write_function_instance
  2655. // Access: Private
  2656. // Description: Writes out the particular function that handles a
  2657. // single instance of an overloaded function.
  2658. ////////////////////////////////////////////////////////////////////
  2659. void InterfaceMakerPythonNative::
  2660. write_function_instance(ostream &out, InterfaceMaker::Object *obj,
  2661. InterfaceMaker::Function *func,
  2662. FunctionRemap *remap, string &expected_params,
  2663. int indent_level, bool is_inplace,
  2664. bool coercion_possible, bool &coercion_attempted,
  2665. ArgsType args_type, bool return_int,
  2666. const string &first_pexpr) {
  2667. string format_specifiers;
  2668. std::string keyword_list;
  2669. string parameter_list;
  2670. string container;
  2671. vector_string pexprs;
  2672. string extra_convert;
  2673. string extra_param_check;
  2674. string extra_cleanup;
  2675. bool is_constructor = (remap->_type == FunctionRemap::T_constructor);
  2676. if (is_constructor && (remap->_flags & FunctionRemap::F_explicit_self) != 0) {
  2677. // If we'll be passing "self" to the constructor, we need to
  2678. // pre-initialize it here. Unfortunately, we can't pre-load the
  2679. // "this" pointer, but the constructor itself can do this.
  2680. indent(out, indent_level)
  2681. << "// Pre-initialize self for the constructor\n";
  2682. CPPType *orig_type = remap->_return_type->get_orig_type();
  2683. TypeIndex type_index = builder.get_type(TypeManager::unwrap(TypeManager::resolve_type(orig_type)), false);
  2684. InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
  2685. const InterrogateType &itype = idb->get_type(type_index);
  2686. indent(out, indent_level)
  2687. << "DTool_PyInit_Finalize(self, NULL, &"
  2688. << CLASS_PREFIX << make_safe_name(itype.get_scoped_name())
  2689. << ", false, false);\n";
  2690. }
  2691. // Make one pass through the parameter list. We will output a
  2692. // one-line temporary variable definition for each parameter, while
  2693. // simultaneously building the ParseTuple() function call and also
  2694. // the parameter expression list for call_function().
  2695. expected_params += methodNameFromCppName(func, "", false);
  2696. expected_params += "(";
  2697. int num_params = 0;
  2698. bool only_pyobjects = true;
  2699. //bool check_exceptions = false;
  2700. int pn;
  2701. for (pn = 0; pn < (int)remap->_parameters.size(); ++pn) {
  2702. if (pn > 0) {
  2703. expected_params += ", ";
  2704. }
  2705. if (((remap->_has_this && pn == 1) ||
  2706. (!remap->_has_this && pn == 0)) && !first_pexpr.empty()) {
  2707. // The first param was already converted.
  2708. pexprs.push_back(first_pexpr);
  2709. continue;
  2710. }
  2711. CPPType *orig_type = remap->_parameters[pn]._remap->get_orig_type();
  2712. CPPType *type = remap->_parameters[pn]._remap->get_new_type();
  2713. string param_name = remap->get_parameter_name(pn);
  2714. // This is the string to convert our local variable to the
  2715. // appropriate C++ type. Normally this is just a cast.
  2716. string pexpr_string =
  2717. "(" + type->get_local_name(&parser) + ")" + param_name;
  2718. if (!remap->_has_this || pn != 0) {
  2719. keyword_list += "(char *)\"" + remap->_parameters[pn]._name + "\", ";
  2720. }
  2721. if (remap->_parameters[pn]._remap->new_type_is_atomic_string()) {
  2722. if (TypeManager::is_char_pointer(orig_type)) {
  2723. indent(out, indent_level) << "char *" << param_name << ";\n";
  2724. format_specifiers += "s";
  2725. parameter_list += ", &" + param_name;
  2726. expected_params += "str";
  2727. } else if (TypeManager::is_wchar_pointer(orig_type)) {
  2728. out << "#if PY_MAJOR_VERSION >= 3\n";
  2729. indent(out, indent_level) << "PyObject *" << param_name << ";\n";
  2730. out << "#else\n";
  2731. indent(out, indent_level) << "PyUnicodeObject *" << param_name << ";\n";
  2732. out << "#endif\n";
  2733. format_specifiers += "U";
  2734. parameter_list += ", &" + param_name;
  2735. extra_convert += " Py_ssize_t " + param_name + "_len = PyUnicode_GetSize((PyObject *)" + param_name + ");"
  2736. " wchar_t *" + param_name + "_str = (wchar_t *)alloca(sizeof(wchar_t) * (" + param_name + "_len + 1));"
  2737. " PyUnicode_AsWideChar(" + param_name + ", " + param_name + "_str, " + param_name + "_len);"
  2738. " " + param_name + "_str[" + param_name + "_len] = 0;";
  2739. pexpr_string = param_name + "_str";
  2740. expected_params += "unicode";
  2741. } else if (TypeManager::is_wstring(orig_type)) {
  2742. out << "#if PY_MAJOR_VERSION >= 3\n";
  2743. indent(out, indent_level) << "PyObject *" << param_name << ";\n";
  2744. out << "#else\n";
  2745. indent(out, indent_level) << "PyUnicodeObject *" << param_name << ";\n";
  2746. out << "#endif\n";
  2747. format_specifiers += "U";
  2748. parameter_list += ", &" + param_name;
  2749. extra_convert += " Py_ssize_t " + param_name + "_len = PyUnicode_GetSize((PyObject *)" + param_name + ");"
  2750. " wchar_t *" + param_name + "_str = (wchar_t *)alloca(sizeof(wchar_t) * " + param_name + "_len);"
  2751. " PyUnicode_AsWideChar(" + param_name + ", " + param_name + "_str, " + param_name + "_len);";
  2752. pexpr_string = "basic_string<wchar_t>(" +
  2753. param_name + "_str, " +
  2754. param_name + "_len)";
  2755. expected_params += "unicode";
  2756. } else if (TypeManager::is_const_ptr_to_basic_string_wchar(orig_type)) {
  2757. out << "#if PY_MAJOR_VERSION >= 3\n";
  2758. indent(out, indent_level) << "PyObject *" << param_name << ";\n";
  2759. out << "#else\n";
  2760. indent(out, indent_level) << "PyUnicodeObject *" << param_name << ";\n";
  2761. out << "#endif\n";
  2762. format_specifiers += "U";
  2763. parameter_list += ", &" + param_name;
  2764. extra_convert += " Py_ssize_t " + param_name + "_len = PyUnicode_GetSize((PyObject *)" + param_name + ");"
  2765. " wchar_t *" + param_name + "_str = (wchar_t *)alloca(sizeof(wchar_t) * " + param_name + "_len);"
  2766. " PyUnicode_AsWideChar(" + param_name + ", " + param_name + "_str, " + param_name + "_len);";
  2767. pexpr_string = "&basic_string<wchar_t>(" +
  2768. param_name + "_str, " +
  2769. param_name + "_len)";
  2770. expected_params += "unicode";
  2771. } else {
  2772. indent(out, indent_level) << "char *" << param_name << "_str;\n";
  2773. indent(out, indent_level) << "Py_ssize_t " << param_name << "_len;\n";
  2774. if (args_type == AT_single_arg) {
  2775. out << "#if PY_MAJOR_VERSION >= 3\n";
  2776. indent(out, indent_level)
  2777. << param_name << "_str = PyUnicode_AsUTF8AndSize(arg, &"
  2778. << param_name << "_len);\n";
  2779. out << "#else\n";
  2780. indent(out, indent_level) << "if (PyString_AsStringAndSize(arg, &"
  2781. << param_name << "_str, &" << param_name << "_len) == -1) {\n";
  2782. indent(out, indent_level + 2) << param_name << "_str = NULL;\n";
  2783. indent(out, indent_level) << "}\n";
  2784. out << "#endif\n";
  2785. extra_param_check = " && " + param_name + "_str != NULL";
  2786. } else {
  2787. format_specifiers += "s#";
  2788. parameter_list += ", &" + param_name
  2789. + "_str, &" + param_name + "_len";
  2790. }
  2791. if (TypeManager::is_const_ptr_to_basic_string_char(orig_type)) {
  2792. pexpr_string = "&basic_string<char>(" +
  2793. param_name + "_str, " +
  2794. param_name + "_len)";
  2795. } else {
  2796. pexpr_string = "basic_string<char>(" +
  2797. param_name + "_str, " +
  2798. param_name + "_len)";
  2799. }
  2800. expected_params += "str";
  2801. }
  2802. ++num_params;
  2803. only_pyobjects = false;
  2804. } else if (TypeManager::is_bool(type)) {
  2805. if (args_type == AT_single_arg) {
  2806. param_name = "arg";
  2807. } else {
  2808. indent(out, indent_level) << "PyObject *" << param_name << ";\n";
  2809. format_specifiers += "O";
  2810. parameter_list += ", &" + param_name;
  2811. }
  2812. pexpr_string = "(PyObject_IsTrue(" + param_name + ") != 0)";
  2813. expected_params += "bool";
  2814. ++num_params;
  2815. } else if (TypeManager::is_unsigned_longlong(type)) {
  2816. if (args_type == AT_single_arg) {
  2817. param_name = "arg";
  2818. } else {
  2819. indent(out, indent_level) << "PyObject *" << param_name << ";\n";
  2820. format_specifiers += "O";
  2821. parameter_list += ", &" + param_name;
  2822. }
  2823. extra_convert += "PyObject *" + param_name + "_long = PyNumber_Long(" + param_name + ");";
  2824. extra_param_check += " && " + param_name + "_long != NULL";
  2825. pexpr_string = "PyLong_AsUnsignedLongLong(" + param_name + "_long)";
  2826. extra_cleanup += "Py_XDECREF(" + param_name + "_long);";
  2827. expected_params += "unsigned long long";
  2828. ++num_params;
  2829. } else if (TypeManager::is_longlong(type)) {
  2830. if (args_type == AT_single_arg) {
  2831. param_name = "arg";
  2832. } else {
  2833. indent(out, indent_level) << "PyObject *" << param_name << ";\n";
  2834. format_specifiers += "O";
  2835. parameter_list += ", &" + param_name;
  2836. }
  2837. extra_convert += "PyObject *" + param_name + "_long = PyNumber_Long(" + param_name + ");";
  2838. extra_param_check += " && " + param_name + "_long != NULL";
  2839. pexpr_string = "PyLong_AsLongLong(" + param_name + "_long)";
  2840. extra_cleanup += "Py_XDECREF(" + param_name + "_long);";
  2841. expected_params += "long long";
  2842. ++num_params;
  2843. } else if (TypeManager::is_unsigned_integer(type)) {
  2844. if (args_type == AT_single_arg) {
  2845. param_name = "arg";
  2846. } else {
  2847. indent(out, indent_level) << "PyObject *" << param_name << ";\n";
  2848. format_specifiers += "O";
  2849. parameter_list += ", &" + param_name;
  2850. }
  2851. extra_convert += "PyObject *" + param_name + "_long = PyNumber_Long(" + param_name + ");";
  2852. extra_param_check += " && " + param_name + "_long != NULL";
  2853. pexpr_string = "PyLong_AsUnsignedLong(" + param_name + "_long)";
  2854. extra_cleanup += "Py_XDECREF(" + param_name + "_long);";
  2855. expected_params += "unsigned int";
  2856. ++num_params;
  2857. } else if (TypeManager::is_integer(type)) {
  2858. indent(out, indent_level) << "int " << param_name << ";\n";
  2859. format_specifiers += "i";
  2860. parameter_list += ", &" + param_name;
  2861. expected_params += "int";
  2862. only_pyobjects = false;
  2863. ++num_params;
  2864. } else if (TypeManager::is_double(type)) {
  2865. if (args_type == AT_single_arg) {
  2866. pexpr_string = "PyFloat_AsDouble(arg)";
  2867. extra_param_check += " && PyNumber_Check(arg)";
  2868. } else {
  2869. indent(out, indent_level) << "double " << param_name << ";\n";
  2870. format_specifiers += "d";
  2871. parameter_list += ", &" + param_name;
  2872. }
  2873. expected_params += "double";
  2874. only_pyobjects = false;
  2875. ++num_params;
  2876. } else if (TypeManager::is_float(type)) {
  2877. if (args_type == AT_single_arg) {
  2878. pexpr_string = "(float) PyFloat_AsDouble(arg)";
  2879. extra_param_check += " && PyNumber_Check(arg)";
  2880. } else {
  2881. indent(out, indent_level) << "float " << param_name << ";\n";
  2882. format_specifiers += "f";
  2883. parameter_list += ", &" + param_name;
  2884. }
  2885. expected_params += "float";
  2886. only_pyobjects = false;
  2887. ++num_params;
  2888. } else if (TypeManager::is_char_pointer(type)) {
  2889. indent(out, indent_level) << "char *" << param_name << ";\n";
  2890. format_specifiers += "s";
  2891. parameter_list += ", &" + param_name;
  2892. expected_params += "string";
  2893. only_pyobjects = false;
  2894. ++num_params;
  2895. } else if (TypeManager::is_pointer_to_PyStringObject(type)) {
  2896. if (args_type == AT_single_arg) {
  2897. // This is a single-arg function, so there's no need
  2898. // to convert anything.
  2899. param_name = "arg";
  2900. extra_param_check += " && PyString_Check(arg)";
  2901. } else {
  2902. indent(out, indent_level) << "PyStringObject *" << param_name << ";\n";
  2903. format_specifiers += "S";
  2904. parameter_list += ", &" + param_name;
  2905. }
  2906. pexpr_string = param_name;
  2907. expected_params += "string";
  2908. ++num_params;
  2909. } else if (TypeManager::is_pointer_to_PyUnicodeObject(type)) {
  2910. if (args_type == AT_single_arg) {
  2911. // This is a single-arg function, so there's no need
  2912. // to convert anything.
  2913. param_name = "arg";
  2914. extra_param_check += " && PyUnicode_Check(arg)";
  2915. } else {
  2916. indent(out, indent_level) << "PyUnicodeObject *" << param_name << ";\n";
  2917. format_specifiers += "U";
  2918. parameter_list += ", &" + param_name;
  2919. }
  2920. pexpr_string = param_name;
  2921. expected_params += "unicode";
  2922. ++num_params;
  2923. } else if (TypeManager::is_pointer_to_PyObject(type)) {
  2924. if (args_type == AT_single_arg) {
  2925. // This is a single-arg function, so there's no need
  2926. // to convert anything.
  2927. param_name = "arg";
  2928. } else {
  2929. indent(out, indent_level) << "PyObject *" << param_name << ";\n";
  2930. format_specifiers += "O";
  2931. parameter_list += ", &" + param_name;
  2932. }
  2933. pexpr_string = param_name;
  2934. expected_params += "any";
  2935. ++num_params;
  2936. // It's reasonable to assume that a function taking a PyObject
  2937. // might also throw a TypeError if the type is incorrect.
  2938. //check_exceptions = true;
  2939. } else if (TypeManager::is_pointer_to_Py_buffer(type)) {
  2940. if (args_type == AT_single_arg) {
  2941. param_name = "arg";
  2942. } else {
  2943. indent(out, indent_level) << "PyObject *" << param_name << ";\n";
  2944. format_specifiers += "O";
  2945. parameter_list += ", &" + param_name;
  2946. }
  2947. extra_convert += "PyObject *" + param_name + "_buffer = PyMemoryView_FromObject(" + param_name + ");";
  2948. extra_param_check += " && " + param_name + "_buffer != NULL";
  2949. pexpr_string = "PyMemoryView_GET_BUFFER(" + param_name + "_buffer)";
  2950. extra_cleanup += "Py_XDECREF(" + param_name + "_buffer);";
  2951. expected_params += "memoryview";
  2952. ++num_params;
  2953. //check_exceptions = true;
  2954. } else if (TypeManager::is_pointer(type)) {
  2955. CPPType *obj_type = TypeManager::unwrap(TypeManager::resolve_type(type));
  2956. bool const_ok = !TypeManager::is_non_const_pointer_or_ref(orig_type);
  2957. if (const_ok) {
  2958. expected_params += "const ";
  2959. //} else {
  2960. // expected_params += "non-const ";
  2961. }
  2962. expected_params += classNameFromCppName(obj_type->get_simple_name(), false);
  2963. if (!remap->_has_this || pn != 0) {
  2964. if (args_type == AT_single_arg) {
  2965. param_name = "arg";
  2966. } else {
  2967. indent(out, indent_level) << "PyObject *" << param_name << ";\n";
  2968. format_specifiers += "O";
  2969. parameter_list += ", &" + param_name;
  2970. }
  2971. ++num_params;
  2972. TypeIndex p_type_index = builder.get_type(obj_type, false);
  2973. InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
  2974. const InterrogateType &p_itype = idb->get_type(p_type_index);
  2975. bool is_copy_constructor = false;
  2976. if (is_constructor && remap->_parameters.size() == 1 && pn == 0) {
  2977. if (&p_itype == &obj->_itype) {
  2978. // If this is the only one parameter, and it's the same as
  2979. // the "this" type, this is a copy constructor.
  2980. is_copy_constructor = true;
  2981. }
  2982. }
  2983. //make_safe_name(itype.get_scoped_name())
  2984. extra_convert += p_itype.get_scoped_name() + " *" + param_name + "_this = (" + p_itype.get_scoped_name()+" *)";
  2985. // need to a forward scope for this class..
  2986. if (!isExportThisRun(p_itype._cpptype)) {
  2987. _external_imports.insert(make_safe_name(p_itype.get_scoped_name()));
  2988. }
  2989. string class_name;
  2990. string method_prefix;
  2991. if (remap->_cpptype) {
  2992. class_name = remap->_cpptype->get_simple_name();
  2993. method_prefix = classNameFromCppName(class_name, false) + string(".");
  2994. }
  2995. ostringstream str;
  2996. str << "DTOOL_Call_GetPointerThisClass(" << param_name
  2997. << ", &Dtool_" << make_safe_name(p_itype.get_scoped_name())
  2998. << ", " << pn << ", \""
  2999. << method_prefix << methodNameFromCppName(func, class_name, false)
  3000. << "\", " << const_ok;
  3001. if (coercion_possible && !is_copy_constructor) {
  3002. // We never attempt to coerce a copy constructor parameter.
  3003. // That would lead to infinite recursion.
  3004. str << ", coerced_ptr, report_errors";
  3005. coercion_attempted = true;
  3006. } else {
  3007. str << ", NULL, true";
  3008. }
  3009. str << ");\n";
  3010. extra_convert += str.str();
  3011. extra_param_check += " && " + param_name + "_this != NULL";
  3012. pexpr_string = param_name + "_this";
  3013. }
  3014. } else {
  3015. // Ignore a parameter.
  3016. if (args_type == AT_single_arg) {
  3017. param_name = "arg";
  3018. } else {
  3019. indent(out, indent_level) << "PyObject *" << param_name << ";\n";
  3020. format_specifiers += "O";
  3021. parameter_list += ", &" + param_name;
  3022. }
  3023. expected_params += "any";
  3024. ++num_params;
  3025. }
  3026. if (remap->_parameters[pn]._has_name) {
  3027. expected_params += " " + remap->_parameters[pn]._name;
  3028. }
  3029. if (remap->_has_this && pn == 0) {
  3030. container = "local_this";
  3031. if (remap->_const_method) {
  3032. string class_name = remap->_cpptype->get_local_name(&parser);
  3033. container = "(const " + class_name + "*)local_this";
  3034. }
  3035. }
  3036. pexprs.push_back(pexpr_string);
  3037. }
  3038. expected_params += ")\n";
  3039. // If this is the only overload, don't bother checking for type errors.
  3040. // Any type error that is raised will simply pass through to below.
  3041. //if (func->_remaps.size() == 1) {
  3042. // check_exceptions = false;
  3043. //}
  3044. // Track how many curly braces we've opened.
  3045. short open_scopes = 0;
  3046. if (!format_specifiers.empty()) {
  3047. std::string format_specifiers1 = format_specifiers + ":" +
  3048. methodNameFromCppName(func, "", false);
  3049. switch (args_type) {
  3050. case AT_keyword_args:
  3051. // Wrapper takes a varargs tuple and a keyword args dict.
  3052. indent(out, indent_level)
  3053. << "static char *keyword_list[] = {" << keyword_list << "NULL};\n";
  3054. indent(out, indent_level)
  3055. << "if (PyArg_ParseTupleAndKeywords(args, kwds, \""
  3056. << format_specifiers1 << "\", keyword_list" << parameter_list
  3057. << ")) {\n";
  3058. ++open_scopes;
  3059. indent_level += 2;
  3060. break;
  3061. case AT_varargs:
  3062. // Wrapper takes a varargs tuple.
  3063. if (only_pyobjects) {
  3064. // All parameters are PyObject*, so we can use the slightly
  3065. // more efficient PyArg_UnpackTuple function instead.
  3066. indent(out, indent_level)
  3067. << "if (PyArg_UnpackTuple(args, \""
  3068. << methodNameFromCppName(func, "", false)
  3069. << "\", " << num_params
  3070. << ", " << num_params
  3071. << parameter_list << ")) {\n";
  3072. } else {
  3073. indent(out, indent_level)
  3074. << "if (PyArg_ParseTuple(args, \""
  3075. << format_specifiers1 << "\""
  3076. << parameter_list << ")) {\n";
  3077. }
  3078. ++open_scopes;
  3079. indent_level += 2;
  3080. break;
  3081. case AT_single_arg:
  3082. // Wrapper takes a single PyObject* argument.
  3083. if (!only_pyobjects && format_specifiers != "O") {
  3084. indent(out, indent_level)
  3085. << "if (PyArg_Parse(arg, \"" << format_specifiers << "\""
  3086. << parameter_list << ")) {\n";
  3087. ++open_scopes;
  3088. indent_level += 2;
  3089. }
  3090. default:
  3091. break;
  3092. }
  3093. }
  3094. if (!extra_convert.empty()) {
  3095. indent(out, indent_level)
  3096. << extra_convert << "\n";
  3097. }
  3098. if (!extra_param_check.empty()) {
  3099. indent(out, indent_level)
  3100. << "if (" << extra_param_check.substr(4) << ") {\n";
  3101. ++open_scopes;
  3102. indent_level += 2;
  3103. }
  3104. string return_expr;
  3105. if (!remap->_void_return &&
  3106. remap->_return_type->new_type_is_atomic_string()) {
  3107. // Treat strings as a special case. We don't want to format the
  3108. // return expression.
  3109. if (remap->_blocking) {
  3110. // With SIMPLE_THREADS, it's important that we never release the
  3111. // interpreter lock.
  3112. out << "#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)\n";
  3113. indent(out, indent_level)
  3114. << "PyThreadState *_save;\n";
  3115. indent(out, indent_level)
  3116. << "Py_UNBLOCK_THREADS\n";
  3117. out << "#endif // HAVE_THREADS && !SIMPLE_THREADS\n";
  3118. }
  3119. if (track_interpreter) {
  3120. indent(out, indent_level) << "in_interpreter = 0;\n";
  3121. }
  3122. string tt;
  3123. return_expr = remap->call_function(out, indent_level, false, container, pexprs);
  3124. CPPType *type = remap->_return_type->get_orig_type();
  3125. indent(out, indent_level);
  3126. type->output_instance(out, "return_value", &parser);
  3127. // type->output_instance(tt, "return_value", &parser);
  3128. out << " = " << return_expr << ";\n";
  3129. if (track_interpreter) {
  3130. indent(out, indent_level) << "in_interpreter = 1;\n";
  3131. }
  3132. if (remap->_blocking) {
  3133. out << "#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)\n";
  3134. indent(out, indent_level)
  3135. << "Py_BLOCK_THREADS\n";
  3136. out << "#endif // HAVE_THREADS && !SIMPLE_THREADS\n";
  3137. }
  3138. if (!extra_cleanup.empty()) {
  3139. indent(out, indent_level) << extra_cleanup << "\n";
  3140. }
  3141. return_expr = manage_return_value(out, 4, remap, "return_value");
  3142. } else {
  3143. if (remap->_blocking) {
  3144. out << "#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)\n";
  3145. indent(out, indent_level)
  3146. << "PyThreadState *_save;\n";
  3147. indent(out, indent_level)
  3148. << "Py_UNBLOCK_THREADS\n";
  3149. out << "#endif // HAVE_THREADS && !SIMPLE_THREADS\n";
  3150. }
  3151. if (track_interpreter) {
  3152. indent(out, indent_level) << "in_interpreter = 0;\n";
  3153. }
  3154. return_expr = remap->call_function(out, indent_level, true, container, pexprs);
  3155. if (return_expr.empty()) {
  3156. if (track_interpreter) {
  3157. indent(out, indent_level) << "in_interpreter = 1;\n";
  3158. }
  3159. if (remap->_blocking) {
  3160. out << "#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)\n";
  3161. indent(out, indent_level)
  3162. << "Py_BLOCK_THREADS\n";
  3163. out << "#endif // HAVE_THREADS && !SIMPLE_THREADS\n";
  3164. }
  3165. if (!extra_cleanup.empty()) {
  3166. indent(out, indent_level) << extra_cleanup << "\n";
  3167. }
  3168. if (coercion_possible) {
  3169. indent(out, indent_level)
  3170. << "Py_XDECREF(coerced);\n";
  3171. }
  3172. } else {
  3173. CPPType *type = remap->_return_type->get_temporary_type();
  3174. if (!is_inplace) {
  3175. indent(out, indent_level);
  3176. type->output_instance(out, "return_value", &parser);
  3177. out << " = " << return_expr << ";\n";
  3178. }
  3179. if (track_interpreter) {
  3180. indent(out, indent_level) << "in_interpreter = 1;\n";
  3181. }
  3182. if (remap->_blocking) {
  3183. out << "#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)\n";
  3184. indent(out, indent_level)
  3185. << "Py_BLOCK_THREADS\n";
  3186. out << "#endif // HAVE_THREADS && !SIMPLE_THREADS\n";
  3187. }
  3188. if (!extra_cleanup.empty()) {
  3189. indent(out, indent_level) << extra_cleanup << "\n";
  3190. }
  3191. if (coercion_possible) {
  3192. indent(out, indent_level)
  3193. << "Py_XDECREF(coerced);\n";
  3194. }
  3195. if (!is_inplace) {
  3196. if (remap->_return_type->return_value_needs_management()) {
  3197. // If a constructor returns NULL, that means allocation failed.
  3198. indent(out, indent_level) << "if (return_value == NULL) {\n";
  3199. if (return_int) {
  3200. indent(out, indent_level) << " PyErr_NoMemory();\n";
  3201. indent(out, indent_level) << " return -1;\n";
  3202. } else {
  3203. indent(out, indent_level) << " return PyErr_NoMemory();\n";
  3204. }
  3205. indent(out, indent_level) << "}\n";
  3206. }
  3207. return_expr = manage_return_value(out, indent_level, remap, "return_value");
  3208. }
  3209. return_expr = remap->_return_type->temporary_to_return(return_expr);
  3210. }
  3211. }
  3212. // If a method raises TypeError, continue.
  3213. //if (check_exceptions) {
  3214. if (true) {
  3215. indent(out, indent_level)
  3216. << "if (PyErr_Occurred()) {\n";
  3217. delete_return_value(out, indent_level + 2, remap, return_expr);
  3218. indent(out, indent_level)
  3219. << " if (PyErr_ExceptionMatches(PyExc_TypeError)) {\n";
  3220. indent(out, indent_level)
  3221. << " // TypeError raised; continue to next overload type.\n";
  3222. indent(out, indent_level)
  3223. << " } else {\n";
  3224. if (return_int) {
  3225. indent(out, indent_level + 2)
  3226. << " return -1;\n";
  3227. } else {
  3228. indent(out, indent_level + 2)
  3229. << " return (PyObject *)NULL;\n";
  3230. }
  3231. indent(out, indent_level)
  3232. << " }\n";
  3233. indent(out, indent_level)
  3234. << "} else {\n";
  3235. ++open_scopes;
  3236. indent_level += 2;
  3237. }
  3238. // Outputs code to check to see if an assertion has failed while
  3239. // the C++ code was executing, and report this failure back to Python.
  3240. if (watch_asserts) {
  3241. out << "#ifndef NDEBUG\n";
  3242. indent(out, indent_level)
  3243. << "Notify *notify = Notify::ptr();\n";
  3244. indent(out, indent_level)
  3245. << "if (notify->has_assert_failed()) {\n";
  3246. indent(out, indent_level + 2)
  3247. << "PyErr_SetString(PyExc_AssertionError, notify->get_assert_error_message().c_str());\n";
  3248. indent(out, indent_level + 2)
  3249. << "notify->clear_assert_failed();\n";
  3250. delete_return_value(out, indent_level + 2, remap, return_expr);
  3251. if (return_int) {
  3252. indent(out, indent_level + 2) << "return -1;\n";
  3253. } else {
  3254. indent(out, indent_level + 2) << "return (PyObject *)NULL;\n";
  3255. }
  3256. indent(out, indent_level)
  3257. << "}\n";
  3258. out << "#endif\n";
  3259. }
  3260. if (return_expr.empty()) {
  3261. if (return_int) {
  3262. indent(out, indent_level) << "return 0;\n";
  3263. } else {
  3264. indent(out, indent_level) << "Py_INCREF(Py_None);\n";
  3265. indent(out, indent_level) << "return Py_None;\n";
  3266. }
  3267. } else {
  3268. pack_return_value(out, indent_level, remap, return_expr, is_inplace);
  3269. }
  3270. // Close the extra braces opened earlier.
  3271. while (open_scopes > 0) {
  3272. indent_level -= 2;
  3273. indent(out, indent_level) << "}\n";
  3274. --open_scopes;
  3275. }
  3276. }
  3277. ////////////////////////////////////////////////////////////////////
  3278. // Function: InterfaceMakerPythonNative::pack_return_value
  3279. // Access: Private
  3280. // Description: Outputs a command to pack the indicated expression,
  3281. // of the return_type type, as a Python return value.
  3282. ////////////////////////////////////////////////////////////////////
  3283. void InterfaceMakerPythonNative::
  3284. pack_return_value(ostream &out, int indent_level, FunctionRemap *remap,
  3285. const string &return_expr, bool is_inplace) {
  3286. if (remap->_type == FunctionRemap::T_constructor) {
  3287. // should only reach this in the INIT function a a Class .. IE the PY exists before the CPP object
  3288. // this is were we type to returned a class/struct.. ie CPP Type
  3289. CPPType *orig_type = remap->_return_type->get_orig_type();
  3290. TypeIndex type_index = builder.get_type(TypeManager::unwrap(TypeManager::resolve_type(orig_type)), false);
  3291. InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
  3292. const InterrogateType &itype = idb->get_type(type_index);
  3293. indent(out, indent_level)
  3294. << "return DTool_PyInit_Finalize(self, " << return_expr << ", &" << CLASS_PREFIX << make_safe_name(itype.get_scoped_name()) << ", true, false);\n";
  3295. } else {
  3296. ParameterRemap *return_type = remap->_return_type;
  3297. pack_python_value(out, indent_level, remap, return_type, return_expr, "", is_inplace);
  3298. }
  3299. }
  3300. ////////////////////////////////////////////////////////////////////
  3301. // Function: InterfaceMakerPythonNative::pack_python_value
  3302. // Access: Private
  3303. // Description: Outputs a command to pack the indicated expression,
  3304. // of the return_type type, as a Python value.
  3305. // If assign_to is empty, the Python object is
  3306. // returned. Otherwise, it is assigned to a variable
  3307. // of that name (expected to already be declared).
  3308. ////////////////////////////////////////////////////////////////////
  3309. void InterfaceMakerPythonNative::
  3310. pack_python_value(ostream &out, int indent_level, FunctionRemap *remap,
  3311. ParameterRemap *return_type, const string &return_expr,
  3312. const string &assign_to, bool is_inplace) {
  3313. CPPType *orig_type = return_type->get_orig_type();
  3314. CPPType *type = return_type->get_new_type();
  3315. string assign_stmt("return ");
  3316. if (!assign_to.empty()) {
  3317. assign_stmt = assign_to + " = ";
  3318. }
  3319. if (return_type->new_type_is_atomic_string()) {
  3320. if (TypeManager::is_char_pointer(orig_type)) {
  3321. indent(out, indent_level) << "if (" << return_expr << " == NULL) {\n";
  3322. indent(out, indent_level) << " Py_INCREF(Py_None);\n";
  3323. indent(out, indent_level+2) << assign_stmt << "Py_None;\n";
  3324. indent(out, indent_level) << "} else {\n";
  3325. out << "#if PY_MAJOR_VERSION >= 3\n";
  3326. indent(out, indent_level+2) << assign_stmt
  3327. << "PyUnicode_FromString(" << return_expr << ");\n";
  3328. out << "#else\n";
  3329. indent(out, indent_level+2) << assign_stmt
  3330. << "PyString_FromString(" << return_expr << ");\n";
  3331. out << "#endif\n";
  3332. indent(out, indent_level) << "}\n";
  3333. } else if (TypeManager::is_wchar_pointer(orig_type)) {
  3334. indent(out, indent_level) << "if (" << return_expr << " == NULL) {\n";
  3335. indent(out, indent_level) << " Py_INCREF(Py_None);\n";
  3336. indent(out, indent_level+2) << assign_stmt << "Py_None;\n";
  3337. indent(out, indent_level) << "} else {\n";
  3338. indent(out, indent_level+2)
  3339. << assign_stmt << "PyUnicode_FromWideChar("
  3340. << return_expr << ", wcslen(" << return_expr << "));\n";
  3341. indent(out, indent_level) << "}\n";
  3342. } else if (TypeManager::is_wstring(orig_type)) {
  3343. indent(out, indent_level) << assign_stmt
  3344. << "PyUnicode_FromWideChar("
  3345. << return_expr << ".data(), (int) " << return_expr << ".length());\n";
  3346. } else if (TypeManager::is_const_ptr_to_basic_string_wchar(orig_type)) {
  3347. indent(out, indent_level) << "if (" << return_expr << " == NULL) {\n";
  3348. indent(out, indent_level) << " Py_INCREF(Py_None);\n";
  3349. indent(out, indent_level+2) << assign_stmt << "Py_None;\n";
  3350. indent(out, indent_level) << "} else {\n";
  3351. indent(out, indent_level+2) << assign_stmt
  3352. << "PyUnicode_FromWideChar("
  3353. << return_expr << "->data(), (int) " << return_expr << "->length());\n";
  3354. indent(out, indent_level) << "}\n";
  3355. } else if (TypeManager::is_const_ptr_to_basic_string_char(orig_type)) {
  3356. indent(out, indent_level) << "if (" << return_expr<< " == NULL) {\n";
  3357. indent(out, indent_level) << " Py_INCREF(Py_None);\n";
  3358. indent(out, indent_level+2) << assign_stmt << "Py_None;\n";
  3359. indent(out, indent_level) << "} else {\n";
  3360. out << "#if PY_MAJOR_VERSION >= 3\n";
  3361. indent(out, indent_level+2) << assign_stmt
  3362. << "PyUnicode_FromStringAndSize("
  3363. << return_expr << "->data(), (Py_ssize_t)" << return_expr << "->length());\n";
  3364. out << "#else\n";
  3365. indent(out, indent_level+2) << assign_stmt
  3366. << "PyString_FromStringAndSize("
  3367. << return_expr << "->data(), (Py_ssize_t)" << return_expr << "->length());\n";
  3368. out << "#endif\n";
  3369. indent(out, indent_level) << "}\n";
  3370. } else {
  3371. out << "#if PY_MAJOR_VERSION >= 3\n";
  3372. indent(out, indent_level) << assign_stmt
  3373. << "PyUnicode_FromStringAndSize("
  3374. << return_expr << ".data(), (Py_ssize_t)" << return_expr << ".length());\n";
  3375. out << "#else\n";
  3376. indent(out, indent_level) << assign_stmt
  3377. << "PyString_FromStringAndSize("
  3378. << return_expr << ".data(), (Py_ssize_t)" << return_expr << ".length());\n";
  3379. out << "#endif\n";
  3380. }
  3381. } else if (TypeManager::is_bool(type)) {
  3382. indent(out, indent_level) << assign_stmt
  3383. << "PyBool_FromLong(" << return_expr << ");\n";
  3384. } else if (TypeManager::is_unsigned_longlong(type)) {
  3385. indent(out, indent_level) << assign_stmt
  3386. << "PyLong_FromUnsignedLongLong(" << return_expr << ");\n";
  3387. } else if (TypeManager::is_longlong(type)) {
  3388. indent(out, indent_level) << assign_stmt
  3389. << "PyLong_FromLongLong(" << return_expr << ");\n";
  3390. } else if (TypeManager::is_unsigned_integer(type)){
  3391. out << "#if PY_MAJOR_VERSION >= 3\n";
  3392. indent(out, indent_level) << assign_stmt
  3393. << "PyLong_FromUnsignedLong(" << return_expr << ");\n";
  3394. out << "#else\n";
  3395. indent(out, indent_level) << assign_stmt
  3396. << "PyLongOrInt_FromUnsignedLong(" << return_expr << ");\n";
  3397. out << "#endif\n";
  3398. } else if (TypeManager::is_integer(type)) {
  3399. out << "#if PY_MAJOR_VERSION >= 3\n";
  3400. indent(out, indent_level) << assign_stmt
  3401. << "PyLong_FromLong(" << return_expr << ");\n";
  3402. out << "#else\n";
  3403. indent(out, indent_level) << assign_stmt
  3404. << "PyInt_FromLong(" << return_expr << ");\n";
  3405. out << "#endif\n";
  3406. } else if (TypeManager::is_float(type)) {
  3407. indent(out, indent_level) << assign_stmt
  3408. << "PyFloat_FromDouble(" << return_expr << ");\n";
  3409. } else if (TypeManager::is_char_pointer(type)) {
  3410. indent(out, indent_level) << "if (" << return_expr << " == NULL) {\n";
  3411. indent(out, indent_level) << " Py_INCREF(Py_None);\n";
  3412. indent(out, indent_level+2) << assign_stmt << "Py_None;\n";
  3413. indent(out, indent_level) << "} else {\n";
  3414. out << "#if PY_MAJOR_VERSION >= 3\n";
  3415. indent(out, indent_level+2) << assign_stmt
  3416. << "PyUnicode_FromString(" << return_expr << ");\n";
  3417. out << "#else\n";
  3418. indent(out, indent_level+2) << assign_stmt
  3419. << "PyString_FromString(" << return_expr << ");\n";
  3420. out << "#endif\n";
  3421. indent(out, indent_level) << "}\n";
  3422. } else if (TypeManager::is_wchar_pointer(type)) {
  3423. indent(out, indent_level) << "if (" << return_expr << " == NULL) {\n";
  3424. indent(out, indent_level) << " Py_INCREF(Py_None);\n";
  3425. indent(out, indent_level+2) << assign_stmt << "Py_None;\n";
  3426. indent(out, indent_level) << "} else {\n";
  3427. indent(out, indent_level+2) << assign_stmt
  3428. << "PyUnicode_FromWideChar("
  3429. << return_expr << ", wcslen(" << return_expr << "));\n";
  3430. indent(out, indent_level) << "}\n";
  3431. } else if (TypeManager::is_pointer_to_PyObject(type)) {
  3432. indent(out, indent_level)
  3433. << assign_stmt << return_expr << ";\n";
  3434. } else if (TypeManager::is_pointer_to_Py_buffer(type)) {
  3435. indent(out, indent_level) << "if (" << return_expr << " == NULL) {\n";
  3436. indent(out, indent_level) << " Py_INCREF(Py_None);\n";
  3437. indent(out, indent_level+2) << assign_stmt << "Py_None;\n";
  3438. indent(out, indent_level) << "} else {\n";
  3439. indent(out, indent_level+2) << assign_stmt
  3440. << "PyMemoryView_FromBuffer(" << return_expr << ");\n";
  3441. indent(out, indent_level) << "}\n";
  3442. } else if (TypeManager::is_pointer(type)) {
  3443. string const_flag;
  3444. if (TypeManager::is_const_pointer_to_anything(type)) {
  3445. const_flag = "true";
  3446. } else {
  3447. const_flag = "false";
  3448. }
  3449. if (TypeManager::is_struct(orig_type) || TypeManager::is_ref_to_anything(orig_type)) {
  3450. if (TypeManager::is_ref_to_anything(orig_type)) {
  3451. TypeIndex type_index = builder.get_type(TypeManager::unwrap(TypeManager::resolve_type(type)),false);
  3452. InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
  3453. const InterrogateType &itype = idb->get_type(type_index);
  3454. std::string owns_memory_flag("true");
  3455. if (remap->_return_value_needs_management) {
  3456. owns_memory_flag = "true";
  3457. } else {
  3458. owns_memory_flag = "false";
  3459. }
  3460. if (!isExportThisRun(itype._cpptype)) {
  3461. _external_imports.insert(make_safe_name(itype.get_scoped_name()));
  3462. }
  3463. write_python_instance(out, indent_level, return_expr, assign_to, owns_memory_flag, itype.get_scoped_name(), itype._cpptype, is_inplace, const_flag);
  3464. } else {
  3465. std::string owns_memory_flag("true");
  3466. if (remap->_return_value_needs_management) {
  3467. owns_memory_flag = "true";
  3468. } else {
  3469. owns_memory_flag = "false";
  3470. }
  3471. if (remap->_manage_reference_count) {
  3472. TypeIndex type_index = builder.get_type(TypeManager::unwrap(TypeManager::resolve_type(type)),false);
  3473. InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
  3474. const InterrogateType &itype = idb->get_type(type_index);
  3475. if (!isExportThisRun(itype._cpptype)) {
  3476. _external_imports.insert(make_safe_name(itype.get_scoped_name()));
  3477. }
  3478. write_python_instance(out, indent_level, return_expr, assign_to, owns_memory_flag, itype.get_scoped_name(), itype._cpptype, is_inplace, const_flag);
  3479. } else {
  3480. TypeIndex type_index = builder.get_type(TypeManager::unwrap(TypeManager::resolve_type(orig_type)),false);
  3481. InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
  3482. const InterrogateType &itype = idb->get_type(type_index);
  3483. if (!isExportThisRun(itype._cpptype)) {
  3484. _external_imports.insert(make_safe_name(itype.get_scoped_name()));
  3485. }
  3486. write_python_instance(out, indent_level, return_expr, assign_to, owns_memory_flag, itype.get_scoped_name(), itype._cpptype, is_inplace, const_flag);
  3487. }
  3488. }
  3489. } else if (TypeManager::is_struct(orig_type->as_pointer_type()->_pointing_at)) {
  3490. TypeIndex type_index = builder.get_type(TypeManager::unwrap(TypeManager::resolve_type(orig_type)),false);
  3491. InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
  3492. const InterrogateType &itype = idb->get_type(type_index);
  3493. std::string owns_memory_flag("true");
  3494. if (remap->_return_value_needs_management) {
  3495. owns_memory_flag = "true";
  3496. } else {
  3497. owns_memory_flag = "false";
  3498. }
  3499. if (!isExportThisRun(itype._cpptype)) {
  3500. _external_imports.insert(make_safe_name(itype.get_scoped_name()));
  3501. }
  3502. write_python_instance(out, indent_level, return_expr, assign_to, owns_memory_flag, itype.get_scoped_name(), itype._cpptype, is_inplace, const_flag);
  3503. } else {
  3504. indent(out, indent_level) << " Should Never Reach This InterfaceMakerPythonNative::pack_python_value";
  3505. //<< "return PyInt_FromLong((int) " << return_expr << ");\n";
  3506. }
  3507. } else {
  3508. // Return None.
  3509. indent(out, indent_level)
  3510. << assign_stmt << "Py_BuildValue(\"\");\n";
  3511. }
  3512. }
  3513. ////////////////////////////////////////////////////////////////////
  3514. // Function: InterfaceMakerPythonName::write_make_seq
  3515. // Access: Public
  3516. // Description: Generates the synthetic method described by the
  3517. // MAKE_SEQ() macro.
  3518. ////////////////////////////////////////////////////////////////////
  3519. void InterfaceMakerPythonNative::
  3520. write_make_seq(ostream &out, Object *obj, const std::string &ClassName,
  3521. MakeSeq *make_seq) {
  3522. out << "/******************************************************************\n" << " * Python make_seq wrapper\n";
  3523. out << " *******************************************************************/\n";
  3524. out << "static PyObject *" << make_seq->_name + "(PyObject *self, PyObject *) {\n";
  3525. string num_name = methodNameFromCppName(make_seq->_num_name, ClassName, false);
  3526. string element_name = methodNameFromCppName(make_seq->_element_name, ClassName, false);
  3527. out << " return make_list_for_item(self, \"" << num_name
  3528. << "\", \"" << element_name << "\");\n";
  3529. out << "}\n";
  3530. }
  3531. ////////////////////////////////////////////////////////////////////
  3532. // Function: InterfaceMakerPythonNative::record_object
  3533. // Access: Protected
  3534. // Description: Records the indicated type, which may be a struct
  3535. // type, along with all of its associated methods, if
  3536. // any.
  3537. ////////////////////////////////////////////////////////////////////
  3538. InterfaceMaker::Object *InterfaceMakerPythonNative::
  3539. record_object(TypeIndex type_index) {
  3540. if (type_index == 0) {
  3541. return (Object *)NULL;
  3542. }
  3543. Objects::iterator oi = _objects.find(type_index);
  3544. if (oi != _objects.end()) {
  3545. return (*oi).second;
  3546. }
  3547. InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
  3548. const InterrogateType &itype = idb->get_type(type_index);
  3549. if (!is_cpp_type_legal(itype._cpptype)) {
  3550. return (Object *)NULL;
  3551. }
  3552. Object *object = new Object(itype);
  3553. bool inserted = _objects.insert(Objects::value_type(type_index, object)).second;
  3554. assert(inserted);
  3555. Function *function;
  3556. int num_constructors = itype.number_of_constructors();
  3557. for (int ci = 0; ci < num_constructors; ci++) {
  3558. function = record_function(itype, itype.get_constructor(ci));
  3559. if (is_function_legal(function)) {
  3560. object->_constructors.push_back(function);
  3561. }
  3562. }
  3563. int num_methods = itype.number_of_methods();
  3564. int mi;
  3565. for (mi = 0; mi < num_methods; mi++) {
  3566. function = record_function(itype, itype.get_method(mi));
  3567. if (is_function_legal(function)) {
  3568. object->_methods.push_back(function);
  3569. }
  3570. }
  3571. int num_casts = itype.number_of_casts();
  3572. for (mi = 0; mi < num_casts; mi++) {
  3573. function = record_function(itype, itype.get_cast(mi));
  3574. if (is_function_legal(function)) {
  3575. object->_methods.push_back(function);
  3576. }
  3577. }
  3578. int num_derivations = itype.number_of_derivations();
  3579. for (int di = 0; di < num_derivations; di++) {
  3580. TypeIndex d_type_Index = itype.get_derivation(di);
  3581. idb->get_type(d_type_Index);
  3582. if (!interrogate_type_is_unpublished(d_type_Index)) {
  3583. if (itype.derivation_has_upcast(di)) {
  3584. function = record_function(itype, itype.derivation_get_upcast(di));
  3585. if (is_function_legal(function)) {
  3586. object->_methods.push_back(function);
  3587. }
  3588. }
  3589. if (itype.derivation_has_downcast(di)) {
  3590. // Downcasts are methods of the base class, not the child class.
  3591. TypeIndex base_type_index = itype.get_derivation(di);
  3592. const InterrogateType &base_type = idb->get_type(base_type_index);
  3593. function = record_function(base_type, itype.derivation_get_downcast(di));
  3594. if (is_function_legal(function)) {
  3595. Object * pobject = record_object(base_type_index);
  3596. if (pobject != NULL) {
  3597. pobject->_methods.push_back(function);
  3598. }
  3599. }
  3600. }
  3601. }
  3602. }
  3603. int num_elements = itype.number_of_elements();
  3604. for (int ei = 0; ei < num_elements; ei++) {
  3605. ElementIndex element_index = itype.get_element(ei);
  3606. const InterrogateElement &ielement = idb->get_element(element_index);
  3607. Property *property = new Property(ielement);
  3608. if (ielement.has_setter()) {
  3609. FunctionIndex func_index = ielement.get_setter();
  3610. Function *setter = record_function(itype, func_index);
  3611. if (is_function_legal(setter)) {
  3612. property->_setter = setter;
  3613. }
  3614. }
  3615. if (ielement.has_getter()) {
  3616. FunctionIndex func_index = ielement.get_getter();
  3617. Function *getter = record_function(itype, func_index);
  3618. if (is_function_legal(getter)) {
  3619. property->_getter = getter;
  3620. }
  3621. }
  3622. if (property->_getter != NULL) {
  3623. object->_properties.push_back(property);
  3624. } else {
  3625. // No use exporting a property without a getter.
  3626. delete property;
  3627. }
  3628. }
  3629. object->check_protocols();
  3630. int num_nested = itype.number_of_nested_types();
  3631. for (int ni = 0; ni < num_nested; ni++) {
  3632. TypeIndex nested_index = itype.get_nested_type(ni);
  3633. record_object(nested_index);
  3634. }
  3635. return object;
  3636. }
  3637. ////////////////////////////////////////////////////////////////////
  3638. // Function: InterfaceMaker::generate_wrappers
  3639. // Access: Public, Virtual
  3640. // Description: Walks through the set of functions in the database
  3641. // and generates wrappers for each function, storing
  3642. // these in the database. No actual code should be
  3643. // output yet; this just updates the database with the
  3644. // wrapper information.
  3645. ////////////////////////////////////////////////////////////////////
  3646. void InterfaceMakerPythonNative::
  3647. generate_wrappers() {
  3648. inside_python_native = true;
  3649. InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
  3650. // We use a while loop rather than a simple for loop, because we
  3651. // might increase the number of types recursively during the
  3652. // traversal.
  3653. int ti = 0;
  3654. while (ti < idb->get_num_all_types()) {
  3655. TypeIndex type_index = idb->get_all_type(ti);
  3656. record_object(type_index);
  3657. ++ti;
  3658. }
  3659. int num_global_elements = idb->get_num_global_elements();
  3660. for (int gi = 0; gi < num_global_elements; ++gi) {
  3661. TypeIndex type_index = idb->get_global_element(gi);
  3662. record_object(type_index);
  3663. }
  3664. int num_functions = idb->get_num_global_functions();
  3665. for (int fi = 0; fi < num_functions; fi++) {
  3666. FunctionIndex func_index = idb->get_global_function(fi);
  3667. record_function(dummy_type, func_index);
  3668. }
  3669. int num_manifests = idb->get_num_global_manifests();
  3670. for (int mi = 0; mi < num_manifests; mi++) {
  3671. ManifestIndex manifest_index = idb->get_global_manifest(mi);
  3672. const InterrogateManifest &iman = idb->get_manifest(manifest_index);
  3673. if (iman.has_getter()) {
  3674. FunctionIndex func_index = iman.get_getter();
  3675. record_function(dummy_type, func_index);
  3676. }
  3677. }
  3678. int num_elements = idb->get_num_global_elements();
  3679. for (int ei = 0; ei < num_elements; ei++) {
  3680. ElementIndex element_index = idb->get_global_element(ei);
  3681. const InterrogateElement &ielement = idb->get_element(element_index);
  3682. if (ielement.has_getter()) {
  3683. FunctionIndex func_index = ielement.get_getter();
  3684. record_function(dummy_type, func_index);
  3685. }
  3686. if (ielement.has_setter()) {
  3687. FunctionIndex func_index = ielement.get_setter();
  3688. record_function(dummy_type, func_index);
  3689. }
  3690. }
  3691. inside_python_native = false;
  3692. }
  3693. //////////////////////////////////////////////
  3694. // Function :is_cpp_type_legal
  3695. //
  3696. // is the cpp object supported by by the dtool_py interface..
  3697. //////////////////////////////////////////////
  3698. bool InterfaceMakerPythonNative::
  3699. is_cpp_type_legal(CPPType *in_ctype) {
  3700. if (in_ctype == NULL) {
  3701. return false;
  3702. }
  3703. if (builder.in_ignoretype(in_ctype->get_local_name(&parser))) {
  3704. return false;
  3705. }
  3706. //bool answer = false;
  3707. CPPType *type = TypeManager::unwrap(TypeManager::resolve_type(in_ctype));
  3708. type = TypeManager::unwrap(type);
  3709. //CPPType *type = ctype;
  3710. if (TypeManager::is_basic_string_char(type)) {
  3711. return true;
  3712. } else if (TypeManager::is_basic_string_wchar(type)) {
  3713. return true;
  3714. } else if (TypeManager::is_simple(type)) {
  3715. return true;
  3716. } else if (builder.in_forcetype(type->get_local_name(&parser))) {
  3717. return true;
  3718. } else if (TypeManager::IsExported(type)) {
  3719. return true;
  3720. } else if (TypeManager::is_pointer_to_PyObject(in_ctype)) {
  3721. return true;
  3722. } else if (TypeManager::is_pointer_to_Py_buffer(in_ctype)) {
  3723. return true;
  3724. }
  3725. //if (answer == false)
  3726. // printf(" -------------------- Bad Type ?? %s\n",type->get_local_name().c_str());
  3727. return false;
  3728. }
  3729. //////////////////////////////////////////////
  3730. // Function :isExportThisRun
  3731. //
  3732. //////////////////////////////////////////////
  3733. bool InterfaceMakerPythonNative::
  3734. isExportThisRun(CPPType *ctype) {
  3735. CPPType *type = TypeManager::unwrap(ctype);
  3736. if (TypeManager::IsLocal(type)) {
  3737. return true;
  3738. }
  3739. if (builder.in_forcetype(type->get_local_name(&parser))) {
  3740. return true;
  3741. }
  3742. return false;
  3743. }
  3744. //////////////////////////////////////////////
  3745. // Function : isExportThisRun
  3746. /////////////////////////////////////////////
  3747. bool InterfaceMakerPythonNative::
  3748. isExportThisRun(Function *func) {
  3749. if (func == NULL || !is_function_legal(func)) {
  3750. return false;
  3751. }
  3752. Function::Remaps::const_iterator ri;
  3753. for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
  3754. FunctionRemap *remap = (*ri);
  3755. return isExportThisRun(remap->_cpptype);
  3756. }
  3757. return false;
  3758. }
  3759. //////////////////////////////////////////////
  3760. // Function : is_remap_legal
  3761. //////////////////////////////////////////////
  3762. bool InterfaceMakerPythonNative::
  3763. is_remap_legal(FunctionRemap *remap) {
  3764. if (remap == NULL) {
  3765. return false;
  3766. }
  3767. // return must be legal and managable..
  3768. if (!is_cpp_type_legal(remap->_return_type->get_orig_type())) {
  3769. // printf(" is_remap_legal Return Is Bad %s\n",remap->_return_type->get_orig_type()->get_fully_scoped_name().c_str());
  3770. return false;
  3771. }
  3772. // ouch .. bad things will happen here .. do not even try..
  3773. if (remap->_ForcedVoidReturn) {
  3774. return false;
  3775. }
  3776. // all params must be legal
  3777. for (int pn = 0; pn < (int)remap->_parameters.size(); pn++) {
  3778. CPPType *orig_type = remap->_parameters[pn]._remap->get_orig_type();
  3779. if (!is_cpp_type_legal(orig_type)) {
  3780. return false;
  3781. }
  3782. }
  3783. // ok all looks ok.
  3784. return true;
  3785. }
  3786. ////////////////////////////////////////////////////////////////////////
  3787. // Function : is_function_legal
  3788. ////////////////////////////////////////////////////////////////////////
  3789. bool InterfaceMakerPythonNative::
  3790. is_function_legal(Function *func) {
  3791. Function::Remaps::const_iterator ri;
  3792. for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
  3793. FunctionRemap *remap = (*ri);
  3794. if (is_remap_legal(remap)) {
  3795. // printf(" Function Is Marked Legal %s\n",func->_name.c_str());
  3796. return true;
  3797. }
  3798. }
  3799. // printf(" Function Is Marked Illegal %s\n",func->_name.c_str());
  3800. return false;
  3801. }
  3802. ////////////////////////////////////////////////////////
  3803. // Function : IsRunTimeTyped
  3804. ///////////////////////////////////////////////////////
  3805. bool InterfaceMakerPythonNative::
  3806. IsRunTimeTyped(const InterrogateType &itype) {
  3807. TypeIndex ptype_id = itype.get_outer_class();
  3808. if (ptype_id > 0) {
  3809. InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
  3810. InterrogateType ptype = idb->get_type(ptype_id);
  3811. return IsRunTimeTyped(ptype);
  3812. }
  3813. if (itype.get_name() == "TypedObject") {
  3814. return true;
  3815. }
  3816. return false;
  3817. }
  3818. //////////////////////////////////////////////////////////
  3819. // Function : DoesInheritFromIsClass
  3820. //
  3821. // Helper function to check cpp class inharatience..
  3822. ///////////////////////////////////////////////////////////
  3823. bool InterfaceMakerPythonNative::
  3824. DoesInheritFromIsClass(const CPPStructType *inclass, const std::string &name) {
  3825. if (inclass == NULL) {
  3826. return false;
  3827. }
  3828. std::string scoped_name = inclass->get_fully_scoped_name();
  3829. if (scoped_name == name) {
  3830. return true;
  3831. }
  3832. CPPStructType::Derivation::const_iterator bi;
  3833. for (bi = inclass->_derivation.begin();
  3834. bi != inclass->_derivation.end();
  3835. ++bi) {
  3836. const CPPStructType::Base &base = (*bi);
  3837. CPPStructType *base_type = TypeManager::resolve_type(base._base)->as_struct_type();
  3838. if (base_type != NULL) {
  3839. if (DoesInheritFromIsClass(base_type, name)) {
  3840. return true;
  3841. }
  3842. }
  3843. }
  3844. return false;
  3845. }
  3846. ////////////////////////////////////////////////////////////////////////////////////////////
  3847. // Function : HasAGetKeyFunction
  3848. //
  3849. // does the class have a supportable get_key() or get_hash() to return
  3850. // a usable Python hash? Returns the name of the method, or empty
  3851. // string if there is no suitable method.
  3852. //////////////////////////////////////////////////////////////////////////////////////////
  3853. string InterfaceMakerPythonNative::
  3854. HasAGetKeyFunction(const InterrogateType &itype_class) {
  3855. InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
  3856. int num_methods = itype_class.number_of_methods();
  3857. int mi;
  3858. for (mi = 0; mi < num_methods; mi++) {
  3859. FunctionIndex func_index = itype_class.get_method(mi);
  3860. const InterrogateFunction &ifunc = idb->get_function(func_index);
  3861. if (ifunc.get_name() == "get_key" || ifunc.get_name() == "get_hash") {
  3862. if (ifunc._instances != (InterrogateFunction::Instances *)NULL) {
  3863. InterrogateFunction::Instances::const_iterator ii;
  3864. for (ii = ifunc._instances->begin();
  3865. ii != ifunc._instances->end();
  3866. ++ii) {
  3867. CPPInstance *cppinst = (*ii).second;
  3868. CPPFunctionType *cppfunc = cppinst->_type->as_function_type();
  3869. if (cppfunc != NULL) {
  3870. if (cppfunc->_parameters != NULL &&
  3871. cppfunc->_return_type != NULL &&
  3872. TypeManager::is_integer(cppfunc->_return_type)) {
  3873. if (cppfunc->_parameters->_parameters.size() == 0) {
  3874. return ifunc.get_name();
  3875. }
  3876. }
  3877. }
  3878. }
  3879. }
  3880. }
  3881. }
  3882. return string();
  3883. }
  3884. ////////////////////////////////////////////////////////////////////////////////////////////
  3885. // Function : HasAGetClassTypeFunction
  3886. //
  3887. // does the class have a supportable GetClassType which returns a TypeHandle.
  3888. //////////////////////////////////////////////////////////////////////////////////////////
  3889. bool InterfaceMakerPythonNative::
  3890. HasAGetClassTypeFunction(const InterrogateType &itype_class) {
  3891. InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
  3892. int num_methods = itype_class.number_of_methods();
  3893. int mi;
  3894. for (mi = 0; mi < num_methods; mi++) {
  3895. FunctionIndex func_index = itype_class.get_method(mi);
  3896. const InterrogateFunction &ifunc = idb->get_function(func_index);
  3897. if (ifunc.get_name() == "get_class_type") {
  3898. if (ifunc._instances != (InterrogateFunction::Instances *)NULL) {
  3899. InterrogateFunction::Instances::const_iterator ii;
  3900. for (ii = ifunc._instances->begin();ii != ifunc._instances->end();++ii) {
  3901. CPPInstance *cppinst = (*ii).second;
  3902. CPPFunctionType *cppfunc = cppinst->_type->as_function_type();
  3903. if (cppfunc != NULL && cppfunc->_return_type != NULL &&
  3904. cppfunc->_parameters != NULL) {
  3905. CPPType *ret_type = TypeManager::unwrap(cppfunc->_return_type);
  3906. if (TypeManager::is_struct(ret_type) &&
  3907. ret_type->get_simple_name() == "TypeHandle") {
  3908. if (cppfunc->_parameters->_parameters.size() == 0) {
  3909. return true;
  3910. }
  3911. }
  3912. }
  3913. }
  3914. }
  3915. }
  3916. }
  3917. return false;
  3918. }
  3919. ////////////////////////////////////////////////////////////////////
  3920. // Function: InterfaceMakerPythonNative::NeedsAStrFunction
  3921. // Access: Private
  3922. // Description: Returns -1 if the class does not define write() (and
  3923. // therefore cannot support a __str__ function).
  3924. //
  3925. // Returns 1 if the class defines write(ostream).
  3926. //
  3927. // Returns 2 if the class defines write(ostream, int).
  3928. ////////////////////////////////////////////////////////////////////
  3929. int InterfaceMakerPythonNative::
  3930. NeedsAStrFunction(const InterrogateType &itype_class) {
  3931. InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
  3932. int num_methods = itype_class.number_of_methods();
  3933. int mi;
  3934. for (mi = 0; mi < num_methods; ++mi) {
  3935. FunctionIndex func_index = itype_class.get_method(mi);
  3936. const InterrogateFunction &ifunc = idb->get_function(func_index);
  3937. if (ifunc.get_name() == "write") {
  3938. if (ifunc._instances != (InterrogateFunction::Instances *)NULL) {
  3939. InterrogateFunction::Instances::const_iterator ii;
  3940. for (ii = ifunc._instances->begin();
  3941. ii != ifunc._instances->end();
  3942. ++ii) {
  3943. CPPInstance *cppinst = (*ii).second;
  3944. CPPFunctionType *cppfunc = cppinst->_type->as_function_type();
  3945. if (cppfunc != NULL) {
  3946. if (cppfunc->_parameters != NULL &&
  3947. cppfunc->_return_type != NULL &&
  3948. TypeManager::is_void(cppfunc->_return_type)) {
  3949. if (cppfunc->_parameters->_parameters.size() == 1) {
  3950. CPPInstance *inst1 = cppfunc->_parameters->_parameters[0];
  3951. if (TypeManager::is_pointer_to_ostream(inst1->_type)) {
  3952. // write(ostream)
  3953. return 1;
  3954. }
  3955. }
  3956. if (cppfunc->_parameters->_parameters.size() == 2) {
  3957. CPPInstance *inst1 = cppfunc->_parameters->_parameters[0];
  3958. if (TypeManager::is_pointer_to_ostream(inst1->_type)) {
  3959. inst1 = cppfunc->_parameters->_parameters[1];
  3960. if (inst1->_initializer != NULL) {
  3961. // write(ostream, int = 0)
  3962. return 1;
  3963. }
  3964. if (TypeManager::is_integer(inst1->_type)) {
  3965. // write(ostream, int)
  3966. return 2;
  3967. }
  3968. }
  3969. }
  3970. }
  3971. }
  3972. }
  3973. }
  3974. }
  3975. }
  3976. return -1;
  3977. }
  3978. ////////////////////////////////////////////////////////////////////
  3979. // Function: InterfaceMakerPythonNative::NeedsAReprFunction
  3980. // Access: Private
  3981. // Description: Returns -1 if the class does not define output() or
  3982. // python_repr() (and therefore cannot support a
  3983. // __repr__ function).
  3984. //
  3985. // Returns 1 if the class defines python_repr(ostream, string).
  3986. //
  3987. // Returns 2 if the class defines output(ostream).
  3988. //
  3989. // Returns 3 if the class defines an extension
  3990. // function for python_repr(ostream, string).
  3991. ////////////////////////////////////////////////////////////////////
  3992. int InterfaceMakerPythonNative::
  3993. NeedsAReprFunction(const InterrogateType &itype_class) {
  3994. InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
  3995. int num_methods = itype_class.number_of_methods();
  3996. int mi;
  3997. for (mi = 0; mi < num_methods; ++mi) {
  3998. FunctionIndex func_index = itype_class.get_method(mi);
  3999. const InterrogateFunction &ifunc = idb->get_function(func_index);
  4000. if (ifunc.get_name() == "python_repr") {
  4001. if (ifunc._instances != (InterrogateFunction::Instances *)NULL) {
  4002. InterrogateFunction::Instances::const_iterator ii;
  4003. for (ii = ifunc._instances->begin();
  4004. ii != ifunc._instances->end();
  4005. ++ii) {
  4006. CPPInstance *cppinst = (*ii).second;
  4007. CPPFunctionType *cppfunc = cppinst->_type->as_function_type();
  4008. if (cppfunc != NULL) {
  4009. if (cppfunc->_parameters != NULL &&
  4010. cppfunc->_return_type != NULL &&
  4011. TypeManager::is_void(cppfunc->_return_type)) {
  4012. if (cppfunc->_parameters->_parameters.size() == 2) {
  4013. CPPInstance *inst1 = cppfunc->_parameters->_parameters[0];
  4014. if (TypeManager::is_pointer_to_ostream(inst1->_type)) {
  4015. inst1 = cppfunc->_parameters->_parameters[1];
  4016. if (TypeManager::is_string(inst1->_type) ||
  4017. TypeManager::is_char_pointer(inst1->_type)) {
  4018. // python_repr(ostream, string)
  4019. if ((cppinst->_storage_class & CPPInstance::SC_extension) != 0) {
  4020. return 3;
  4021. } else {
  4022. return 1;
  4023. }
  4024. }
  4025. }
  4026. }
  4027. }
  4028. }
  4029. }
  4030. }
  4031. }
  4032. }
  4033. for (mi = 0; mi < num_methods; ++mi) {
  4034. FunctionIndex func_index = itype_class.get_method(mi);
  4035. const InterrogateFunction &ifunc = idb->get_function(func_index);
  4036. if (ifunc.get_name() == "output") {
  4037. if (ifunc._instances != (InterrogateFunction::Instances *)NULL) {
  4038. InterrogateFunction::Instances::const_iterator ii;
  4039. for (ii = ifunc._instances->begin();
  4040. ii != ifunc._instances->end();
  4041. ++ii) {
  4042. CPPInstance *cppinst = (*ii).second;
  4043. CPPFunctionType *cppfunc = cppinst->_type->as_function_type();
  4044. if (cppfunc != NULL) {
  4045. if (cppfunc->_parameters != NULL &&
  4046. cppfunc->_return_type != NULL &&
  4047. TypeManager::is_void(cppfunc->_return_type)) {
  4048. if (cppfunc->_parameters->_parameters.size() == 1) {
  4049. CPPInstance *inst1 = cppfunc->_parameters->_parameters[0];
  4050. if (TypeManager::is_pointer_to_ostream(inst1->_type)) {
  4051. // output(ostream)
  4052. return 2;
  4053. }
  4054. }
  4055. if (cppfunc->_parameters->_parameters.size() >= 2) {
  4056. CPPInstance *inst1 = cppfunc->_parameters->_parameters[0];
  4057. if (TypeManager::is_pointer_to_ostream(inst1->_type)) {
  4058. inst1 = cppfunc->_parameters->_parameters[1];
  4059. if (inst1->_initializer != NULL) {
  4060. // output(ostream, foo = bar, ...)
  4061. return 2;
  4062. }
  4063. }
  4064. }
  4065. }
  4066. }
  4067. }
  4068. }
  4069. }
  4070. }
  4071. return -1;
  4072. }
  4073. ////////////////////////////////////////////////////////////////////
  4074. // Function: InterfaceMakerPythonNative::NeedsARichCompareFunction
  4075. // Access: Private
  4076. // Description: Returns true if the class defines a rich comparison
  4077. // operator.
  4078. ////////////////////////////////////////////////////////////////////
  4079. bool InterfaceMakerPythonNative::
  4080. NeedsARichCompareFunction(const InterrogateType &itype_class) {
  4081. InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
  4082. int num_methods = itype_class.number_of_methods();
  4083. int mi;
  4084. for (mi = 0; mi < num_methods; ++mi) {
  4085. FunctionIndex func_index = itype_class.get_method(mi);
  4086. const InterrogateFunction &ifunc = idb->get_function(func_index);
  4087. if (ifunc.get_name() == "operator <") {
  4088. return true;
  4089. }
  4090. if (ifunc.get_name() == "operator <=") {
  4091. return true;
  4092. }
  4093. if (ifunc.get_name() == "operator ==") {
  4094. return true;
  4095. }
  4096. if (ifunc.get_name() == "operator !=") {
  4097. return true;
  4098. }
  4099. if (ifunc.get_name() == "operator >") {
  4100. return true;
  4101. }
  4102. if (ifunc.get_name() == "operator >=") {
  4103. return true;
  4104. }
  4105. }
  4106. return false;
  4107. }
  4108. ////////////////////////////////////////////////////////////////////
  4109. // Function: InterfaceMakerPythonNative::output_quoted
  4110. // Access: Private
  4111. // Description: Outputs the indicated string as a single quoted,
  4112. // multi-line string to the generated C++ source code.
  4113. // The output point is left on the last line of the
  4114. // string, following the trailing quotation mark.
  4115. ////////////////////////////////////////////////////////////////////
  4116. void InterfaceMakerPythonNative::
  4117. output_quoted(ostream &out, int indent_level, const std::string &str) {
  4118. indent(out, indent_level)
  4119. << '"';
  4120. std::string::const_iterator si;
  4121. for (si = str.begin(); si != str.end(); ++si) {
  4122. switch (*si) {
  4123. case '"':
  4124. case '\\':
  4125. out << '\\' << *si;
  4126. break;
  4127. case '\n':
  4128. out << "\\n\"\n";
  4129. indent(out, indent_level)
  4130. << '"';
  4131. break;
  4132. default:
  4133. if (!isprint(*si)) {
  4134. out << "\\" << oct << setw(3) << setfill('0') << (unsigned int)(*si)
  4135. << dec;
  4136. } else {
  4137. out << *si;
  4138. }
  4139. }
  4140. }
  4141. out << '"';
  4142. }