abi-compliance-checker.pl 305 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326
  1. #!/usr/bin/perl
  2. ###########################################################################
  3. # ABI-compliance-checker v1.13, lightweight tool for statically checking
  4. # backward binary compatibility of shared C/C++ libraries in Linux.
  5. # Copyright (C) The Linux Foundation
  6. # Copyright (C) Institute for System Programming, RAS
  7. # Author: Andrey Ponomarenko
  8. #
  9. # This program is free software: you can redistribute it and/or modify
  10. # it under the terms of the GNU General Public License as published by
  11. # the Free Software Foundation, either version 2 of the License, or
  12. # (at your option) any later version.
  13. #
  14. # This program is distributed in the hope that it will be useful,
  15. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. # GNU General Public License for more details.
  18. #
  19. # You should have received a copy of the GNU General Public License
  20. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. ###########################################################################
  22. use Getopt::Long;
  23. Getopt::Long::Configure ("posix_default", "no_ignore_case");
  24. use Data::Dumper;
  25. my $ABI_COMPLIANCE_CHECKER_VERSION = "1.13";
  26. my ($Help, $ShowVersion, %Descriptor, $TargetLibraryName, $HeaderCheckingMode_Separately, $GenerateDescriptor, $TestSystem, $DumpInfo_DescriptorPath, $CheckHeadersOnly, $InterfacesListPath, $AppPath, $ShowExpendTime);
  27. my $CmdName = get_FileName($0);
  28. GetOptions("h|help!" => \$Help,
  29. "v|version!" => \$ShowVersion,
  30. #general options
  31. "l|library=s" => \$TargetLibraryName,
  32. "d1|descriptor1=s" => \$Descriptor{1}{"Path"},
  33. "d2|descriptor2=s" => \$Descriptor{2}{"Path"},
  34. #extra options
  35. "app|application=s" => \$AppPath,
  36. "symbols_list|int_list=s" => \$InterfacesListPath,
  37. "dump_abi|dump_info=s" => \$DumpInfo_DescriptorPath,
  38. "headers_only!" => \$CheckHeadersOnly,
  39. #other options
  40. "d|descriptor_template!" => \$GenerateDescriptor,
  41. "separately!" => \$HeaderCheckingMode_Separately,
  42. "test!" => \$TestSystem,
  43. "time!" => \$ShowExpendTime
  44. ) or exit(1);
  45. sub HELP_MESSAGE()
  46. {
  47. print STDERR <<"EOM"
  48. NAME:
  49. $CmdName - check ABI compatibility of shared C/C++ library versions
  50. DESCRIPTION:
  51. Lightweight tool for statically checking backward binary compatibility of shared C/C++ libraries
  52. in Linux. It checks header files along with shared objects in two library versions and searches
  53. for ABI changes that may lead to incompatibility. Breakage of the binary compatibility may result
  54. in crashing or incorrect behavior of applications built with an old version of a library when
  55. it is running with a new one.
  56. ABI Compliance Checker was intended for library developers that are interested in ensuring
  57. backward binary compatibility. Also it can be used for checking forward binary compatibility
  58. and checking applications portability to the new library version.
  59. This tool is free software: you can redistribute it and/or modify it under the terms of the GNU GPL.
  60. USAGE:
  61. $CmdName [options]
  62. EXAMPLE OF USE:
  63. $CmdName -l <library_name> -d1 <1st_version_descriptor> -d2 <2nd_version_descriptor>
  64. GENERAL OPTIONS:
  65. -h|-help
  66. Print this help.
  67. -v|-version
  68. Print version.
  69. -l|-library <name>
  70. Library name (without version).
  71. It affects only on the path and the title of the report.
  72. -d1|-descriptor1 <path>
  73. Path to descriptor of 1st library version.
  74. -d2|-descriptor2 <path>
  75. Path to descriptor of 2nd library version.
  76. EXTRA OPTIONS:
  77. -app|-application <path>
  78. This option allow to specify the application that should be tested for portability
  79. to the new library version.
  80. -dump_abi|-dump_info <descriptor_path>
  81. Dump library ABI information using specified descriptor.
  82. This command will create '<library>_<ver1>.abi.tar.gz' file in the directory 'abi_dumps/<library>/'.
  83. You can transfer it anywhere and pass instead of library descriptor.
  84. -headers_only
  85. Check header files without shared objects. It is easy to run, but may provide
  86. a low quality ABI compliance report with false positives and without
  87. detecting of added/withdrawn interfaces.
  88. -symbols_list|-int_list <path>
  89. This option allow to specify a file with a list of interfaces (mangled names in C++)
  90. that should be checked, other library interfaces will not be checked.
  91. OTHER OPTIONS:
  92. -d|-descriptor_template
  93. Create library descriptor template 'library-descriptor.xml' in the current directory.
  94. -separately
  95. Check headers individually. This mode requires more time for checking ABI compliance,
  96. but possible compiler errors in one header can't affect others.
  97. -test
  98. Run internal tests (create two binary-incompatible versions of an artificial library
  99. and run ABI-Compliance-Checker on it).
  100. DESCRIPTOR EXAMPLE:
  101. <version>
  102. 1.28.0
  103. </version>
  104. <headers>
  105. /usr/local/atk/atk-1.28.0/include/
  106. </headers>
  107. <libs>
  108. /usr/local/atk/atk-1.28.0/lib/libatk-1.0.so
  109. </libs>
  110. <include_paths>
  111. /usr/include/glib-2.0/
  112. /usr/lib/glib-2.0/include/
  113. </include_paths>
  114. Report bugs to <abi-compliance-checker\@linuxtesting.org>
  115. For more information, please see: http://ispras.linux-foundation.org/index.php/ABI_compliance_checker
  116. EOM
  117. ;
  118. }
  119. my $Descriptor_Template = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
  120. <descriptor>
  121. <!-- Template for the library version descriptor -->
  122. <!--
  123. Necessary sections
  124. -->
  125. <version>
  126. <!-- Version of the library -->
  127. </version>
  128. <headers>
  129. <!-- The list of paths to header files and/or
  130. directories with header files, one per line -->
  131. </headers>
  132. <libs>
  133. <!-- The list of paths to shared objects and/or
  134. directories with shared objects, one per line -->
  135. </libs>
  136. <!--
  137. Additional sections
  138. -->
  139. <include_paths>
  140. <!-- The list of paths to be searched for header files
  141. needed for compiling of library headers, one per line -->
  142. </include_paths>
  143. <gcc_options>
  144. <!-- Additional gcc options, one per line -->
  145. </gcc_options>
  146. <opaque_types>
  147. <!-- The list of opaque types, one per line -->
  148. </opaque_types>
  149. <skip_interfaces>
  150. <!-- The list of functions (mangled/symbol names in C++)
  151. that should be skipped while testing, one per line -->
  152. </skip_interfaces>
  153. <include_preamble>
  154. <!-- The list of header files that should be included before other headers, one per line.
  155. For example, it is a tree.h for libxml2 and ft2build.h for freetype2 -->
  156. </include_preamble>
  157. </descriptor>";
  158. my %Operator_Indication = (
  159. "not" => "~",
  160. "assign" => "=",
  161. "andassign" => "&=",
  162. "orassign" => "|=",
  163. "xorassign" => "^=",
  164. "or" => "|",
  165. "xor" => "^",
  166. "addr" => "&",
  167. "and" => "&",
  168. "lnot" => "!",
  169. "eq" => "==",
  170. "ne" => "!=",
  171. "lt" => "<",
  172. "lshift" => "<<",
  173. "lshiftassign" => "<<=",
  174. "rshiftassign" => ">>=",
  175. "call" => "()",
  176. "mod" => "%",
  177. "modassign" => "%=",
  178. "subs" => "[]",
  179. "land" => "&&",
  180. "lor" => "||",
  181. "rshift" => ">>",
  182. "ref" => "->",
  183. "le" => "<=",
  184. "deref" => "*",
  185. "mult" => "*",
  186. "preinc" => "++",
  187. "delete" => " delete",
  188. "vecnew" => " new[]",
  189. "vecdelete" => " delete[]",
  190. "predec" => "--",
  191. "postinc" => "++",
  192. "postdec" => "--",
  193. "plusassign" => "+=",
  194. "plus" => "+",
  195. "minus" => "-",
  196. "minusassign" => "-=",
  197. "gt" => ">",
  198. "ge" => ">=",
  199. "new" => " new",
  200. "multassign" => "*=",
  201. "divassign" => "/=",
  202. "div" => "/",
  203. "neg" => "-",
  204. "pos" => "+",
  205. "memref" => "->*",
  206. "compound" => ","
  207. );
  208. sub num_to_str($)
  209. {
  210. my $Number = $_[0];
  211. if(int($Number)>3)
  212. {
  213. return $Number."th";
  214. }
  215. elsif(int($Number)==1)
  216. {
  217. return "1st";
  218. }
  219. elsif(int($Number)==2)
  220. {
  221. return "2nd";
  222. }
  223. elsif(int($Number)==3)
  224. {
  225. return "3rd";
  226. }
  227. else
  228. {
  229. return "";
  230. }
  231. }
  232. #Global variables
  233. my $REPORT_PATH;
  234. my %ERR_PATH;
  235. my $POINTER_SIZE;
  236. my $MAX_COMMAND_LINE_ARGUMENTS = 4096;
  237. my %Cache;
  238. my %FuncAttr;
  239. my %LibInfo;
  240. my %HeaderCompileError;
  241. my $StartTime;
  242. my %CompilerOptions;
  243. my %AddedInt;
  244. my %WithdrawnInt;
  245. my @RecurLib;
  246. my %CheckedSoLib;
  247. #Constants checking
  248. my %ConstantsSrc;
  249. my %Constants;
  250. #Types
  251. my %TypeDescr;
  252. my %TemplateInstance_Func;
  253. my %TemplateInstance;
  254. my %OpaqueTypes;
  255. my %Tid_TDid;
  256. my %CheckedTypes;
  257. my %Typedef_BaseName;
  258. my %StdCxxTypedef;
  259. my %TName_Tid;
  260. my %EnumMembName_Id;
  261. #Interfaces
  262. my %FuncDescr;
  263. my %ClassFunc;
  264. my %ClassVirtFunc;
  265. my %ClassIdVirtFunc;
  266. my %ClassId;
  267. my %tr_name;
  268. my %mangled_name;
  269. my %InternalInterfaces;
  270. my %InterfacesList;
  271. my %InterfacesList_App;
  272. my %CheckedInterfaces;
  273. my %DepInterfaces;
  274. #Headers
  275. my %Include_Preamble;
  276. my %Headers;
  277. my %HeaderName_Destinations;
  278. my %Header_Dependency;
  279. #Shared objects
  280. my %SoLib_DefaultPath;
  281. #Merging
  282. my %CompleteSignature;
  283. my @RecurTypes;
  284. my %Interface_Library;
  285. my %Library_Interface;
  286. my %Language;
  287. my %SoNames_All;
  288. my $Version;
  289. #Symbols versioning
  290. my %SymVer;
  291. #Problem descriptions
  292. my %CompatProblems;
  293. my %ConstantProblems;
  294. #Rerorts
  295. my $ContentID = 1;
  296. my $ContentSpanStart = "<span class=\"section\" onclick=\"javascript:showContent(this, 'CONTENT_ID')\">\n";
  297. my $ContentSpanEnd = "</span>\n";
  298. my $ContentDivStart = "<div id=\"CONTENT_ID\" style=\"display:none;\">\n";
  299. my $ContentDivEnd = "</div>\n";
  300. my $Content_Counter = 0;
  301. sub readDescriptor($)
  302. {
  303. my $LibVersion = $_[0];
  304. if(not -e $Descriptor{$LibVersion}{"Path"})
  305. {
  306. return;
  307. }
  308. my $Descriptor_File = readFile($Descriptor{$LibVersion}{"Path"});
  309. $Descriptor_File =~ s/\/\*(.|\n)+?\*\///g;
  310. $Descriptor_File =~ s/<\!--(.|\n)+?-->//g;
  311. if(not $Descriptor_File)
  312. {
  313. print "ERROR: descriptor d$LibVersion is empty\n";
  314. exit(1);
  315. }
  316. $Descriptor{$LibVersion}{"Version"} = parseTag(\$Descriptor_File, "version");
  317. if(not $Descriptor{$LibVersion}{"Version"})
  318. {
  319. print "ERROR: version in the descriptor d$LibVersion was not specified (section <version>)\n\n";
  320. exit(1);
  321. }
  322. $Descriptor{$LibVersion}{"Headers"} = parseTag(\$Descriptor_File, "headers");
  323. if(not $Descriptor{$LibVersion}{"Headers"})
  324. {
  325. print "ERROR: header files in the descriptor d$LibVersion were not specified (section <headers>)\n";
  326. exit(1);
  327. }
  328. if(not $CheckHeadersOnly)
  329. {
  330. $Descriptor{$LibVersion}{"Libs"} = parseTag(\$Descriptor_File, "libs");
  331. if(not $Descriptor{$LibVersion}{"Libs"})
  332. {
  333. print "ERROR: shared objects in the descriptor d$LibVersion were not specified (section <libs>)\n";
  334. exit(1);
  335. }
  336. }
  337. $Descriptor{$LibVersion}{"Include_Paths"} = parseTag(\$Descriptor_File, "include_paths");
  338. $Descriptor{$LibVersion}{"Gcc_Options"} = parseTag(\$Descriptor_File, "gcc_options");
  339. foreach my $Option (split("\n", $Descriptor{$LibVersion}{"Gcc_Options"}))
  340. {
  341. $Option =~ s/\A\s+|\s+\Z//g;
  342. next if(not $Option);
  343. $CompilerOptions{$LibVersion} .= " ".$Option;
  344. }
  345. $Descriptor{$LibVersion}{"Opaque_Types"} = parseTag(\$Descriptor_File, "opaque_types");
  346. foreach my $Type_Name (split("\n", $Descriptor{$LibVersion}{"Opaque_Types"}))
  347. {
  348. $Type_Name =~ s/\A\s+|\s+\Z//g;
  349. next if(not $Type_Name);
  350. $OpaqueTypes{$LibVersion}{$Type_Name} = 1;
  351. }
  352. $Descriptor{$LibVersion}{"Skip_interfaces"} = parseTag(\$Descriptor_File, "skip_interfaces");
  353. foreach my $Interface_Name (split("\n", $Descriptor{$LibVersion}{"Skip_interfaces"}))
  354. {
  355. $Interface_Name =~ s/\A\s+|\s+\Z//g;
  356. next if(not $Interface_Name);
  357. $InternalInterfaces{$LibVersion}{$Interface_Name} = 1;
  358. }
  359. $Descriptor{$LibVersion}{"Include_Preamble"} = parseTag(\$Descriptor_File, "include_preamble");
  360. my $Position = 0;
  361. foreach my $Header_Name (split("\n", $Descriptor{$LibVersion}{"Include_Preamble"}))
  362. {
  363. $Header_Name =~ s/\A\s+|\s+\Z//g;
  364. next if(not $Header_Name);
  365. $Include_Preamble{$LibVersion}{$Header_Name}{"Position"} = $Position;
  366. $Position+=1;
  367. }
  368. my $Descriptors_Dir = "descriptors_storage/$TargetLibraryName";
  369. system("mkdir", "-p", $Descriptors_Dir);
  370. my $Descriptor_Name = $TargetLibraryName."_".$Descriptor{$LibVersion}{"Version"}.".desc";
  371. if($Descriptor{$LibVersion}{"Path"} ne $Descriptors_Dir."/".$Descriptor_Name)
  372. {
  373. system("cp", "-f", $Descriptor{$LibVersion}{"Path"}, $Descriptors_Dir."/".$Descriptor_Name);
  374. }
  375. $ERR_PATH{$LibVersion} = "header_compile_errors/$TargetLibraryName/".$Descriptor{$LibVersion}{"Version"};
  376. }
  377. sub parseTag($$)
  378. {
  379. my ($CodeRef, $Tag) = @_;
  380. return "" if(not $CodeRef or not ${$CodeRef} or not $Tag);
  381. if(${$CodeRef} =~ s/\<$Tag\>((.|\n)+?)\<\/$Tag\>//)
  382. {
  383. my $Content = $1;
  384. $Content=~s/(\A\s+|\s+\Z)//g;
  385. return $Content;
  386. }
  387. else
  388. {
  389. return "";
  390. }
  391. }
  392. my %check_node=(
  393. "array_type"=>1,
  394. "binfo"=>1,
  395. "boolean_type"=>1,
  396. "complex_type"=>1,
  397. "const_decl"=>1,
  398. "enumeral_type"=>1,
  399. "field_decl"=>1,
  400. "function_decl"=>1,
  401. "function_type"=>1,
  402. "identifier_node"=>1,
  403. "integer_cst"=>1,
  404. "integer_type"=>1,
  405. "method_type"=>1,
  406. "namespace_decl"=>1,
  407. "parm_decl"=>1,
  408. "pointer_type"=>1,
  409. "real_cst"=>1,
  410. "real_type"=>1,
  411. "record_type"=>1,
  412. "reference_type"=>1,
  413. "string_cst"=>1,
  414. "template_decl"=>1,
  415. "template_type_parm"=>1,
  416. "tree_list"=>1,
  417. "tree_vec"=>1,
  418. "type_decl"=>1,
  419. "union_type"=>1,
  420. "var_decl"=>1,
  421. "void_type"=>1);
  422. sub getInfo($)
  423. {
  424. my $InfoPath = $_[0];
  425. return if(not $InfoPath or not -f $InfoPath);
  426. my $InfoPath_New = $InfoPath.".1";
  427. #my $Keywords = join("\\|", keys(%check_node));#|grep "$Keywords"
  428. system("sed ':a;N;\$!ba;s/\\n[^\@]//g' ".esc($InfoPath)."|sed 's/ [ ]\\+/ /g' > ".esc($InfoPath_New));
  429. system("rm", "-fr", $InfoPath);
  430. #getting info
  431. open(INFO, $InfoPath_New) || die ("can't open file '\$InfoPath_New\': $!\n");
  432. while(<INFO>)
  433. {
  434. chomp;
  435. if(/\A@([0-9]+)[ ]+([a-zA-Z_]+)[ ]+(.*)\Z/)
  436. {
  437. next if(not $check_node{$2});
  438. $LibInfo{$Version}{$1}{"info_type"}=$2;
  439. $LibInfo{$Version}{$1}{"info"}=$3;
  440. }
  441. }
  442. close(INFO);
  443. system("rm", "-fr", $InfoPath_New);
  444. #processing info
  445. setTemplateParams_All();
  446. getTypeDescr_All();
  447. getFuncDescr_All();
  448. getVarDescr_All();
  449. %LibInfo = ();
  450. %TemplateInstance = ();
  451. }
  452. sub setTemplateParams_All()
  453. {
  454. foreach (keys(%{$LibInfo{$Version}}))
  455. {
  456. if($LibInfo{$Version}{$_}{"info_type"} eq "template_decl")
  457. {
  458. setTemplateParams($_);
  459. }
  460. }
  461. }
  462. sub setTemplateParams($)
  463. {
  464. my $TypeInfoId = $_[0];
  465. my $Info = $LibInfo{$Version}{$TypeInfoId}{"info"};
  466. if($Info =~ /(inst|spcs)[ ]*:[ ]*@([0-9]+) /)
  467. {
  468. my $TmplInst_InfoId = $2;
  469. setTemplateInstParams($TmplInst_InfoId);
  470. my $TmplInst_Info = $LibInfo{$Version}{$TmplInst_InfoId}{"info"};
  471. while($TmplInst_Info =~ /chan[ ]*:[ ]*@([0-9]+) /)
  472. {
  473. $TmplInst_InfoId = $1;
  474. $TmplInst_Info = $LibInfo{$Version}{$TmplInst_InfoId}{"info"};
  475. setTemplateInstParams($TmplInst_InfoId);
  476. }
  477. }
  478. }
  479. sub setTemplateInstParams($)
  480. {
  481. my $TmplInst_Id = $_[0];
  482. my $Info = $LibInfo{$Version}{$TmplInst_Id}{"info"};
  483. my ($Params_InfoId, $ElemId) = ();
  484. if($Info =~ /purp[ ]*:[ ]*@([0-9]+) /)
  485. {
  486. $Params_InfoId = $1;
  487. }
  488. if($Info =~ /valu[ ]*:[ ]*@([0-9]+) /)
  489. {
  490. $ElemId = $1;
  491. }
  492. if($Params_InfoId and $ElemId)
  493. {
  494. my $Params_Info = $LibInfo{$Version}{$Params_InfoId}{"info"};
  495. while($Params_Info =~ s/ ([0-9]+)[ ]*:[ ]*@([0-9]+) //)
  496. {
  497. my ($Param_Pos, $Param_TypeId) = ($1, $2);
  498. return if($LibInfo{$Version}{$Param_TypeId}{"info_type"} eq "template_type_parm");
  499. if($LibInfo{$ElemId}{"info_type"} eq "function_decl")
  500. {
  501. $TemplateInstance_Func{$Version}{$ElemId}{$Param_Pos} = $Param_TypeId;
  502. }
  503. else
  504. {
  505. $TemplateInstance{$Version}{getTypeDeclId($ElemId)}{$ElemId}{$Param_Pos} = $Param_TypeId;
  506. }
  507. }
  508. }
  509. }
  510. sub getTypeDeclId($)
  511. {
  512. my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
  513. if($TypeInfo =~ /name[ ]*:[ ]*@([0-9]+)/)
  514. {
  515. return $1;
  516. }
  517. else
  518. {
  519. return "";
  520. }
  521. }
  522. sub isFuncPtr($)
  523. {
  524. my $Ptd = pointTo($_[0]);
  525. if($Ptd)
  526. {
  527. if(($LibInfo{$Version}{$_[0]}{"info"} =~ m/unql[ ]*:/) and not ($LibInfo{$Version}{$_[0]}{"info"} =~ m/qual[ ]*:/))
  528. {
  529. return 0;
  530. }
  531. elsif(($LibInfo{$Version}{$_[0]}{"info_type"} eq "pointer_type") and ($LibInfo{$Version}{$Ptd}{"info_type"} eq "function_type" or $LibInfo{$Version}{$Ptd}{"info_type"} eq "method_type"))
  532. {
  533. return 1;
  534. }
  535. else
  536. {
  537. return 0;
  538. }
  539. }
  540. else
  541. {
  542. return 0;
  543. }
  544. }
  545. sub pointTo($)
  546. {
  547. my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
  548. if($TypeInfo =~ /ptd[ ]*:[ ]*@([0-9]+)/)
  549. {
  550. return $1;
  551. }
  552. else
  553. {
  554. return "";
  555. }
  556. }
  557. sub getTypeDescr_All()
  558. {
  559. foreach (sort {int($a)<=>int($b)} keys(%{$LibInfo{$Version}}))
  560. {
  561. if($LibInfo{$Version}{$_}{"info_type"}=~/_type\Z/ and $LibInfo{$Version}{$_}{"info_type"}!~/function_type|method_type/)
  562. {
  563. getTypeDescr(getTypeDeclId($_), $_);
  564. }
  565. }
  566. $TypeDescr{$Version}{""}{-1}{"Name"} = "...";
  567. $TypeDescr{$Version}{""}{-1}{"Type"} = "Intrinsic";
  568. $TypeDescr{$Version}{""}{-1}{"Tid"} = -1;
  569. }
  570. sub getTypeDescr($$)
  571. {
  572. my ($TypeDeclId, $TypeId) = @_;
  573. $Tid_TDid{$Version}{$TypeId} = $TypeDeclId;
  574. %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = getTypeAttr($TypeDeclId, $TypeId);
  575. if(not $TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"})
  576. {
  577. delete($TypeDescr{$Version}{$TypeDeclId}{$TypeId});
  578. return;
  579. }
  580. if(not $TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}})
  581. {
  582. $TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}} = $TypeId;
  583. }
  584. }
  585. sub getTypeAttr($$)
  586. {
  587. my ($TypeDeclId, $TypeId) = @_;
  588. my ($BaseTypeSpec, %TypeAttr) = ();
  589. if($TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"})
  590. {
  591. return %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}};
  592. }
  593. $TypeAttr{"Tid"} = $TypeId;
  594. $TypeAttr{"TDid"} = $TypeDeclId;
  595. $TypeAttr{"Type"} = getTypeType($TypeDeclId, $TypeId);
  596. if($TypeAttr{"Type"} eq "Unknown")
  597. {
  598. return ();
  599. }
  600. elsif($TypeAttr{"Type"} eq "FuncPtr")
  601. {
  602. %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = getFuncPtrAttr(pointTo($TypeId), $TypeDeclId, $TypeId);
  603. $TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}} = $TypeId;
  604. return %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}};
  605. }
  606. elsif($TypeAttr{"Type"} eq "Array")
  607. {
  608. ($TypeAttr{"BaseType"}{"Tid"}, $TypeAttr{"BaseType"}{"TDid"}, $BaseTypeSpec) = selectBaseType($TypeDeclId, $TypeId);
  609. my %BaseTypeAttr = getTypeAttr($TypeAttr{"BaseType"}{"TDid"}, $TypeAttr{"BaseType"}{"Tid"});
  610. my $ArrayElemNum = getSize($TypeId)/8;
  611. $ArrayElemNum = $ArrayElemNum/$BaseTypeAttr{"Size"} if($BaseTypeAttr{"Size"});
  612. $TypeAttr{"Size"} = $ArrayElemNum;
  613. if($ArrayElemNum)
  614. {
  615. $TypeAttr{"Name"} = $BaseTypeAttr{"Name"}."[".$ArrayElemNum."]";
  616. }
  617. else
  618. {
  619. $TypeAttr{"Name"} = $BaseTypeAttr{"Name"}."[]";
  620. }
  621. $TypeAttr{"Name"} = correctName($TypeAttr{"Name"});
  622. $TypeAttr{"Library"} = $BaseTypeAttr{"Library"};
  623. $TypeAttr{"Header"} = $BaseTypeAttr{"Header"};
  624. %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = %TypeAttr;
  625. $TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}} = $TypeId;
  626. return %TypeAttr;
  627. }
  628. elsif($TypeAttr{"Type"} =~ /Intrinsic|Union|Struct|Enum|Class/)
  629. {
  630. if($TemplateInstance{$Version}{$TypeDeclId}{$TypeId})
  631. {
  632. my @Template_Params = ();
  633. foreach my $Param_Pos (sort {int($a)<=>int($b)} keys(%{$TemplateInstance{$Version}{$TypeDeclId}{$TypeId}}))
  634. {
  635. my $Type_Id = $TemplateInstance{$Version}{$TypeDeclId}{$TypeId}{$Param_Pos};
  636. my $Param = get_TemplateParam($Type_Id);
  637. if($Param eq "")
  638. {
  639. return ();
  640. }
  641. @Template_Params = (@Template_Params, $Param);
  642. }
  643. %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = getTrivialTypeAttr($TypeDeclId, $TypeId);
  644. $TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"} = $TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}."< ".join(", ", @Template_Params)." >";
  645. $TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"} = correctName($TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"});
  646. $TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}} = $TypeId;
  647. return %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}};
  648. }
  649. else
  650. {
  651. %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = getTrivialTypeAttr($TypeDeclId, $TypeId);
  652. return %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}};
  653. }
  654. }
  655. else
  656. {
  657. ($TypeAttr{"BaseType"}{"Tid"}, $TypeAttr{"BaseType"}{"TDid"}, $BaseTypeSpec) = selectBaseType($TypeDeclId, $TypeId);
  658. my %BaseTypeAttr = getTypeAttr($TypeAttr{"BaseType"}{"TDid"}, $TypeAttr{"BaseType"}{"Tid"});
  659. if($BaseTypeSpec and $BaseTypeAttr{"Name"})
  660. {
  661. if(($TypeAttr{"Type"} eq "Pointer") and $BaseTypeAttr{"Name"}=~/\([\*]+\)/)
  662. {
  663. $TypeAttr{"Name"} = $BaseTypeAttr{"Name"};
  664. $TypeAttr{"Name"} =~ s/\(([*]+)\)/($1*)/g;
  665. }
  666. else
  667. {
  668. $TypeAttr{"Name"} = $BaseTypeAttr{"Name"}." ".$BaseTypeSpec;
  669. }
  670. }
  671. elsif($BaseTypeAttr{"Name"})
  672. {
  673. $TypeAttr{"Name"} = $BaseTypeAttr{"Name"};
  674. }
  675. if($TypeAttr{"Type"} eq "Typedef")
  676. {
  677. $TypeAttr{"Name"} = getNameByInfo($TypeDeclId);
  678. $TypeAttr{"NameSpace"} = getNameSpace($TypeDeclId);
  679. if($TypeAttr{"NameSpace"})
  680. {
  681. $TypeAttr{"Name"} = $TypeAttr{"NameSpace"}."::".$TypeAttr{"Name"};
  682. }
  683. ($TypeAttr{"Header"}, $TypeAttr{"Line"}) = getLocation($TypeDeclId);
  684. if($TypeAttr{"NameSpace"}=~/\Astd(::|\Z)/ and $BaseTypeAttr{"NameSpace"}=~/\Astd(::|\Z)/)
  685. {
  686. $StdCxxTypedef{$Version}{$BaseTypeAttr{"Name"}} = $TypeAttr{"Name"};
  687. }
  688. $Typedef_BaseName{$Version}{$TypeAttr{"Name"}} = $BaseTypeAttr{"Name"};
  689. }
  690. if(not $TypeAttr{"Size"})
  691. {
  692. if($TypeAttr{"Type"} eq "Pointer")
  693. {
  694. $TypeAttr{"Size"} = $POINTER_SIZE;
  695. }
  696. else
  697. {
  698. $TypeAttr{"Size"} = $BaseTypeAttr{"Size"};
  699. }
  700. }
  701. $TypeAttr{"Name"} = correctName($TypeAttr{"Name"});
  702. $TypeAttr{"Library"} = $BaseTypeAttr{"Library"};
  703. $TypeAttr{"Header"} = $BaseTypeAttr{"Header"} if(not $TypeAttr{"Header"});
  704. %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = %TypeAttr;
  705. $TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}} = $TypeId;
  706. return %TypeAttr;
  707. }
  708. }
  709. sub get_TemplateParam($)
  710. {
  711. my $Type_Id = $_[0];
  712. if(getNodeType($Type_Id) eq "integer_cst")
  713. {
  714. return getNodeIntCst($Type_Id);
  715. }
  716. elsif(getNodeType($Type_Id) eq "string_cst")
  717. {
  718. return getNodeStrCst($Type_Id);
  719. }
  720. else
  721. {
  722. my $Type_DId = getTypeDeclId($Type_Id);
  723. my %ParamAttr = getTypeAttr($Type_DId, $Type_Id);
  724. if(not $ParamAttr{"Name"})
  725. {
  726. return "";
  727. }
  728. if($ParamAttr{"Name"}=~/\>/)
  729. {
  730. if($StdCxxTypedef{$Version}{$ParamAttr{"Name"}})
  731. {
  732. return $StdCxxTypedef{$Version}{$ParamAttr{"Name"}};
  733. }
  734. elsif(my $Covered = cover_stdcxx_typedef($ParamAttr{"Name"}))
  735. {
  736. return $Covered;
  737. }
  738. else
  739. {
  740. return $ParamAttr{"Name"};
  741. }
  742. }
  743. else
  744. {
  745. return $ParamAttr{"Name"};
  746. }
  747. }
  748. }
  749. sub cover_stdcxx_typedef($)
  750. {
  751. my $TypeName = $_[0];
  752. my $TypeName_Covered = $TypeName;
  753. while($TypeName=~s/>[ ]*(const|volatile|restrict| |\*|\&)\Z/>/g){};
  754. if(my $Cover = $StdCxxTypedef{$Version}{$TypeName})
  755. {
  756. $TypeName = esc_l($TypeName);
  757. $TypeName_Covered=~s/$TypeName/$Cover /g;
  758. }
  759. return correctName($TypeName_Covered);
  760. }
  761. sub getNodeType($)
  762. {
  763. return $LibInfo{$Version}{$_[0]}{"info_type"};
  764. }
  765. sub getNodeIntCst($)
  766. {
  767. my $CstId = $_[0];
  768. my $CstTypeId = getTreeAttr($CstId, "type");
  769. if($EnumMembName_Id{$Version}{$CstId})
  770. {
  771. return $EnumMembName_Id{$Version}{$CstId};
  772. }
  773. elsif($LibInfo{$Version}{$_[0]}{"info"} =~ /low[ ]*:[ ]*([^ ]+) /)
  774. {
  775. if($1 eq "0")
  776. {
  777. if(getNodeType($CstTypeId) eq "boolean_type")
  778. {
  779. return "false";
  780. }
  781. else
  782. {
  783. return "0";
  784. }
  785. }
  786. elsif($1 eq "1")
  787. {
  788. if(getNodeType($CstTypeId) eq "boolean_type")
  789. {
  790. return "true";
  791. }
  792. else
  793. {
  794. return "1";
  795. }
  796. }
  797. else
  798. {
  799. return $1;
  800. }
  801. }
  802. else
  803. {
  804. return "";
  805. }
  806. }
  807. sub getNodeStrCst($)
  808. {
  809. if($LibInfo{$Version}{$_[0]}{"info"} =~ /low[ ]*:[ ]*(.+)[ ]+lngt/)
  810. {
  811. return $1;
  812. }
  813. else
  814. {
  815. return "";
  816. }
  817. }
  818. sub esc_l($)
  819. {
  820. my $String = $_[0];
  821. $String=~s/([()*])/\\$1/g;
  822. return $String;
  823. }
  824. sub getFuncPtrAttr($$$)
  825. {
  826. my ($FuncTypeId, $TypeDeclId, $TypeId) = @_;
  827. my $FuncInfo = $LibInfo{$Version}{$FuncTypeId}{"info"};
  828. my $FuncInfo_Type = $LibInfo{$Version}{$FuncTypeId}{"info_type"};
  829. my $FuncPtrCorrectName = "";
  830. my %TypeAttr = ("Size"=>$POINTER_SIZE, "Type"=>"FuncPtr", "TDid"=>$TypeDeclId, "Tid"=>$TypeId);
  831. my @ParamTypeName;
  832. if($FuncInfo =~ /retn[ ]*:[ ]*\@([0-9]+) /)
  833. {
  834. my $ReturnTypeId = $1;
  835. my %ReturnAttr = getTypeAttr(getTypeDeclId($ReturnTypeId), $ReturnTypeId);
  836. $FuncPtrCorrectName .= $ReturnAttr{"Name"};
  837. $TypeAttr{"Return"} = $ReturnTypeId;
  838. }
  839. if($FuncInfo =~ /prms[ ]*:[ ]*@([0-9]+) /)
  840. {
  841. my $ParamTypeInfoId = $1;
  842. my $Position = 0;
  843. while($ParamTypeInfoId)
  844. {
  845. my $ParamTypeInfo = $LibInfo{$Version}{$ParamTypeInfoId}{"info"};
  846. last if($ParamTypeInfo !~ /valu[ ]*:[ ]*@([0-9]+) /);
  847. my $ParamTypeId = $1;
  848. my %ParamAttr = getTypeAttr(getTypeDeclId($ParamTypeId), $ParamTypeId);
  849. last if($ParamAttr{"Name"} eq "void");
  850. $TypeAttr{"Memb"}{$Position}{"type"} = $ParamTypeId;
  851. push(@ParamTypeName, $ParamAttr{"Name"});
  852. last if($ParamTypeInfo !~ /chan[ ]*:[ ]*@([0-9]+) /);
  853. $ParamTypeInfoId = $1;
  854. $Position+=1;
  855. }
  856. }
  857. if($FuncInfo_Type eq "function_type")
  858. {
  859. $FuncPtrCorrectName .= " (*) (".join(", ", @ParamTypeName).")";
  860. }
  861. elsif($FuncInfo_Type eq "method_type")
  862. {
  863. if($FuncInfo =~ /clas[ ]*:[ ]*@([0-9]+) /)
  864. {
  865. my $ClassId = $1;
  866. my $ClassName = $TypeDescr{$Version}{getTypeDeclId($ClassId)}{$ClassId}{"Name"};
  867. if($ClassName)
  868. {
  869. $FuncPtrCorrectName .= " ($ClassName\:\:*) (".join(", ", @ParamTypeName).")";
  870. }
  871. else
  872. {
  873. $FuncPtrCorrectName .= " (*) (".join(", ", @ParamTypeName).")";
  874. }
  875. }
  876. else
  877. {
  878. $FuncPtrCorrectName .= " (*) (".join(", ", @ParamTypeName).")";
  879. }
  880. }
  881. $TypeAttr{"Name"} = correctName($FuncPtrCorrectName);
  882. return %TypeAttr;
  883. }
  884. sub getTypeName($)
  885. {
  886. my $Info = $LibInfo{$Version}{$_[0]}{"info"};
  887. if($Info =~ /name[ ]*:[ ]*@([0-9]+) /)
  888. {
  889. return getNameByInfo($1);
  890. }
  891. else
  892. {
  893. if($LibInfo{$Version}{$_[0]}{"info_type"} eq "integer_type")
  894. {
  895. if($LibInfo{$Version}{$_[0]}{"info"} =~ /unsigned/)
  896. {
  897. return "unsigned int";
  898. }
  899. else
  900. {
  901. return "int";
  902. }
  903. }
  904. else
  905. {
  906. return "";
  907. }
  908. }
  909. }
  910. sub selectBaseType($$)
  911. {
  912. my ($TypeDeclId, $TypeId) = @_;
  913. my $TypeInfo = $LibInfo{$Version}{$TypeId}{"info"};
  914. my $BaseTypeDeclId;
  915. my $Type_Type = getTypeType($TypeDeclId, $TypeId);
  916. #qualifications
  917. if(($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*c /) and ($LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@([0-9]+) /))
  918. {
  919. return ($1, getTypeDeclId($1), "const");
  920. }
  921. elsif(($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*r /) and ($LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@([0-9]+) /))
  922. {
  923. return ($1, getTypeDeclId($1), "restrict");
  924. }
  925. elsif(($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*v /) and ($LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@([0-9]+) /))
  926. {
  927. return ($1, getTypeDeclId($1), "volatile");
  928. }
  929. elsif((not ($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:/)) and ($LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@([0-9]+) /))
  930. {#typedefs
  931. return ($1, getTypeDeclId($1), "");
  932. }
  933. elsif($LibInfo{$Version}{$TypeId}{"info_type"} eq "reference_type")
  934. {
  935. if($TypeInfo =~ /refd[ ]*:[ ]*@([0-9]+) /)
  936. {
  937. return ($1, getTypeDeclId($1), "&");
  938. }
  939. else
  940. {
  941. return (0, 0, "");
  942. }
  943. }
  944. elsif($LibInfo{$Version}{$TypeId}{"info_type"} eq "array_type")
  945. {
  946. if($TypeInfo =~ /elts[ ]*:[ ]*@([0-9]+) /)
  947. {
  948. return ($1, getTypeDeclId($1), "");
  949. }
  950. else
  951. {
  952. return (0, 0, "");
  953. }
  954. }
  955. elsif($LibInfo{$Version}{$TypeId}{"info_type"} eq "pointer_type")
  956. {
  957. if($TypeInfo =~ /ptd[ ]*:[ ]*@([0-9]+) /)
  958. {
  959. return ($1, getTypeDeclId($1), "*");
  960. }
  961. else
  962. {
  963. return (0, 0, "");
  964. }
  965. }
  966. else
  967. {
  968. return (0, 0, "");
  969. }
  970. }
  971. sub getFuncDescr_All()
  972. {
  973. foreach (sort {int($b)<=>int($a)} keys(%{$LibInfo{$Version}}))
  974. {
  975. if($LibInfo{$Version}{$_}{"info_type"} eq "function_decl")
  976. {
  977. getFuncDescr($_);
  978. }
  979. }
  980. }
  981. sub getVarDescr_All()
  982. {
  983. foreach (sort {int($b)<=>int($a)} keys(%{$LibInfo{$Version}}))
  984. {
  985. if($LibInfo{$Version}{$_}{"info_type"} eq "var_decl")
  986. {
  987. getVarDescr($_);
  988. }
  989. }
  990. }
  991. sub getVarDescr($)
  992. {
  993. my $FuncInfoId = $_[0];
  994. if($LibInfo{$Version}{getNameSpaceId($FuncInfoId)}{"info_type"} eq "function_decl")
  995. {
  996. return;
  997. }
  998. ($FuncDescr{$Version}{$FuncInfoId}{"Header"}, $FuncDescr{$Version}{$FuncInfoId}{"Line"}) = getLocation($FuncInfoId);
  999. if((not $FuncDescr{$Version}{$FuncInfoId}{"Header"}) or ($FuncDescr{$Version}{$FuncInfoId}{"Header"}=~/\<built\-in\>|\<internal\>/))
  1000. {
  1001. delete($FuncDescr{$Version}{$FuncInfoId});
  1002. return;
  1003. }
  1004. $FuncDescr{$Version}{$FuncInfoId}{"ShortName"} = getNameByInfo($FuncInfoId);
  1005. $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} = getFuncMnglName($FuncInfoId);
  1006. if($FuncDescr{$Version}{$FuncInfoId}{"MnglName"} and $FuncDescr{$Version}{$FuncInfoId}{"MnglName"}!~/\A_Z/)
  1007. {
  1008. delete($FuncDescr{$Version}{$FuncInfoId});
  1009. return;
  1010. }
  1011. if(not $FuncDescr{$Version}{$FuncInfoId}{"MnglName"})
  1012. {
  1013. $FuncDescr{$Version}{$FuncInfoId}{"Name"} = $FuncDescr{$Version}{$FuncInfoId}{"ShortName"};
  1014. $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} = $FuncDescr{$Version}{$FuncInfoId}{"ShortName"};
  1015. }
  1016. if(not is_in_library($FuncDescr{$Version}{$FuncInfoId}{"MnglName"}, $Version) and not $CheckHeadersOnly)
  1017. {
  1018. delete $FuncDescr{$Version}{$FuncInfoId};
  1019. return;
  1020. }
  1021. $FuncDescr{$Version}{$FuncInfoId}{"Return"} = getTypeId($FuncInfoId);
  1022. delete($FuncDescr{$Version}{$FuncInfoId}{"Return"}) if(not $FuncDescr{$Version}{$FuncInfoId}{"Return"});
  1023. $FuncDescr{$Version}{$FuncInfoId}{"Data"} = 1;
  1024. set_Class_And_Namespace($FuncInfoId);
  1025. setFuncAccess($FuncInfoId);
  1026. if($FuncDescr{$Version}{$FuncInfoId}{"MnglName"} =~ /\A_ZTV/)
  1027. {
  1028. delete($FuncDescr{$Version}{$FuncInfoId}{"Return"});
  1029. }
  1030. if($FuncDescr{$Version}{$FuncInfoId}{"ShortName"} =~ /\A_Z/)
  1031. {
  1032. delete($FuncDescr{$Version}{$FuncInfoId}{"ShortName"});
  1033. }
  1034. }
  1035. sub getTrivialTypeAttr($$)
  1036. {
  1037. my ($TypeInfoId, $TypeId) = @_;
  1038. my %TypeAttr = ();
  1039. return if(getTypeTypeByTypeId($TypeId)!~/Intrinsic|Union|Struct|Enum/);
  1040. setTypeAccess($TypeId, \%TypeAttr);
  1041. ($TypeAttr{"Header"}, $TypeAttr{"Line"}) = getLocation($TypeInfoId);
  1042. if(($TypeAttr{"Header"} eq "<built-in>") or ($TypeAttr{"Header"} eq "<internal>"))
  1043. {
  1044. delete($TypeAttr{"Header"});
  1045. }
  1046. $TypeAttr{"Name"} = getNameByInfo($TypeInfoId);
  1047. $TypeAttr{"Name"} = getTypeName($TypeId) if(not $TypeAttr{"Name"});
  1048. my $NameSpaceId = getNameSpaceId($TypeInfoId);
  1049. if($NameSpaceId ne $TypeId)
  1050. {
  1051. $TypeAttr{"NameSpace"} = getNameSpace($TypeInfoId);
  1052. }
  1053. if($TypeAttr{"NameSpace"} and isNotAnon($TypeAttr{"Name"}))
  1054. {
  1055. $TypeAttr{"Name"} = $TypeAttr{"NameSpace"}."::".$TypeAttr{"Name"};
  1056. }
  1057. $TypeAttr{"Name"} = correctName($TypeAttr{"Name"});
  1058. if(isAnon($TypeAttr{"Name"}))
  1059. {
  1060. $TypeAttr{"Name"} = "anon-";
  1061. $TypeAttr{"Name"} .= $TypeAttr{"Header"}."-".$TypeAttr{"Line"};
  1062. }
  1063. $TypeAttr{"Size"} = getSize($TypeId)/8;
  1064. $TypeAttr{"Type"} = getTypeType($TypeInfoId, $TypeId);
  1065. if($TypeAttr{"Type"} eq "Struct" and has_methods($TypeId))
  1066. {
  1067. $TypeAttr{"Type"} = "Class";
  1068. }
  1069. if(($TypeAttr{"Type"} eq "Struct") or ($TypeAttr{"Type"} eq "Class"))
  1070. {
  1071. setBaseClasses($TypeInfoId, $TypeId, \%TypeAttr);
  1072. }
  1073. setTypeMemb($TypeInfoId, $TypeId, \%TypeAttr);
  1074. $TypeAttr{"Tid"} = $TypeId;
  1075. $TypeAttr{"TDid"} = $TypeInfoId;
  1076. $Tid_TDid{$Version}{$TypeId} = $TypeInfoId;
  1077. if(not $TName_Tid{$Version}{$TypeAttr{"Name"}})
  1078. {
  1079. $TName_Tid{$Version}{$TypeAttr{"Name"}} = $TypeId;
  1080. }
  1081. return %TypeAttr;
  1082. }
  1083. sub has_methods($)
  1084. {
  1085. my $TypeId = $_[0];
  1086. my $Info = $LibInfo{$Version}{$TypeId}{"info"};
  1087. return ($Info=~/(fncs)[ ]*:[ ]*@([0-9]+) /);
  1088. }
  1089. sub setBaseClasses($$$)
  1090. {
  1091. my ($TypeInfoId, $TypeId, $TypeAttr) = @_;
  1092. my $Info = $LibInfo{$Version}{$TypeId}{"info"};
  1093. if($Info =~ /binf[ ]*:[ ]*@([0-9]+) /)
  1094. {
  1095. $Info = $LibInfo{$Version}{$1}{"info"};
  1096. while($Info =~ /accs[ ]*:[ ]*([a-z]+) /)
  1097. {
  1098. last if($Info !~ s/accs[ ]*:[ ]*([a-z]+) //);
  1099. my $Access = $1;
  1100. last if($Info !~ s/binf[ ]*:[ ]*@([0-9]+) //);
  1101. my $BInfoId = $1;
  1102. my $ClassId = getBinfClassId($BInfoId);
  1103. if($Access eq "pub")
  1104. {
  1105. $TypeAttr->{"BaseClass"}{$ClassId} = "public";
  1106. }
  1107. elsif($Access eq "prot")
  1108. {
  1109. $TypeAttr->{"BaseClass"}{$ClassId} = "protected";
  1110. }
  1111. elsif($Access eq "priv")
  1112. {
  1113. $TypeAttr->{"BaseClass"}{$ClassId} = "private";
  1114. }
  1115. else
  1116. {
  1117. $TypeAttr->{"BaseClass"}{$ClassId} = "private";
  1118. }
  1119. }
  1120. }
  1121. }
  1122. sub getBinfClassId($)
  1123. {
  1124. my $Info = $LibInfo{$Version}{$_[0]}{"info"};
  1125. $Info =~ /type[ ]*:[ ]*@([0-9]+) /;
  1126. return $1;
  1127. }
  1128. sub get_func_signature($)
  1129. {
  1130. my $FuncInfoId = $_[0];
  1131. my $PureSignature = $FuncDescr{$Version}{$FuncInfoId}{"ShortName"};
  1132. my @ParamTypes = ();
  1133. foreach my $ParamPos (sort {int($a) <=> int($b)} keys(%{$FuncDescr{$Version}{$FuncInfoId}{"Param"}}))
  1134. {#checking parameters
  1135. my $ParamType_Id = $FuncDescr{$Version}{$FuncInfoId}{"Param"}{$ParamPos}{"type"};
  1136. my $ParamType_Name = uncover_typedefs($TypeDescr{$Version}{getTypeDeclId($ParamType_Id)}{$ParamType_Id}{"Name"});
  1137. @ParamTypes = (@ParamTypes, $ParamType_Name);
  1138. }
  1139. $PureSignature = $PureSignature."(".join(", ", @ParamTypes).")";
  1140. $PureSignature = delete_keywords($PureSignature);
  1141. return correctName($PureSignature);
  1142. }
  1143. sub delete_keywords($)
  1144. {
  1145. my $TypeName = $_[0];
  1146. $TypeName =~ s/(\W|\A)(enum |struct |union |class )/$1/g;
  1147. return $TypeName;
  1148. }
  1149. sub uncover_typedefs($)
  1150. {
  1151. my $TypeName = $_[0];
  1152. return "" if(not $TypeName);
  1153. return $Cache{"uncover_typedefs"}{$Version}{$TypeName} if(defined $Cache{"uncover_typedefs"}{$Version}{$TypeName});
  1154. my ($TypeName_New, $TypeName_Pre) = (correctName($TypeName), "");
  1155. while($TypeName_New ne $TypeName_Pre)
  1156. {
  1157. $TypeName_Pre = $TypeName_New;
  1158. my $TypeName_Copy = $TypeName_New;
  1159. my %Words = ();
  1160. while($TypeName_Copy=~s/(\W|\A)([a-z_][\w:]*)(\W|\Z)//io)
  1161. {
  1162. my $Word = $2;
  1163. next if(not $Word or $Word=~/\A(true|false|const|int|long|void|short|float|unsigned|char|double|class|struct|union|enum)\Z/);
  1164. $Words{$Word} = 1;
  1165. }
  1166. foreach my $Word (keys(%Words))
  1167. {
  1168. my $BaseType_Name = $Typedef_BaseName{$Version}{$Word};
  1169. next if($TypeName_New=~/(\W|\A)(struct $Word|union $Word|enum $Word)(\W|\Z)/);
  1170. next if(not $BaseType_Name);
  1171. if($BaseType_Name=~/\([*]+\)/)
  1172. {
  1173. $TypeName_New =~ /$Word(.*)\Z/;
  1174. my $Type_Suffix = $1;
  1175. $TypeName_New = $BaseType_Name;
  1176. if($TypeName_New =~ s/\(([*]+)\)/($1 $Type_Suffix)/)
  1177. {
  1178. $TypeName_New = correctName($TypeName_New);
  1179. }
  1180. }
  1181. else
  1182. {
  1183. if($TypeName_New =~ s/(\W|\A)$Word(\W|\Z)/$1$BaseType_Name$2/g)
  1184. {
  1185. $TypeName_New = correctName($TypeName_New);
  1186. }
  1187. }
  1188. }
  1189. }
  1190. $Cache{"uncover_typedefs"}{$Version}{$TypeName} = $TypeName_New;
  1191. return $TypeName_New;
  1192. }
  1193. sub isInternal($)
  1194. {
  1195. my $FuncInfoId = $_[0];
  1196. my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
  1197. return 0 if($FuncInfo !~ /mngl[ ]*:[ ]*@([0-9]+) /);
  1198. my $FuncMnglNameInfoId = $1;
  1199. return ($LibInfo{$Version}{$FuncMnglNameInfoId}{"info"} =~ /\*[ ]*INTERNAL[ ]*\*/);
  1200. }
  1201. sub set_Class_And_Namespace($)
  1202. {
  1203. my $FuncInfoId = $_[0];
  1204. my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
  1205. if($FuncInfo =~ /scpe[ ]*:[ ]*@([0-9]+) /)
  1206. {
  1207. my $NameSpaceInfoId = $1;
  1208. if($LibInfo{$Version}{$NameSpaceInfoId}{"info_type"} eq "namespace_decl")
  1209. {
  1210. my $NameSpaceInfo = $LibInfo{$Version}{$NameSpaceInfoId}{"info"};
  1211. if($NameSpaceInfo =~ /name[ ]*:[ ]*@([0-9]+) /)
  1212. {
  1213. my $NameSpaceId = $1;
  1214. my $NameSpaceIdentifier = $LibInfo{$Version}{$NameSpaceId}{"info"};
  1215. if($NameSpaceIdentifier =~ /strg[ ]*:[ ]*(.*)[ ]+lngt/)
  1216. {
  1217. my $NameSpace = $1;
  1218. $NameSpace =~ s/[ ]+\Z//g;
  1219. $FuncDescr{$Version}{$FuncInfoId}{"NameSpace"} = $NameSpace;
  1220. }
  1221. }
  1222. }
  1223. elsif($LibInfo{$Version}{$NameSpaceInfoId}{"info_type"} eq "record_type")
  1224. {
  1225. $FuncDescr{$Version}{$FuncInfoId}{"Class"} = $NameSpaceInfoId;
  1226. }
  1227. }
  1228. }
  1229. sub getFuncDescr($)
  1230. {
  1231. my $FuncInfoId = $_[0];
  1232. return if(isInternal($FuncInfoId));
  1233. ($FuncDescr{$Version}{$FuncInfoId}{"Header"}, $FuncDescr{$Version}{$FuncInfoId}{"Line"}) = getLocation($FuncInfoId);
  1234. if(not $FuncDescr{$Version}{$FuncInfoId}{"Header"} or $FuncDescr{$Version}{$FuncInfoId}{"Header"}=~/\<built\-in\>|\<internal\>/)
  1235. {
  1236. delete($FuncDescr{$Version}{$FuncInfoId});
  1237. return;
  1238. }
  1239. setFuncAccess($FuncInfoId);
  1240. setFuncKind($FuncInfoId);
  1241. if($FuncDescr{$Version}{$FuncInfoId}{"PseudoTemplate"})
  1242. {
  1243. delete($FuncDescr{$Version}{$FuncInfoId});
  1244. return;
  1245. }
  1246. $FuncDescr{$Version}{$FuncInfoId}{"Type"} = getFuncType($FuncInfoId);
  1247. $FuncDescr{$Version}{$FuncInfoId}{"Return"} = getFuncReturn($FuncInfoId);
  1248. delete($FuncDescr{$Version}{$FuncInfoId}{"Return"}) if(not $FuncDescr{$Version}{$FuncInfoId}{"Return"});
  1249. $FuncDescr{$Version}{$FuncInfoId}{"ShortName"} = getFuncShortName(getFuncOrig($FuncInfoId));
  1250. if($FuncDescr{$Version}{$FuncInfoId}{"ShortName"} =~ /\._/)
  1251. {
  1252. delete($FuncDescr{$Version}{$FuncInfoId});
  1253. return;
  1254. }
  1255. if(defined $TemplateInstance_Func{$Version}{$FuncInfoId})
  1256. {
  1257. my @TmplParams = ();
  1258. foreach my $ParamPos (sort {int($a) <=> int($b)} keys(%{$TemplateInstance_Func{$Version}{$FuncInfoId}}))
  1259. {
  1260. my $Param = get_TemplateParam($TemplateInstance_Func{$Version}{$FuncInfoId}{$ParamPos});
  1261. if($Param eq "")
  1262. {
  1263. delete($FuncDescr{$Version}{$FuncInfoId});
  1264. return;
  1265. }
  1266. push(@TmplParams, $Param);
  1267. }
  1268. $FuncDescr{$Version}{$FuncInfoId}{"ShortName"} .= "<".join(", ", @TmplParams).">";
  1269. }
  1270. setFuncParams($FuncInfoId);
  1271. $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} = getFuncMnglName($FuncInfoId);
  1272. if($FuncDescr{$Version}{$FuncInfoId}{"MnglName"} and $FuncDescr{$Version}{$FuncInfoId}{"MnglName"}!~/\A_Z/)
  1273. {
  1274. delete($FuncDescr{$Version}{$FuncInfoId});
  1275. return;
  1276. }
  1277. if((is_in_library($FuncDescr{$Version}{$FuncInfoId}{"ShortName"}, $Version) or $CheckHeadersOnly) and not $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} and ($FuncDescr{$Version}{$FuncInfoId}{"Type"} eq "Function"))
  1278. {
  1279. $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} = $FuncDescr{$Version}{$FuncInfoId}{"ShortName"};
  1280. }
  1281. set_Class_And_Namespace($FuncInfoId);
  1282. if(not $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} and not $FuncDescr{$Version}{$FuncInfoId}{"Class"})
  1283. {#this section only for c++ functions without class that have not been mangled in the tree
  1284. $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} = $mangled_name{get_func_signature($FuncInfoId)};
  1285. }
  1286. if(not is_in_library($FuncDescr{$Version}{$FuncInfoId}{"MnglName"}, $Version) and not $CheckHeadersOnly)
  1287. {#src only
  1288. delete($FuncDescr{$Version}{$FuncInfoId});
  1289. return;
  1290. }
  1291. if($FuncDescr{$Version}{$FuncInfoId}{"Constructor"} or $FuncDescr{$Version}{$FuncInfoId}{"Destructor"})
  1292. {
  1293. delete($FuncDescr{$Version}{$FuncInfoId}{"Return"});
  1294. }
  1295. my $FuncBody = getFuncBody($FuncInfoId);
  1296. if($FuncBody eq "defined")
  1297. {
  1298. $FuncDescr{$Version}{$FuncInfoId}{"InLine"} = 1;
  1299. }
  1300. if($CheckHeadersOnly and $FuncDescr{$Version}{$FuncInfoId}{"InLine"})
  1301. {
  1302. delete($FuncDescr{$Version}{$FuncInfoId});
  1303. return;
  1304. }
  1305. if(($FuncDescr{$Version}{$FuncInfoId}{"Type"} eq "Method") or $FuncDescr{$Version}{$FuncInfoId}{"Constructor"} or $FuncDescr{$Version}{$FuncInfoId}{"Destructor"})
  1306. {
  1307. if($FuncDescr{$Version}{$FuncInfoId}{"MnglName"}!~/\A_Z/)
  1308. {
  1309. delete($FuncDescr{$Version}{$FuncInfoId});
  1310. return;
  1311. }
  1312. }
  1313. if(getFuncSpec($FuncInfoId) eq "Virt")
  1314. {#virtual methods
  1315. $FuncDescr{$Version}{$FuncInfoId}{"Virt"} = 1;
  1316. }
  1317. if(getFuncSpec($FuncInfoId) eq "PureVirt")
  1318. {#pure virtual methods
  1319. $FuncDescr{$Version}{$FuncInfoId}{"PureVirt"} = 1;
  1320. }
  1321. if($FuncDescr{$Version}{$FuncInfoId}{"MnglName"} =~ /\A_Z/ and $FuncDescr{$Version}{$FuncInfoId}{"Class"})
  1322. {
  1323. if($FuncDescr{$Version}{$FuncInfoId}{"Type"} eq "Function")
  1324. {#static methods
  1325. $FuncDescr{$Version}{$FuncInfoId}{"Static"} = 1;
  1326. }
  1327. }
  1328. if(getFuncLink($FuncInfoId) eq "Static")
  1329. {
  1330. $FuncDescr{$Version}{$FuncInfoId}{"Static"} = 1;
  1331. }
  1332. delete($FuncDescr{$Version}{$FuncInfoId}{"Type"});
  1333. }
  1334. sub getFuncBody($)
  1335. {
  1336. my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
  1337. if($FuncInfo =~ /body[ ]*:[ ]*undefined(\ |\Z)/i)
  1338. {
  1339. return "undefined";
  1340. }
  1341. elsif($FuncInfo =~ /body[ ]*:[ ]*@([0-9]+)(\ |\Z)/i)
  1342. {
  1343. return "defined";
  1344. }
  1345. else
  1346. {
  1347. return "";
  1348. }
  1349. }
  1350. sub getTypeShortName($)
  1351. {
  1352. my $TypeName = $_[0];
  1353. $TypeName =~ s/\<.*\>//g;
  1354. $TypeName =~ s/.*\:\://g;
  1355. return $TypeName;
  1356. }
  1357. sub getBackRef($)
  1358. {
  1359. my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
  1360. if($TypeInfo =~ /name[ ]*:[ ]*@([0-9]+) /)
  1361. {
  1362. return $1;
  1363. }
  1364. else
  1365. {
  1366. return "";
  1367. }
  1368. }
  1369. sub getTypeId($)
  1370. {
  1371. my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
  1372. if($TypeInfo =~ /type[ ]*:[ ]*@([0-9]+) /)
  1373. {
  1374. return $1;
  1375. }
  1376. else
  1377. {
  1378. return "";
  1379. }
  1380. }
  1381. sub getFuncId($)
  1382. {
  1383. my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
  1384. if($FuncInfo =~ /type[ ]*:[ ]*@([0-9]+) /)
  1385. {
  1386. return $1;
  1387. }
  1388. else
  1389. {
  1390. return "";
  1391. }
  1392. }
  1393. sub setTypeMemb($$)
  1394. {
  1395. my ($TypeDeclId, $TypeId, $TypeAttr) = @_;
  1396. my $TypeInfo = $LibInfo{$Version}{$TypeId}{"info"};
  1397. my $TypeMembInfoId;
  1398. my $TypeType = $TypeAttr->{"Type"};
  1399. my $Position = 0;
  1400. my $BasePosition = 0;
  1401. my $TypeTypeInfoId;
  1402. my $StructMembName;
  1403. if($TypeType eq "Enum")
  1404. {
  1405. $TypeMembInfoId = getEnumMembInfoId($TypeId);
  1406. while($TypeMembInfoId)
  1407. {
  1408. $TypeAttr->{"Memb"}{$Position}{"value"} = getEnumMembVal($TypeMembInfoId);
  1409. my $MembName = getEnumMembName($TypeMembInfoId);
  1410. $TypeAttr->{"Memb"}{$Position}{"name"} = getEnumMembName($TypeMembInfoId);
  1411. $EnumMembName_Id{$Version}{getTreeAttr($TypeMembInfoId, "valu")} = ($TypeAttr->{"NameSpace"})?$TypeAttr->{"NameSpace"}."::".$MembName:$MembName;
  1412. $TypeMembInfoId = getNextMembInfoId($TypeMembInfoId);
  1413. $Position += 1;
  1414. }
  1415. }
  1416. elsif(($TypeType eq "Struct") or ($TypeType eq "Class") or ($TypeType eq "Union"))
  1417. {
  1418. $TypeMembInfoId = getStructMembInfoId($TypeId);
  1419. while($TypeMembInfoId)
  1420. {
  1421. if($LibInfo{$Version}{$TypeMembInfoId}{"info_type"} ne "field_decl")
  1422. {
  1423. $TypeMembInfoId = getNextStructMembInfoId($TypeMembInfoId);
  1424. next;
  1425. }
  1426. $StructMembName = getStructMembName($TypeMembInfoId);
  1427. if($StructMembName =~ /_vptr\./)
  1428. {#virtual tables
  1429. $TypeMembInfoId = getNextStructMembInfoId($TypeMembInfoId);
  1430. next;
  1431. }
  1432. if(not $StructMembName)
  1433. {#base classes
  1434. #$TypeAttr->{"Base"}{$BasePosition}{"type"} = getStructMembType($TypeMembInfoId);
  1435. #$TypeAttr->{"Base"}{$BasePosition}{"access"} = getStructMembAccess($TypeMembInfoId);
  1436. $BasePosition += 1;
  1437. $TypeMembInfoId = getNextStructMembInfoId($TypeMembInfoId);
  1438. next;
  1439. }
  1440. $TypeAttr->{"Memb"}{$Position}{"type"} = getStructMembType($TypeMembInfoId);
  1441. $TypeAttr->{"Memb"}{$Position}{"name"} = $StructMembName;
  1442. $TypeAttr->{"Memb"}{$Position}{"access"} = getStructMembAccess($TypeMembInfoId);
  1443. $TypeAttr->{"Memb"}{$Position}{"bitfield"} = getStructMembBitFieldSize($TypeMembInfoId);
  1444. $TypeMembInfoId = getNextStructMembInfoId($TypeMembInfoId);
  1445. $Position += 1;
  1446. }
  1447. }
  1448. }
  1449. sub setFuncParams($)
  1450. {
  1451. my $FuncInfoId = $_[0];
  1452. my $ParamInfoId = getFuncParamInfoId($FuncInfoId);
  1453. my $FunctionType = getFuncType($FuncInfoId);
  1454. if($FunctionType eq "Method")
  1455. {
  1456. $ParamInfoId = getNextElem($ParamInfoId);
  1457. }
  1458. my $Position = 0;
  1459. while($ParamInfoId)
  1460. {
  1461. my $ParamTypeId = getFuncParamType($ParamInfoId);
  1462. last if($TypeDescr{$Version}{getTypeDeclId($ParamTypeId)}{$ParamTypeId}{"Name"} eq "void");
  1463. if($TypeDescr{$Version}{getTypeDeclId($ParamTypeId)}{$ParamTypeId}{"Type"} eq "Restrict")
  1464. {#delete restrict spec
  1465. $ParamTypeId = getRestrictBase($ParamTypeId);
  1466. }
  1467. $FuncDescr{$Version}{$FuncInfoId}{"Param"}{$Position}{"type"} = $ParamTypeId;
  1468. $FuncDescr{$Version}{$FuncInfoId}{"Param"}{$Position}{"name"} = getFuncParamName($ParamInfoId);
  1469. if(not $FuncDescr{$Version}{$FuncInfoId}{"Param"}{$Position}{"name"})
  1470. {
  1471. $FuncDescr{$Version}{$FuncInfoId}{"Param"}{$Position}{"name"} = "p".($Position+1);
  1472. }
  1473. $ParamInfoId = getNextElem($ParamInfoId);
  1474. $Position += 1;
  1475. }
  1476. if(detect_nolimit_args($FuncInfoId))
  1477. {
  1478. $FuncDescr{$Version}{$FuncInfoId}{"Param"}{$Position}{"type"} = -1;
  1479. }
  1480. }
  1481. sub detect_nolimit_args($)
  1482. {
  1483. my $FuncInfoId = $_[0];
  1484. my $FuncTypeId = getFuncTypeId($FuncInfoId);
  1485. my $ParamListElemId = getFuncParamTreeListId($FuncTypeId);
  1486. my $HaveVoid = 0;
  1487. my $Position = 0;
  1488. while($ParamListElemId)
  1489. {
  1490. my $ParamTypeId = getTreeAttr($ParamListElemId, "valu");
  1491. if($TypeDescr{$Version}{getTypeDeclId($ParamTypeId)}{$ParamTypeId}{"Name"} eq "void")
  1492. {
  1493. $HaveVoid = 1;
  1494. last;
  1495. }
  1496. $ParamListElemId = getNextElem($ParamListElemId);
  1497. $Position += 1;
  1498. }
  1499. return ($Position>=1 and not $HaveVoid);
  1500. }
  1501. sub getFuncParamTreeListId($)
  1502. {
  1503. my $FuncTypeId = $_[0];
  1504. if($LibInfo{$Version}{$FuncTypeId}{"info"} =~ /prms[ ]*:[ ]*@([0-9]+) /)
  1505. {
  1506. return $1;
  1507. }
  1508. else
  1509. {
  1510. return "";
  1511. }
  1512. }
  1513. sub getTreeAttr($$)
  1514. {
  1515. my ($Id, $Attr) = @_;
  1516. if($LibInfo{$Version}{$Id}{"info"} =~ /$Attr[ ]*:[ ]*@([0-9]+) /)
  1517. {
  1518. return $1;
  1519. }
  1520. else
  1521. {
  1522. return "";
  1523. }
  1524. }
  1525. sub getRestrictBase($)
  1526. {
  1527. my $TypeId = $_[0];
  1528. my $TypeDeclId = getTypeDeclId($TypeId);
  1529. my $BaseTypeId = $TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"BaseType"}{"Tid"};
  1530. my $BaseTypeDeclId = $TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"BaseType"}{"TDid"};
  1531. return $BaseTypeId;
  1532. }
  1533. sub setFuncAccess($)
  1534. {
  1535. my $FuncInfoId = $_[0];
  1536. if($LibInfo{$Version}{$FuncInfoId}{"info"} =~ /accs[ ]*:[ ]*([a-zA-Z]+) /)
  1537. {
  1538. my $Access = $1;
  1539. if($Access eq "prot")
  1540. {
  1541. $FuncDescr{$Version}{$FuncInfoId}{"Protected"} = 1;
  1542. }
  1543. elsif($Access eq "priv")
  1544. {
  1545. $FuncDescr{$Version}{$FuncInfoId}{"Private"} = 1;
  1546. }
  1547. }
  1548. }
  1549. sub setTypeAccess($$)
  1550. {
  1551. my ($TypeId, $TypeAttr) = @_;
  1552. my $TypeInfo = $LibInfo{$Version}{$TypeId}{"info"};
  1553. if($TypeInfo =~ /accs[ ]*:[ ]*([a-zA-Z]+) /)
  1554. {
  1555. my $Access = $1;
  1556. if($Access eq "prot")
  1557. {
  1558. $TypeAttr->{"Protected"} = 1;
  1559. }
  1560. elsif($Access eq "priv")
  1561. {
  1562. $TypeAttr->{"Private"} = 1;
  1563. }
  1564. }
  1565. }
  1566. sub setFuncKind($)
  1567. {
  1568. my $FuncInfoId = $_[0];
  1569. if($LibInfo{$Version}{$FuncInfoId}{"info"} =~ /pseudo tmpl/)
  1570. {
  1571. $FuncDescr{$Version}{$FuncInfoId}{"PseudoTemplate"} = 1;
  1572. }
  1573. elsif($LibInfo{$Version}{$FuncInfoId}{"info"} =~ /note[ ]*:[ ]*constructor /)
  1574. {
  1575. $FuncDescr{$Version}{$FuncInfoId}{"Constructor"} = 1;
  1576. }
  1577. elsif($LibInfo{$Version}{$FuncInfoId}{"info"} =~ /note[ ]*:[ ]*destructor /)
  1578. {
  1579. $FuncDescr{$Version}{$FuncInfoId}{"Destructor"} = 1;
  1580. }
  1581. }
  1582. sub getFuncSpec($)
  1583. {
  1584. my $FuncInfoId = $_[0];
  1585. my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
  1586. if($FuncInfo =~ m/spec[ ]*:[ ]*pure /)
  1587. {
  1588. return "PureVirt";
  1589. }
  1590. elsif($FuncInfo =~ m/spec[ ]*:[ ]*virt /)
  1591. {
  1592. return "Virt";
  1593. }
  1594. else
  1595. {
  1596. if($FuncInfo =~ /spec[ ]*:[ ]*([a-zA-Z]+) /)
  1597. {
  1598. return $1;
  1599. }
  1600. else
  1601. {
  1602. return "";
  1603. }
  1604. }
  1605. }
  1606. sub getFuncClass($)
  1607. {
  1608. my $FuncInfoId = $_[0];
  1609. my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
  1610. if($FuncInfo =~ /scpe[ ]*:[ ]*@([0-9]+) /)
  1611. {
  1612. return $1;
  1613. }
  1614. else
  1615. {
  1616. return "";
  1617. }
  1618. }
  1619. sub getFuncLink($)
  1620. {
  1621. my $FuncInfoId = $_[0];
  1622. my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
  1623. if($FuncInfo =~ /link[ ]*:[ ]*static /)
  1624. {
  1625. return "Static";
  1626. }
  1627. else
  1628. {
  1629. if($FuncInfo =~ /link[ ]*:[ ]*([a-zA-Z]+) /)
  1630. {
  1631. return $1;
  1632. }
  1633. else
  1634. {
  1635. return "";
  1636. }
  1637. }
  1638. }
  1639. sub getNextElem($)
  1640. {
  1641. my $FuncInfoId = $_[0];
  1642. my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
  1643. if($FuncInfo =~ /chan[ ]*:[ ]*@([0-9]+) /)
  1644. {
  1645. return $1;
  1646. }
  1647. else
  1648. {
  1649. return "";
  1650. }
  1651. }
  1652. sub getFuncParamInfoId($)
  1653. {
  1654. my $FuncInfoId = $_[0];
  1655. my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
  1656. if($FuncInfo =~ /args[ ]*:[ ]*@([0-9]+) /)
  1657. {
  1658. return $1;
  1659. }
  1660. else
  1661. {
  1662. return "";
  1663. }
  1664. }
  1665. sub getFuncParamType($)
  1666. {
  1667. my $ParamInfoId = $_[0];
  1668. my $ParamInfo = $LibInfo{$Version}{$ParamInfoId}{"info"};
  1669. if($ParamInfo =~ /type[ ]*:[ ]*@([0-9]+) /)
  1670. {
  1671. return $1;
  1672. }
  1673. else
  1674. {
  1675. return "";
  1676. }
  1677. }
  1678. sub getFuncParamName($)
  1679. {
  1680. my $ParamInfoId = $_[0];
  1681. my $ParamInfo = $LibInfo{$Version}{$ParamInfoId}{"info"};
  1682. return "" if($ParamInfo !~ /name[ ]*:[ ]*@([0-9]+) /);
  1683. my $NameInfoId = $1;
  1684. return "" if($LibInfo{$Version}{$NameInfoId}{"info"} !~ /strg[ ]*:[ ]*(.*)[ ]+lngt/);
  1685. my $FuncParamName = $1;
  1686. $FuncParamName =~ s/[ ]+\Z//g;
  1687. return $FuncParamName;
  1688. }
  1689. sub getEnumMembInfoId($)
  1690. {
  1691. my $TypeInfoId = $_[0];
  1692. my $TypeInfo = $LibInfo{$Version}{$TypeInfoId}{"info"};
  1693. if($TypeInfo =~ /csts[ ]*:[ ]*@([0-9]+) /)
  1694. {
  1695. return $1;
  1696. }
  1697. else
  1698. {
  1699. return "";
  1700. }
  1701. }
  1702. sub getStructMembInfoId($)
  1703. {
  1704. my $TypeInfoId = $_[0];
  1705. my $TypeInfo = $LibInfo{$Version}{$TypeInfoId}{"info"};
  1706. if($TypeInfo =~ /flds[ ]*:[ ]*@([0-9]+) /)
  1707. {
  1708. return $1;
  1709. }
  1710. else
  1711. {
  1712. return "";
  1713. }
  1714. }
  1715. sub getNameSpace($)
  1716. {
  1717. my $TypeInfoId = $_[0];
  1718. my $TypeInfo = $LibInfo{$Version}{$TypeInfoId}{"info"};
  1719. return "" if($TypeInfo !~ /scpe[ ]*:[ ]*@([0-9]+) /);
  1720. my $NameSpaceInfoId = $1;
  1721. if($LibInfo{$Version}{$NameSpaceInfoId}{"info_type"} eq "namespace_decl")
  1722. {
  1723. my $NameSpaceInfo = $LibInfo{$Version}{$NameSpaceInfoId}{"info"};
  1724. if($NameSpaceInfo =~ /name[ ]*:[ ]*@([0-9]+) /)
  1725. {
  1726. my $NameSpaceId = $1;
  1727. my $NameSpaceIdentifier = $LibInfo{$Version}{$NameSpaceId}{"info"};
  1728. return "" if($NameSpaceIdentifier !~ /strg[ ]*:[ ]*(.*)[ ]+lngt/);
  1729. my $NameSpace = $1;
  1730. $NameSpace =~ s/[ ]+\Z//g;
  1731. my $BaseNameSpace = getNameSpace($NameSpaceInfoId);
  1732. $NameSpace = $BaseNameSpace."::".$NameSpace if($BaseNameSpace);
  1733. return $NameSpace;
  1734. }
  1735. else
  1736. {
  1737. return "";
  1738. }
  1739. }
  1740. elsif($LibInfo{$Version}{$NameSpaceInfoId}{"info_type"} eq "record_type")
  1741. {
  1742. my %NameSpaceAttr = getTypeAttr(getTypeDeclId($NameSpaceInfoId), $NameSpaceInfoId);
  1743. return $NameSpaceAttr{"Name"};
  1744. }
  1745. else
  1746. {
  1747. return "";
  1748. }
  1749. }
  1750. sub getNameSpaceId($)
  1751. {
  1752. my $TypeInfoId = $_[0];
  1753. my $TypeInfo = $LibInfo{$Version}{$TypeInfoId}{"info"};
  1754. if($TypeInfo =~ /scpe[ ]*:[ ]*@([0-9]+) /)
  1755. {
  1756. return $1;
  1757. }
  1758. else
  1759. {
  1760. return "";
  1761. }
  1762. }
  1763. sub getEnumMembName($)
  1764. {
  1765. my $TypeMembInfoId = $_[0];
  1766. return "" if($LibInfo{$Version}{$TypeMembInfoId}{"info"} !~ /purp[ ]*:[ ]*@([0-9]+)/);
  1767. my $Purp = $1;
  1768. return "" if($LibInfo{$Version}{$Purp}{"info"} !~ /strg[ ]*:[ ]*(.*)[ ]+lngt/);
  1769. my $EnumMembName = $1;
  1770. $EnumMembName =~ s/[ ]+\Z//g;
  1771. return $EnumMembName;
  1772. }
  1773. sub getStructMembName($)
  1774. {
  1775. my $TypeMembInfoId = $_[0];
  1776. return "" if($LibInfo{$Version}{$TypeMembInfoId}{"info"} !~ /name[ ]*:[ ]*@([0-9]+) /);
  1777. my $NameInfoId = $1;
  1778. return "" if($LibInfo{$Version}{$NameInfoId}{"info"} !~ /strg[ ]*:[ ]*(.*)[ ]+lngt/);
  1779. my $StructMembName = $1;
  1780. $StructMembName =~ s/[ ]+\Z//g;
  1781. return $StructMembName;
  1782. }
  1783. sub getEnumMembVal($)
  1784. {
  1785. my $TypeMembInfoId = $_[0];
  1786. return "" if($LibInfo{$Version}{$TypeMembInfoId}{"info"} !~ /valu[ ]*:[ ]*@([0-9]+) /);
  1787. my $Valu = $1;
  1788. if($LibInfo{$Version}{$Valu}{"info"} =~ /low[ ]*:[ ]*(-?[0-9]+) /)
  1789. {
  1790. return $1;
  1791. }
  1792. else
  1793. {
  1794. return "";
  1795. }
  1796. }
  1797. sub getSize($)
  1798. {
  1799. my $Info = $LibInfo{$Version}{$_[0]}{"info"};
  1800. if($Info =~ /size[ ]*:[ ]*@([0-9]+) /)
  1801. {
  1802. my $SizeInfoId = $1;
  1803. if($LibInfo{$Version}{$SizeInfoId}{"info"} =~ /low[ ]*:[ ]*(-?[0-9]+) /)
  1804. {
  1805. return $1;
  1806. }
  1807. else
  1808. {
  1809. return "";
  1810. }
  1811. }
  1812. else
  1813. {
  1814. return 0;
  1815. }
  1816. }
  1817. sub getStructMembType($)
  1818. {
  1819. my $TypeMembInfoId = $_[0];
  1820. if($LibInfo{$Version}{$TypeMembInfoId}{"info"} =~ /type[ ]*:[ ]*@([0-9]+) /)
  1821. {
  1822. return $1;
  1823. }
  1824. else
  1825. {
  1826. return "";
  1827. }
  1828. }
  1829. sub getStructMembBitFieldSize($)
  1830. {
  1831. my $TypeMembInfoId = $_[0];
  1832. if($LibInfo{$Version}{$TypeMembInfoId}{"info"} =~ / bitfield /)
  1833. {
  1834. return getSize($TypeMembInfoId);
  1835. }
  1836. else
  1837. {
  1838. return 0;
  1839. }
  1840. }
  1841. sub getStructMembAccess($)
  1842. {
  1843. my $MembInfo = $LibInfo{$Version}{$_[0]}{"info"};
  1844. if($MembInfo =~ /accs[ ]*:[ ]*([a-zA-Z]+) /)
  1845. {
  1846. my $Access = $1;
  1847. if($Access eq "prot")
  1848. {
  1849. return "protected";
  1850. }
  1851. elsif($Access eq "priv")
  1852. {
  1853. return "private";
  1854. }
  1855. else
  1856. {
  1857. return "public";
  1858. }
  1859. }
  1860. else
  1861. {
  1862. return "public";
  1863. }
  1864. }
  1865. sub getNextMembInfoId($)
  1866. {
  1867. my $TypeMembInfoId = $_[0];
  1868. if($LibInfo{$Version}{$TypeMembInfoId}{"info"} =~ /chan[ ]*:[ ]*@([0-9]+) /)
  1869. {
  1870. return $1;
  1871. }
  1872. else
  1873. {
  1874. return "";
  1875. }
  1876. }
  1877. sub getNextStructMembInfoId($)
  1878. {
  1879. my $TypeMembInfoId = $_[0];
  1880. if($LibInfo{$Version}{$TypeMembInfoId}{"info"} =~ /chan[ ]*:[ ]*@([0-9]+) /)
  1881. {
  1882. return $1;
  1883. }
  1884. else
  1885. {
  1886. return "";
  1887. }
  1888. }
  1889. sub fieldHasName($)
  1890. {
  1891. my $TypeMembInfoId = $_[0];
  1892. if($LibInfo{$Version}{$TypeMembInfoId}{"info_type"} eq "field_decl")
  1893. {
  1894. if($LibInfo{$Version}{$TypeMembInfoId}{"info"} =~ /name[ ]*:[ ]*@([0-9]+) /)
  1895. {
  1896. return $1;
  1897. }
  1898. else
  1899. {
  1900. return "";
  1901. }
  1902. }
  1903. else
  1904. {
  1905. return 0;
  1906. }
  1907. }
  1908. sub getTypeHeader($)
  1909. {
  1910. my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
  1911. if($TypeInfo =~ /srcp[ ]*:[ ]*([0-9a-zA-Z\_\-\<\>\.\+]+):([0-9]+) /)
  1912. {
  1913. return ($1, $2);
  1914. }
  1915. else
  1916. {
  1917. return ();
  1918. }
  1919. }
  1920. sub register_header($$$)
  1921. {
  1922. my ($Destination, $Position, $LibVersion) = @_;
  1923. return if(not $Destination);
  1924. if($Destination=~/\A\// and not -f $Destination)
  1925. {
  1926. print "\nERROR: specified header \'$Destination\' does not exist\n";
  1927. return;
  1928. }
  1929. my $Header_Name = get_FileName($Destination);
  1930. $Headers{$LibVersion}{$Destination}{"Name"} = $Header_Name;
  1931. $Headers{$LibVersion}{$Destination}{"Position"} = $Position;
  1932. $Headers{$LibVersion}{$Destination}{"Identity"} = $Destination;
  1933. $HeaderName_Destinations{$LibVersion}{$Header_Name}{$Destination} = 1;
  1934. }
  1935. sub headerSearch($)
  1936. {
  1937. my $LibVersion = $_[0];
  1938. foreach my $Dest (split("\n", $Descriptor{$LibVersion}{"Include_Paths"}))
  1939. {
  1940. $Dest =~ s/\A\s+|\s+\Z//g;
  1941. next if(not $Dest);
  1942. if(not -e $Dest)
  1943. {
  1944. print "ERROR: can't access \'$Dest\'\n";
  1945. }
  1946. $Header_Dependency{$LibVersion}{$Dest} = 1;
  1947. }
  1948. foreach my $Dest (split("\n", $Descriptor{$LibVersion}{"Headers"}))
  1949. {#fill %Header_Dependency
  1950. if(-d $Dest)
  1951. {
  1952. foreach my $Dir (cmd_find($Dest,"d",""))
  1953. {
  1954. chomp($Dir);
  1955. $Header_Dependency{$LibVersion}{$Dir} = 1;
  1956. }
  1957. }
  1958. elsif(-f $Dest)
  1959. {
  1960. $Header_Dependency{$LibVersion}{get_Dir($Dest)} = 1;
  1961. }
  1962. }
  1963. my $Position = 0;
  1964. foreach my $Dest (split("\n", $Descriptor{$LibVersion}{"Headers"}))
  1965. {
  1966. $Dest =~ s/\A\s+|\s+\Z//g;
  1967. next if(not $Dest);
  1968. if(is_header($Dest, $LibVersion))
  1969. {
  1970. register_header($Dest, $Position, $LibVersion);
  1971. $Position += 1;
  1972. }
  1973. elsif(-d $Dest)
  1974. {
  1975. foreach my $Destination (sort {lc($a) cmp lc($b)} (cmd_find($Dest,"f","")))
  1976. {
  1977. chomp($Destination);
  1978. next if(not is_header($Destination, $LibVersion));
  1979. register_header($Destination, $Position, $LibVersion);
  1980. $Position += 1;
  1981. }
  1982. }
  1983. else
  1984. {
  1985. print "WARNING: \'$Dest\' was not found in the specified include paths\n";
  1986. register_header($Dest, $Position, $LibVersion);
  1987. $Position += 1;
  1988. }
  1989. }
  1990. if(keys(%{$Headers{$LibVersion}})==1)
  1991. {
  1992. my $Destination = (keys(%{$Headers{$LibVersion}}))[0];
  1993. $Headers{$LibVersion}{$Destination}{"Identity"} = $Headers{$LibVersion}{$Destination}{"Name"};
  1994. }
  1995. foreach my $Header_Name (keys(%{$HeaderName_Destinations{$LibVersion}}))
  1996. {#set relative paths (for dublicates)
  1997. if(keys(%{$HeaderName_Destinations{$LibVersion}{$Header_Name}})>1)
  1998. {
  1999. my $FirstDest = (keys(%{$HeaderName_Destinations{$LibVersion}{$Header_Name}}))[0];
  2000. my $Prefix = get_Dir($FirstDest);
  2001. while($Prefix =~ /\A(.+)\/[^\/]+\Z/)
  2002. {
  2003. my $NewPrefix = $1;
  2004. my $Changes_Number = 0;
  2005. my %Identity = ();
  2006. foreach my $Dest (keys(%{$HeaderName_Destinations{$LibVersion}{$Header_Name}}))
  2007. {
  2008. if($Dest =~ /\A$Prefix\/(.*)\Z/)
  2009. {
  2010. $Identity{$Dest} = $1;
  2011. $Changes_Number+=1;
  2012. }
  2013. }
  2014. if($Changes_Number eq keys(%{$HeaderName_Destinations{$LibVersion}{$Header_Name}}))
  2015. {
  2016. foreach my $Dest (keys(%{$HeaderName_Destinations{$LibVersion}{$Header_Name}}))
  2017. {
  2018. $Headers{$LibVersion}{$Dest}{"Identity"} = $Identity{$Dest};
  2019. }
  2020. last;
  2021. }
  2022. $Prefix = $NewPrefix;
  2023. }
  2024. }
  2025. }
  2026. if(not keys(%{$Headers{$LibVersion}}))
  2027. {
  2028. print "ERROR: header files were not found\n";
  2029. exit(1);
  2030. }
  2031. }
  2032. sub get_FileName($)
  2033. {
  2034. my $Path = $_[0];
  2035. if($Path =~ /\A(.*\/)([^\/]*)\Z/)
  2036. {
  2037. return $2;
  2038. }
  2039. else
  2040. {
  2041. return $Path;
  2042. }
  2043. }
  2044. sub get_Dir($)
  2045. {
  2046. my $Path = $_[0];
  2047. return "" if($Path =~ m*\A\./*);
  2048. if($Path =~ /\A(.*)\/([^\/]*)\Z/)
  2049. {
  2050. return $1;
  2051. }
  2052. else
  2053. {
  2054. return "";
  2055. }
  2056. }
  2057. sub esc($)
  2058. {
  2059. my $Str = $_[0];
  2060. $Str =~ s/([()\[\]{}$ &'"`;,<>])/\\$1/g;
  2061. return $Str;
  2062. }
  2063. sub getLocation($)
  2064. {
  2065. my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
  2066. if($TypeInfo =~ /srcp[ ]*:[ ]*([0-9a-zA-Z\_\-\<\>\.\+]+):([0-9]+) /)
  2067. {
  2068. return ($1, $2);
  2069. }
  2070. else
  2071. {
  2072. return ();
  2073. }
  2074. }
  2075. sub getHeader($)
  2076. {
  2077. my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
  2078. if($TypeInfo =~ /srcp[ ]*:[ ]*([0-9a-zA-Z\_\-\<\>\.\+]+):([0-9]+) /)
  2079. {
  2080. return $1;
  2081. }
  2082. else
  2083. {
  2084. return "";
  2085. }
  2086. }
  2087. sub getLine($)
  2088. {
  2089. my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
  2090. if($TypeInfo =~ /srcp[ ]*:[ ]*([0-9a-zA-Z\_\-\<\>\.\+]+):([0-9]+) /)
  2091. {
  2092. return $2;
  2093. }
  2094. else
  2095. {
  2096. return "";
  2097. }
  2098. }
  2099. sub getTypeType($$)
  2100. {
  2101. my ($TypeDeclId, $TypeId) = @_;
  2102. return "Const" if($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*c / and $LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@/);
  2103. return "Typedef" if($LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:/ and $LibInfo{$Version}{$TypeId}{"info"} !~ /qual[ ]*:/);
  2104. return "Volatile" if($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*v / and $LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@/);
  2105. return "Restrict" if($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*r / and $LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@/);
  2106. my $TypeType = getTypeTypeByTypeId($TypeId);
  2107. if($TypeType eq "Struct")
  2108. {
  2109. if($TypeDeclId and $LibInfo{$Version}{$TypeDeclId}{"info_type"} eq "template_decl")
  2110. {
  2111. return "Template";
  2112. }
  2113. else
  2114. {
  2115. return "Struct";
  2116. }
  2117. }
  2118. else
  2119. {
  2120. return $TypeType;
  2121. }
  2122. }
  2123. sub getTypeTypeByTypeId($)
  2124. {
  2125. my $TypeId = $_[0];
  2126. my $TypeType = $LibInfo{$Version}{$TypeId}{"info_type"};
  2127. if($TypeType =~ /integer_type|real_type|boolean_type|void_type|complex_type/)
  2128. {
  2129. return "Intrinsic";
  2130. }
  2131. elsif(isFuncPtr($TypeId))
  2132. {
  2133. return "FuncPtr";
  2134. }
  2135. elsif($TypeType eq "pointer_type")
  2136. {
  2137. return "Pointer";
  2138. }
  2139. elsif($TypeType eq "reference_type")
  2140. {
  2141. return "Ref";
  2142. }
  2143. elsif($TypeType eq "union_type")
  2144. {
  2145. return "Union";
  2146. }
  2147. elsif($TypeType eq "enumeral_type")
  2148. {
  2149. return "Enum";
  2150. }
  2151. elsif($TypeType eq "record_type")
  2152. {
  2153. return "Struct";
  2154. }
  2155. elsif($TypeType eq "array_type")
  2156. {
  2157. return "Array";
  2158. }
  2159. elsif($TypeType eq "complex_type")
  2160. {
  2161. return "Intrinsic";
  2162. }
  2163. elsif($TypeType eq "function_type")
  2164. {
  2165. return "FunctionType";
  2166. }
  2167. elsif($TypeType eq "method_type")
  2168. {
  2169. return "MethodType";
  2170. }
  2171. else
  2172. {
  2173. return "Unknown";
  2174. }
  2175. }
  2176. sub getNameByInfo($)
  2177. {
  2178. my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
  2179. return "" if($TypeInfo !~ /name[ ]*:[ ]*@([0-9]+) /);
  2180. my $TypeNameInfoId = $1;
  2181. return "" if($LibInfo{$Version}{$TypeNameInfoId}{"info"} !~ /strg[ ]*:[ ]*(.*)[ ]+lngt/);
  2182. my $TypeName = $1;
  2183. $TypeName =~ s/[ ]+\Z//g;
  2184. return $TypeName;
  2185. }
  2186. sub getFuncShortName($)
  2187. {
  2188. my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
  2189. if($FuncInfo =~ / operator /)
  2190. {
  2191. if($FuncInfo =~ /note[ ]*:[ ]*conversion /)
  2192. {
  2193. return "operator ".get_TypeName($FuncDescr{$Version}{$_[0]}{"Return"});
  2194. }
  2195. else
  2196. {
  2197. return "" if($FuncInfo !~ / operator[ ]+([a-zA-Z]+) /);
  2198. return "operator".$Operator_Indication{$1};
  2199. }
  2200. }
  2201. else
  2202. {
  2203. return "" if($FuncInfo !~ /name[ ]*:[ ]*@([0-9]+) /);
  2204. my $FuncNameInfoId = $1;
  2205. return "" if($LibInfo{$Version}{$FuncNameInfoId}{"info"} !~ /strg[ ]*:[ ]*([^ ]*)[ ]+lngt/);
  2206. return $1;
  2207. }
  2208. }
  2209. sub getFuncMnglName($)
  2210. {
  2211. my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
  2212. return "" if($FuncInfo !~ /mngl[ ]*:[ ]*@([0-9]+) /);
  2213. my $FuncMnglNameInfoId = $1;
  2214. return "" if($LibInfo{$Version}{$FuncMnglNameInfoId}{"info"} !~ /strg[ ]*:[ ]*([^ ]*)[ ]+/);
  2215. my $FuncMnglName = $1;
  2216. $FuncMnglName =~ s/[ ]+\Z//g;
  2217. return $FuncMnglName;
  2218. }
  2219. sub getFuncReturn($)
  2220. {
  2221. my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
  2222. return "" if($FuncInfo !~ /type[ ]*:[ ]*@([0-9]+) /);
  2223. my $FuncTypeInfoId = $1;
  2224. return "" if($LibInfo{$Version}{$FuncTypeInfoId}{"info"} !~ /retn[ ]*:[ ]*@([0-9]+) /);
  2225. my $FuncReturnTypeId = $1;
  2226. if($TypeDescr{$Version}{getTypeDeclId($FuncReturnTypeId)}{$FuncReturnTypeId}{"Type"} eq "Restrict")
  2227. {#delete restrict spec
  2228. $FuncReturnTypeId = getRestrictBase($FuncReturnTypeId);
  2229. }
  2230. return $FuncReturnTypeId;
  2231. }
  2232. sub getFuncOrig($)
  2233. {
  2234. my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
  2235. if($FuncInfo =~ /orig[ ]*:[ ]*@([0-9]+) /)
  2236. {
  2237. return $1;
  2238. }
  2239. else
  2240. {
  2241. return $_[0];
  2242. }
  2243. }
  2244. sub unmangleArray(@)
  2245. {
  2246. if($#_>$MAX_COMMAND_LINE_ARGUMENTS)
  2247. {
  2248. my @Half = splice(@_, 0, ($#_+1)/2);
  2249. return (unmangleArray(@Half), unmangleArray(@_))
  2250. }
  2251. else
  2252. {
  2253. my $UnmangleCommand = "c++filt ".join(" ", @_);
  2254. return split("\n", `$UnmangleCommand`);
  2255. }
  2256. }
  2257. sub get_Signature($$)
  2258. {
  2259. my ($Interface, $LibVersion) = @_;
  2260. return $Cache{"get_Signature"}{$Interface}{$LibVersion} if($Cache{"get_Signature"}{$Interface}{$LibVersion});
  2261. my ($MnglName, $SymbolVersion) = ($Interface, "");
  2262. if($Interface =~ /\A([^@]+)[\@]+([^@]+)\Z/)
  2263. {
  2264. ($MnglName, $SymbolVersion) = ($1, $2);
  2265. }
  2266. if($MnglName =~ /\A(_ZGV|_ZTI|_ZTS|_ZTT|_ZTV|_ZThn|_ZTv0_n)/)
  2267. {
  2268. $Cache{"get_Signature"}{$Interface}{$LibVersion} = $tr_name{$MnglName}.(($SymbolVersion)?"\@".$SymbolVersion:"");
  2269. return $Cache{"get_Signature"}{$Interface}{$LibVersion};
  2270. }
  2271. if(not $CompleteSignature{$LibVersion}{$Interface})
  2272. {
  2273. if($Interface =~ /\A_Z/)
  2274. {
  2275. $Cache{"get_Signature"}{$Interface}{$LibVersion} = $tr_name{$MnglName}.(($SymbolVersion)?"\@".$SymbolVersion:"");
  2276. return $Cache{"get_Signature"}{$Interface}{$LibVersion};
  2277. }
  2278. else
  2279. {
  2280. $Cache{"get_Signature"}{$Interface}{$LibVersion} = $Interface;
  2281. return $Interface;
  2282. }
  2283. }
  2284. my ($Func_Signature, @Param_Types_FromUnmangledName) = ();
  2285. my $ShortName = $CompleteSignature{$LibVersion}{$Interface}{"ShortName"};
  2286. if($Interface =~ /\A_Z/)
  2287. {
  2288. if($CompleteSignature{$LibVersion}{$Interface}{"Class"})
  2289. {
  2290. $Func_Signature = get_TypeName($CompleteSignature{$LibVersion}{$Interface}{"Class"}, $LibVersion)."::".(($CompleteSignature{$LibVersion}{$Interface}{"Destructor"})?"~":"").$ShortName;
  2291. }
  2292. else
  2293. {
  2294. $Func_Signature = $ShortName;
  2295. }
  2296. @Param_Types_FromUnmangledName = get_Signature_Parts($tr_name{$MnglName}, 0);
  2297. }
  2298. else
  2299. {
  2300. $Func_Signature = $MnglName;
  2301. }
  2302. my @ParamArray = ();
  2303. foreach my $Pos (sort {int($a) <=> int($b)} keys(%{$CompleteSignature{$LibVersion}{$Interface}{"Param"}}))
  2304. {
  2305. next if($Pos eq "");
  2306. my $ParamTypeId = $CompleteSignature{$LibVersion}{$Interface}{"Param"}{$Pos}{"type"};
  2307. my $ParamTypeName = $TypeDescr{$LibVersion}{$Tid_TDid{$LibVersion}{$ParamTypeId}}{$ParamTypeId}{"Name"};
  2308. $ParamTypeName = $Param_Types_FromUnmangledName[$Pos] if(not $ParamTypeName);
  2309. if(my $ParamName = $CompleteSignature{$LibVersion}{$Interface}{"Param"}{$Pos}{"name"})
  2310. {
  2311. if($ParamTypeName=~/\([*]+\)/)
  2312. {
  2313. $ParamTypeName=~s/\(([*]+)\)/\($1$ParamName\)/;
  2314. push(@ParamArray, $ParamTypeName);
  2315. }
  2316. else
  2317. {
  2318. push(@ParamArray, $ParamTypeName." ".$ParamName);
  2319. }
  2320. }
  2321. else
  2322. {
  2323. push(@ParamArray, $ParamTypeName);
  2324. }
  2325. }
  2326. if(not $CompleteSignature{$LibVersion}{$Interface}{"Data"})
  2327. {
  2328. if($Interface=~/\A_Z/)
  2329. {
  2330. if($CompleteSignature{$LibVersion}{$Interface}{"Constructor"})
  2331. {
  2332. if($Interface=~/C1/)
  2333. {
  2334. $Func_Signature .= " [in-charge]";
  2335. }
  2336. elsif($Interface=~/C2/)
  2337. {
  2338. $Func_Signature .= " [not-in-charge]";
  2339. }
  2340. }
  2341. elsif($CompleteSignature{$LibVersion}{$Interface}{"Destructor"})
  2342. {
  2343. if($Interface=~/D1/)
  2344. {
  2345. $Func_Signature .= " [in-charge]";
  2346. }
  2347. elsif($Interface=~/D2/)
  2348. {
  2349. $Func_Signature .= " [not-in-charge]";
  2350. }
  2351. elsif($Interface=~/D0/)
  2352. {
  2353. $Func_Signature .= " [in-charge-deleting]";
  2354. }
  2355. }
  2356. }
  2357. $Func_Signature .= " (".join(", ", @ParamArray).")";
  2358. }
  2359. if($Interface=~/\A_ZNK/)
  2360. {
  2361. $Func_Signature .= " const";
  2362. }
  2363. $Func_Signature .= "\@".$SymbolVersion if($SymbolVersion);
  2364. $Cache{"get_Signature"}{$Interface}{$LibVersion} = $Func_Signature;
  2365. return $Func_Signature;
  2366. }
  2367. sub getVarNameByAttr($)
  2368. {
  2369. my $FuncInfoId = $_[0];
  2370. my $VarName;
  2371. return "" if(not $FuncDescr{$Version}{$FuncInfoId}{"ShortName"});
  2372. if($FuncDescr{$Version}{$FuncInfoId}{"Class"})
  2373. {
  2374. $VarName .= $TypeDescr{$Version}{getTypeDeclId($FuncDescr{$Version}{$FuncInfoId}{"Class"})}{$FuncDescr{$Version}{$FuncInfoId}{"Class"}}{"Name"};
  2375. $VarName .= "::";
  2376. }
  2377. $VarName .= $FuncDescr{$Version}{$FuncInfoId}{"ShortName"};
  2378. return $VarName;
  2379. }
  2380. sub mangleFuncName($)
  2381. {
  2382. my $FuncId = $_[0];
  2383. }
  2384. sub getFuncType($)
  2385. {
  2386. my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
  2387. return "" if($FuncInfo !~ /type[ ]*:[ ]*@([0-9]+) /);
  2388. my $FuncTypeInfoId = $1;
  2389. my $FunctionType = $LibInfo{$Version}{$FuncTypeInfoId}{"info_type"};
  2390. if($FunctionType eq "method_type")
  2391. {
  2392. return "Method";
  2393. }
  2394. elsif($FunctionType eq "function_type")
  2395. {
  2396. return "Function";
  2397. }
  2398. else
  2399. {
  2400. return $FunctionType;
  2401. }
  2402. }
  2403. sub getFuncTypeId($)
  2404. {
  2405. my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
  2406. if($FuncInfo =~ /type[ ]*:[ ]*@([0-9]+)( |\Z)/)
  2407. {
  2408. return $1;
  2409. }
  2410. else
  2411. {
  2412. return 0;
  2413. }
  2414. }
  2415. sub isNotAnon($)
  2416. {
  2417. return (not isAnon($_[0]));
  2418. }
  2419. sub isAnon($)
  2420. {
  2421. return (($_[0] =~ m/\.\_[0-9]+/) or ($_[0] =~ m/anon-/));
  2422. }
  2423. sub unmangled_Compact($$)
  2424. #Removes all non-essential (for C++ language) whitespace from a string. If
  2425. #the whitespace is essential it will be replaced with exactly one ' '
  2426. #character. Works correctly only for unmangled names.
  2427. #If level > 1 is supplied, can relax its intent to compact the string.
  2428. {
  2429. my $result=$_[0];
  2430. my $level = $_[1] || 1;
  2431. my $o1 = ($level>1)?' ':'';
  2432. #First, we reduce all spaces that we can
  2433. my $coms='[-()<>:*&~!|+=%@~"?.,/[^'."']";
  2434. my $coms_nobr='[-()<:*&~!|+=%@~"?.,'."']";
  2435. my $clos='[),;:\]]';
  2436. $result=~s/^\s+//gm;
  2437. $result=~s/\s+$//gm;
  2438. $result=~s/((?!\n)\s)+/ /g;
  2439. $result=~s/(\w+)\s+($coms+)/$1$o1$2/gm;
  2440. #$result=~s/(\w)(\()/$1$o1$2/gm if $o1;
  2441. $result=~s/($coms+)\s+(\w+)/$1$o1$2/gm;
  2442. $result=~s/(\()\s+(\w)/$1$2/gm if $o1;
  2443. $result=~s/(\w)\s+($clos)/$1$2/gm;
  2444. $result=~s/($coms+)\s+($coms+)/$1 $2/gm;
  2445. $result=~s/($coms_nobr+)\s+($coms+)/$1$o1$2/gm;
  2446. $result=~s/($coms+)\s+($coms_nobr+)/$1$o1$2/gm;
  2447. #don't forget about >> and <:. In unmangled names global-scope modifier
  2448. #is not used, so <: will always be a digraph and requires no special treatment.
  2449. #We also try to remove other parts that are better to be removed here than in other places
  2450. #double-cv
  2451. $result=~s/\bconst\s+const\b/const/gm;
  2452. $result=~s/\bvolatile\s+volatile\b/volatile/gm;
  2453. $result=~s/\bconst\s+volatile\b\s+const\b/const volatile/gm;
  2454. $result=~s/\bvolatile\s+const\b\s+volatile\b/const volatile/gm;
  2455. #Place cv in proper order
  2456. $result=~s/\bvolatile\s+const\b/const volatile/gm;
  2457. return $result;
  2458. }
  2459. sub unmangled_PostProcess($)
  2460. {
  2461. my $result = $_[0];
  2462. #s/\bunsigned int\b/unsigned/g;
  2463. $result =~ s/\bshort unsigned int\b/unsigned short/g;
  2464. $result =~ s/\bshort int\b/short/g;
  2465. $result =~ s/\blong long unsigned int\b/unsigned long long/g;
  2466. $result =~ s/\blong unsigned int\b/unsigned long/g;
  2467. $result =~ s/\blong long int\b/long long/g;
  2468. $result =~ s/\blong int\b/long/g;
  2469. $result =~ s/\)const\b/\) const/g;
  2470. $result =~ s/\blong long unsigned\b/unsigned long long/g;
  2471. $result =~ s/\blong unsigned\b/unsigned long/g;
  2472. return $result;
  2473. }
  2474. # From libtodb2/libtodb.pm
  2475. # Trim string spaces.
  2476. sub trim($)
  2477. {
  2478. my $string = shift;
  2479. $string =~ s/^\s+//;
  2480. $string =~ s/\s+$//;
  2481. return $string;
  2482. }
  2483. sub correctName($)
  2484. {#type name correction
  2485. my $CorrectName = $_[0];
  2486. $CorrectName = unmangled_Compact($CorrectName, 1);
  2487. $CorrectName = unmangled_PostProcess($CorrectName);
  2488. return $CorrectName;
  2489. }
  2490. sub getDump_AllInOne()
  2491. {
  2492. return if(not keys(%Headers));
  2493. `mkdir -p temp && rm -f temp/*`;
  2494. my $Header_Depend = "";
  2495. foreach my $Dep (sort {length($a) <=> length($b)} keys(%{$Header_Dependency{$Version}}))
  2496. {
  2497. $Header_Depend .= " -I".esc($Dep);
  2498. }
  2499. my $Lib_VersionName = esc($TargetLibraryName)."_v".$Version;
  2500. open(LIB_HEADER, ">temp/$TargetLibraryName"."_v$Version.h");
  2501. foreach my $Preamble_Header (sort {int($Include_Preamble{$Version}{$a}{"Position"})<=>int($Include_Preamble{$Version}{$b}{"Position"})} keys(%{$Include_Preamble{$Version}}))
  2502. {
  2503. print LIB_HEADER "#include <$Preamble_Header>\n";
  2504. }
  2505. foreach my $Destination (sort {int($Headers{$Version}{$a}{"Position"})<=>int($Headers{$Version}{$b}{"Position"})} keys(%{$Headers{$Version}}))
  2506. {
  2507. my $HName = get_FileName($Destination);
  2508. next if($Include_Preamble{$Version}{$Destination} or ($Include_Preamble{$Version}{$HName} and $HeaderName_Destinations{$Version}{$HName} and keys(%{$HeaderName_Destinations{$Version}{$HName}})==1));
  2509. print LIB_HEADER "#include <$Destination>\n";
  2510. }
  2511. close(LIB_HEADER);
  2512. system("g++ >".esc($ERR_PATH{$Version})." 2>&1 -fdump-translation-unit temp/$Lib_VersionName.h $CompilerOptions{$Version} $Header_Depend");
  2513. if($?)
  2514. {
  2515. print "WARNING: some errors have occured while compiling header(s), fix it first!\nyou can see compilation errors in the file \'$ERR_PATH{$Version}\'\n";
  2516. }
  2517. $ConstantsSrc{$Version} = cmd_preprocessor("temp/$Lib_VersionName.h", $CompilerOptions{$Version}." ".$Header_Depend, "define\\ \\|undef\\ \\|#[ ]\\+[0-9]\\+ \".*\"");
  2518. system("mkdir", "-p", "header_compile_errors/$TargetLibraryName/temp/");
  2519. system("cp", "-f", "temp/$TargetLibraryName"."_v$Version.h", "header_compile_errors/$TargetLibraryName/temp/");
  2520. return (split("\n", `find . -maxdepth 1 -name "$Lib_VersionName\.h*\.tu"`))[0];
  2521. }
  2522. sub getDump_Separately($)
  2523. {
  2524. `mkdir -p temp`;
  2525. `rm -f temp/*`;
  2526. my $Destination = $_[0];
  2527. my $Header_Depend = "";
  2528. foreach my $Dep (sort {length($a) <=> length($b)} keys(%{$Header_Dependency{$Version}}))
  2529. {
  2530. $Header_Depend .= " -I".esc($Dep);
  2531. }
  2532. my $Lib_VersionName = esc($TargetLibraryName)."_v".$Version;
  2533. open(LIB_HEADER, ">temp/$TargetLibraryName"."_v$Version.h");
  2534. foreach my $Preamble_Header (sort {int($Include_Preamble{$Version}{$a}{"Position"})<=>int($Include_Preamble{$Version}{$b}{"Position"})} keys(%{$Include_Preamble{$Version}}))
  2535. {
  2536. print LIB_HEADER "#include <$Preamble_Header>\n";
  2537. }
  2538. my $Destination_HName = get_FileName($Destination);
  2539. if(not ( $Include_Preamble{$Version}{$Destination} or ($Include_Preamble{$Version}{$Destination_HName} and $HeaderName_Destinations{$Version}{$Destination_HName} and keys(%{$HeaderName_Destinations{$Version}{$Destination_HName}})==1) ))
  2540. {
  2541. print LIB_HEADER "#include <$Destination>\n";
  2542. }
  2543. close(LIB_HEADER);
  2544. system("g++ >>".esc($ERR_PATH{$Version})." 2>&1 -fdump-translation-unit temp/$Lib_VersionName.h $CompilerOptions{$Version} $Header_Depend");
  2545. if($?)
  2546. {
  2547. $HeaderCompileError{get_FileName($Destination)} = 1;
  2548. }
  2549. $ConstantsSrc{$Version} .= cmd_preprocessor("temp/$Lib_VersionName.h", $CompilerOptions{$Version}." ".$Header_Depend, "define\\ \\|undef\\ \\|#[ ]\\+[0-9]\\+ \".*\"");
  2550. return (split("\n", `find . -maxdepth 1 -name "$Lib_VersionName\.h*\.tu"`))[0];
  2551. }
  2552. sub cmd_file($)
  2553. {
  2554. my $Path = $_[0];
  2555. return "" if(not $Path or not -e $Path);
  2556. my $Cmd = "file ".esc($Path);
  2557. my $Cmd_Out = `$Cmd`;
  2558. return $Cmd_Out;
  2559. }
  2560. sub cmd_preprocessor($$$)
  2561. {
  2562. my ($Path, $AddOpt, $Grep) = @_;
  2563. return "" if(not $Path or not -f $Path);
  2564. my $Cmd = "g++ -dD -E -x c++-header ".esc($Path)." 2>/dev/null $AddOpt";
  2565. if($Grep)
  2566. {
  2567. $Cmd .= " | grep \"$Grep\"";
  2568. }
  2569. my $Cmd_Out = `$Cmd`;
  2570. return $Cmd_Out;
  2571. }
  2572. sub cmd_cat($$)
  2573. {
  2574. my ($Path, $Grep) = @_;
  2575. return "" if(not $Path or not -e $Path);
  2576. my $Cmd = "cat ".esc($Path);
  2577. if($Grep)
  2578. {
  2579. $Cmd .= " | grep \"$Grep\"";
  2580. }
  2581. my $Cmd_Out = `$Cmd`;
  2582. return $Cmd_Out;
  2583. }
  2584. sub cmd_find($$$)
  2585. {
  2586. my ($Path, $Type, $Name) = @_;
  2587. return () if(not $Path or not -e $Path);
  2588. my $Cmd = "find ".esc($Path);
  2589. if($Type)
  2590. {
  2591. $Cmd .= " -type $Type";
  2592. }
  2593. if($Name)
  2594. {
  2595. $Cmd .= " -name \"$Name\"";
  2596. }
  2597. return split("\n", `$Cmd`);
  2598. }
  2599. sub cmd_tar($)
  2600. {
  2601. my $Path = $_[0];
  2602. return "" if(not $Path or not -e $Path);
  2603. my $Cmd = "tar -xvzf ".esc($Path);
  2604. my $Cmd_Out = `$Cmd`;
  2605. return $Cmd_Out;
  2606. }
  2607. sub is_header($$)
  2608. {
  2609. my ($Destination, $LibVersion) = @_;
  2610. return 0 if(-d $Destination);
  2611. return 1 if($Destination =~ /\.(h|hh|hhh|hpp|tcc)\Z/i);
  2612. return 0 if($Destination =~ /\.\w+\Z/i);#cpp|c|gch|tu|fs|pas
  2613. if($Destination =~ /\A\//)
  2614. {
  2615. return (cmd_file($Destination) =~ /:[ ]*ASCII C[\+]* program text/);
  2616. }
  2617. else
  2618. {
  2619. foreach my $Prefix (keys(%{$Header_Dependency{$LibVersion}}))
  2620. {
  2621. my $Path = $Prefix."/".$Destination;
  2622. if(-f $Path)
  2623. {
  2624. if(cmd_file($Path) =~ /:[ ]*ASCII C[\+]* program text/)
  2625. {
  2626. return 1;
  2627. }
  2628. }
  2629. }
  2630. return 0;
  2631. }
  2632. }
  2633. sub parseHeaders_AllInOne($)
  2634. {
  2635. $Version = $_[0];
  2636. print "checking header(s) ".$Descriptor{$Version}{"Version"}." ...\n";
  2637. system("mkdir", "-p", "header_compile_errors/".$TargetLibraryName);
  2638. system("rm", "-fr", $ERR_PATH{$Version});
  2639. my $DumpPath = getDump_AllInOne();
  2640. if(not $DumpPath)
  2641. {
  2642. print "\nERROR: can't create gcc syntax tree for header(s)\nyou can see compilation errors in the file '$ERR_PATH{$Version}'\n";
  2643. exit(1);
  2644. }
  2645. getInfo($DumpPath);
  2646. parse_constants();
  2647. system("rm", "-fr", "temp");
  2648. }
  2649. sub parseHeader($)
  2650. {
  2651. my $Destination = $_[0];
  2652. my $DumpPath = getDump_Separately($Destination);
  2653. if(not $DumpPath)
  2654. {
  2655. print "ERROR: can't create gcc syntax tree for header\nyou can see compilation errors in the file '$ERR_PATH{$Version}'\n";
  2656. exit(1);
  2657. }
  2658. getInfo($DumpPath);
  2659. parse_constants();
  2660. system("rm", "-fr", "temp");
  2661. }
  2662. sub is_in_library($$)
  2663. {
  2664. my ($MnglName, $LibVersion) = @_;
  2665. return ($Interface_Library{$LibVersion}{$MnglName} or ($SymVer{$LibVersion}{$MnglName} and $Interface_Library{$LibVersion}{$SymVer{$LibVersion}{$MnglName}}));
  2666. }
  2667. sub prepareInterfaces($)
  2668. {
  2669. my $LibVersion = $_[0];
  2670. my (@MnglNames, @UnMnglNames) = ();
  2671. if($CheckHeadersOnly)
  2672. {
  2673. foreach my $FuncInfoId (sort keys(%{$FuncDescr{$LibVersion}}))
  2674. {
  2675. if($FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"} =~ /\A_Z/)
  2676. {
  2677. push(@MnglNames, $FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"});
  2678. }
  2679. }
  2680. if($#MnglNames > -1)
  2681. {
  2682. @UnMnglNames = reverse(unmangleArray(@MnglNames));
  2683. foreach my $FuncInfoId (sort keys(%{$FuncDescr{$LibVersion}}))
  2684. {
  2685. if($FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"} =~ /\A_Z/)
  2686. {
  2687. my $UnmangledName = pop(@UnMnglNames);
  2688. $tr_name{$FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"}} = $UnmangledName;
  2689. }
  2690. }
  2691. }
  2692. }
  2693. my (%NotMangled_Int, %Mangled_Int) = ();
  2694. foreach my $FuncInfoId (keys(%{$FuncDescr{$LibVersion}}))
  2695. {
  2696. my $MnglName = $FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"};
  2697. if($MnglName=~/\A_Z/)
  2698. {
  2699. $Mangled_Int{$FuncInfoId} = $MnglName;
  2700. }
  2701. else
  2702. {
  2703. $NotMangled_Int{$FuncInfoId} = $MnglName;
  2704. }
  2705. next if(not $MnglName or not is_in_library($MnglName, $LibVersion) and not $CheckHeadersOnly);
  2706. next if($MnglName =~ /\A_Z/ and $tr_name{$MnglName} =~ /\.\_[0-9]/);
  2707. next if(not $FuncDescr{$LibVersion}{$FuncInfoId}{"Header"});
  2708. %{$CompleteSignature{$LibVersion}{$MnglName}} = %{$FuncDescr{$LibVersion}{$FuncInfoId}};
  2709. #interface and its symlink have same signatures
  2710. if($SymVer{$LibVersion}{$MnglName})
  2711. {
  2712. %{$CompleteSignature{$LibVersion}{$SymVer{$LibVersion}{$MnglName}}} = %{$FuncDescr{$LibVersion}{$FuncInfoId}};
  2713. }
  2714. delete($FuncDescr{$LibVersion}{$FuncInfoId});
  2715. }
  2716. if(keys(%Mangled_Int))
  2717. {
  2718. foreach my $Interface_Id (keys(%NotMangled_Int))
  2719. {
  2720. delete($CompleteSignature{$LibVersion}{$NotMangled_Int{$Interface_Id}});
  2721. }
  2722. }
  2723. }
  2724. my %UsedType;
  2725. sub cleanData($)
  2726. {
  2727. my $LibVersion = $_[0];
  2728. foreach my $FuncInfoId (keys(%{$FuncDescr{$LibVersion}}))
  2729. {
  2730. my $MnglName = $FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"};
  2731. if(not $MnglName or not is_in_library($MnglName, $LibVersion) and not $CheckHeadersOnly)
  2732. {
  2733. delete($FuncDescr{$LibVersion}{$FuncInfoId});
  2734. next;
  2735. }
  2736. if(defined $InterfacesListPath and not $InterfacesList{$MnglName})
  2737. {
  2738. delete($FuncDescr{$LibVersion}{$FuncInfoId});
  2739. next;
  2740. }
  2741. if(defined $AppPath and not $InterfacesList_App{$MnglName})
  2742. {
  2743. delete($FuncDescr{$LibVersion}{$FuncInfoId});
  2744. next;
  2745. }
  2746. my %FuncInfo = %{$FuncDescr{$LibVersion}{$FuncInfoId}};
  2747. detect_TypeUsing($Tid_TDid{$LibVersion}{$FuncInfo{"Return"}}, $FuncInfo{"Return"}, $LibVersion);
  2748. detect_TypeUsing($Tid_TDid{$LibVersion}{$FuncInfo{"Class"}}, $FuncInfo{"Class"}, $LibVersion);
  2749. foreach my $Param_Pos (keys(%{$FuncInfo{"Param"}}))
  2750. {
  2751. my $Param_TypeId = $FuncInfo{"Param"}{$Param_Pos}{"type"};
  2752. detect_TypeUsing($Tid_TDid{$LibVersion}{$Param_TypeId}, $Param_TypeId, $LibVersion);
  2753. }
  2754. }
  2755. foreach my $TDid (keys(%{$TypeDescr{$LibVersion}}))
  2756. {
  2757. foreach my $Tid (keys(%{$TypeDescr{$LibVersion}{$TDid}}))
  2758. {
  2759. if(not $UsedType{$LibVersion}{$TDid}{$Tid})
  2760. {
  2761. delete($TypeDescr{$LibVersion}{$TDid}{$Tid});
  2762. if(not keys(%{$TypeDescr{$LibVersion}{$TDid}}))
  2763. {
  2764. delete($TypeDescr{$LibVersion}{$TDid});
  2765. }
  2766. delete($Tid_TDid{$LibVersion}{$Tid}) if($Tid_TDid{$LibVersion}{$Tid} eq $TDid);
  2767. }
  2768. }
  2769. }
  2770. }
  2771. sub detect_TypeUsing($$$)
  2772. {
  2773. my ($TypeDeclId, $TypeId, $LibVersion) = @_;
  2774. return if($UsedType{$LibVersion}{$TypeDeclId}{$TypeId});
  2775. my %Type = get_Type($TypeDeclId, $TypeId, $LibVersion);
  2776. if($Type{"Type"} =~ /Struct|Union|Class|FuncPtr|Enum/)
  2777. {
  2778. $UsedType{$LibVersion}{$TypeDeclId}{$TypeId} = 1;
  2779. foreach my $Memb_Pos (keys(%{$Type{"Memb"}}))
  2780. {
  2781. my $Member_TypeId = $Type{"Memb"}{$Memb_Pos}{"type"};
  2782. detect_TypeUsing($Tid_TDid{$LibVersion}{$Member_TypeId}, $Member_TypeId, $LibVersion);
  2783. }
  2784. if($Type{"Type"} eq "FuncPtr")
  2785. {
  2786. my $ReturnType = $Type{"Return"};
  2787. detect_TypeUsing($Tid_TDid{$LibVersion}{$ReturnType}, $ReturnType, $LibVersion);
  2788. }
  2789. }
  2790. elsif($Type{"Type"} =~ /Const|Pointer|Ref|Volatile|Restrict|Array|/)
  2791. {
  2792. $UsedType{$LibVersion}{$TypeDeclId}{$TypeId} = 1;
  2793. detect_TypeUsing($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion);
  2794. }
  2795. elsif($Type{"Type"} eq "Intrinsic")
  2796. {
  2797. $UsedType{$LibVersion}{$TypeDeclId}{$TypeId} = 1;
  2798. }
  2799. else
  2800. {
  2801. delete($TypeDescr{$LibVersion}{$TypeDeclId}{$TypeId});
  2802. if(not keys(%{$TypeDescr{$LibVersion}{$TypeDeclId}}))
  2803. {
  2804. delete($TypeDescr{$LibVersion}{$TypeDeclId});
  2805. }
  2806. delete($Tid_TDid{$LibVersion}{$TypeId}) if($Tid_TDid{$LibVersion}{$TypeId} eq $TypeDeclId);
  2807. }
  2808. }
  2809. sub initializeClassVirtFunc($)
  2810. {
  2811. my $LibVersion = $_[0];
  2812. foreach my $Interface (keys(%{$CompleteSignature{$LibVersion}}))
  2813. {
  2814. if($CompleteSignature{$LibVersion}{$Interface}{"Virt"})
  2815. {
  2816. my $ClassName = $TypeDescr{$LibVersion}{$Tid_TDid{$LibVersion}{$CompleteSignature{$LibVersion}{$Interface}{"Class"}}}{$CompleteSignature{$LibVersion}{$Interface}{"Class"}}{"Name"};
  2817. $ClassVirtFunc{$LibVersion}{$ClassName}{$Interface} = 1;
  2818. $ClassIdVirtFunc{$LibVersion}{$CompleteSignature{$LibVersion}{$Interface}{"Class"}}{$Interface} = 1;
  2819. $ClassId{$LibVersion}{$ClassName} = $CompleteSignature{$LibVersion}{$Interface}{"Class"};
  2820. }
  2821. }
  2822. }
  2823. sub checkVirtFuncRedefinitions($)
  2824. {
  2825. my $LibVersion = $_[0];
  2826. foreach my $Class_Name (keys(%{$ClassVirtFunc{$LibVersion}}))
  2827. {
  2828. $CheckedTypes{$Class_Name} = 1;
  2829. foreach my $VirtFuncName (keys(%{$ClassVirtFunc{$LibVersion}{$Class_Name}}))
  2830. {
  2831. $CompleteSignature{$LibVersion}{$VirtFuncName}{"VirtualRedefine"} = find_virtual_method_in_base_classes($VirtFuncName, $ClassId{$LibVersion}{$Class_Name}, $LibVersion);
  2832. }
  2833. }
  2834. }
  2835. sub setVirtFuncPositions($)
  2836. {
  2837. my $LibVersion = $_[0];
  2838. foreach my $Class_Name (keys(%{$ClassVirtFunc{$LibVersion}}))
  2839. {
  2840. $CheckedTypes{$Class_Name} = 1;
  2841. my $Position = 0;
  2842. foreach my $VirtFuncName (sort {int($CompleteSignature{$LibVersion}{$a}{"Line"}) <=> int($CompleteSignature{$LibVersion}{$b}{"Line"})} keys(%{$ClassVirtFunc{$LibVersion}{$Class_Name}}))
  2843. {
  2844. if($ClassVirtFunc{1}{$Class_Name}{$VirtFuncName} and $ClassVirtFunc{2}{$Class_Name}{$VirtFuncName} and not $CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"} and not $CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"})
  2845. {
  2846. $CompleteSignature{$LibVersion}{$VirtFuncName}{"Position"} = $Position;
  2847. $Position += 1;
  2848. }
  2849. }
  2850. }
  2851. }
  2852. sub check_VirtualTable($$)
  2853. {
  2854. my ($TargetFunction, $LibVersion) = @_;
  2855. my $Class_Id = $CompleteSignature{$LibVersion}{$TargetFunction}{"Class"};
  2856. my $Class_DId = $Tid_TDid{$LibVersion}{$Class_Id};
  2857. my %Class_Type = get_Type($Class_DId, $Class_Id, $LibVersion);
  2858. $CheckedTypes{$Class_Type{"Name"}} = 1;
  2859. foreach my $VirtFuncName (keys(%{$ClassVirtFunc{2}{$Class_Type{"Name"}}}))
  2860. {#Added
  2861. if($ClassId{1}{$Class_Type{"Name"}} and not $ClassVirtFunc{1}{$Class_Type{"Name"}}{$VirtFuncName} and $AddedInt{$VirtFuncName})
  2862. {
  2863. if($CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"})
  2864. {
  2865. if($TargetFunction eq $VirtFuncName)
  2866. {
  2867. my $BaseClass_Id = $CompleteSignature{2}{$CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"}}{"Class"};
  2868. my %BaseClass_Type = get_Type($Tid_TDid{2}{$BaseClass_Id}, $BaseClass_Id, 2);
  2869. my $BaseClass_Name = $BaseClass_Type{"Name"};
  2870. %{$CompatProblems{$TargetFunction}{"Virtual_Function_Redefinition"}{$tr_name{$CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"}}}}=(
  2871. "Type_Name"=>$Class_Type{"Name"},
  2872. "Type_Type"=>$Class_Type{"Type"},
  2873. "Header"=>$CompleteSignature{2}{$TargetFunction}{"Header"},
  2874. "Line"=>$CompleteSignature{2}{$TargetFunction}{"Line"},
  2875. "Target"=>$tr_name{$CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"}},
  2876. "Signature"=>$tr_name{$TargetFunction},
  2877. "Old_Value"=>$tr_name{$CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"}},
  2878. "New_Value"=>$tr_name{$TargetFunction},
  2879. "Old_SoName"=>$Interface_Library{1}{$TargetFunction},
  2880. "New_SoName"=>$Interface_Library{2}{$TargetFunction} );
  2881. }
  2882. }
  2883. elsif($TargetFunction ne $VirtFuncName)
  2884. {
  2885. %{$CompatProblems{$TargetFunction}{"Added_Virtual_Function"}{$tr_name{$VirtFuncName}}}=(
  2886. "Type_Name"=>$Class_Type{"Name"},
  2887. "Type_Type"=>$Class_Type{"Type"},
  2888. "Header"=>$Class_Type{"Header"},
  2889. "Line"=>$Class_Type{"Line"},
  2890. "Target"=>$tr_name{$VirtFuncName},
  2891. "Signature"=>$tr_name{$TargetFunction},
  2892. "Old_SoName"=>$Interface_Library{1}{$TargetFunction},
  2893. "New_SoName"=>$Interface_Library{2}{$TargetFunction} );
  2894. }
  2895. }
  2896. }
  2897. foreach my $VirtFuncName (keys(%{$ClassVirtFunc{1}{$Class_Type{"Name"}}}))
  2898. {#Withdrawn
  2899. if($ClassId{2}{$Class_Type{"Name"}} and not $ClassVirtFunc{2}{$Class_Type{"Name"}}{$VirtFuncName} and $WithdrawnInt{$VirtFuncName})
  2900. {
  2901. if($CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"})
  2902. {
  2903. if($TargetFunction eq $VirtFuncName)
  2904. {
  2905. my $BaseClass_Id = $CompleteSignature{1}{$CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"}}{"Class"};
  2906. my $BaseClass_Name = $TypeDescr{1}{$Tid_TDid{1}{$BaseClass_Id}}{$BaseClass_Id}{"Name"};
  2907. %{$CompatProblems{$TargetFunction}{"Virtual_Function_Redefinition_B"}{$tr_name{$CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"}}}}=(
  2908. "Type_Name"=>$Class_Type{"Name"},
  2909. "Type_Type"=>$Class_Type{"Type"},
  2910. "Header"=>$CompleteSignature{2}{$TargetFunction}{"Header"},
  2911. "Line"=>$CompleteSignature{2}{$TargetFunction}{"Line"},
  2912. "Target"=>$tr_name{$CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"}},
  2913. "Signature"=>$tr_name{$TargetFunction},
  2914. "Old_Value"=>$tr_name{$TargetFunction},
  2915. "New_Value"=>$tr_name{$CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"}},
  2916. "Old_SoName"=>$Interface_Library{1}{$TargetFunction},
  2917. "New_SoName"=>$Interface_Library{2}{$TargetFunction} );
  2918. }
  2919. }
  2920. else
  2921. {
  2922. %{$CompatProblems{$TargetFunction}{"Withdrawn_Virtual_Function"}{$tr_name{$VirtFuncName}}}=(
  2923. "Type_Name"=>$Class_Type{"Name"},
  2924. "Type_Type"=>$Class_Type{"Type"},
  2925. "Header"=>$Class_Type{"Header"},
  2926. "Line"=>$Class_Type{"Line"},
  2927. "Target"=>$tr_name{$VirtFuncName},
  2928. "Signature"=>$tr_name{$TargetFunction},
  2929. "Old_SoName"=>$Interface_Library{1}{$TargetFunction},
  2930. "New_SoName"=>$Interface_Library{2}{$TargetFunction} );
  2931. }
  2932. }
  2933. }
  2934. }
  2935. sub find_virtual_method_in_base_classes($$$)
  2936. {
  2937. my ($VirtFuncName, $Checked_ClassId, $LibVersion) = @_;
  2938. foreach my $BaseClass_Id (keys(%{$TypeDescr{$LibVersion}{$Tid_TDid{$LibVersion}{$Checked_ClassId}}{$Checked_ClassId}{"BaseClass"}}))
  2939. {
  2940. my $VirtMethodInClass = find_virtual_method_in_class($VirtFuncName, $BaseClass_Id, $LibVersion);
  2941. if($VirtMethodInClass)
  2942. {
  2943. return $VirtMethodInClass;
  2944. }
  2945. my $VirtMethodInBaseClasses = find_virtual_method_in_base_classes($VirtFuncName, $BaseClass_Id, $LibVersion);
  2946. if($VirtMethodInBaseClasses)
  2947. {
  2948. return $VirtMethodInBaseClasses;
  2949. }
  2950. }
  2951. return "";
  2952. }
  2953. sub find_virtual_method_in_class($$$)
  2954. {
  2955. my ($VirtFuncName, $Checked_ClassId, $LibVersion) = @_;
  2956. my $Suffix = getFuncSuffix($VirtFuncName, $LibVersion);
  2957. foreach my $Checked_VirtFuncName (keys(%{$ClassIdVirtFunc{$LibVersion}{$Checked_ClassId}}))
  2958. {
  2959. if($Suffix eq getFuncSuffix($Checked_VirtFuncName, $LibVersion)
  2960. and ((not $CompleteSignature{$LibVersion}{$VirtFuncName}{"Constructor"} and not $CompleteSignature{$LibVersion}{$VirtFuncName}{"Destructor"} and $CompleteSignature{$LibVersion}{$VirtFuncName}{"ShortName"} eq $CompleteSignature{$LibVersion}{$Checked_VirtFuncName}{"ShortName"}) or ($CompleteSignature{$LibVersion}{$VirtFuncName}{"Constructor"} or $CompleteSignature{$LibVersion}{$VirtFuncName}{"Destructor"})))
  2961. {
  2962. return $Checked_VirtFuncName;
  2963. }
  2964. }
  2965. return "";
  2966. }
  2967. sub getFuncSuffix($$)
  2968. {
  2969. my ($FuncName, $LibVersion) = @_;
  2970. my $ClassId = $CompleteSignature{$LibVersion}{$FuncName}{"Class"};
  2971. my $ClassName = $TypeDescr{$LibVersion}{$Tid_TDid{$LibVersion}{$ClassId}}{$ClassId}{"Name"};
  2972. my $ShortName = $CompleteSignature{$LibVersion}{$FuncName}{"ShortName"};
  2973. my $Suffix = $tr_name{$FuncName};
  2974. $Suffix =~ s/\A$ClassName\:\:[~]*$ShortName[ ]*//g;
  2975. return $Suffix;
  2976. }
  2977. sub isRecurType($$$$)
  2978. {
  2979. foreach (@RecurTypes)
  2980. {
  2981. if($_->{"Tid1"} eq $_[0]
  2982. and $_->{"TDid1"} eq $_[1]
  2983. and $_->{"Tid2"} eq $_[2]
  2984. and $_->{"TDid2"} eq $_[3])
  2985. {
  2986. return 1;
  2987. }
  2988. }
  2989. return 0;
  2990. }
  2991. sub find_MemberPair_Pos_byName($$)
  2992. {
  2993. my ($Member_Name, $Pair_Type) = @_;
  2994. foreach my $MemberPair_Pos (sort keys(%{$Pair_Type->{"Memb"}}))
  2995. {
  2996. if($Pair_Type->{"Memb"}{$MemberPair_Pos}{"name"} eq $Member_Name)
  2997. {
  2998. return $MemberPair_Pos;
  2999. }
  3000. }
  3001. return "lost";
  3002. }
  3003. sub getBitfieldSum($$)
  3004. {
  3005. my ($Member_Pos, $Pair_Type) = @_;
  3006. my $BitfieldSum = 0;
  3007. while($Member_Pos>-1)
  3008. {
  3009. return $BitfieldSum if(not $Pair_Type->{"Memb"}{$Member_Pos}{"bitfield"});
  3010. $BitfieldSum += $Pair_Type->{"Memb"}{$Member_Pos}{"bitfield"};
  3011. $Member_Pos -= 1;
  3012. }
  3013. return $BitfieldSum;
  3014. }
  3015. sub find_MemberPair_Pos_byVal($$)
  3016. {
  3017. my ($Member_Value, $Pair_Type) = @_;
  3018. foreach my $MemberPair_Pos (sort keys(%{$Pair_Type->{"Memb"}}))
  3019. {
  3020. if($Pair_Type->{"Memb"}{$MemberPair_Pos}{"value"} eq $Member_Value)
  3021. {
  3022. return $MemberPair_Pos;
  3023. }
  3024. }
  3025. return "lost";
  3026. }
  3027. my %Priority_Value=(
  3028. "High"=>3,
  3029. "Medium"=>2,
  3030. "Low"=>1
  3031. );
  3032. sub max_priority($$)
  3033. {
  3034. my ($Priority1, $Priority2) = @_;
  3035. if(cmp_priority($Priority1, $Priority2))
  3036. {
  3037. return $Priority1;
  3038. }
  3039. else
  3040. {
  3041. return $Priority2;
  3042. }
  3043. }
  3044. sub cmp_priority($$)
  3045. {
  3046. my ($Priority1, $Priority2) = @_;
  3047. return ($Priority_Value{$Priority1}>$Priority_Value{$Priority2});
  3048. }
  3049. sub set_Problems_Priority()
  3050. {
  3051. foreach my $InterfaceName (sort keys(%CompatProblems))
  3052. {
  3053. foreach my $Kind (sort keys(%{$CompatProblems{$InterfaceName}}))
  3054. {
  3055. foreach my $Location (sort keys(%{$CompatProblems{$InterfaceName}{$Kind}}))
  3056. {
  3057. my $IsInTypeInternals = $CompatProblems{$InterfaceName}{$Kind}{$Location}{"IsInTypeInternals"};
  3058. my $InitialType_Type = $CompatProblems{$InterfaceName}{$Kind}{$Location}{"InitialType_Type"};
  3059. if($Kind eq "Function_Become_Static")
  3060. {
  3061. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
  3062. }
  3063. elsif($Kind eq "Function_Become_NonStatic")
  3064. {
  3065. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
  3066. }
  3067. elsif($Kind eq "Parameter_Type_And_Size")
  3068. {
  3069. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
  3070. }
  3071. elsif($Kind eq "Parameter_Type")
  3072. {
  3073. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
  3074. }
  3075. elsif($Kind eq "Withdrawn_Parameter")
  3076. {
  3077. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
  3078. }
  3079. elsif($Kind eq "Added_Parameter")
  3080. {
  3081. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
  3082. }
  3083. elsif($Kind eq "Parameter_BaseType_And_Size")
  3084. {
  3085. if($InitialType_Type eq "Pointer")
  3086. {
  3087. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
  3088. }
  3089. else
  3090. {
  3091. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
  3092. }
  3093. }
  3094. elsif($Kind eq "Parameter_BaseType")
  3095. {
  3096. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
  3097. }
  3098. elsif($Kind eq "Parameter_PointerLevel")
  3099. {
  3100. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
  3101. }
  3102. elsif($Kind eq "Return_Type_And_Size")
  3103. {
  3104. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
  3105. }
  3106. elsif($Kind eq "Return_Type")
  3107. {
  3108. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
  3109. }
  3110. elsif($Kind eq "Return_BaseType_And_Size")
  3111. {
  3112. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
  3113. }
  3114. elsif($Kind eq "Return_BaseType")
  3115. {
  3116. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
  3117. }
  3118. elsif($Kind eq "Return_PointerLevel")
  3119. {
  3120. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
  3121. }
  3122. if($Kind eq "Added_Virtual_Function")
  3123. {
  3124. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
  3125. }
  3126. elsif($Kind eq "Withdrawn_Virtual_Function")
  3127. {
  3128. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
  3129. }
  3130. elsif($Kind eq "Virtual_Function_Position")
  3131. {
  3132. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
  3133. }
  3134. elsif($Kind eq "Virtual_Function_Redefinition")
  3135. {
  3136. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
  3137. }
  3138. elsif($Kind eq "Virtual_Function_Redefinition_B")
  3139. {
  3140. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
  3141. }
  3142. elsif($Kind eq "Size")
  3143. {
  3144. if(($InitialType_Type eq "Pointer") or ($InitialType_Type eq "Array"))
  3145. {
  3146. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
  3147. }
  3148. else
  3149. {
  3150. if($IsInTypeInternals)
  3151. {
  3152. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
  3153. }
  3154. else
  3155. {
  3156. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
  3157. }
  3158. }
  3159. }
  3160. elsif($Kind eq "BaseType")
  3161. {
  3162. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
  3163. }
  3164. elsif($Kind eq "Added_Member_And_Size")
  3165. {
  3166. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
  3167. }
  3168. elsif($Kind eq "Added_Middle_Member_And_Size")
  3169. {
  3170. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
  3171. }
  3172. elsif($Kind eq "Withdrawn_Member_And_Size")
  3173. {
  3174. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
  3175. }
  3176. elsif($Kind eq "Withdrawn_Member")
  3177. {
  3178. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
  3179. }
  3180. elsif($Kind eq "Withdrawn_Middle_Member_And_Size")
  3181. {
  3182. if($IsInTypeInternals)
  3183. {
  3184. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
  3185. }
  3186. else
  3187. {
  3188. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
  3189. }
  3190. }
  3191. elsif($Kind eq "Withdrawn_Middle_Member")
  3192. {
  3193. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
  3194. }
  3195. elsif($Kind eq "Member_Rename")
  3196. {
  3197. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
  3198. }
  3199. elsif($Kind eq "Enum_Member_Value")
  3200. {
  3201. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
  3202. }
  3203. elsif($Kind eq "Enum_Member_Name")
  3204. {
  3205. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
  3206. }
  3207. elsif($Kind eq "Member_Type_And_Size")
  3208. {
  3209. if(($InitialType_Type eq "Pointer") or ($InitialType_Type eq "Array"))
  3210. {
  3211. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
  3212. }
  3213. else
  3214. {
  3215. if($IsInTypeInternals)
  3216. {
  3217. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
  3218. }
  3219. else
  3220. {
  3221. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
  3222. }
  3223. }
  3224. }
  3225. elsif($Kind eq "Member_Type")
  3226. {
  3227. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
  3228. }
  3229. elsif($Kind eq "Member_BaseType_And_Size")
  3230. {
  3231. if(($InitialType_Type eq "Pointer") or ($InitialType_Type eq "Array"))
  3232. {
  3233. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
  3234. }
  3235. else
  3236. {
  3237. if($IsInTypeInternals)
  3238. {
  3239. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
  3240. }
  3241. else
  3242. {
  3243. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
  3244. }
  3245. }
  3246. }
  3247. elsif($Kind eq "Member_BaseType")
  3248. {
  3249. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
  3250. }
  3251. elsif($Kind eq "Member_PointerLevel")
  3252. {
  3253. if(($InitialType_Type eq "Pointer") or ($InitialType_Type eq "Array"))
  3254. {
  3255. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
  3256. }
  3257. else
  3258. {
  3259. if($IsInTypeInternals)
  3260. {
  3261. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
  3262. }
  3263. else
  3264. {
  3265. $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
  3266. }
  3267. }
  3268. }
  3269. }
  3270. }
  3271. }
  3272. }
  3273. sub pushType($$$$)
  3274. {
  3275. my %TypeDescriptor=(
  3276. "Tid1" => $_[0],
  3277. "TDid1" => $_[1],
  3278. "Tid2" => $_[2],
  3279. "TDid2" => $_[3] );
  3280. push(@RecurTypes, \%TypeDescriptor);
  3281. }
  3282. sub mergeTypes($$$$)
  3283. {
  3284. my ($Type1_Id, $Type1_DId, $Type2_Id, $Type2_DId) = @_;
  3285. my (%Sub_SubProblems, %SubProblems) = ();
  3286. if((not $Type1_Id and not $Type1_DId) or (not $Type2_Id and not $Type2_DId))
  3287. {#Not Empty Inputs Only
  3288. return ();
  3289. }
  3290. if($Cache{"mergeTypes"}{$Type1_Id}{$Type1_DId}{$Type2_Id}{$Type2_DId})
  3291. {#Already Merged
  3292. return %{$Cache{"mergeTypes"}{$Type1_Id}{$Type1_DId}{$Type2_Id}{$Type2_DId}};
  3293. }
  3294. my %Type1 = get_Type($Type1_DId, $Type1_Id, 1);
  3295. my %Type2 = get_Type($Type2_DId, $Type2_Id, 2);
  3296. my %Type1_Pure = get_PureType($Type1_DId, $Type1_Id, 1);
  3297. my %Type2_Pure = get_PureType($Type2_DId, $Type2_Id, 2);
  3298. return () if(not $Type1_Pure{"Size"} or not $Type2_Pure{"Size"});
  3299. if(isRecurType($Type1_Pure{"Tid"}, $Type1_Pure{"TDid"}, $Type2_Pure{"Tid"}, $Type2_Pure{"TDid"}))
  3300. {#Recursive Declarations
  3301. return ();
  3302. }
  3303. return if(not $Type1_Pure{"Name"} or not $Type2_Pure{"Name"});
  3304. return if($OpaqueTypes{1}{$Type1_Pure{"Name"}} or $OpaqueTypes{2}{$Type1_Pure{"Name"}} or $OpaqueTypes{1}{$Type1{"Name"}} or $OpaqueTypes{2}{$Type1{"Name"}});
  3305. my %Typedef_1 = goToFirst($Type1{"TDid"}, $Type1{"Tid"}, 1, "Typedef");
  3306. my %Typedef_2 = goToFirst($Type2{"TDid"}, $Type2{"Tid"}, 2, "Typedef");
  3307. if($Typedef_1{"Type"} eq "Typedef" and $Typedef_2{"Type"} eq "Typedef" and $Typedef_1{"Name"} eq $Typedef_2{"Name"})
  3308. {
  3309. my %Base_1 = get_OneStep_BaseType($Typedef_1{"TDid"}, $Typedef_1{"Tid"}, 1);
  3310. my %Base_2 = get_OneStep_BaseType($Typedef_2{"TDid"}, $Typedef_2{"Tid"}, 2);
  3311. if($Base_1{"Name"}!~/anon\-/ and $Base_2{"Name"}!~/anon\-/
  3312. and ($Base_1{"Name"} ne $Base_2{"Name"}))
  3313. {
  3314. %{$SubProblems{"BaseType"}{$Typedef_1{"Name"}}}=(
  3315. "Type_Name"=>$Typedef_1{"Name"},
  3316. "Type_Type"=>"Typedef",
  3317. "Header"=>$Typedef_2{"Header"},
  3318. "Line"=>$Typedef_2{"Line"},
  3319. "Old_Value"=>$Base_1{"Name"},
  3320. "New_Value"=>$Base_2{"Name"} );
  3321. }
  3322. }
  3323. if(($Type1_Pure{"Name"} ne $Type2_Pure{"Name"}) and ($Type1_Pure{"Type"} ne "Pointer") and $Type1_Pure{"Name"}!~/anon\-/)
  3324. {#Different types
  3325. return ();
  3326. }
  3327. pushType($Type1_Pure{"Tid"}, $Type1_Pure{"TDid"}, $Type2_Pure{"Tid"}, $Type2_Pure{"TDid"});
  3328. if(($Type1_Pure{"Name"} eq $Type2_Pure{"Name"}) and ($Type1_Pure{"Type"} =~ /Struct|Class|Union/))
  3329. {#Check Size
  3330. if($Type1_Pure{"Size"} ne $Type2_Pure{"Size"})
  3331. {
  3332. %{$SubProblems{"Size"}{$Type1_Pure{"Name"}}}=(
  3333. "Type_Name"=>$Type1_Pure{"Name"},
  3334. "Type_Type"=>$Type1_Pure{"Type"},
  3335. "Header"=>$Type2_Pure{"Header"},
  3336. "Line"=>$Type2_Pure{"Line"},
  3337. "Old_Value"=>$Type1_Pure{"Size"},
  3338. "New_Value"=>$Type2_Pure{"Size"} );
  3339. }
  3340. }
  3341. if($Type1_Pure{"Name"} and $Type2_Pure{"Name"} and ($Type1_Pure{"Name"} ne $Type2_Pure{"Name"}) and ($Type1_Pure{"Name"} !~ /\Avoid[ ]*\*/) and ($Type2_Pure{"Name"} =~ /\Avoid[ ]*\*/))
  3342. {#Check "void *"
  3343. pop(@RecurTypes);
  3344. return ();
  3345. }
  3346. if($Type1_Pure{"BaseType"}{"Tid"} and $Type2_Pure{"BaseType"}{"Tid"})
  3347. {#Check Base Types
  3348. %Sub_SubProblems = &mergeTypes($Type1_Pure{"BaseType"}{"Tid"}, $Type1_Pure{"BaseType"}{"TDid"}, $Type2_Pure{"BaseType"}{"Tid"}, $Type2_Pure{"BaseType"}{"TDid"});
  3349. foreach my $Sub_SubProblemType (keys(%Sub_SubProblems))
  3350. {
  3351. foreach my $Sub_SubLocation (keys(%{$Sub_SubProblems{$Sub_SubProblemType}}))
  3352. {
  3353. %{$SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}} = %{$Sub_SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}};
  3354. $SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}{"InitialType_Type"} = $Type1_Pure{"Type"};
  3355. }
  3356. }
  3357. }
  3358. foreach my $Member_Pos (sort keys(%{$Type1_Pure{"Memb"}}))
  3359. {#Check Members
  3360. next if($Type1_Pure{"Memb"}{$Member_Pos}{"access"} eq "private");
  3361. my $Member_Name = $Type1_Pure{"Memb"}{$Member_Pos}{"name"};
  3362. next if(not $Member_Name);
  3363. my $Member_Location = $Member_Name;
  3364. my $MemberPair_Pos = find_MemberPair_Pos_byName($Member_Name, \%Type2_Pure);
  3365. if(($MemberPair_Pos eq "lost") and (($Type2_Pure{"Type"} eq "Struct") or ($Type2_Pure{"Type"} eq "Class")))
  3366. {#Withdrawn_Member
  3367. if($Member_Pos > keys(%{$Type2_Pure{"Memb"}}) - 1)
  3368. {
  3369. if($Type1_Pure{"Size"} ne $Type2_Pure{"Size"})
  3370. {
  3371. %{$SubProblems{"Withdrawn_Member_And_Size"}{$Member_Name}}=(
  3372. "Target"=>$Member_Name,
  3373. "Type_Name"=>$Type1_Pure{"Name"},
  3374. "Type_Type"=>$Type1_Pure{"Type"},
  3375. "Header"=>$Type2_Pure{"Header"},
  3376. "Line"=>$Type2_Pure{"Line"},
  3377. "Old_Size"=>$Type1_Pure{"Size"},
  3378. "New_Size"=>$Type2_Pure{"Size"} );
  3379. }
  3380. else
  3381. {
  3382. %{$SubProblems{"Withdrawn_Member"}{$Member_Name}}=(
  3383. "Target"=>$Member_Name,
  3384. "Type_Name"=>$Type1_Pure{"Name"},
  3385. "Type_Type"=>$Type1_Pure{"Type"},
  3386. "Header"=>$Type2_Pure{"Header"},
  3387. "Line"=>$Type2_Pure{"Line"} );
  3388. }
  3389. next;
  3390. }
  3391. elsif($Member_Pos < keys(%{$Type1_Pure{"Memb"}}) - 1)
  3392. {
  3393. my $MemberType_Id = $Type1_Pure{"Memb"}{$Member_Pos}{"type"};
  3394. my %MemberType_Pure = get_PureType($Tid_TDid{1}{$MemberType_Id}, $MemberType_Id, 1);
  3395. my $MemberStraightPairType_Id = $Type2_Pure{"Memb"}{$Member_Pos}{"type"};
  3396. my %MemberStraightPairType_Pure = get_PureType($Tid_TDid{2}{$MemberStraightPairType_Id}, $MemberStraightPairType_Id, 2);
  3397. if(($MemberType_Pure{"Size"} eq $MemberStraightPairType_Pure{"Size"}) and find_MemberPair_Pos_byName($Type2_Pure{"Memb"}{$Member_Pos}{"name"}, \%Type1_Pure) eq "lost")
  3398. {
  3399. %{$SubProblems{"Member_Rename"}{$Member_Name}}=(
  3400. "Target"=>$Member_Name,
  3401. "Type_Name"=>$Type1_Pure{"Name"},
  3402. "Type_Type"=>$Type1_Pure{"Type"},
  3403. "Header"=>$Type2_Pure{"Header"},
  3404. "Line"=>$Type2_Pure{"Line"},
  3405. "Old_Value"=>$Type1_Pure{"Memb"}{$Member_Pos}{"name"},
  3406. "New_Value"=>$Type2_Pure{"Memb"}{$Member_Pos}{"name"} );
  3407. $MemberPair_Pos = $Member_Pos;
  3408. }
  3409. else
  3410. {
  3411. if($Type1_Pure{"Memb"}{$Member_Pos}{"bitfield"})
  3412. {
  3413. my $BitfieldSum = getBitfieldSum($Member_Pos-1, \%Type1_Pure)%($POINTER_SIZE*8);
  3414. if($BitfieldSum and $BitfieldSum-$Type2_Pure{"Memb"}{$Member_Pos}{"bitfield"}>=0)
  3415. {
  3416. %{$SubProblems{"Withdrawn_Middle_Member"}{$Member_Name}}=(
  3417. "Target"=>$Member_Name,
  3418. "Type_Name"=>$Type1_Pure{"Name"},
  3419. "Type_Type"=>$Type1_Pure{"Type"},
  3420. "Header"=>$Type2_Pure{"Header"},
  3421. "Line"=>$Type2_Pure{"Line"} );
  3422. next;
  3423. }
  3424. }
  3425. %{$SubProblems{"Withdrawn_Middle_Member_And_Size"}{$Member_Name}}=(
  3426. "Target"=>$Member_Name,
  3427. "Type_Name"=>$Type1_Pure{"Name"},
  3428. "Type_Type"=>$Type1_Pure{"Type"},
  3429. "Header"=>$Type2_Pure{"Header"},
  3430. "Line"=>$Type2_Pure{"Line"} );
  3431. next;
  3432. }
  3433. }
  3434. }
  3435. if($Type1_Pure{"Type"} eq "Enum")
  3436. {
  3437. my $Member_Value1 = $Type1_Pure{"Memb"}{$Member_Pos}{"value"};
  3438. next if(not $Member_Value1);
  3439. my $Member_Value2 = $Type2_Pure{"Memb"}{$MemberPair_Pos}{"value"};
  3440. if($MemberPair_Pos eq "lost")
  3441. {
  3442. $MemberPair_Pos = find_MemberPair_Pos_byVal($Member_Value1, \%Type2_Pure);
  3443. if($MemberPair_Pos ne "lost")
  3444. {
  3445. %{$SubProblems{"Enum_Member_Name"}{$Type1_Pure{"Memb"}{$Member_Pos}{"value"}}}=(
  3446. "Target"=>$Type1_Pure{"Memb"}{$Member_Pos}{"value"},
  3447. "Type_Name"=>$Type1_Pure{"Name"},
  3448. "Type_Type"=>"Enum",
  3449. "Header"=>$Type2_Pure{"Header"},
  3450. "Line"=>$Type2_Pure{"Line"},
  3451. "Old_Value"=>$Type1_Pure{"Memb"}{$Member_Pos}{"name"},
  3452. "New_Value"=>$Type2_Pure{"Memb"}{$MemberPair_Pos}{"name"} );
  3453. }
  3454. }
  3455. else
  3456. {
  3457. if($Member_Value1 ne "" and $Member_Value2 ne "")
  3458. {
  3459. if($Member_Value1 ne $Member_Value2)
  3460. {
  3461. %{$SubProblems{"Enum_Member_Value"}{$Member_Name}}=(
  3462. "Target"=>$Member_Name,
  3463. "Type_Name"=>$Type1_Pure{"Name"},
  3464. "Type_Type"=>"Enum",
  3465. "Header"=>$Type2_Pure{"Header"},
  3466. "Line"=>$Type2_Pure{"Line"},
  3467. "Old_Value"=>$Type1_Pure{"Memb"}{$Member_Pos}{"value"},
  3468. "New_Value"=>$Type2_Pure{"Memb"}{$MemberPair_Pos}{"value"} );
  3469. }
  3470. }
  3471. }
  3472. next;
  3473. }
  3474. my $MemberType1_Id = $Type1_Pure{"Memb"}{$Member_Pos}{"type"};
  3475. my $MemberType2_Id = $Type2_Pure{"Memb"}{$MemberPair_Pos}{"type"};
  3476. %Sub_SubProblems = detectTypeChange($MemberType1_Id, $MemberType2_Id, "Member");
  3477. foreach my $Sub_SubProblemType (keys(%Sub_SubProblems))
  3478. {
  3479. %{$SubProblems{$Sub_SubProblemType}{$Member_Name}}=(
  3480. "Target"=>$Member_Name,
  3481. "Member_Position"=>$Member_Pos,
  3482. "Type_Name"=>$Type1_Pure{"Name"},
  3483. "Type_Type"=>$Type1_Pure{"Type"},
  3484. "Header"=>$Type2_Pure{"Header"},
  3485. "Line"=>$Type2_Pure{"Line"});
  3486. @{$SubProblems{$Sub_SubProblemType}{$Member_Name}}{keys(%{$Sub_SubProblems{$Sub_SubProblemType}})} = values %{$Sub_SubProblems{$Sub_SubProblemType}};
  3487. }
  3488. if($MemberType1_Id and $MemberType2_Id)
  3489. {#checking member type change (replace)
  3490. %Sub_SubProblems = &mergeTypes($MemberType1_Id, $Tid_TDid{1}{$MemberType1_Id}, $MemberType2_Id, $Tid_TDid{2}{$MemberType2_Id});
  3491. foreach my $Sub_SubProblemType (keys(%Sub_SubProblems))
  3492. {
  3493. foreach my $Sub_SubLocation (keys(%{$Sub_SubProblems{$Sub_SubProblemType}}))
  3494. {
  3495. my $NewLocation = ($Sub_SubLocation)?$Member_Location."->".$Sub_SubLocation:$Member_Location;
  3496. %{$SubProblems{$Sub_SubProblemType}{$NewLocation}}=(
  3497. "IsInTypeInternals"=>"Yes");
  3498. @{$SubProblems{$Sub_SubProblemType}{$NewLocation}}{keys(%{$Sub_SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}})} = values %{$Sub_SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}};
  3499. if($Sub_SubLocation !~ /\-\>/)
  3500. {
  3501. $SubProblems{$Sub_SubProblemType}{$NewLocation}{"Member_Type_Name"} = get_TypeName($MemberType1_Id, 1);
  3502. $SubProblems{$Sub_SubProblemType}{$NewLocation}{"Start_Type_Name"} = get_TypeName($MemberType1_Id, 1);
  3503. }
  3504. }
  3505. }
  3506. }
  3507. }
  3508. if(($Type2_Pure{"Type"} eq "Struct") or ($Type2_Pure{"Type"} eq "Class"))
  3509. {
  3510. foreach my $Member_Pos (sort keys(%{$Type2_Pure{"Memb"}}))
  3511. {#checking added members
  3512. next if(not $Type2_Pure{"Memb"}{$Member_Pos}{"name"});
  3513. my $MemberPair_Pos = find_MemberPair_Pos_byName($Type2_Pure{"Memb"}{$Member_Pos}{"name"}, \%Type1_Pure);
  3514. if($MemberPair_Pos eq "lost")
  3515. {#Added_Member
  3516. if($Member_Pos > keys(%{$Type1_Pure{"Memb"}}) - 1)
  3517. {
  3518. if($Type1_Pure{"Size"} ne $Type2_Pure{"Size"})
  3519. {
  3520. if($Type2_Pure{"Memb"}{$Member_Pos}{"bitfield"})
  3521. {
  3522. my $BitfieldSum = getBitfieldSum($Member_Pos-1, \%Type2_Pure)%($POINTER_SIZE*8);
  3523. next if($BitfieldSum and $BitfieldSum<=$POINTER_SIZE*8-$Type2_Pure{"Memb"}{$Member_Pos}{"bitfield"});
  3524. }
  3525. %{$SubProblems{"Added_Member_And_Size"}{$Type2_Pure{"Memb"}{$Member_Pos}{"name"}}}=(
  3526. "Target"=>$Type2_Pure{"Memb"}{$Member_Pos}{"name"},
  3527. "Type_Name"=>$Type1_Pure{"Name"},
  3528. "Type_Type"=>$Type1_Pure{"Type"},
  3529. "Header"=>$Type2_Pure{"Header"},
  3530. "Line"=>$Type2_Pure{"Line"} );
  3531. }
  3532. }
  3533. else
  3534. {
  3535. my $MemberType_Id = $Type2_Pure{"Memb"}{$Member_Pos}{"type"};
  3536. my $MemberType_DId = $Tid_TDid{2}{$MemberType_Id};
  3537. my %MemberType_Pure = get_PureType($MemberType_DId, $MemberType_Id, 2);
  3538. my $MemberStraightPairType_Id = $Type1_Pure{"Memb"}{$Member_Pos}{"type"};
  3539. my %MemberStraightPairType_Pure = get_PureType($Tid_TDid{1}{$MemberStraightPairType_Id}, $MemberStraightPairType_Id, 1);
  3540. if(($MemberType_Pure{"Size"} eq $MemberStraightPairType_Pure{"Size"}) and find_MemberPair_Pos_byName($Type1_Pure{"Memb"}{$Member_Pos}{"name"}, \%Type2_Pure) eq "lost")
  3541. {
  3542. next if($Type1_Pure{"Memb"}{$Member_Pos}{"access"} eq "private");
  3543. %{$SubProblems{"Member_Rename"}{$Type2_Pure{"Memb"}{$Member_Pos}{"name"}}}=(
  3544. "Target"=>$Type1_Pure{"Memb"}{$Member_Pos}{"name"},
  3545. "Type_Name"=>$Type1_Pure{"Name"},
  3546. "Type_Type"=>$Type1_Pure{"Type"},
  3547. "Header"=>$Type2_Pure{"Header"},
  3548. "Line"=>$Type2_Pure{"Line"},
  3549. "Old_Value"=>$Type1_Pure{"Memb"}{$Member_Pos}{"name"},
  3550. "New_Value"=>$Type2_Pure{"Memb"}{$Member_Pos}{"name"} );
  3551. }
  3552. else
  3553. {
  3554. if($Type1_Pure{"Size"} ne $Type2_Pure{"Size"})
  3555. {
  3556. if($Type2_Pure{"Memb"}{$Member_Pos}{"bitfield"})
  3557. {
  3558. my $BitfieldSum = getBitfieldSum($Member_Pos-1, \%Type2_Pure)%($POINTER_SIZE*8);
  3559. next if($BitfieldSum and $BitfieldSum<=$POINTER_SIZE*8-$Type2_Pure{"Memb"}{$Member_Pos}{"bitfield"});
  3560. }
  3561. %{$SubProblems{"Added_Middle_Member_And_Size"}{$Type2_Pure{"Memb"}{$Member_Pos}{"name"}}}=(
  3562. "Target"=>$Type2_Pure{"Memb"}{$Member_Pos}{"name"},
  3563. "Type_Name"=>$Type1_Pure{"Name"},
  3564. "Type_Type"=>$Type1_Pure{"Type"},
  3565. "Header"=>$Type2_Pure{"Header"},
  3566. "Line"=>$Type2_Pure{"Line"} );
  3567. }
  3568. }
  3569. }
  3570. }
  3571. }
  3572. }
  3573. %{$Cache{"mergeTypes"}{$Type1_Id}{$Type1_DId}{$Type2_Id}{$Type2_DId}} = %SubProblems;
  3574. pop(@RecurTypes);
  3575. return %SubProblems;
  3576. }
  3577. sub get_TypeName($$)
  3578. {
  3579. my ($TypeId, $LibVersion) = @_;
  3580. return $TypeDescr{$LibVersion}{$Tid_TDid{$LibVersion}{$TypeId}}{$TypeId}{"Name"};
  3581. }
  3582. sub goToFirst($$$$)
  3583. {
  3584. my ($TypeDId, $TypeId, $LibVersion, $Type_Type) = @_;
  3585. if(defined $Cache{"goToFirst"}{$TypeDId}{$TypeId}{$LibVersion}{$Type_Type})
  3586. {
  3587. return %{$Cache{"goToFirst"}{$TypeDId}{$TypeId}{$LibVersion}{$Type_Type}};
  3588. }
  3589. return () if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
  3590. my %Type = %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
  3591. return () if(not $Type{"Type"});
  3592. if($Type{"Type"} ne $Type_Type)
  3593. {
  3594. return () if(not $Type{"BaseType"}{"TDid"} and not $Type{"BaseType"}{"Tid"});
  3595. %Type = goToFirst($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion, $Type_Type);
  3596. }
  3597. $Cache{"goToFirst"}{$TypeDId}{$TypeId}{$LibVersion}{$Type_Type} = \%Type;
  3598. return %Type;
  3599. }
  3600. my %TypeSpecAttributes = (
  3601. "Ref" => 1,
  3602. "Const" => 1,
  3603. "Volatile" => 1,
  3604. "Restrict" => 1,
  3605. "Typedef" => 1
  3606. );
  3607. sub get_PureType($$$)
  3608. {
  3609. my ($TypeDId, $TypeId, $LibVersion) = @_;
  3610. return "" if(not $TypeId);
  3611. if(defined $Cache{"get_PureType"}{$TypeDId}{$TypeId}{$LibVersion})
  3612. {
  3613. return %{$Cache{"get_PureType"}{$TypeDId}{$TypeId}{$LibVersion}};
  3614. }
  3615. return "" if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
  3616. my %Type = %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
  3617. if($Type{"Type"} =~ /Struct|Union|Typedef|Class|Enum/)
  3618. {
  3619. $CheckedTypes{$Type{"Name"}} = 1;
  3620. }
  3621. return %Type if(not $Type{"BaseType"}{"TDid"} and not $Type{"BaseType"}{"Tid"});
  3622. if($TypeSpecAttributes{$Type{"Type"}})
  3623. {
  3624. %Type = get_PureType($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion);
  3625. }
  3626. $Cache{"get_PureType"}{$TypeDId}{$TypeId}{$LibVersion} = \%Type;
  3627. return %Type;
  3628. }
  3629. sub get_PointerLevel($$$)
  3630. {
  3631. my ($TypeDId, $TypeId, $LibVersion) = @_;
  3632. return "" if(not $TypeId);
  3633. if(defined $Cache{"get_PointerLevel"}{$TypeDId}{$TypeId}{$LibVersion})
  3634. {
  3635. return $Cache{"get_PointerLevel"}{$TypeDId}{$TypeId}{$LibVersion};
  3636. }
  3637. return "" if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
  3638. my %Type = %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
  3639. return 0 if(not $Type{"BaseType"}{"TDid"} and not $Type{"BaseType"}{"Tid"});
  3640. my $PointerLevel = 0;
  3641. if($Type{"Type"} eq "Pointer")
  3642. {
  3643. $PointerLevel += 1;
  3644. }
  3645. $PointerLevel += get_PointerLevel($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion);
  3646. $Cache{"get_PointerLevel"}{$TypeDId}{$TypeId}{$LibVersion} = $PointerLevel;
  3647. return $PointerLevel;
  3648. }
  3649. sub get_BaseType($$$)
  3650. {
  3651. my ($TypeDId, $TypeId, $LibVersion) = @_;
  3652. return "" if(not $TypeId);
  3653. if(defined $Cache{"get_BaseType"}{$TypeDId}{$TypeId}{$LibVersion})
  3654. {
  3655. return %{$Cache{"get_BaseType"}{$TypeDId}{$TypeId}{$LibVersion}};
  3656. }
  3657. return "" if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
  3658. my %Type = %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
  3659. if($Type{"Type"} =~ /Struct|Union|Typedef|Class|Enum/)
  3660. {
  3661. $CheckedTypes{$Type{"Name"}} = 1;
  3662. }
  3663. return %Type if(not $Type{"BaseType"}{"TDid"} and not $Type{"BaseType"}{"Tid"});
  3664. %Type = get_BaseType($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion);
  3665. $Cache{"get_BaseType"}{$TypeDId}{$TypeId}{$LibVersion} = \%Type;
  3666. return %Type;
  3667. }
  3668. sub get_OneStep_BaseType($$$)
  3669. {
  3670. my ($TypeDId, $TypeId, $LibVersion) = @_;
  3671. return "" if(not $TypeId);
  3672. return "" if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
  3673. my %Type = %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
  3674. return %Type if(not $Type{"BaseType"}{"TDid"} and not $Type{"BaseType"}{"Tid"});
  3675. return get_Type($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion);
  3676. }
  3677. sub get_Type($$$)
  3678. {
  3679. my ($TypeDId, $TypeId, $LibVersion) = @_;
  3680. return "" if(not $TypeId);
  3681. return "" if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
  3682. return %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
  3683. }
  3684. sub mergeLibs()
  3685. {
  3686. foreach my $Interface (sort keys(%AddedInt))
  3687. {#checking added interfaces
  3688. next if($InternalInterfaces{1}{$Interface} or $InternalInterfaces{2}{$Interface});
  3689. next if(defined $InterfacesListPath and not $InterfacesList{$Interface});
  3690. next if(defined $AppPath and not $InterfacesList_App{$Interface});
  3691. next if($FuncAttr{2}{$Interface}{"Private"});
  3692. next if(not $FuncAttr{2}{$Interface}{"Header"});
  3693. %{$CompatProblems{$Interface}{"Added_Interface"}{"SharedLibrary"}}=(
  3694. "Header"=>$FuncAttr{2}{$Interface}{"Header"},
  3695. "Line"=>$FuncAttr{2}{$Interface}{"Line"},
  3696. "Signature"=>$FuncAttr{2}{$Interface}{"Signature"},
  3697. "New_SoName"=>$Interface_Library{2}{$Interface} );
  3698. }
  3699. foreach my $Interface (sort keys(%WithdrawnInt))
  3700. {#checking withdrawn interfaces
  3701. next if($InternalInterfaces{1}{$Interface} or $InternalInterfaces{2}{$Interface});
  3702. next if(defined $InterfacesListPath and not $InterfacesList{$Interface});
  3703. next if(defined $AppPath and not $InterfacesList_App{$Interface});
  3704. next if($FuncAttr{1}{$Interface}{"Private"});
  3705. next if(not $FuncAttr{1}{$Interface}{"Header"});
  3706. %{$CompatProblems{$Interface}{"Withdrawn_Interface"}{"SharedLibrary"}}=(
  3707. "Header"=>$FuncAttr{1}{$Interface}{"Header"},
  3708. "Line"=>$FuncAttr{1}{$Interface}{"Line"},
  3709. "Signature"=>$FuncAttr{1}{$Interface}{"Signature"},
  3710. "Old_SoName"=>$Interface_Library{1}{$Interface} );
  3711. }
  3712. }
  3713. sub mergeSignatures()
  3714. {
  3715. my %SubProblems = ();
  3716. prepareInterfaces(1);
  3717. prepareInterfaces(2);
  3718. %FuncDescr=();
  3719. initializeClassVirtFunc(1);
  3720. initializeClassVirtFunc(2);
  3721. checkVirtFuncRedefinitions(1);
  3722. checkVirtFuncRedefinitions(2);
  3723. setVirtFuncPositions(1);
  3724. setVirtFuncPositions(2);
  3725. foreach my $Interface (sort keys(%AddedInt))
  3726. {#collecting the attributes of added interfaces
  3727. next if($CheckedInterfaces{$Interface});
  3728. if($CompleteSignature{2}{$Interface})
  3729. {
  3730. if($CompleteSignature{2}{$Interface}{"Private"})
  3731. {
  3732. $FuncAttr{2}{$Interface}{"Private"} = 1;
  3733. }
  3734. if($CompleteSignature{2}{$Interface}{"Protected"})
  3735. {
  3736. $FuncAttr{2}{$Interface}{"Protected"} = 1;
  3737. }
  3738. if($CompleteSignature{2}{$Interface}{"Header"})
  3739. {
  3740. $FuncAttr{2}{$Interface}{"Header"} = $CompleteSignature{2}{$Interface}{"Header"};
  3741. }
  3742. if($CompleteSignature{2}{$Interface}{"Line"})
  3743. {
  3744. $FuncAttr{2}{$Interface}{"Line"} = $CompleteSignature{2}{$Interface}{"Line"};
  3745. }
  3746. $FuncAttr{2}{$Interface}{"Signature"} = get_Signature($Interface, 2);
  3747. foreach my $ParamPos (keys(%{$CompleteSignature{2}{$Interface}{"Param"}}))
  3748. {
  3749. my $ParamType_Id = $CompleteSignature{2}{$Interface}{"Param"}{$ParamPos}{"type"};
  3750. my $ParamType_DId = $Tid_TDid{2}{$ParamType_Id};
  3751. my %ParamType = get_Type($ParamType_DId, $ParamType_Id, 2);
  3752. }
  3753. #checking virtual table
  3754. check_VirtualTable($Interface, 2);
  3755. $CheckedInterfaces{$Interface} = 1;
  3756. }
  3757. }
  3758. foreach my $Interface (sort keys(%WithdrawnInt))
  3759. {#collecting the attributes of withdrawn interfaces
  3760. next if($CheckedInterfaces{$Interface});
  3761. if($CompleteSignature{1}{$Interface})
  3762. {
  3763. if($CompleteSignature{1}{$Interface}{"Private"})
  3764. {
  3765. $FuncAttr{1}{$Interface}{"Private"} = 1;
  3766. }
  3767. if($CompleteSignature{1}{$Interface}{"Protected"})
  3768. {
  3769. $FuncAttr{1}{$Interface}{"Protected"} = 1;
  3770. }
  3771. if($CompleteSignature{1}{$Interface}{"Header"})
  3772. {
  3773. $FuncAttr{1}{$Interface}{"Header"} = $CompleteSignature{1}{$Interface}{"Header"};
  3774. }
  3775. if($CompleteSignature{1}{$Interface}{"Line"})
  3776. {
  3777. $FuncAttr{1}{$Interface}{"Line"} = $CompleteSignature{1}{$Interface}{"Line"};
  3778. }
  3779. $FuncAttr{1}{$Interface}{"Signature"} = get_Signature($Interface, 1);
  3780. foreach my $ParamPos (keys(%{$CompleteSignature{1}{$Interface}{"Param"}}))
  3781. {
  3782. my $ParamType_Id = $CompleteSignature{1}{$Interface}{"Param"}{$ParamPos}{"type"};
  3783. my $ParamType_DId = $Tid_TDid{1}{$ParamType_Id};
  3784. my %ParamType = get_Type($ParamType_DId, $ParamType_Id, 1);
  3785. }
  3786. #checking virtual table
  3787. check_VirtualTable($Interface, 1);
  3788. $CheckedInterfaces{$Interface} = 1;
  3789. }
  3790. }
  3791. foreach my $Interface (sort keys(%{$CompleteSignature{1}}))
  3792. {#checking interfaces
  3793. if(($Interface !~ /\@/) and ($SymVer{1}{$Interface} =~ /\A(.*)[\@]+/))
  3794. {
  3795. next if($1 eq $Interface);
  3796. }
  3797. my ($MnglName, $SymbolVersion) = ($Interface, "");
  3798. if($Interface =~ /\A([^@]+)[\@]+([^@]+)\Z/)
  3799. {
  3800. ($MnglName, $SymbolVersion) = ($1, $2);
  3801. }
  3802. next if($InternalInterfaces{1}{$Interface} or $InternalInterfaces{2}{$Interface});
  3803. next if(defined $InterfacesListPath and not $InterfacesList{$Interface});
  3804. next if(defined $AppPath and not $InterfacesList_App{$Interface});
  3805. next if($CheckedInterfaces{$Interface});
  3806. next if($CompleteSignature{1}{$Interface}{"Private"});
  3807. next if(not $CompleteSignature{1}{$Interface}{"Header"} or not $CompleteSignature{2}{$Interface}{"Header"});
  3808. next if(not $CompleteSignature{1}{$Interface}{"MnglName"} or not $CompleteSignature{2}{$Interface}{"MnglName"});
  3809. next if((not $CompleteSignature{1}{$Interface}{"PureVirt"} and $CompleteSignature{2}{$Interface}{"PureVirt"}) or ($CompleteSignature{1}{$Interface}{"PureVirt"} and not $CompleteSignature{2}{$Interface}{"PureVirt"}));
  3810. $CheckedInterfaces{$Interface} = 1;
  3811. #checking virtual table
  3812. check_VirtualTable($Interface, 1);
  3813. #checking attributes
  3814. if($CompleteSignature{2}{$Interface}{"Static"} and not $CompleteSignature{1}{$Interface}{"Static"})
  3815. {
  3816. %{$CompatProblems{$Interface}{"Function_Become_Static"}{"Attributes"}}=(
  3817. "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
  3818. "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
  3819. "Signature"=>get_Signature($Interface, 1),
  3820. "Old_SoName"=>$Interface_Library{1}{$Interface},
  3821. "New_SoName"=>$Interface_Library{2}{$Interface} );
  3822. }
  3823. elsif(not $CompleteSignature{2}{$Interface}{"Static"} and $CompleteSignature{1}{$Interface}{"Static"})
  3824. {
  3825. %{$CompatProblems{$Interface}{"Function_Become_NonStatic"}{"Attributes"}}=(
  3826. "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
  3827. "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
  3828. "Signature"=>get_Signature($Interface, 1),
  3829. "Old_SoName"=>$Interface_Library{1}{$Interface},
  3830. "New_SoName"=>$Interface_Library{2}{$Interface} );
  3831. }
  3832. if($CompleteSignature{1}{$Interface}{"Virt"} and $CompleteSignature{2}{$Interface}{"Virt"})
  3833. {
  3834. if($CompleteSignature{1}{$Interface}{"Position"}!=$CompleteSignature{2}{$Interface}{"Position"})
  3835. {
  3836. my $Class_Id = $CompleteSignature{1}{$Interface}{"Class"};
  3837. my $Class_DId = $Tid_TDid{1}{$Class_Id};
  3838. my %Class_Type = get_Type($Class_DId, $Class_Id, 1);
  3839. %{$CompatProblems{$Interface}{"Virtual_Function_Position"}{$tr_name{$MnglName}}}=(
  3840. "Type_Name"=>$Class_Type{"Name"},
  3841. "Type_Type"=>$Class_Type{"Type"},
  3842. "Header"=>$Class_Type{"Header"},
  3843. "Line"=>$Class_Type{"Line"},
  3844. "Old_Value"=>$CompleteSignature{1}{$Interface}{"Position"},
  3845. "New_Value"=>$CompleteSignature{2}{$Interface}{"Position"},
  3846. "Signature"=>get_Signature($Interface, 1),
  3847. "Target"=>$tr_name{$MnglName},
  3848. "Old_SoName"=>$Interface_Library{1}{$Interface},
  3849. "New_SoName"=>$Interface_Library{2}{$Interface} );
  3850. }
  3851. }
  3852. foreach my $ParamPos (sort {int($a) <=> int($b)} keys(%{$CompleteSignature{2}{$Interface}{"Param"}}))
  3853. {#checking added parameters
  3854. last if($Interface=~/\A_Z/);
  3855. if(not defined $CompleteSignature{1}{$Interface}{"Param"}{$ParamPos})
  3856. {#checking withdrawn parameters
  3857. my $ParamType2_Id = $CompleteSignature{2}{$Interface}{"Param"}{$ParamPos}{"type"};
  3858. my $Parameter_Name = $CompleteSignature{2}{$Interface}{"Param"}{$ParamPos}{"name"};
  3859. last if(get_TypeName($ParamType2_Id, 2) eq "...");
  3860. %{$CompatProblems{$Interface}{"Added_Parameter"}{num_to_str($ParamPos+1)." Parameter"}}=(
  3861. "Target"=>$Parameter_Name,
  3862. "Parameter_Position"=>$ParamPos,
  3863. "Signature"=>get_Signature($Interface, 1),
  3864. "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
  3865. "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
  3866. "Old_SoName"=>$Interface_Library{1}{$Interface},
  3867. "New_SoName"=>$Interface_Library{2}{$Interface});
  3868. }
  3869. }
  3870. foreach my $ParamPos (sort {int($a) <=> int($b)} keys(%{$CompleteSignature{1}{$Interface}{"Param"}}))
  3871. {#checking parameters
  3872. my $ParamType1_Id = $CompleteSignature{1}{$Interface}{"Param"}{$ParamPos}{"type"};
  3873. my $Parameter_Name = $CompleteSignature{1}{$Interface}{"Param"}{$ParamPos}{"name"};
  3874. if(not defined $CompleteSignature{2}{$Interface}{"Param"}{$ParamPos} and get_TypeName($ParamType1_Id, 1) ne "..." and $Interface!~/\A_Z/)
  3875. {#checking withdrawn parameters
  3876. %{$CompatProblems{$Interface}{"Withdrawn_Parameter"}{num_to_str($ParamPos+1)." Parameter"}}=(
  3877. "Target"=>$Parameter_Name,
  3878. "Parameter_Position"=>$ParamPos,
  3879. "Signature"=>get_Signature($Interface, 1),
  3880. "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
  3881. "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
  3882. "Old_SoName"=>$Interface_Library{1}{$Interface},
  3883. "New_SoName"=>$Interface_Library{2}{$Interface});
  3884. next;
  3885. }
  3886. my $ParamType2_Id = $CompleteSignature{2}{$Interface}{"Param"}{$ParamPos}{"type"};
  3887. next if(not $ParamType1_Id or not $ParamType2_Id);
  3888. my $Parameter_Location = ($Parameter_Name)?$Parameter_Name:num_to_str($ParamPos+1)." Parameter";
  3889. #checking type change(replace)
  3890. %SubProblems = detectTypeChange($ParamType1_Id, $ParamType2_Id, "Parameter");
  3891. foreach my $SubProblemType (keys(%SubProblems))
  3892. {
  3893. %{$CompatProblems{$Interface}{$SubProblemType}{$Parameter_Location}}=(
  3894. "Target"=>$Parameter_Name,
  3895. "Parameter_Position"=>$ParamPos,
  3896. "Signature"=>get_Signature($Interface, 1),
  3897. "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
  3898. "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
  3899. "Old_SoName"=>$Interface_Library{1}{$Interface},
  3900. "New_SoName"=>$Interface_Library{2}{$Interface});
  3901. @{$CompatProblems{$Interface}{$SubProblemType}{$Parameter_Location}}{keys(%{$SubProblems{$SubProblemType}})} = values %{$SubProblems{$SubProblemType}};
  3902. }
  3903. @RecurTypes = ();
  3904. #checking type definition changes
  3905. %SubProblems = mergeTypes($ParamType1_Id, $Tid_TDid{1}{$ParamType1_Id}, $ParamType2_Id, $Tid_TDid{2}{$ParamType2_Id});
  3906. foreach my $SubProblemType (keys(%SubProblems))
  3907. {
  3908. foreach my $SubLocation (keys(%{$SubProblems{$SubProblemType}}))
  3909. {
  3910. my $NewLocation = ($SubLocation)?$Parameter_Location."->".$SubLocation:$Parameter_Location;
  3911. %{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}=(
  3912. "Signature"=>get_Signature($Interface, 1),
  3913. "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
  3914. "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
  3915. "Old_SoName"=>$Interface_Library{1}{$Interface},
  3916. "New_SoName"=>$Interface_Library{2}{$Interface},
  3917. "Parameter_Type_Name"=>get_TypeName($ParamType1_Id, 1),
  3918. "Parameter_Position"=>$ParamPos,
  3919. "Parameter_Name"=>$Parameter_Name);
  3920. @{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}{keys(%{$SubProblems{$SubProblemType}{$SubLocation}})} = values %{$SubProblems{$SubProblemType}{$SubLocation}};
  3921. if($SubLocation !~ /\-\>/)
  3922. {
  3923. $CompatProblems{$Interface}{$SubProblemType}{$NewLocation}{"Start_Type_Name"} = get_TypeName($ParamType1_Id, 1);
  3924. }
  3925. }
  3926. }
  3927. }
  3928. #checking return type
  3929. my $ReturnType1_Id = $CompleteSignature{1}{$Interface}{"Return"};
  3930. my $ReturnType2_Id = $CompleteSignature{2}{$Interface}{"Return"};
  3931. %SubProblems = detectTypeChange($ReturnType1_Id, $ReturnType2_Id, "Return");
  3932. foreach my $SubProblemType (keys(%SubProblems))
  3933. {
  3934. %{$CompatProblems{$Interface}{$SubProblemType}{"RetVal"}}=(
  3935. "Signature"=>get_Signature($Interface, 1),
  3936. "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
  3937. "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
  3938. "Old_SoName"=>$Interface_Library{1}{$Interface},
  3939. "New_SoName"=>$Interface_Library{2}{$Interface});
  3940. @{$CompatProblems{$Interface}{$SubProblemType}{"RetVal"}}{keys(%{$SubProblems{$SubProblemType}})} = values %{$SubProblems{$SubProblemType}};
  3941. }
  3942. if($ReturnType1_Id and $ReturnType2_Id)
  3943. {
  3944. @RecurTypes = ();
  3945. %SubProblems = mergeTypes($ReturnType1_Id, $Tid_TDid{1}{$ReturnType1_Id}, $ReturnType2_Id, $Tid_TDid{2}{$ReturnType2_Id});
  3946. foreach my $SubProblemType (keys(%SubProblems))
  3947. {
  3948. foreach my $SubLocation (keys(%{$SubProblems{$SubProblemType}}))
  3949. {
  3950. my $NewLocation = ($SubLocation)?"RetVal->".$SubLocation:"RetVal";
  3951. %{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}=(
  3952. "Signature"=>get_Signature($Interface, 1),
  3953. "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
  3954. "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
  3955. "Old_SoName"=>$Interface_Library{1}{$Interface},
  3956. "New_SoName"=>$Interface_Library{2}{$Interface},
  3957. "Return_Type_Name"=>get_TypeName($ReturnType1_Id, 1) );
  3958. @{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}{keys(%{$SubProblems{$SubProblemType}{$SubLocation}})} = values %{$SubProblems{$SubProblemType}{$SubLocation}};
  3959. if($SubLocation !~ /\-\>/)
  3960. {
  3961. $CompatProblems{$Interface}{$SubProblemType}{$NewLocation}{"Start_Type_Name"} = get_TypeName($ReturnType1_Id, 1);
  3962. }
  3963. }
  3964. }
  3965. }
  3966. #checking object type
  3967. my $ObjectType1_Id = $CompleteSignature{1}{$Interface}{"Class"};
  3968. my $ObjectType2_Id = $CompleteSignature{2}{$Interface}{"Class"};
  3969. if($ObjectType1_Id and $ObjectType2_Id)
  3970. {
  3971. my $ThisType1_Id = getTypeIdByName(get_TypeName($ObjectType1_Id, 1)."*const", 1);
  3972. my $ThisType2_Id = getTypeIdByName(get_TypeName($ObjectType2_Id, 2)."*const", 2);
  3973. if($ThisType1_Id and $ThisType2_Id)
  3974. {
  3975. @RecurTypes = ();
  3976. %SubProblems = mergeTypes($ThisType1_Id, $Tid_TDid{1}{$ThisType1_Id}, $ThisType2_Id, $Tid_TDid{2}{$ThisType2_Id});
  3977. foreach my $SubProblemType (keys(%SubProblems))
  3978. {
  3979. foreach my $SubLocation (keys(%{$SubProblems{$SubProblemType}}))
  3980. {
  3981. my $NewLocation = ($SubLocation)?"Obj->".$SubLocation:"Obj";
  3982. %{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}=(
  3983. "Signature"=>get_Signature($Interface, 1),
  3984. "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
  3985. "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
  3986. "Old_SoName"=>$Interface_Library{1}{$Interface},
  3987. "New_SoName"=>$Interface_Library{2}{$Interface},
  3988. "Object_Type_Name"=>get_TypeName($ObjectType1_Id, 1) );
  3989. @{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}{keys(%{$SubProblems{$SubProblemType}{$SubLocation}})} = values %{$SubProblems{$SubProblemType}{$SubLocation}};
  3990. if($SubLocation !~ /\-\>/)
  3991. {
  3992. $CompatProblems{$Interface}{$SubProblemType}{$NewLocation}{"Start_Type_Name"} = get_TypeName($ObjectType1_Id, 1);
  3993. }
  3994. }
  3995. }
  3996. }
  3997. }
  3998. }
  3999. set_Problems_Priority();
  4000. }
  4001. sub getTypeIdByName($$)
  4002. {
  4003. my ($TypeName, $Version) = @_;
  4004. return $TName_Tid{$Version}{correctName($TypeName)};
  4005. }
  4006. sub detectTypeChange($$$)
  4007. {
  4008. my ($Type1_Id, $Type2_Id, $Prefix) = @_;
  4009. my %LocalProblems = ();
  4010. my $Type1_DId = $Tid_TDid{1}{$Type1_Id};
  4011. my $Type2_DId = $Tid_TDid{2}{$Type2_Id};
  4012. my %Type1 = get_Type($Type1_DId, $Type1_Id, 1);
  4013. my %Type2 = get_Type($Type2_DId, $Type2_Id, 2);
  4014. my %Type1_Base = get_BaseType($Type1_DId, $Type1_Id, 1);
  4015. my %Type2_Base = get_BaseType($Type2_DId, $Type2_Id, 2);
  4016. my %Type1_Pure = get_PureType($Type1_DId, $Type1_Id, 1);
  4017. my %Type2_Pure = get_PureType($Type2_DId, $Type2_Id, 2);
  4018. my $Type1_PointerLevel = get_PointerLevel($Type1_DId, $Type1_Id, 1);
  4019. my $Type2_PointerLevel = get_PointerLevel($Type2_DId, $Type2_Id, 2);
  4020. return () if(not $Type1{"Name"} or not $Type2{"Name"} or not $Type1{"Size"} or not $Type2{"Size"} or not $Type1_Pure{"Size"} or not $Type2_Pure{"Size"} or not $Type1_Base{"Name"} or not $Type2_Base{"Name"} or not $Type1_Base{"Size"} or not $Type2_Base{"Size"} or $Type1_PointerLevel eq "" or $Type2_PointerLevel eq "");
  4021. if($Type1_Base{"Name"} ne $Type2_Base{"Name"})
  4022. {#base type change
  4023. if($Type1_Base{"Name"}!~/anon\-/ and $Type2_Base{"Name"}!~/anon\-/)
  4024. {
  4025. if($Type1_Base{"Size"}!=$Type2_Base{"Size"})
  4026. {
  4027. %{$LocalProblems{$Prefix."_BaseType_And_Size"}}=(
  4028. "Old_Value"=>$Type1_Base{"Name"},
  4029. "New_Value"=>$Type2_Base{"Name"},
  4030. "Old_Size"=>$Type1_Base{"Size"},
  4031. "New_Size"=>$Type2_Base{"Size"},
  4032. "InitialType_Type"=>$Type1_Pure{"Type"});
  4033. }
  4034. else
  4035. {
  4036. %{$LocalProblems{$Prefix."_BaseType"}}=(
  4037. "Old_Value"=>$Type1_Base{"Name"},
  4038. "New_Value"=>$Type2_Base{"Name"},
  4039. "InitialType_Type"=>$Type1_Pure{"Type"});
  4040. }
  4041. }
  4042. }
  4043. elsif($Type1{"Name"} ne $Type2{"Name"})
  4044. {#type change
  4045. if($Type1{"Name"}!~/anon\-/ and $Type2{"Name"}!~/anon\-/)
  4046. {
  4047. if($Type1{"Size"}!=$Type2{"Size"})
  4048. {
  4049. %{$LocalProblems{$Prefix."_Type_And_Size"}}=(
  4050. "Old_Value"=>$Type1{"Name"},
  4051. "New_Value"=>$Type2{"Name"},
  4052. "Old_Size"=>($Type1{"Type"} eq "Array")?$Type1{"Size"}*$Type1_Base{"Size"}:$Type1{"Size"},
  4053. "New_Size"=>($Type2{"Type"} eq "Array")?$Type2{"Size"}*$Type2_Base{"Size"}:$Type2{"Size"},
  4054. "InitialType_Type"=>$Type1_Pure{"Type"});
  4055. }
  4056. else
  4057. {
  4058. %{$LocalProblems{$Prefix."_Type"}}=(
  4059. "Old_Value"=>$Type1{"Name"},
  4060. "New_Value"=>$Type2{"Name"},
  4061. "InitialType_Type"=>$Type1_Pure{"Type"});
  4062. }
  4063. }
  4064. }
  4065. if($Type1_PointerLevel!=$Type2_PointerLevel)
  4066. {
  4067. %{$LocalProblems{$Prefix."_PointerLevel"}}=(
  4068. "Old_Value"=>$Type1_PointerLevel,
  4069. "New_Value"=>$Type2_PointerLevel);
  4070. }
  4071. return %LocalProblems;
  4072. }
  4073. sub htmlSpecChars($)
  4074. {
  4075. my $Str = $_[0];
  4076. $Str =~ s/\&([^#])/&amp;$1/g;
  4077. $Str =~ s/</&lt;/g;
  4078. $Str =~ s/>/&gt;/g;
  4079. $Str =~ s/([^ ])( )([^ ])/$1\@ALONE_SP\@$3/g;
  4080. $Str =~ s/ /&nbsp;/g;
  4081. $Str =~ s/\@ALONE_SP\@/ /g;
  4082. $Str =~ s/\n/<br\/>/g;
  4083. return $Str;
  4084. }
  4085. sub highLight_Signature($)
  4086. {
  4087. my $Signature = $_[0];
  4088. return highLight_Signature_PPos_Italic($Signature, "", 0, 0);
  4089. }
  4090. sub highLight_Signature_Italic($)
  4091. {
  4092. my $Signature = $_[0];
  4093. return highLight_Signature_PPos_Italic($Signature, "", 1, 0);
  4094. }
  4095. sub highLight_Signature_Italic_Color($)
  4096. {
  4097. my $Signature = $_[0];
  4098. return highLight_Signature_PPos_Italic($Signature, "", 1, 1);
  4099. }
  4100. sub highLight_Signature_PPos_Italic($$$$)
  4101. {
  4102. my ($FullSignature, $Parameter_Position, $ItalicParams, $ColorParams) = @_;
  4103. my ($Signature, $SymbolVersion) = ($FullSignature, "");
  4104. if($FullSignature =~ /\A(.+)[\@]+(.+)\Z/)
  4105. {
  4106. ($Signature, $SymbolVersion) = ($1, $2);
  4107. }
  4108. if($Signature=~/\Atypeinfo\W/)
  4109. {
  4110. return $Signature.(($SymbolVersion)?"<span class='symver'> \@ $SymbolVersion</span>":"");
  4111. }
  4112. if($Signature!~/\)(| const)\Z/)
  4113. {
  4114. return $Signature.(($SymbolVersion)?"<span class='symver'> \@ $SymbolVersion</span>":"");
  4115. }
  4116. $Signature =~ /(.+?)\(.*\)(| const)\Z/;
  4117. my ($Begin, $End) = ($1, $2);
  4118. my @Parts = ();
  4119. my $Part_Num = 0;
  4120. foreach my $Part (get_Signature_Parts($Signature, 1))
  4121. {
  4122. $Part =~ s/\A\s+|\s+\Z//g;
  4123. my ($Part_Styled, $ParamName) = ($Part, "");
  4124. if($Part=~/\([\*]+(\w+)\)/i)
  4125. {#func-ptr
  4126. $ParamName = $1;
  4127. }
  4128. elsif($Part=~/(\w+)[\,\)]*\Z/i)
  4129. {
  4130. $ParamName = $1;
  4131. }
  4132. if(not $ParamName)
  4133. {
  4134. push(@Parts, $Part);
  4135. next;
  4136. }
  4137. if($ItalicParams and not $TName_Tid{1}{$Part} and not $TName_Tid{2}{$Part})
  4138. {
  4139. if(($Parameter_Position ne "") and ($Part_Num == $Parameter_Position))
  4140. {
  4141. $Part_Styled =~ s!(\W)$ParamName([\,\)]|\Z)!$1<span class='focus_param'>$ParamName</span>$2!ig;
  4142. }
  4143. elsif($ColorParams)
  4144. {
  4145. $Part_Styled =~ s!(\W)$ParamName([\,\)]|\Z)!$1<span class='color_param'>$ParamName</span>$2!ig;
  4146. }
  4147. else
  4148. {
  4149. $Part_Styled =~ s!(\W)$ParamName([\,\)]|\Z)!$1<span style='font-style:italic;'>$ParamName</span>$2!ig;
  4150. }
  4151. }
  4152. $Part_Styled = "<span style='white-space:nowrap;'>".$Part_Styled."</span>";
  4153. push(@Parts, $Part_Styled);
  4154. $Part_Num += 1;
  4155. }
  4156. $Signature = $Begin."<span class='int_p'>"."(".join(" ", @Parts).")"."</span>".$End;
  4157. $Signature =~ s!\[\]![<span style='padding-left:2px;'>]</span>!g;
  4158. $Signature =~ s!operator=!operator<span style='padding-left:2px'>=</span>!g;
  4159. $Signature =~ s!(\[in-charge\]|\[not-in-charge\]|\[in-charge-deleting\])!<span style='color:Black;font-weight:normal;'>$1</span>!g;
  4160. return $Signature.(($SymbolVersion)?"<span class='symver'> \@ $SymbolVersion</span>":"");
  4161. }
  4162. sub get_Signature_Parts($$)
  4163. {
  4164. my ($Signature, $Comma) = @_;
  4165. my @Parts = ();
  4166. my $Bracket_Num = 0;
  4167. my $Bracket2_Num = 0;
  4168. my $Parameters = $Signature;
  4169. if($Signature=~/&gt;|&lt;/)
  4170. {
  4171. $Parameters=~s/&gt;/>/g;
  4172. $Parameters=~s/&lt;/</g;
  4173. }
  4174. my $Part_Num = 0;
  4175. if($Parameters =~ s/.+?\((.*)\)(| const)\Z/$1/)
  4176. {
  4177. foreach my $Pos (0 .. length($Parameters) - 1)
  4178. {
  4179. my $Symbol = substr($Parameters, $Pos, 1);
  4180. $Bracket_Num += 1 if($Symbol eq "(");
  4181. $Bracket_Num -= 1 if($Symbol eq ")");
  4182. $Bracket2_Num += 1 if($Symbol eq "<");
  4183. $Bracket2_Num -= 1 if($Symbol eq ">");
  4184. if($Symbol eq "," and $Bracket_Num==0 and $Bracket2_Num==0)
  4185. {
  4186. $Parts[$Part_Num] .= $Symbol if($Comma);
  4187. $Part_Num += 1;
  4188. }
  4189. else
  4190. {
  4191. $Parts[$Part_Num] .= $Symbol;
  4192. }
  4193. }
  4194. if($Signature=~/&gt;|&lt;/)
  4195. {
  4196. foreach my $Part (@Parts)
  4197. {
  4198. $Part=~s/\>/&gt;/g;
  4199. $Part=~s/\</&lt;/g;
  4200. }
  4201. }
  4202. return @Parts;
  4203. }
  4204. else
  4205. {
  4206. return ();
  4207. }
  4208. }
  4209. my %TypeProblems_Kind=(
  4210. "Added_Virtual_Function"=>1,
  4211. "Withdrawn_Virtual_Function"=>1,
  4212. "Virtual_Function_Position"=>1,
  4213. "Virtual_Function_Redefinition"=>1,
  4214. "Virtual_Function_Redefinition_B"=>1,
  4215. "Size"=>1,
  4216. "Added_Member_And_Size"=>1,
  4217. "Added_Middle_Member_And_Size"=>1,
  4218. "Withdrawn_Member_And_Size"=>1,
  4219. "Withdrawn_Member"=>1,
  4220. "Withdrawn_Middle_Member_And_Size"=>1,
  4221. "Member_Rename"=>1,
  4222. "Enum_Member_Value"=>1,
  4223. "Enum_Member_Name"=>1,
  4224. "Member_Type_And_Size"=>1,
  4225. "Member_Type"=>1,
  4226. "Member_BaseType_And_Size"=>1,
  4227. "Member_BaseType"=>1,
  4228. "Member_PointerLevel"=>1,
  4229. "BaseType"=>1
  4230. );
  4231. my %InterfaceProblems_Kind=(
  4232. "Added_Interface"=>1,
  4233. "Withdrawn_Interface"=>1,
  4234. "Function_Become_Static"=>1,
  4235. "Function_Become_NonStatic"=>1,
  4236. "Parameter_Type_And_Size"=>1,
  4237. "Parameter_Type"=>1,
  4238. "Parameter_BaseType_And_Size"=>1,
  4239. "Parameter_BaseType"=>1,
  4240. "Parameter_PointerLevel"=>1,
  4241. "Return_Type_And_Size"=>1,
  4242. "Return_Type"=>1,
  4243. "Return_BaseType_And_Size"=>1,
  4244. "Return_BaseType"=>1,
  4245. "Return_PointerLevel"=>1,
  4246. "Withdrawn_Parameter"=>1,
  4247. "Added_Parameter"=>1
  4248. );
  4249. sub testSystem_cpp()
  4250. {
  4251. print "testing for C++ library changes\n";
  4252. my (@DataDefs_v1, @Sources_v1, @DataDefs_v2, @Sources_v2) = ();
  4253. #Withdrawn_Parameter
  4254. @DataDefs_v1 = (@DataDefs_v1, "int func_withdrawn_parameter(int param, int withdrawn_param);");
  4255. @Sources_v1 = (@Sources_v1, "int func_withdrawn_parameter(int param, int withdrawn_param)\n{\n return 0;\n}");
  4256. @DataDefs_v2 = (@DataDefs_v2, "int func_withdrawn_parameter(int param);");
  4257. @Sources_v2 = (@Sources_v2, "int func_withdrawn_parameter(int param)\n{\n return 0;\n}");
  4258. #Added_Parameter
  4259. @DataDefs_v1 = (@DataDefs_v1, "int func_added_parameter(int param);");
  4260. @Sources_v1 = (@Sources_v1, "int func_added_parameter(int param)\n{\n return 0;\n}");
  4261. @DataDefs_v2 = (@DataDefs_v2, "int func_added_parameter(int param, int added_param);");
  4262. @Sources_v2 = (@Sources_v2, "int func_added_parameter(int param, int added_param)\n{\n return 0;\n}");
  4263. #Added_Virtual_Function
  4264. @DataDefs_v1 = (@DataDefs_v1, "class type_test_added_virtual_function\n{\npublic:\n int func1(int param);\n virtual int func2(int param);\n};");
  4265. @Sources_v1 = (@Sources_v1, "int type_test_added_virtual_function::func1(int param)\n{\n return param;\n}");
  4266. @Sources_v1 = (@Sources_v1, "int type_test_added_virtual_function::func2(int param)\n{\n return param;\n}");
  4267. @DataDefs_v2 = (@DataDefs_v2, "class type_test_added_virtual_function\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
  4268. @Sources_v2 = (@Sources_v2, "int type_test_added_virtual_function::func1(int param)\n{\n return param;\n}");
  4269. @Sources_v2 = (@Sources_v2, "int type_test_added_virtual_function::func2(int param)\n{\n return param;\n}");
  4270. #added simple function
  4271. @DataDefs_v2 = (@DataDefs_v2, "typedef int (*FUNCPTR_TYPE)(int a, int b);\nint added_function_param_funcptr(FUNCPTR_TYPE*const** f);");
  4272. @Sources_v2 = (@Sources_v2, "int added_function_param_funcptr(FUNCPTR_TYPE*const** f)\n{\n return 0;\n}");
  4273. #Withdrawn_Virtual_Function
  4274. @DataDefs_v1 = (@DataDefs_v1, "class type_test_withdrawn_virtual_function\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
  4275. @Sources_v1 = (@Sources_v1, "int type_test_withdrawn_virtual_function::func1(int param)\n{\n return param;\n}");
  4276. @Sources_v1 = (@Sources_v1, "int type_test_withdrawn_virtual_function::func2(int param)\n{\n return param;\n}");
  4277. @DataDefs_v2 = (@DataDefs_v2, "class type_test_withdrawn_virtual_function\n{\npublic:\n int func1(int param);\n virtual int func2(int param);\n};");
  4278. @Sources_v2 = (@Sources_v2, "int type_test_withdrawn_virtual_function::func1(int param)\n{\n return param;\n}");
  4279. @Sources_v2 = (@Sources_v2, "int type_test_withdrawn_virtual_function::func2(int param)\n{\n return param;\n}");
  4280. #Virtual_Function_Position
  4281. @DataDefs_v1 = (@DataDefs_v1, "class type_test_virtual_function_position\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
  4282. @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position::func1(int param)\n{\n return param;\n}");
  4283. @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position::func2(int param)\n{\n return param;\n}");
  4284. @DataDefs_v2 = (@DataDefs_v2, "class type_test_virtual_function_position\n{\npublic:\n virtual int func2(int param);\n virtual int func1(int param);\n};");
  4285. @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position::func1(int param)\n{\n return param;\n}");
  4286. @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position::func2(int param)\n{\n return param;\n}");
  4287. #virtual functions safe replace
  4288. @DataDefs_v1 = (@DataDefs_v1, "class type_test_virtual_function_position_safe_replace_base\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
  4289. @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position_safe_replace_base::func1(int param)\n{\n return param;\n}");
  4290. @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position_safe_replace_base::func2(int param)\n{\n return param;\n}");
  4291. @DataDefs_v2 = (@DataDefs_v2, "class type_test_virtual_function_position_safe_replace_base\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
  4292. @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position_safe_replace_base::func1(int param)\n{\n return param;\n}");
  4293. @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position_safe_replace_base::func2(int param)\n{\n return param;\n}");
  4294. @DataDefs_v1 = (@DataDefs_v1, "class type_test_virtual_function_position_safe_replace:public type_test_virtual_function_position_safe_replace_base\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
  4295. @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position_safe_replace::func1(int param)\n{\n return param;\n}");
  4296. @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position_safe_replace::func2(int param)\n{\n return param;\n}");
  4297. @DataDefs_v2 = (@DataDefs_v2, "class type_test_virtual_function_position_safe_replace:public type_test_virtual_function_position_safe_replace_base\n{\npublic:\n virtual int func2(int param);\n virtual int func1(int param);\n};");
  4298. @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position_safe_replace::func1(int param)\n{\n return param;\n}");
  4299. @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position_safe_replace::func2(int param)\n{\n return param;\n}");
  4300. #virtual table changes
  4301. @DataDefs_v1 = (@DataDefs_v1, "class type_test_virtual_table_base\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
  4302. @DataDefs_v1 = (@DataDefs_v1, "class type_test_virtual_table:public type_test_virtual_table_base\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
  4303. @Sources_v1 = (@Sources_v1, "int type_test_virtual_table_base::func1(int param)\n{\n return param;\n}");
  4304. @Sources_v1 = (@Sources_v1, "int type_test_virtual_table_base::func2(int param)\n{\n return param;\n}");
  4305. @Sources_v1 = (@Sources_v1, "int type_test_virtual_table::func1(int param)\n{\n return param;\n}");
  4306. @Sources_v1 = (@Sources_v1, "int type_test_virtual_table::func2(int param)\n{\n return param;\n}");
  4307. @DataDefs_v2 = (@DataDefs_v2, "class type_test_virtual_table_base\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
  4308. @DataDefs_v2 = (@DataDefs_v2, "class type_test_virtual_table:public type_test_virtual_table_base\n{\npublic:\n virtual int func2(int param);\n virtual int func1(int param);\n};");
  4309. @Sources_v2 = (@Sources_v2, "int type_test_virtual_table_base::func1(int param)\n{\n return param;\n}");
  4310. @Sources_v2 = (@Sources_v2, "int type_test_virtual_table_base::func2(int param)\n{\n return param;\n}");
  4311. @Sources_v2 = (@Sources_v2, "int type_test_virtual_table::func1(int param)\n{\n return param;\n}");
  4312. @Sources_v2 = (@Sources_v2, "int type_test_virtual_table::func2(int param)\n{\n return param;\n}");
  4313. #Virtual_Function_Redefinition
  4314. @DataDefs_v1 = (@DataDefs_v1, "class type_test_virtual_function_redefinition_base\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
  4315. @DataDefs_v1 = (@DataDefs_v1, "class type_test_virtual_function_redefinition:public type_test_virtual_function_redefinition_base\n{\npublic:\n virtual int func3(int param);\n};");
  4316. @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_redefinition_base::func1(int param)\n{\n return param;\n}");
  4317. @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_redefinition_base::func2(int param)\n{\n return param;\n}");
  4318. @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_redefinition::func3(int param)\n{\n return param;\n}");
  4319. @DataDefs_v2 = (@DataDefs_v2, "class type_test_virtual_function_redefinition_base\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
  4320. @DataDefs_v2 = (@DataDefs_v2, "class type_test_virtual_function_redefinition:public type_test_virtual_function_redefinition_base\n{\npublic:\n virtual int func2(int param);\n virtual int func3(int param);\n};");
  4321. @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_redefinition_base::func1(int param){\n return param;\n}");
  4322. @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_redefinition_base::func2(int param){\n return param;\n}");
  4323. @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_redefinition::func2(int param)\n{\n return param;\n}");
  4324. @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_redefinition::func3(int param)\n{\n return param;\n}");
  4325. #size change
  4326. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_size\n{\npublic:\n virtual type_test_size func1(type_test_size param);\n int i;\n long j;\n double k;\n type_test_size* p;\n};");
  4327. @Sources_v1 = (@Sources_v1, "type_test_size type_test_size::func1(type_test_size param)\n{\n return param;\n}");
  4328. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_size\n{\npublic:\n virtual type_test_size func1(type_test_size param);\n int i;\n long j;\n double k;\n type_test_size* p;\n int added_member;\n};");
  4329. @Sources_v2 = (@Sources_v2, "type_test_size type_test_size::func1(type_test_size param)\n{\n return param;\n}");
  4330. #Added_Member_And_Size
  4331. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_added_member\n{\npublic:\n virtual type_test_added_member func1(type_test_added_member param);\n int i;\n long j;\n double k;\n type_test_added_member* p;\n};");
  4332. @Sources_v1 = (@Sources_v1, "type_test_added_member type_test_added_member::func1(type_test_added_member param)\n{\n return param;\n}");
  4333. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_added_member\n{\npublic:\n virtual type_test_added_member func1(type_test_added_member param);\n int i;\n long j;\n double k;\n type_test_added_member* p;\n int added_member;\n};");
  4334. @Sources_v2 = (@Sources_v2, "type_test_added_member type_test_added_member::func1(type_test_added_member param)\n{\n return param;\n}");
  4335. #Method object changes
  4336. @DataDefs_v1 = (@DataDefs_v1, "class type_test_object_added_member\n{\npublic:\n virtual int func1(int param);\n int i;\n long j;\n double k;\n type_test_added_member* p;\n};");
  4337. @Sources_v1 = (@Sources_v1, "int type_test_object_added_member::func1(int param)\n{\n return param;\n}");
  4338. @DataDefs_v2 = (@DataDefs_v2, "class type_test_object_added_member\n{\npublic:\n virtual int func1(int param);\n int i;\n long j;\n double k;\n type_test_added_member* p;\n int added_member;\n};");
  4339. @Sources_v2 = (@Sources_v2, "int type_test_object_added_member::func1(int param)\n{\n return param;\n}");
  4340. #added bitfield
  4341. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_added_bitfield\n{\npublic:\n virtual type_test_added_bitfield func1(type_test_added_bitfield param);\n int i;\n long j;\n double k;\n int b1 : 32;\n int b2 : 31;\n type_test_added_bitfield* p;\n};");
  4342. @Sources_v1 = (@Sources_v1, "type_test_added_bitfield type_test_added_bitfield::func1(type_test_added_bitfield param)\n{\n return param;\n}");
  4343. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_added_bitfield\n{\npublic:\n virtual type_test_added_bitfield func1(type_test_added_bitfield param);\n int i;\n long j;\n double k;\n int b1 : 32;\n int b2 : 31;\n int added_bitfield : 1;\n type_test_added_bitfield* p;\n};");
  4344. @Sources_v2 = (@Sources_v2, "type_test_added_bitfield type_test_added_bitfield::func1(type_test_added_bitfield param)\n{\n return param;\n}");
  4345. #withdrawn bitfield
  4346. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_withdrawn_bitfield\n{\npublic:\n virtual type_test_withdrawn_bitfield func1(type_test_withdrawn_bitfield param);\n int i;\n long j;\n double k;\n int b1 : 32;\n int b2 : 31;\n int withdrawn_bitfield : 1;\n type_test_withdrawn_bitfield* p;\n};");
  4347. @Sources_v1 = (@Sources_v1, "type_test_withdrawn_bitfield type_test_withdrawn_bitfield::func1(type_test_withdrawn_bitfield param)\n{\n return param;\n}");
  4348. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_withdrawn_bitfield\n{\npublic:\n virtual type_test_withdrawn_bitfield func1(type_test_withdrawn_bitfield param);\n int i;\n long j;\n double k;\n int b1 : 32;\n int b2 : 31;\n type_test_withdrawn_bitfield* p;\n};");
  4349. @Sources_v2 = (@Sources_v2, "type_test_withdrawn_bitfield type_test_withdrawn_bitfield::func1(type_test_withdrawn_bitfield param)\n{\n return param;\n}");
  4350. #Added_Middle_Member_And_Size
  4351. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_added_middle_member\n{\npublic:\n virtual type_test_added_middle_member func1(type_test_added_middle_member param);\n int i;\n long j;\n double k;\n type_test_added_middle_member* p;\n};");
  4352. @Sources_v1 = (@Sources_v1, "type_test_added_middle_member type_test_added_middle_member::func1(type_test_added_middle_member param)\n{\n return param;\n}");
  4353. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_added_middle_member\n{\npublic:\n virtual type_test_added_middle_member func1(type_test_added_middle_member param);\n int i;\n int added_middle_member;\n long j;\n double k;\n type_test_added_middle_member* p;\n};");
  4354. @Sources_v2 = (@Sources_v2, "type_test_added_middle_member type_test_added_middle_member::func1(type_test_added_middle_member param)\n{\n return param;\n}");
  4355. #Member_Rename
  4356. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_rename\n{\npublic:\n virtual type_test_member_rename func1(type_test_member_rename param);\n long i;\n long j;\n double k;\n type_test_member_rename* p;\n};");
  4357. @Sources_v1 = (@Sources_v1, "type_test_member_rename type_test_member_rename::func1(type_test_member_rename param)\n{\n return param;\n}");
  4358. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_rename\n{\npublic:\n virtual type_test_member_rename func1(type_test_member_rename param);\n long renamed_member;\n long j;\n double k;\n type_test_member_rename* p;\n};");
  4359. @Sources_v2 = (@Sources_v2, "type_test_member_rename type_test_member_rename::func1(type_test_member_rename param)\n{\n return param;\n}");
  4360. #Withdrawn_Member_And_Size
  4361. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_withdrawn_member\n{\npublic:\n virtual type_test_withdrawn_member func1(type_test_withdrawn_member param);\n int i;\n long j;\n double k;\n type_test_withdrawn_member* p;\n int withdrawn_member;\n};");
  4362. @Sources_v1 = (@Sources_v1, "type_test_withdrawn_member type_test_withdrawn_member::func1(type_test_withdrawn_member param)\n{\n return param;\n}");
  4363. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_withdrawn_member\n{\npublic:\n virtual type_test_withdrawn_member func1(type_test_withdrawn_member param);\n int i;\n long j;\n double k;\n type_test_withdrawn_member* p;\n};");
  4364. @Sources_v2 = (@Sources_v2, "type_test_withdrawn_member type_test_withdrawn_member::func1(type_test_withdrawn_member param)\n{\n return param;\n}");
  4365. #Withdrawn_Middle_Member_And_Size
  4366. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_withdrawn_middle_member\n{\npublic:\n virtual type_test_withdrawn_middle_member func1(type_test_withdrawn_middle_member param);\n int i;\n int withdrawn_middle_member;\n long j;\n double k;\n type_test_withdrawn_middle_member* p;\n};");
  4367. @Sources_v1 = (@Sources_v1, "type_test_withdrawn_middle_member type_test_withdrawn_middle_member::func1(type_test_withdrawn_middle_member param)\n{\n return param;\n}");
  4368. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_withdrawn_middle_member\n{\npublic:\n virtual type_test_withdrawn_middle_member func1(type_test_withdrawn_middle_member param);\n int i;\n long j;\n double k;\n type_test_withdrawn_middle_member* p;\n};");
  4369. @Sources_v2 = (@Sources_v2, "type_test_withdrawn_middle_member type_test_withdrawn_middle_member::func1(type_test_withdrawn_middle_member param)\n{\n return param;\n}");
  4370. #Enum_Member_Value
  4371. @DataDefs_v1 = (@DataDefs_v1, "enum type_test_enum_member_value_change\n{\n MEMBER_1=1,\n MEMBER_2=2\n};");
  4372. @DataDefs_v1 = (@DataDefs_v1, "int func_test_enum_member_value_change(enum type_test_enum_member_value_change param);");
  4373. @Sources_v1 = (@Sources_v1,
  4374. "int func_test_enum_member_value_change(enum type_test_enum_member_value_change param)
  4375. {
  4376. switch(param)
  4377. {
  4378. case 1:
  4379. return 1;
  4380. case 2:
  4381. return 2;
  4382. }
  4383. return 0;
  4384. }");
  4385. @DataDefs_v2 = (@DataDefs_v2, "enum type_test_enum_member_value_change\n{\n MEMBER_1=2,\n MEMBER_2=1\n};");
  4386. @DataDefs_v2 = (@DataDefs_v2, "int func_test_enum_member_value_change(enum type_test_enum_member_value_change param);");
  4387. @Sources_v2 = (@Sources_v2,
  4388. "int func_test_enum_member_value_change(enum type_test_enum_member_value_change param)
  4389. {
  4390. switch(param)
  4391. {
  4392. case 1:
  4393. return 1;
  4394. case 2:
  4395. return 2;
  4396. }
  4397. return 0;
  4398. }");
  4399. #Enum_Member_Name
  4400. @DataDefs_v1 = (@DataDefs_v1, "enum type_test_enum_member_rename\n{\n BRANCH_1=1,\n BRANCH_2=2\n};");
  4401. @DataDefs_v1 = (@DataDefs_v1, "int func_test_enum_member_rename(enum type_test_enum_member_rename param);");
  4402. @Sources_v1 = (@Sources_v1,
  4403. "int func_test_enum_member_rename(enum type_test_enum_member_rename param)
  4404. {
  4405. switch(param)
  4406. {
  4407. case 1:
  4408. return 1;
  4409. case 2:
  4410. return 2;
  4411. }
  4412. return 0;
  4413. }");
  4414. @DataDefs_v2 = (@DataDefs_v2, "enum type_test_enum_member_rename\n{\n BRANCH_FIRST=1,\n BRANCH_SECOND=1\n};");
  4415. @DataDefs_v2 = (@DataDefs_v2, "int func_test_enum_member_rename(enum type_test_enum_member_rename param);");
  4416. @Sources_v2 = (@Sources_v2,
  4417. "int func_test_enum_member_rename(enum type_test_enum_member_rename param)
  4418. {
  4419. switch(param)
  4420. {
  4421. case 1:
  4422. return 1;
  4423. case 2:
  4424. return 2;
  4425. }
  4426. return 0;
  4427. }");
  4428. #Member_Type_And_Size
  4429. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_type_and_size\n{\npublic:\n type_test_member_type_and_size func1(type_test_member_type_and_size param);\n int i;\n long j;\n double k;\n type_test_member_type_and_size* p;\n};");
  4430. @Sources_v1 = (@Sources_v1, "type_test_member_type_and_size type_test_member_type_and_size::func1(type_test_member_type_and_size param)\n{\n return param;\n}");
  4431. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_type_and_size\n{\npublic:\n type_test_member_type_and_size func1(type_test_member_type_and_size param);\n long long i;\n long j;\n double k;\n type_test_member_type_and_size* p;\n};");
  4432. @Sources_v2 = (@Sources_v2, "type_test_member_type_and_size type_test_member_type_and_size::func1(type_test_member_type_and_size param)\n{\n return param;\n}");
  4433. #Member_Type
  4434. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_type\n{\npublic:\n type_test_member_type func1(type_test_member_type param);\n int i;\n long j;\n double k;\n type_test_member_type* p;\n};");
  4435. @Sources_v1 = (@Sources_v1, "type_test_member_type type_test_member_type::func1(type_test_member_type param)\n{\n return param;\n}");
  4436. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_type\n{\npublic:\n type_test_member_type func1(type_test_member_type param);\n float i;\n long j;\n double k;\n type_test_member_type* p;\n};");
  4437. @Sources_v2 = (@Sources_v2, "type_test_member_type type_test_member_type::func1(type_test_member_type param)\n{\n return param;\n}");
  4438. #Member_BaseType
  4439. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_basetype\n{\npublic:\n type_test_member_basetype func1(type_test_member_basetype param);\n int *i;\n long j;\n double k;\n type_test_member_basetype* p;\n};");
  4440. @Sources_v1 = (@Sources_v1, "type_test_member_basetype type_test_member_basetype::func1(type_test_member_basetype param)\n{\n return param;\n}");
  4441. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_basetype\n{\npublic:\n type_test_member_basetype func1(type_test_member_basetype param);\n long long *i;\n long j;\n double k;\n type_test_member_basetype* p;\n};");
  4442. @Sources_v2 = (@Sources_v2, "type_test_member_basetype type_test_member_basetype::func1(type_test_member_basetype param)\n{\n return param;\n}");
  4443. #Member_PointerLevel_And_Size
  4444. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_pointerlevel_and_size\n{\npublic:\n type_test_member_pointerlevel_and_size func1(type_test_member_pointerlevel_and_size param);\n long long i;\n long j;\n double k;\n type_test_member_pointerlevel_and_size* p;\n};");
  4445. @Sources_v1 = (@Sources_v1, "type_test_member_pointerlevel_and_size type_test_member_pointerlevel_and_size::func1(type_test_member_pointerlevel_and_size param)\n{\n return param;\n}");
  4446. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_pointerlevel_and_size\n{\npublic:\n type_test_member_pointerlevel_and_size func1(type_test_member_pointerlevel_and_size param);\n long long *i;\n long j;\n double k;\n type_test_member_pointerlevel_and_size* p;\n};");
  4447. @Sources_v2 = (@Sources_v2, "type_test_member_pointerlevel_and_size type_test_member_pointerlevel_and_size::func1(type_test_member_pointerlevel_and_size param)\n{\n return param;\n}");
  4448. #Member_PointerLevel
  4449. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_pointerlevel\n{\npublic:\n type_test_member_pointerlevel func1(type_test_member_pointerlevel param);\n int **i;\n long j;\n double k;\n type_test_member_pointerlevel* p;\n};");
  4450. @Sources_v1 = (@Sources_v1, "type_test_member_pointerlevel type_test_member_pointerlevel::func1(type_test_member_pointerlevel param)\n{\n return param;\n}");
  4451. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_pointerlevel\n{\npublic:\n type_test_member_pointerlevel func1(type_test_member_pointerlevel param);\n int *i;\n long j;\n double k;\n type_test_member_pointerlevel* p;\n};");
  4452. @Sources_v2 = (@Sources_v2, "type_test_member_pointerlevel type_test_member_pointerlevel::func1(type_test_member_pointerlevel param)\n{\n return param;\n}");
  4453. #Added_Interface (function)
  4454. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_added_interface\n{\npublic:\n type_test_added_interface func1(type_test_added_interface param);\n int i;\n long j;\n double k;\n type_test_added_interface* p;\n};");
  4455. @Sources_v1 = (@Sources_v1, "type_test_added_interface type_test_added_interface::func1(type_test_added_interface param)\n{\n return param;\n}");
  4456. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_added_interface\n{\npublic:\n type_test_added_interface func1(type_test_added_interface param);\n type_test_added_interface added_func(type_test_added_interface param);\n int i;\n long j;\n double k;\n type_test_added_interface* p;\n};");
  4457. @DataDefs_v2 = (@DataDefs_v2, "int added_func_2(void *** param);");
  4458. @Sources_v2 = (@Sources_v2, "type_test_added_interface type_test_added_interface::func1(type_test_added_interface param)\n{\n return param;\n}");
  4459. @Sources_v2 = (@Sources_v2, "type_test_added_interface type_test_added_interface::added_func(type_test_added_interface param)\n{\n return param;\n}");
  4460. @Sources_v2 = (@Sources_v2, "int added_func_2(void *** param)\n{\n return 0;\n}");
  4461. #Added_Interface (global variable)
  4462. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_added_variable\n{\npublic:\n int func1(type_test_added_variable param);\n int i;\n long j;\n double k;\n type_test_added_variable* p;\n};");
  4463. @Sources_v1 = (@Sources_v1, "int type_test_added_variable::func1(type_test_added_variable param)\n{\n return i;\n}");
  4464. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_added_variable\n{\npublic:\n int func1(type_test_added_variable param);\n static int i;\n long j;\n double k;\n type_test_added_variable* p;\n};");
  4465. @Sources_v2 = (@Sources_v2, "int type_test_added_variable::func1(type_test_added_variable param)\n{\n return type_test_added_variable::i;\n}");
  4466. @Sources_v2 = (@Sources_v2, "int type_test_added_variable::i=0;");
  4467. #Withdrawn_Interface
  4468. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_withdrawn_interface\n{\npublic:\n type_test_withdrawn_interface func1(type_test_withdrawn_interface param);\n type_test_withdrawn_interface withdrawn_func(type_test_withdrawn_interface param);\n int i;\n long j;\n double k;\n type_test_withdrawn_interface* p;\n};");
  4469. @DataDefs_v1 = (@DataDefs_v1, "int withdrawn_func_2(void *** param);");
  4470. @Sources_v1 = (@Sources_v1, "type_test_withdrawn_interface type_test_withdrawn_interface::func1(type_test_withdrawn_interface param)\n{\n return param;\n}");
  4471. @Sources_v1 = (@Sources_v1, "type_test_withdrawn_interface type_test_withdrawn_interface::withdrawn_func(type_test_withdrawn_interface param)\n{\n return param;\n}");
  4472. @Sources_v1 = (@Sources_v1, "int withdrawn_func_2(void *** param)\n{\n return 0;\n}");
  4473. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_withdrawn_interface\n{\npublic:\n type_test_withdrawn_interface func1(type_test_withdrawn_interface param);\n int i;\n long j;\n double k;\n type_test_withdrawn_interface* p;\n};");
  4474. @Sources_v2 = (@Sources_v2, "type_test_withdrawn_interface type_test_withdrawn_interface::func1(type_test_withdrawn_interface param)\n{\n return param;\n}");
  4475. #Function_Become_Static
  4476. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_become_static\n{\npublic:\n type_test_become_static func_become_static(type_test_become_static param);\n int **i;\n long j;\n double k;\n type_test_become_static* p;\n};");
  4477. @Sources_v1 = (@Sources_v1, "type_test_become_static type_test_become_static::func_become_static(type_test_become_static param)\n{\n return param;\n}");
  4478. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_become_static\n{\npublic:\n static type_test_become_static func_become_static(type_test_become_static param);\n int **i;\n long j;\n double k;\n type_test_become_static* p;\n};");
  4479. @Sources_v2 = (@Sources_v2, "type_test_become_static type_test_become_static::func_become_static(type_test_become_static param)\n{\n return param;\n}");
  4480. #Function_Become_NonStatic
  4481. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_become_nonstatic\n{\npublic:\n static type_test_become_nonstatic func_become_nonstatic(type_test_become_nonstatic param);\n int **i;\n long j;\n double k;\n type_test_become_nonstatic* p;\n};");
  4482. @Sources_v1 = (@Sources_v1, "type_test_become_nonstatic type_test_become_nonstatic::func_become_nonstatic(type_test_become_nonstatic param)\n{\n return param;\n}");
  4483. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_become_nonstatic\n{\npublic:\n type_test_become_nonstatic func_become_nonstatic(type_test_become_nonstatic param);\n int **i;\n long j;\n double k;\n type_test_become_nonstatic* p;\n};");
  4484. @Sources_v2 = (@Sources_v2, "type_test_become_nonstatic type_test_become_nonstatic::func_become_nonstatic(type_test_become_nonstatic param)\n{\n return param;\n}");
  4485. #Parameter_Type_And_Size
  4486. @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_type_and_size(int param, int other_param);");
  4487. @Sources_v1 = (@Sources_v1, "int func_parameter_type_and_size(int param, int other_param)\n{\n return other_param;\n}");
  4488. @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_type_and_size(long long param, int other_param);");
  4489. @Sources_v2 = (@Sources_v2, "int func_parameter_type_and_size(long long param, int other_param)\n{\n return other_param;\n}");
  4490. #Parameter_Type
  4491. @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_type(int param, int other_param);");
  4492. @Sources_v1 = (@Sources_v1, "int func_parameter_type(int param, int other_param)\n{\n return other_param;\n}");
  4493. @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_type(float param, int other_param);");
  4494. @Sources_v2 = (@Sources_v2, "int func_parameter_type(float param, int other_param)\n{\n return other_param;\n}");
  4495. #Parameter_BaseType
  4496. @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_basetypechange(int *param);");
  4497. @Sources_v1 = (@Sources_v1, "int func_parameter_basetypechange(int *param)\n{\n return sizeof(*param);\n}");
  4498. @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_basetypechange(long long *param);");
  4499. @Sources_v2 = (@Sources_v2, "int func_parameter_basetypechange(long long *param)\n{\n return sizeof(*param);\n}");
  4500. #Parameter_PointerLevel_And_Size
  4501. @DataDefs_v1 = (@DataDefs_v1, "long long func_parameter_pointerlevel_and_size(long long param);");
  4502. @Sources_v1 = (@Sources_v1, "long long func_parameter_pointerlevel_and_size(long long param)\n{\n return param;\n}");
  4503. @DataDefs_v2 = (@DataDefs_v2, "long long func_parameter_pointerlevel_and_size(long long *param);");
  4504. @Sources_v2 = (@Sources_v2, "long long func_parameter_pointerlevel_and_size(long long *param)\n{\n return param[5];\n}");
  4505. #Parameter_PointerLevel
  4506. @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_pointerlevel(int *param);");
  4507. @Sources_v1 = (@Sources_v1, "int func_parameter_pointerlevel(int *param)\n{\n return param[5];\n}");
  4508. @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_pointerlevel(int **param);");
  4509. @Sources_v2 = (@Sources_v2, "int func_parameter_pointerlevel(int **param)\n{\n return param[5][5];\n}");
  4510. #Return_Type_And_Size
  4511. @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_size(int param);");
  4512. @Sources_v1 = (@Sources_v1, "int func_return_type_and_size(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}");
  4513. @DataDefs_v2 = (@DataDefs_v2, "long long func_return_type_and_size(int param);");
  4514. @Sources_v2 = (@Sources_v2, "long long func_return_type_and_size(int param)\n{\n return 2^(sizeof(long long)*8-1)-1;\n}");
  4515. #Return_Type
  4516. @DataDefs_v1 = (@DataDefs_v1, "int func_return_type(int param);");
  4517. @Sources_v1 = (@Sources_v1, "int func_return_type(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}");
  4518. @DataDefs_v2 = (@DataDefs_v2, "float func_return_type(int param);");
  4519. @Sources_v2 = (@Sources_v2, "float func_return_type(int param)\n{\n return 0.7;\n}");
  4520. #Return_BaseType
  4521. @DataDefs_v1 = (@DataDefs_v1, "int *func_return_basetype(int param);");
  4522. @Sources_v1 = (@Sources_v1, "int *func_return_basetype(int param)\n{\n int *x = new int[10];\n return x;\n}");
  4523. @DataDefs_v2 = (@DataDefs_v2, "long long *func_return_basetype(int param);");
  4524. @Sources_v2 = (@Sources_v2, "long long *func_return_basetype(int param)\n{\n long long *x = new long long[10];\n return x;\n}");
  4525. #Return_PointerLevel_And_Size
  4526. @DataDefs_v1 = (@DataDefs_v1, "long long func_return_pointerlevel_and_size(int param);");
  4527. @Sources_v1 = (@Sources_v1, "long long func_return_pointerlevel_and_size(int param)\n{\n return 100;\n}");
  4528. @DataDefs_v2 = (@DataDefs_v2, "long long *func_return_pointerlevel_and_size(int param);");
  4529. @Sources_v2 = (@Sources_v2, "long long *func_return_pointerlevel_and_size(int param)\n{\n long long* x = new long long[10];\n return x;\n}");
  4530. #Return_PointerLevel
  4531. @DataDefs_v1 = (@DataDefs_v1, "int* func_return_pointerlevel(int param);");
  4532. @Sources_v1 = (@Sources_v1, "int* func_return_pointerlevel(int param)\n{\n int* x = new int[10];\n return x;\n}");
  4533. @DataDefs_v2 = (@DataDefs_v2, "int **func_return_pointerlevel(int param);");
  4534. @Sources_v2 = (@Sources_v2, "int **func_return_pointerlevel(int param)\n{\n int** x = new int*[10];\n return x;\n}");
  4535. #typedef to anon struct
  4536. @DataDefs_v1 = (@DataDefs_v1, "
  4537. typedef struct
  4538. {
  4539. public:
  4540. int i;
  4541. long j;
  4542. double k;
  4543. } type_test_anon_typedef;
  4544. int func_test_anon_typedef(type_test_anon_typedef param);");
  4545. @Sources_v1 = (@Sources_v1, "int func_test_anon_typedef(type_test_anon_typedef param)\n{\n return 0;\n}");
  4546. @DataDefs_v2 = (@DataDefs_v2, "
  4547. typedef struct
  4548. {
  4549. public:
  4550. int i;
  4551. long j;
  4552. double k;
  4553. union {
  4554. int dummy[256];
  4555. struct {
  4556. char q_skiptable[256];
  4557. const char *p;
  4558. int l;
  4559. } p;
  4560. };
  4561. } type_test_anon_typedef;
  4562. int func_test_anon_typedef(type_test_anon_typedef param);");
  4563. @Sources_v2 = (@Sources_v2, "int func_test_anon_typedef(type_test_anon_typedef param)\n{\n return 0;\n}");
  4564. #opaque type
  4565. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_opaque\n{\npublic:\n virtual type_test_opaque func1(type_test_opaque param);\n int i;\n long j;\n double k;\n type_test_opaque* p;\n};");
  4566. @Sources_v1 = (@Sources_v1, "type_test_opaque type_test_opaque::func1(type_test_opaque param)\n{\n return param;\n}");
  4567. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_opaque\n{\npublic:\n virtual type_test_opaque func1(type_test_opaque param);\n int i;\n long j;\n double k;\n type_test_opaque* p;\n int added_member;\n};");
  4568. @Sources_v2 = (@Sources_v2, "type_test_opaque type_test_opaque::func1(type_test_opaque param)\n{\n return param;\n}");
  4569. #internal function
  4570. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_internal\n{\npublic:\n virtual type_test_internal func1(type_test_internal param);\n int i;\n long j;\n double k;\n type_test_internal* p;\n};");
  4571. @Sources_v1 = (@Sources_v1, "type_test_internal type_test_internal::func1(type_test_internal param)\n{\n return param;\n}");
  4572. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_internal\n{\npublic:\n virtual type_test_internal func1(type_test_internal param);\n int i;\n long j;\n double k;\n type_test_internal* p;\n int added_member;\n};");
  4573. @Sources_v2 = (@Sources_v2, "type_test_internal type_test_internal::func1(type_test_internal param)\n{\n return param;\n}");
  4574. #starting versioning
  4575. @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_start_versioning(int param);");
  4576. @Sources_v1 = (@Sources_v1, "int func_return_type_and_start_versioning(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}");
  4577. @DataDefs_v2 = (@DataDefs_v2, "int func_return_type_and_start_versioning(int param);");
  4578. @Sources_v2 = (@Sources_v2, "int func_return_type_and_start_versioning(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver _Z37func_return_type_and_start_versioningi,_Z37func_return_type_and_start_versioningi\@TEST_2.0\");");
  4579. #Return_Type And Good Versioning
  4580. @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_good_versioning(int param);");
  4581. @Sources_v1 = (@Sources_v1, "int func_return_type_and_good_versioning(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver _Z36func_return_type_and_good_versioningi,_Z36func_return_type_and_good_versioningi\@TEST_1.0\");");
  4582. @DataDefs_v2 = (@DataDefs_v2, "int func_return_type_and_good_versioning_old(int param);");
  4583. @Sources_v2 = (@Sources_v2, "int func_return_type_and_good_versioning_old(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver _Z40func_return_type_and_good_versioning_oldi,_Z36func_return_type_and_good_versioningi\@TEST_1.0\");");
  4584. @DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_good_versioning(int param);");
  4585. @Sources_v2 = (@Sources_v2, "float func_return_type_and_good_versioning(int param)\n{\n return 0.7;\n}\n__asm__(\".symver _Z36func_return_type_and_good_versioningi,_Z36func_return_type_and_good_versioningi\@TEST_2.0\");");
  4586. #Return_Type and bad versioning
  4587. @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_bad_versioning(int param);");
  4588. @Sources_v1 = (@Sources_v1, "int func_return_type_and_bad_versioning(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver _Z35func_return_type_and_bad_versioningi,_Z35func_return_type_and_bad_versioningi\@TEST_1.0\");");
  4589. @DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_bad_versioning_old(int param);");
  4590. @Sources_v2 = (@Sources_v2, "float func_return_type_and_bad_versioning_old(int param)\n{\n return 0.7;\n}\n__asm__(\".symver _Z39func_return_type_and_bad_versioning_oldi,_Z35func_return_type_and_bad_versioningi\@TEST_1.0\");");
  4591. @DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_bad_versioning(int param);");
  4592. @Sources_v2 = (@Sources_v2, "float func_return_type_and_bad_versioning(int param)\n{\n return 0.7;\n}\n__asm__(\".symver _Z35func_return_type_and_bad_versioningi,_Z35func_return_type_and_bad_versioningi\@TEST_2.0\");");
  4593. #unnamed struct fields within structs
  4594. @DataDefs_v1 = (@DataDefs_v1, "
  4595. typedef struct {
  4596. int a;
  4597. struct {
  4598. int b;
  4599. float c;
  4600. };
  4601. int d;
  4602. } type_test_unnamed;
  4603. int func_test_unnamed(type_test_unnamed param);");
  4604. @Sources_v1 = (@Sources_v1, "int func_test_unnamed(type_test_unnamed param)\n{\n return 0;\n}");
  4605. @DataDefs_v2 = (@DataDefs_v2, "
  4606. typedef struct {
  4607. int a;
  4608. struct {
  4609. long double b;
  4610. float c;
  4611. };
  4612. int d;
  4613. } type_test_unnamed;
  4614. int func_test_unnamed(type_test_unnamed param);");
  4615. @Sources_v2 = (@Sources_v2, "int func_test_unnamed(type_test_unnamed param)\n{\n return 0;\n}");
  4616. #constants
  4617. @DataDefs_v1 = (@DataDefs_v1, "#define TEST_PUBLIC_CONSTANT \"old_value\"");
  4618. @DataDefs_v2 = (@DataDefs_v2, "#define TEST_PUBLIC_CONSTANT \"new_value\"");
  4619. @DataDefs_v1 = (@DataDefs_v1, "#define TEST_PRIVATE_CONSTANT \"old_value\"\n#undef TEST_PRIVATE_CONSTANT");
  4620. @DataDefs_v2 = (@DataDefs_v2, "#define TEST_PRIVATE_CONSTANT \"new_value\"\n#undef TEST_PRIVATE_CONSTANT");
  4621. #unions
  4622. @DataDefs_v1 = (@DataDefs_v1, "
  4623. union type_test_union {
  4624. int a;
  4625. struct {
  4626. int b;
  4627. float c;
  4628. };
  4629. int d;
  4630. };
  4631. int func_test_union(type_test_union param);");
  4632. @Sources_v1 = (@Sources_v1, "int func_test_union(type_test_union param)\n{\n return 0;\n}");
  4633. @DataDefs_v2 = (@DataDefs_v2, "
  4634. union type_test_union {
  4635. int a;
  4636. long double new_member;
  4637. struct {
  4638. int b;
  4639. float c;
  4640. };
  4641. int d;
  4642. };
  4643. int func_test_union(type_test_union param);");
  4644. @Sources_v2 = (@Sources_v2, "int func_test_union(type_test_union param)\n{\n return 0;\n}");
  4645. #typedefs
  4646. @DataDefs_v1 = (@DataDefs_v1, "typedef float TYPEDEF_TYPE;\nint func_parameter_typedef_change(TYPEDEF_TYPE param);");
  4647. @Sources_v1 = (@Sources_v1, "int func_parameter_typedef_change(TYPEDEF_TYPE param)\n{\n return 1;\n}");
  4648. @DataDefs_v2 = (@DataDefs_v2, "typedef int TYPEDEF_TYPE;\nint func_parameter_typedef_change(TYPEDEF_TYPE param);");
  4649. @Sources_v2 = (@Sources_v2, "int func_parameter_typedef_change(TYPEDEF_TYPE param)\n{\n return 1;\n}");
  4650. #typedefs in member type
  4651. @DataDefs_v1 = (@DataDefs_v1, "typedef float TYPEDEF_TYPE_2;\nstruct type_test_member_typedef_change{\n public:\nTYPEDEF_TYPE_2 m;};\nint func_test_member_typedef_change(type_test_member_typedef_change param);");
  4652. @Sources_v1 = (@Sources_v1, "int func_test_member_typedef_change(type_test_member_typedef_change param)\n{\n return 1;\n}");
  4653. @DataDefs_v2 = (@DataDefs_v2, "typedef int TYPEDEF_TYPE_2;\nstruct type_test_member_typedef_change{\n public:\nTYPEDEF_TYPE_2 m;};\nint func_test_member_typedef_change(type_test_member_typedef_change param);");
  4654. @Sources_v2 = (@Sources_v2, "int func_test_member_typedef_change(type_test_member_typedef_change param)\n{\n return 1;\n}");
  4655. create_TestSuite("abi_changes_test_cpp", "C++", join("\n\n", @DataDefs_v1), join("\n\n", @Sources_v1), join("\n\n", @DataDefs_v2), join("\n\n", @Sources_v2), "type_test_opaque", "_ZN18type_test_internal5func1ES_");
  4656. }
  4657. sub testSystem_c()
  4658. {
  4659. print "\ntesting for C library changes\n";
  4660. my (@DataDefs_v1, @Sources_v1, @DataDefs_v2, @Sources_v2) = ();
  4661. #Withdrawn_Parameter
  4662. @DataDefs_v1 = (@DataDefs_v1, "int func_withdrawn_parameter(int param, int withdrawn_param);");
  4663. @Sources_v1 = (@Sources_v1, "int func_withdrawn_parameter(int param, int withdrawn_param)\n{\n return 0;\n}");
  4664. @DataDefs_v2 = (@DataDefs_v2, "int func_withdrawn_parameter(int param);");
  4665. @Sources_v2 = (@Sources_v2, "int func_withdrawn_parameter(int param)\n{\n return 0;\n}");
  4666. #Added_Parameter
  4667. @DataDefs_v1 = (@DataDefs_v1, "int func_added_parameter(int param);");
  4668. @Sources_v1 = (@Sources_v1, "int func_added_parameter(int param)\n{\n return 0;\n}");
  4669. @DataDefs_v2 = (@DataDefs_v2, "int func_added_parameter(int param, int added_param);");
  4670. @Sources_v2 = (@Sources_v2, "int func_added_parameter(int param, int added_param)\n{\n return 0;\n}");
  4671. #added function with typedef funcptr parameter
  4672. @DataDefs_v2 = (@DataDefs_v2, "typedef int (*FUNCPTR_TYPE)(int a, int b);\nint added_function_param_typedef_funcptr(FUNCPTR_TYPE*const** f);");
  4673. @Sources_v2 = (@Sources_v2, "int added_function_param_typedef_funcptr(FUNCPTR_TYPE*const** f)\n{\n return 0;\n}");
  4674. #added function with funcptr parameter
  4675. @DataDefs_v2 = (@DataDefs_v2, "int added_function_param_funcptr(int(*func)(int, int));");
  4676. @Sources_v2 = (@Sources_v2, "int added_function_param_funcptr(int(*func)(int, int))\n{\n return 0;\n}");
  4677. #added function with no limited parameters
  4678. @DataDefs_v2 = (@DataDefs_v2, "int added_function_nolimit_param(float p1, ...);");
  4679. @Sources_v2 = (@Sources_v2, "int added_function_nolimit_param(float p1, ...)\n{\n return 0;\n}");
  4680. #size change
  4681. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_size\n{\n long long i[5];\n long j;\n double k;\n struct type_test_size* p;\n};");
  4682. @DataDefs_v1 = (@DataDefs_v1, "int func_test_type_size(struct type_test_size param, int param_2);");
  4683. @Sources_v1 = (@Sources_v1, "int func_test_type_size(struct type_test_size param, int param_2)\n{\n return param_2;\n}");
  4684. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_size\n{\n long long i[5];\n long long j;\n double k;\n struct type_test_size* p;\n};");
  4685. @DataDefs_v2 = (@DataDefs_v2, "int func_test_type_size(struct type_test_size param, int param_2);");
  4686. @Sources_v2 = (@Sources_v2, "int func_test_type_size(struct type_test_size param, int param_2)\n{\n return param_2;\n}");
  4687. #Added_Member_And_Size
  4688. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_added_member\n{\n int i;\n long j;\n double k;\n struct type_test_added_member* p;\n};");
  4689. @DataDefs_v1 = (@DataDefs_v1, "int func_test_added_member(struct type_test_added_member param, int param_2);");
  4690. @Sources_v1 = (@Sources_v1, "int func_test_added_member(struct type_test_added_member param, int param_2)\n{\n return param_2;\n}");
  4691. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_added_member\n{\n int i;\n long j;\n double k;\n struct type_test_added_member* p;\n int added_member;\n};");
  4692. @DataDefs_v2 = (@DataDefs_v2, "int func_test_added_member(struct type_test_added_member param, int param_2);");
  4693. @Sources_v2 = (@Sources_v2, "int func_test_added_member(struct type_test_added_member param, int param_2)\n{\n return param_2;\n}");
  4694. #Added_Middle_Member_And_Size
  4695. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_added_middle_member\n{\n int i;\n long j;\n double k;\n struct type_test_added_member* p;\n};");
  4696. @DataDefs_v1 = (@DataDefs_v1, "int func_test_added_middle_member(struct type_test_added_middle_member param, int param_2);");
  4697. @Sources_v1 = (@Sources_v1, "int func_test_added_middle_member(struct type_test_added_middle_member param, int param_2)\n{\n return param_2;\n}");
  4698. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_added_middle_member\n{\n int i;\n int added_middle_member;\n long j;\n double k;\n struct type_test_added_member* p;\n};");
  4699. @DataDefs_v2 = (@DataDefs_v2, "int func_test_added_middle_member(struct type_test_added_middle_member param, int param_2);");
  4700. @Sources_v2 = (@Sources_v2, "int func_test_added_middle_member(struct type_test_added_middle_member param, int param_2)\n{\n return param_2;\n}");
  4701. #Member_Rename
  4702. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_rename\n{\n long i;\n long j;\n double k;\n struct type_test_member_rename* p;\n};");
  4703. @DataDefs_v1 = (@DataDefs_v1, "int func_test_member_rename(struct type_test_member_rename param, int param_2);");
  4704. @Sources_v1 = (@Sources_v1, "int func_test_member_rename(struct type_test_member_rename param, int param_2)\n{\n return param_2;\n}");
  4705. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_rename\n{\n long renamed_member;\n long j;\n double k;\n struct type_test_member_rename* p;\n};");
  4706. @DataDefs_v2 = (@DataDefs_v2, "int func_test_member_rename(struct type_test_member_rename param, int param_2);");
  4707. @Sources_v2 = (@Sources_v2, "int func_test_member_rename(struct type_test_member_rename param, int param_2)\n{\n return param_2;\n}");
  4708. #Withdrawn_Member_And_Size
  4709. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_withdrawn_member\n{\n int i;\n long j;\n double k;\n struct type_test_withdrawn_member* p;\n int withdrawn_member;\n};");
  4710. @DataDefs_v1 = (@DataDefs_v1, "int func_test_withdrawn_member(struct type_test_withdrawn_member param, int param_2);");
  4711. @Sources_v1 = (@Sources_v1, "int func_test_withdrawn_member(struct type_test_withdrawn_member param, int param_2)\n{\n return param_2;\n}");
  4712. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_withdrawn_member\n{\n int i;\n long j;\n double k;\n struct type_test_withdrawn_member* p;\n};");
  4713. @DataDefs_v2 = (@DataDefs_v2, "int func_test_withdrawn_member(struct type_test_withdrawn_member param, int param_2);");
  4714. @Sources_v2 = (@Sources_v2, "int func_test_withdrawn_member(struct type_test_withdrawn_member param, int param_2)\n{\n return param_2;\n}");
  4715. #Withdrawn_Middle_Member
  4716. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_withdrawn_middle_member\n{\n int i;\n int withdrawn_middle_member;\n long j;\n double k;\n struct type_test_withdrawn_middle_member* p;\n};");
  4717. @DataDefs_v1 = (@DataDefs_v1, "int func_test_withdrawn_middle_member(struct type_test_withdrawn_middle_member param, int param_2);");
  4718. @Sources_v1 = (@Sources_v1, "int func_test_withdrawn_middle_member(struct type_test_withdrawn_middle_member param, int param_2)\n{\n return param_2;\n}");
  4719. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_withdrawn_middle_member\n{\n int i;\n long j;\n double k;\n struct type_test_withdrawn_middle_member* p;\n};");
  4720. @DataDefs_v2 = (@DataDefs_v2, "int func_test_withdrawn_middle_member(struct type_test_withdrawn_middle_member param, int param_2);");
  4721. @Sources_v2 = (@Sources_v2, "int func_test_withdrawn_middle_member(struct type_test_withdrawn_middle_member param, int param_2)\n{\n return param_2;\n}");
  4722. #Enum_Member_Value
  4723. @DataDefs_v1 = (@DataDefs_v1, "enum type_test_enum_member_value_change\n{\n MEMBER_1=1,\n MEMBER_2=2\n};");
  4724. @DataDefs_v1 = (@DataDefs_v1, "int func_test_enum_member_value_change(enum type_test_enum_member_value_change param);");
  4725. @Sources_v1 = (@Sources_v1,
  4726. "int func_test_enum_member_value_change(enum type_test_enum_member_value_change param)
  4727. {
  4728. switch(param)
  4729. {
  4730. case 1:
  4731. return 1;
  4732. case 2:
  4733. return 2;
  4734. }
  4735. return 0;
  4736. }");
  4737. @DataDefs_v2 = (@DataDefs_v2, "enum type_test_enum_member_value_change\n{\n MEMBER_1=2,\n MEMBER_2=1\n};");
  4738. @DataDefs_v2 = (@DataDefs_v2, "int func_test_enum_member_value_change(enum type_test_enum_member_value_change param);");
  4739. @Sources_v2 = (@Sources_v2,
  4740. "int func_test_enum_member_value_change(enum type_test_enum_member_value_change param)
  4741. {
  4742. switch(param)
  4743. {
  4744. case 1:
  4745. return 1;
  4746. case 2:
  4747. return 2;
  4748. }
  4749. return 0;
  4750. }");
  4751. #Enum_Member_Name
  4752. @DataDefs_v1 = (@DataDefs_v1, "enum type_test_enum_member_rename\n{\n BRANCH_1=1,\n BRANCH_2=2\n};");
  4753. @DataDefs_v1 = (@DataDefs_v1, "int func_test_enum_member_rename(enum type_test_enum_member_rename param);");
  4754. @Sources_v1 = (@Sources_v1,
  4755. "int func_test_enum_member_rename(enum type_test_enum_member_rename param)
  4756. {
  4757. switch(param)
  4758. {
  4759. case 1:
  4760. return 1;
  4761. case 2:
  4762. return 2;
  4763. }
  4764. return 0;
  4765. }");
  4766. @DataDefs_v2 = (@DataDefs_v2, "enum type_test_enum_member_rename\n{\n BRANCH_FIRST=1,\n BRANCH_SECOND=1\n};");
  4767. @DataDefs_v2 = (@DataDefs_v2, "int func_test_enum_member_rename(enum type_test_enum_member_rename param);");
  4768. @Sources_v2 = (@Sources_v2,
  4769. "int func_test_enum_member_rename(enum type_test_enum_member_rename param)
  4770. {
  4771. switch(param)
  4772. {
  4773. case 1:
  4774. return 1;
  4775. case 2:
  4776. return 2;
  4777. }
  4778. return 0;
  4779. }");
  4780. #Member_Type_And_Size
  4781. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_type_and_size\n{\n int i;\n long j;\n double k;\n struct type_test_member_type_and_size* p;\n};");
  4782. @DataDefs_v1 = (@DataDefs_v1, "int func_test_member_type_and_size(struct type_test_member_type_and_size param, int param_2);");
  4783. @Sources_v1 = (@Sources_v1, "int func_test_member_type_and_size(struct type_test_member_type_and_size param, int param_2)\n{\n return param_2;\n}");
  4784. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_type_and_size\n{\n int i;\n long j;\n long double k;\n struct type_test_member_type_and_size* p;\n};");
  4785. @DataDefs_v2 = (@DataDefs_v2, "int func_test_member_type_and_size(struct type_test_member_type_and_size param, int param_2);");
  4786. @Sources_v2 = (@Sources_v2, "int func_test_member_type_and_size(struct type_test_member_type_and_size param, int param_2)\n{\n return param_2;\n}");
  4787. #Member_Type
  4788. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_type\n{\n int i;\n long j;\n double k;\n struct type_test_member_type* p;\n};");
  4789. @DataDefs_v1 = (@DataDefs_v1, "int func_test_member_type(struct type_test_member_type param, int param_2);");
  4790. @Sources_v1 = (@Sources_v1, "int func_test_member_type(struct type_test_member_type param, int param_2)\n{\n return param_2;\n}");
  4791. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_type\n{\n float i;\n long j;\n double k;\n struct type_test_member_type* p;\n};");
  4792. @DataDefs_v2 = (@DataDefs_v2, "int func_test_member_type(struct type_test_member_type param, int param_2);");
  4793. @Sources_v2 = (@Sources_v2, "int func_test_member_type(struct type_test_member_type param, int param_2)\n{\n return param_2;\n}");
  4794. #Member_BaseType
  4795. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_basetype\n{\n int i;\n long *j;\n double k;\n struct type_test_member_basetype* p;\n};");
  4796. @DataDefs_v1 = (@DataDefs_v1, "int func_test_member_basetype(struct type_test_member_basetype param, int param_2);");
  4797. @Sources_v1 = (@Sources_v1, "int func_test_member_basetype(struct type_test_member_basetype param, int param_2)\n{\n return param_2;\n}");
  4798. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_basetype\n{\n int i;\n long long *j;\n double k;\n struct type_test_member_basetype* p;\n};");
  4799. @DataDefs_v2 = (@DataDefs_v2, "int func_test_member_basetype(struct type_test_member_basetype param, int param_2);");
  4800. @Sources_v2 = (@Sources_v2, "int func_test_member_basetype(struct type_test_member_basetype param, int param_2)\n{\n return param_2;\n}");
  4801. #Member_PointerLevel_And_Size
  4802. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_pointerlevel_and_size\n{\n int i;\n long long j;\n double k;\n struct type_test_member_pointerlevel_and_size* p;\n};");
  4803. @DataDefs_v1 = (@DataDefs_v1, "int func_test_member_pointerlevel_and_size(struct type_test_member_pointerlevel_and_size param, int param_2);");
  4804. @Sources_v1 = (@Sources_v1, "int func_test_member_pointerlevel_and_size(struct type_test_member_pointerlevel_and_size param, int param_2)\n{\n return param_2;\n}");
  4805. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_pointerlevel_and_size\n{\n int i;\n long long *j;\n double k;\n struct type_test_member_pointerlevel_and_size* p;\n};");
  4806. @DataDefs_v2 = (@DataDefs_v2, "int func_test_member_pointerlevel_and_size(struct type_test_member_pointerlevel_and_size param, int param_2);");
  4807. @Sources_v2 = (@Sources_v2, "int func_test_member_pointerlevel_and_size(struct type_test_member_pointerlevel_and_size param, int param_2)\n{\n return param_2;\n}");
  4808. #Member_PointerLevel
  4809. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_pointerlevel\n{\n int i;\n long *j;\n double k;\n struct type_test_member_pointerlevel* p;\n};");
  4810. @DataDefs_v1 = (@DataDefs_v1, "int func_test_member_pointerlevel(struct type_test_member_pointerlevel param, int param_2);");
  4811. @Sources_v1 = (@Sources_v1, "int func_test_member_pointerlevel(struct type_test_member_pointerlevel param, int param_2)\n{\n return param_2;\n}");
  4812. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_pointerlevel\n{\n int i;\n long **j;\n double k;\n struct type_test_member_pointerlevel* p;\n};");
  4813. @DataDefs_v2 = (@DataDefs_v2, "int func_test_member_pointerlevel(struct type_test_member_pointerlevel param, int param_2);");
  4814. @Sources_v2 = (@Sources_v2, "int func_test_member_pointerlevel(struct type_test_member_pointerlevel param, int param_2)\n{\n return param_2;\n}");
  4815. #Added_Interface
  4816. @DataDefs_v2 = (@DataDefs_v2, "int added_func(int param);");
  4817. @Sources_v2 = (@Sources_v2, "int added_func(int param)\n{\n return param;\n}");
  4818. #Withdrawn_Interface
  4819. @DataDefs_v1 = (@DataDefs_v1, "int withdrawn_func(int param);");
  4820. @Sources_v1 = (@Sources_v1, "int withdrawn_func(int param)\n{\n return param;\n}");
  4821. #Parameter_Type_And_Size
  4822. @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_type_and_size(int param, int other_param);");
  4823. @Sources_v1 = (@Sources_v1, "int func_parameter_type_and_size(int param, int other_param)\n{\n return other_param;\n}");
  4824. @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_type_and_size(long long param, int other_param);");
  4825. @Sources_v2 = (@Sources_v2, "int func_parameter_type_and_size(long long param, int other_param)\n{\n return other_param;\n}");
  4826. #Parameter_Type
  4827. @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_type(int param, int other_param);");
  4828. @Sources_v1 = (@Sources_v1, "int func_parameter_type(int param, int other_param)\n{\n return other_param;\n}");
  4829. @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_type(float param, int other_param);");
  4830. @Sources_v2 = (@Sources_v2, "int func_parameter_type(float param, int other_param)\n{\n return other_param;\n}");
  4831. #Parameter_BaseType (Typedef)
  4832. @DataDefs_v1 = (@DataDefs_v1, "typedef int* PARAM_TYPEDEF;\nint func_parameter_basetypechange_typedef(PARAM_TYPEDEF param);");
  4833. @Sources_v1 = (@Sources_v1, "int func_parameter_basetypechange_typedef(PARAM_TYPEDEF param)\n{\n return 0;\n}");
  4834. @DataDefs_v2 = (@DataDefs_v2, "typedef const int* PARAM_TYPEDEF;\nint func_parameter_basetypechange_typedef(PARAM_TYPEDEF param);");
  4835. @Sources_v2 = (@Sources_v2, "int func_parameter_basetypechange_typedef(PARAM_TYPEDEF param)\n{\n return 0;\n}");
  4836. #Parameter_BaseType
  4837. @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_basetypechange(int *param);");
  4838. @Sources_v1 = (@Sources_v1, "int func_parameter_basetypechange(int *param)\n{\n return sizeof(*param);\n}");
  4839. @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_basetypechange(long long *param);");
  4840. @Sources_v2 = (@Sources_v2, "int func_parameter_basetypechange(long long *param)\n{\n return sizeof(*param);\n}");
  4841. #Parameter_PointerLevel_And_Size
  4842. @DataDefs_v1 = (@DataDefs_v1, "long long func_parameter_pointerlevel_and_size(long long param);");
  4843. @Sources_v1 = (@Sources_v1, "long long func_parameter_pointerlevel_and_size(long long param)\n{\n return param;\n}");
  4844. @DataDefs_v2 = (@DataDefs_v2, "long long func_parameter_pointerlevel_and_size(long long *param);");
  4845. @Sources_v2 = (@Sources_v2, "long long func_parameter_pointerlevel_and_size(long long *param)\n{\n return param[5];\n}");
  4846. #Parameter_PointerLevel
  4847. @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_pointerlevel(int *param);");
  4848. @Sources_v1 = (@Sources_v1, "int func_parameter_pointerlevel(int *param)\n{\n return param[5];\n}");
  4849. @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_pointerlevel(int **param);");
  4850. @Sources_v2 = (@Sources_v2, "int func_parameter_pointerlevel(int **param)\n{\n return param[5][5];\n}");
  4851. #Return_Type_And_Size
  4852. @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_size(int param);");
  4853. @Sources_v1 = (@Sources_v1, "int func_return_type_and_size(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}");
  4854. @DataDefs_v2 = (@DataDefs_v2, "long long func_return_type_and_size(int param);");
  4855. @Sources_v2 = (@Sources_v2, "long long func_return_type_and_size(int param)\n{\n return 2^(sizeof(long long)*8-1)-1;\n}");
  4856. #Return_Type
  4857. @DataDefs_v1 = (@DataDefs_v1, "int func_return_type(int param);");
  4858. @Sources_v1 = (@Sources_v1, "int func_return_type(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}");
  4859. @DataDefs_v2 = (@DataDefs_v2, "float func_return_type(int param);");
  4860. @Sources_v2 = (@Sources_v2, "float func_return_type(int param)\n{\n return 0.7;\n}");
  4861. #Return_BaseType
  4862. @DataDefs_v1 = (@DataDefs_v1, "int *func_return_basetypechange(int param);");
  4863. @Sources_v1 = (@Sources_v1, "int *func_return_basetypechange(int param)\n{\n int *x = (int*)malloc(10*sizeof(int));\n *x = 2^(sizeof(int)*8-1)-1;\n return x;\n}");
  4864. @DataDefs_v2 = (@DataDefs_v2, "long long *func_return_basetypechange(int param);");
  4865. @Sources_v2 = (@Sources_v2, "long long *func_return_basetypechange(int param)\n{\n long long *x = (long long*)malloc(10*sizeof(long long));\n *x = 2^(sizeof(long long)*8-1)-1;\n return x;\n}");
  4866. #Return_PointerLevel_And_Size
  4867. @DataDefs_v1 = (@DataDefs_v1, "long long func_return_pointerlevel_and_size(int param);");
  4868. @Sources_v1 = (@Sources_v1, "long long func_return_pointerlevel_and_size(int param)\n{\n return 100;\n}");
  4869. @DataDefs_v2 = (@DataDefs_v2, "long long *func_return_pointerlevel_and_size(int param);");
  4870. @Sources_v2 = (@Sources_v2, "long long *func_return_pointerlevel_and_size(int param)\n{\n long long *x = (long long*)malloc(10*sizeof(long long));\n *x = 2^(sizeof(long long)*8-1)-1;\n return x;\n}");
  4871. #Return_PointerLevel
  4872. @DataDefs_v1 = (@DataDefs_v1, "long long *func_return_pointerlevel(int param);");
  4873. @Sources_v1 = (@Sources_v1, "long long *func_return_pointerlevel(int param)\n{\n long long *x = (long long*)malloc(10*sizeof(long long));\n *x = 2^(sizeof(long long)*8-1)-1;\n return x;\n}");
  4874. @DataDefs_v2 = (@DataDefs_v2, "long long **func_return_pointerlevel(int param);");
  4875. @Sources_v2 = (@Sources_v2, "long long **func_return_pointerlevel(int param)\n{\n long long *x = (long long*)malloc(10*sizeof(long long));\n *x = 2^(sizeof(long long)*8-1)-1;\n long *y = (long*)malloc(sizeof(long long));\n *y=(long)&x;\n return (long long **)y;\n}");
  4876. #typedef to anon struct
  4877. @DataDefs_v1 = (@DataDefs_v1, "
  4878. typedef struct
  4879. {
  4880. int i;
  4881. long j;
  4882. double k;
  4883. } type_test_anon_typedef;
  4884. int func_test_anon_typedef(type_test_anon_typedef param);");
  4885. @Sources_v1 = (@Sources_v1, "int func_test_anon_typedef(type_test_anon_typedef param)\n{\n return 0;\n}");
  4886. @DataDefs_v2 = (@DataDefs_v2, "
  4887. typedef struct
  4888. {
  4889. int i;
  4890. long j;
  4891. double k;
  4892. union {
  4893. int dummy[256];
  4894. struct {
  4895. char q_skiptable[256];
  4896. const char *p;
  4897. int l;
  4898. } p;
  4899. };
  4900. } type_test_anon_typedef;
  4901. int func_test_anon_typedef(type_test_anon_typedef param);");
  4902. @Sources_v2 = (@Sources_v2, "int func_test_anon_typedef(type_test_anon_typedef param)\n{\n return 0;\n}");
  4903. #opaque type
  4904. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_opaque\n{\n long long i[5];\n long j;\n double k;\n struct type_test_opaque* p;\n};");
  4905. @DataDefs_v1 = (@DataDefs_v1, "int func_test_opaque(struct type_test_opaque param, int param_2);");
  4906. @Sources_v1 = (@Sources_v1, "int func_test_opaque(struct type_test_opaque param, int param_2)\n{\n return param_2;\n}");
  4907. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_opaque\n{\n long long i[5];\n long long j;\n double k;\n struct type_test_opaque* p;\n};");
  4908. @DataDefs_v2 = (@DataDefs_v2, "int func_test_opaque(struct type_test_opaque param, int param_2);");
  4909. @Sources_v2 = (@Sources_v2, "int func_test_opaque(struct type_test_opaque param, int param_2)\n{\n return param_2;\n}");
  4910. #internal function
  4911. @DataDefs_v1 = (@DataDefs_v1, "struct type_test_internal\n{\n long long i[5];\n long j;\n double k;\n struct type_test_internal* p;\n};");
  4912. @DataDefs_v1 = (@DataDefs_v1, "int func_test_internal(struct type_test_internal param, int param_2);");
  4913. @Sources_v1 = (@Sources_v1, "int func_test_internal(struct type_test_internal param, int param_2)\n{\n return param_2;\n}");
  4914. @DataDefs_v2 = (@DataDefs_v2, "struct type_test_internal\n{\n long long i[5];\n long long j;\n double k;\n struct type_test_internal* p;\n};");
  4915. @DataDefs_v2 = (@DataDefs_v2, "int func_test_internal(struct type_test_internal param, int param_2);");
  4916. @Sources_v2 = (@Sources_v2, "int func_test_internal(struct type_test_internal param, int param_2)\n{\n return param_2;\n}");
  4917. #starting versioning
  4918. @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_start_versioning(int param);");
  4919. @Sources_v1 = (@Sources_v1, "int func_return_type_and_start_versioning(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}");
  4920. @DataDefs_v2 = (@DataDefs_v2, "int func_return_type_and_start_versioning(int param);");
  4921. @Sources_v2 = (@Sources_v2, "int func_return_type_and_start_versioning(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver func_return_type_and_start_versioning,func_return_type_and_start_versioning\@TEST_2.0\");");
  4922. #Return_Type and good versioning
  4923. @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_good_versioning(int param);");
  4924. @Sources_v1 = (@Sources_v1, "int func_return_type_and_good_versioning(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver func_return_type_and_good_versioning,func_return_type_and_good_versioning\@TEST_1.0\");");
  4925. @DataDefs_v2 = (@DataDefs_v2, "int func_return_type_and_good_versioning_old(int param);");
  4926. @Sources_v2 = (@Sources_v2, "int func_return_type_and_good_versioning_old(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver func_return_type_and_good_versioning_old,func_return_type_and_good_versioning\@TEST_1.0\");");
  4927. @DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_good_versioning(int param);");
  4928. @Sources_v2 = (@Sources_v2, "float func_return_type_and_good_versioning(int param)\n{\n return 0.7;\n}\n__asm__(\".symver func_return_type_and_good_versioning,func_return_type_and_good_versioning\@TEST_2.0\");");
  4929. #Return_Type and bad versioning
  4930. @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_bad_versioning(int param);");
  4931. @Sources_v1 = (@Sources_v1, "int func_return_type_and_bad_versioning(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver func_return_type_and_bad_versioning,func_return_type_and_bad_versioning\@TEST_1.0\");");
  4932. @DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_bad_versioning_old(int param);");
  4933. @Sources_v2 = (@Sources_v2, "float func_return_type_and_bad_versioning_old(int param)\n{\n return 0.7;\n}\n__asm__(\".symver func_return_type_and_bad_versioning_old,func_return_type_and_bad_versioning\@TEST_1.0\");");
  4934. @DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_bad_versioning(int param);");
  4935. @Sources_v2 = (@Sources_v2, "float func_return_type_and_bad_versioning(int param)\n{\n return 0.7;\n}\n__asm__(\".symver func_return_type_and_bad_versioning,func_return_type_and_bad_versioning\@TEST_2.0\");");
  4936. #unnamed struct/union fields within structs/unions
  4937. @DataDefs_v1 = (@DataDefs_v1, "
  4938. typedef struct {
  4939. int a;
  4940. union {
  4941. int b;
  4942. float c;
  4943. };
  4944. int d;
  4945. } type_test_unnamed;
  4946. int func_test_unnamed(type_test_unnamed param);");
  4947. @Sources_v1 = (@Sources_v1, "int func_test_unnamed(type_test_unnamed param)\n{\n return 0;\n}");
  4948. @DataDefs_v2 = (@DataDefs_v2, "
  4949. typedef struct {
  4950. int a;
  4951. union {
  4952. long double b;
  4953. float c;
  4954. };
  4955. int d;
  4956. } type_test_unnamed;
  4957. int func_test_unnamed(type_test_unnamed param);");
  4958. @Sources_v2 = (@Sources_v2, "int func_test_unnamed(type_test_unnamed param)\n{\n return 0;\n}");
  4959. #constants
  4960. @DataDefs_v1 = (@DataDefs_v1, "#define TEST_PUBLIC_CONSTANT \"old_value\"");
  4961. @DataDefs_v2 = (@DataDefs_v2, "#define TEST_PUBLIC_CONSTANT \"new_value\"");
  4962. @DataDefs_v1 = (@DataDefs_v1, "#define TEST_PRIVATE_CONSTANT \"old_value\"\n#undef TEST_PRIVATE_CONSTANT");
  4963. @DataDefs_v2 = (@DataDefs_v2, "#define TEST_PRIVATE_CONSTANT \"new_value\"\n#undef TEST_PRIVATE_CONSTANT");
  4964. #anon ptr typedef
  4965. @DataDefs_v1 = (@DataDefs_v1, "
  4966. #ifdef __cplusplus
  4967. extern \"C\" {
  4968. #endif
  4969. typedef struct {
  4970. int a;
  4971. } *type_test_anonptr_typedef;
  4972. extern __attribute__ ((visibility(\"default\"))) int func_test_anonptr_typedef(type_test_anonptr_typedef param);
  4973. #ifdef __cplusplus
  4974. }
  4975. #endif");
  4976. @Sources_v1 = (@Sources_v1, "__attribute__ ((visibility(\"default\"))) int func_test_anonptr_typedef(type_test_anonptr_typedef param)\n{\n return 0;\n}");
  4977. @DataDefs_v2 = (@DataDefs_v2, "
  4978. #ifdef __cplusplus
  4979. extern \"C\" {
  4980. #endif
  4981. typedef struct {
  4982. float a;
  4983. } *type_test_anonptr_typedef;
  4984. extern __attribute__ ((visibility(\"default\"))) int func_test_anonptr_typedef(type_test_anonptr_typedef param);
  4985. #ifdef __cplusplus
  4986. }
  4987. #endif");
  4988. @Sources_v2 = (@Sources_v2, "__attribute__ ((visibility(\"default\"))) int func_test_anonptr_typedef(type_test_anonptr_typedef param)\n{\n return 0;\n}");
  4989. #typedefs
  4990. @DataDefs_v1 = (@DataDefs_v1, "typedef float TYPEDEF_TYPE;\nint func_parameter_typedef_change(TYPEDEF_TYPE param);");
  4991. @Sources_v1 = (@Sources_v1, "int func_parameter_typedef_change(TYPEDEF_TYPE param)\n{\n return 1.0;\n}");
  4992. @DataDefs_v2 = (@DataDefs_v2, "typedef int TYPEDEF_TYPE;\nint func_parameter_typedef_change(TYPEDEF_TYPE param);");
  4993. @Sources_v2 = (@Sources_v2, "int func_parameter_typedef_change(TYPEDEF_TYPE param)\n{\n return 1;\n}");
  4994. #typedefs in member type
  4995. @DataDefs_v1 = (@DataDefs_v1, "typedef float TYPEDEF_TYPE_2;\nstruct type_test_member_typedef_change{\nTYPEDEF_TYPE_2 m;};\nint func_test_member_typedef_change(struct type_test_member_typedef_change param);");
  4996. @Sources_v1 = (@Sources_v1, "int func_test_member_typedef_change(struct type_test_member_typedef_change param)\n{\n return 1;\n}");
  4997. @DataDefs_v2 = (@DataDefs_v2, "typedef int TYPEDEF_TYPE_2;\nstruct type_test_member_typedef_change{\nTYPEDEF_TYPE_2 m;};\nint func_test_member_typedef_change(struct type_test_member_typedef_change param);");
  4998. @Sources_v2 = (@Sources_v2, "int func_test_member_typedef_change(struct type_test_member_typedef_change param)\n{\n return 1;\n}");
  4999. create_TestSuite("abi_changes_test_c", "C", join("\n\n", @DataDefs_v1), join("\n\n", @Sources_v1), join("\n\n", @DataDefs_v2), join("\n\n", @Sources_v2), "type_test_opaque", "func_test_internal");
  5000. }
  5001. sub create_TestSuite($$$$$$$$)
  5002. {
  5003. my ($Dir, $Lang, $DataDefs_v1, $Sources_v1, $DataDefs_v2, $Sources_v2, $Opaque, $Private) = @_;
  5004. my $Ext = ($Lang eq "C++")?"cpp":"c";
  5005. my $Gcc = ($Lang eq "C++")?"g++":"gcc";
  5006. #creating test suite
  5007. my $Path_v1 = "$Dir/lib_abi_changes_test.v1";
  5008. my $Path_v2 = "$Dir/lib_abi_changes_test.v2";
  5009. system("rm", "-fr", $Path_v1, $Path_v2);
  5010. system("mkdir", "-p", $Path_v1, $Path_v2);
  5011. writeFile("$Path_v1/version", "TEST_1.0 {\n};\nTEST_2.0 {\n};\n");
  5012. writeFile("$Path_v1/lib_abi_changes_test.h", "#include <stdlib.h>\n".$DataDefs_v1."\n");
  5013. writeFile("$Path_v1/lib_abi_changes_test.$Ext", "#include \"lib_abi_changes_test.h\"\n".$Sources_v1."\n");
  5014. writeFile("$Dir/descriptor.v1", "<version>\n 1.0.0\n</version>\n\n<headers>\n ".$ENV{"PWD"}."/$Path_v1/\n</headers>\n\n<libs>\n ".$ENV{"PWD"}."/$Path_v1/\n</libs>\n\n<opaque_types>\n $Opaque\n</opaque_types>\n\n<skip_interfaces>\n $Private\n</skip_interfaces>\n\n<include_paths>\n ".$ENV{"PWD"}."/$Path_v1\n</include_paths>\n");
  5015. writeFile("$Path_v2/version", "TEST_1.0 {\n};\nTEST_2.0 {\n};\n");
  5016. writeFile("$Path_v2/lib_abi_changes_test.h", "#include <stdlib.h>\n".$DataDefs_v2."\n");
  5017. writeFile("$Path_v2/lib_abi_changes_test.$Ext", "#include \"lib_abi_changes_test.h\"\n".$Sources_v2."\n");
  5018. writeFile("$Dir/descriptor.v2", "<version>\n 2.0.0\n</version>\n\n<headers>\n ".$ENV{"PWD"}."/$Path_v2/\n</headers>\n\n<libs>\n ".$ENV{"PWD"}."/$Path_v2/\n</libs>\n\n<opaque_types>\n $Opaque\n</opaque_types>\n\n<skip_interfaces>\n $Private\n</skip_interfaces>\n\n<include_paths>\n ".$ENV{"PWD"}."/$Path_v2\n</include_paths>\n");
  5019. system("$Gcc $Path_v1/lib_abi_changes_test.h");
  5020. if($?)
  5021. {
  5022. print "ERROR: can't compile \'$Path_v1/lib_abi_changes_test.h\'\n";
  5023. return;
  5024. }
  5025. system("$Gcc -Wl,--version-script $Path_v1/version -shared $Path_v1/lib_abi_changes_test.$Ext -o $Path_v1/lib_abi_changes_test.so");
  5026. if($?)
  5027. {
  5028. print "ERROR: can't compile \'$Path_v1/lib_abi_changes_test.$Ext\'\n";
  5029. return;
  5030. }
  5031. system("$Gcc $Path_v2/lib_abi_changes_test.h");
  5032. if($?)
  5033. {
  5034. print "ERROR: can't compile \'$Path_v2/lib_abi_changes_test.h\'\n";
  5035. return;
  5036. }
  5037. system("$Gcc -Wl,--version-script $Path_v2/version -shared $Path_v2/lib_abi_changes_test.$Ext -o $Path_v2/lib_abi_changes_test.so");
  5038. if($?)
  5039. {
  5040. print "ERROR: can't compile \'$Path_v2/lib_abi_changes_test.$Ext\'\n";
  5041. return;
  5042. }
  5043. #running abi-compliance-checker
  5044. system("$0 -l lib_$Dir -d1 $Dir/descriptor.v1 -d2 $Dir/descriptor.v2");
  5045. }
  5046. sub writeFile($$)
  5047. {
  5048. my ($Path, $Content) = @_;
  5049. return if(not $Path);
  5050. open (FILE, ">".$Path) || die ("Can't open file $Path\n");
  5051. print FILE $Content;
  5052. close(FILE);
  5053. }
  5054. sub readFile($)
  5055. {
  5056. my $Path = $_[0];
  5057. return "" if(not $Path or not -f $Path);
  5058. open (FILE, $Path);
  5059. my $Content = join("\n", <FILE>);
  5060. close(FILE);
  5061. return toUnix($Content);
  5062. }
  5063. sub toUnix($)
  5064. {
  5065. my $Text = $_[0];
  5066. $Text=~s/\r//g;
  5067. return $Text;
  5068. }
  5069. sub getArch()
  5070. {
  5071. my $Arch = $ENV{"CPU"};
  5072. if(not $Arch)
  5073. {
  5074. $Arch = `uname -m`;
  5075. chomp($Arch);
  5076. }
  5077. if(not $Arch)
  5078. {
  5079. $Arch = `uname -p`;
  5080. chomp($Arch);
  5081. }
  5082. $Arch = "x86" if($Arch =~ /i[3-7]86/);
  5083. return $Arch;
  5084. }
  5085. sub get_Report_Header()
  5086. {
  5087. my $Report_Header = "<h1>ABI compliance report for the library <span style='color:Blue;white-space:nowrap;'>$TargetLibraryName </span> from version <span style='color:Red;white-space:nowrap;'>".$Descriptor{1}{"Version"}."</span> to <span style='color:Red;white-space:nowrap;'>".$Descriptor{2}{"Version"}."</span> on <span style='color:Blue;'>".getArch()."</span> ".(($AppPath)?"relating to the portability of application <span style='color:Blue;'>".get_FileName($AppPath)."</span>":"")."</h1>\n";
  5088. return "<!--Header-->\n".$Report_Header."<!--Header_End-->\n";
  5089. }
  5090. sub get_SourceInfo()
  5091. {
  5092. my $CheckedHeaders = "<!--Checked_Headers-->\n<a name='Checked_Headers'></a><h2 style='margin-bottom:0px;padding-bottom:0px;'>Checked header files (".keys(%{$Headers{1}}).")</h2><hr/>\n";
  5093. foreach my $Header_Dest (sort {lc($Headers{1}{$a}{"Name"}) cmp lc($Headers{1}{$b}{"Name"})} keys(%{$Headers{1}}))
  5094. {
  5095. my $Header_Name = $Headers{1}{$Header_Dest}{"Name"};
  5096. my $Dest_Count = keys(%{$HeaderName_Destinations{1}{$Header_Name}});
  5097. my $Identity = $Headers{1}{$Header_Dest}{"Identity"};
  5098. my $Dest_Comment = ($Dest_Count>1 and $Identity=~/\//)?" ($Identity)":"";
  5099. $CheckedHeaders .= "<span class='header_list_elem'>$Header_Name"."$Dest_Comment</span><br/>\n";
  5100. }
  5101. $CheckedHeaders .= "<!--Checked_Headers_End--><br/><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
  5102. my $CheckedLibs = "<!--Checked_Libs-->\n<a name='Checked_Libs'></a><h2 style='margin-bottom:0px;padding-bottom:0px;'>Checked shared objects (".keys(%{$SoNames_All{1}}).")</h2><hr/>\n";
  5103. foreach my $Library (sort {lc($a) cmp lc($b)} keys(%{$SoNames_All{1}}))
  5104. {
  5105. $CheckedLibs .= "<span class='solib_list_elem'>$Library</span><br/>\n";
  5106. }
  5107. $CheckedLibs .= "<!--Checked_Libs_End--><br/><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
  5108. return $CheckedHeaders.$CheckedLibs;
  5109. }
  5110. sub get_TypeProblems_Count($$)
  5111. {
  5112. my ($TypeChanges, $TargetPriority) = @_;
  5113. my $Type_Problems_Count = 0;
  5114. foreach my $TypeName (sort keys(%{$TypeChanges}))
  5115. {
  5116. my %Kinds_Target = ();
  5117. foreach my $Kind (keys(%{$TypeChanges->{$TypeName}}))
  5118. {
  5119. foreach my $Location (keys(%{$TypeChanges->{$TypeName}{$Kind}}))
  5120. {
  5121. my $Priority = $TypeChanges->{$TypeName}{$Kind}{$Location}{"Priority"};
  5122. next if($Priority ne $TargetPriority);
  5123. my $Target = $TypeChanges->{$TypeName}{$Kind}{$Location}{"Target"};
  5124. next if($Kinds_Target{$Kind}{$Target});
  5125. $Kinds_Target{$Kind}{$Target} = 1;
  5126. $Type_Problems_Count += 1;
  5127. }
  5128. }
  5129. }
  5130. return $Type_Problems_Count;
  5131. }
  5132. sub get_Summary()
  5133. {
  5134. my ($Added, $Withdrawn, $I_Problems_High, $I_Problems_Medium, $I_Problems_Low, $T_Problems_High, $T_Problems_Medium, $T_Problems_Low) = (0,0,0,0,0,0,0,0);
  5135. foreach my $Interface (sort keys(%CompatProblems))
  5136. {
  5137. foreach my $Kind (sort keys(%{$CompatProblems{$Interface}}))
  5138. {
  5139. if($InterfaceProblems_Kind{$Kind})
  5140. {
  5141. foreach my $Location (sort keys(%{$CompatProblems{$Interface}{$Kind}}))
  5142. {
  5143. if($Kind eq "Added_Interface")
  5144. {
  5145. $Added += 1;
  5146. }
  5147. elsif($Kind eq "Withdrawn_Interface")
  5148. {
  5149. $Withdrawn += 1;
  5150. }
  5151. else
  5152. {
  5153. if($CompatProblems{$Interface}{$Kind}{$Location}{"Priority"} eq "High")
  5154. {
  5155. $I_Problems_High += 1;
  5156. }
  5157. elsif($CompatProblems{$Interface}{$Kind}{$Location}{"Priority"} eq "Medium")
  5158. {
  5159. $I_Problems_Medium += 1;
  5160. }
  5161. elsif($CompatProblems{$Interface}{$Kind}{$Location}{"Priority"} eq "Low")
  5162. {
  5163. $I_Problems_Low += 1;
  5164. }
  5165. }
  5166. }
  5167. }
  5168. }
  5169. }
  5170. my (%TypeChanges, %Type_MaxPriority);
  5171. foreach my $Interface (sort keys(%CompatProblems))
  5172. {
  5173. foreach my $Kind (keys(%{$CompatProblems{$Interface}}))
  5174. {
  5175. if($TypeProblems_Kind{$Kind})
  5176. {
  5177. foreach my $Location (keys(%{$CompatProblems{$Interface}{$Kind}}))
  5178. {
  5179. my $Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Type_Name"};
  5180. my $Priority = $CompatProblems{$Interface}{$Kind}{$Location}{"Priority"};
  5181. %{$TypeChanges{$Type_Name}{$Kind}{$Location}} = %{$CompatProblems{$Interface}{$Kind}{$Location}};
  5182. $Type_MaxPriority{$Type_Name}{$Kind} = max_priority($Type_MaxPriority{$Type_Name}{$Kind}, $Priority);
  5183. }
  5184. }
  5185. }
  5186. }
  5187. foreach my $Type_Name (keys(%TypeChanges))
  5188. {
  5189. foreach my $Kind (keys(%{$TypeChanges{$Type_Name}}))
  5190. {
  5191. foreach my $Location (keys(%{$TypeChanges{$Type_Name}{$Kind}}))
  5192. {
  5193. my $Priority = $TypeChanges{$Type_Name}{$Kind}{$Location}{"Priority"};
  5194. if(cmp_priority($Type_MaxPriority{$Type_Name}{$Kind}, $Priority))
  5195. {
  5196. delete($TypeChanges{$Type_Name}{$Kind}{$Location});
  5197. }
  5198. }
  5199. }
  5200. }
  5201. $T_Problems_High = get_TypeProblems_Count(\%TypeChanges, "High");
  5202. $T_Problems_Medium = get_TypeProblems_Count(\%TypeChanges, "Medium");
  5203. $T_Problems_Low = get_TypeProblems_Count(\%TypeChanges, "Low");
  5204. #summary
  5205. my $Summary = "<h2 style='margin-bottom:0px;padding-bottom:0px;'>Summary</h2><hr/>";
  5206. $Summary .= "<table cellpadding='3' border='1' style='border-collapse:collapse;'>";
  5207. my $Checked_Headers_Link = "0";
  5208. $Checked_Headers_Link = "<a href='#Checked_Headers' style='color:Blue;'>".keys(%{$Headers{1}})."</a>" if(keys(%{$Headers{1}})>0);
  5209. $Summary .= "<tr><td class='table_header summary_item'>Total header files checked</td><td class='summary_item_value'>$Checked_Headers_Link</td></tr>";
  5210. my $Checked_Libs_Link = "0";
  5211. $Checked_Libs_Link = "<a href='#Checked_Libs' style='color:Blue;'>".keys(%{$SoNames_All{1}})."</a>" if(keys(%{$SoNames_All{1}})>0);
  5212. $Summary .= "<tr><td class='table_header summary_item'>Total shared objects checked</td><td class='summary_item_value'>$Checked_Libs_Link</td></tr>";
  5213. $Summary .= "<tr><td class='table_header summary_item'>Total interfaces / types checked</td><td class='summary_item_value'>".keys(%CheckedInterfaces)." / ".keys(%CheckedTypes)."</td></tr>";
  5214. my $Verdict = "<span style='color:Green;'><b>Compatible</b></span>";
  5215. $Verdict = "<span style='color:Red;'><b>Incompatible</b></span>" if(($Withdrawn>0) or ($I_Problems_High>0) or ($T_Problems_High>0));
  5216. $Summary .= "<tr><td class='table_header summary_item'>Verdict</td><td class='summary_item_value'>$Verdict</td></tr>";
  5217. $Summary .= "</table>\n";
  5218. #problem summary
  5219. my $Problem_Summary = "<h2 style='margin-bottom:0px;padding-bottom:0px;'>Problem Summary</h2><hr/>";
  5220. $Problem_Summary .= "<table cellpadding='3' border='1' style='border-collapse:collapse;'>";
  5221. my $Added_Link = "0";
  5222. $Added_Link = "<a href='#Added' style='color:Blue;'>$Added</a>" if($Added>0);
  5223. $Problem_Summary .= "<tr><td class='table_header summary_item' colspan='2'>Added interfaces</td><td class='summary_item_value'>$Added_Link</td></tr>";
  5224. my $WIthdrawn_Link = "0";
  5225. $WIthdrawn_Link = "<a href='#Withdrawn' style='color:Blue;'>$Withdrawn</a>" if($Withdrawn>0);
  5226. $Problem_Summary .= "<tr><td class='table_header summary_item' colspan='2'>Withdrawn interfaces</td><td class='summary_item_value'>$WIthdrawn_Link</td></tr>";
  5227. my $TH_Link = "0";
  5228. $TH_Link = "<a href='#Type_Problems_High' style='color:Blue;'>$T_Problems_High</a>" if($T_Problems_High>0);
  5229. $Problem_Summary .= "<tr><td class='table_header summary_item' rowspan='3'>Problems in<br/>Data Types</td><td class='table_header summary_item' style='color:Red;'>High risk</td><td align='right' class='summary_item_value'>$TH_Link</td></tr>";
  5230. my $TM_Link = "0";
  5231. $TM_Link = "<a href='#Type_Problems_Medium' style='color:Blue;'>$T_Problems_Medium</a>" if($T_Problems_Medium>0);
  5232. $Problem_Summary .= "<tr><td class='table_header summary_item'>Medium risk</td><td class='summary_item_value'>$TM_Link</td></tr>";
  5233. my $TL_Link = "0";
  5234. $TL_Link = "<a href='#Type_Problems_Low' style='color:Blue;'>$T_Problems_Low</a>" if($T_Problems_Low>0);
  5235. $Problem_Summary .= "<tr><td class='table_header summary_item'>Low risk</td><td class='summary_item_value'>$TL_Link</td></tr>";
  5236. my $IH_Link = "0";
  5237. $IH_Link = "<a href='#Interface_Problems_High' style='color:Blue;'>$I_Problems_High</a>" if($I_Problems_High>0);
  5238. $Problem_Summary .= "<tr><td class='table_header summary_item' rowspan='3'>Interface<br/>problems</td><td class='table_header summary_item' style='color:Red;'>High risk</td><td class='summary_item_value'>$IH_Link</td></tr>";
  5239. my $IM_Link = "0";
  5240. $IM_Link = "<a href='#Interface_Problems_Medium' style='color:Blue;'>$I_Problems_Medium</a>" if($I_Problems_Medium>0);
  5241. $Problem_Summary .= "<tr><td class='table_header summary_item'>Medium risk</td><td class='summary_item_value'>$IM_Link</td></tr>";
  5242. my $IL_Link = "0";
  5243. $IL_Link = "<a href='#Interface_Problems_Low' style='color:Blue;'>$I_Problems_Low</a>" if($I_Problems_Low>0);
  5244. $Problem_Summary .= "<tr><td class='table_header summary_item'>Low risk</td><td class='summary_item_value'>$IL_Link</td></tr>";
  5245. my $ChangedConstants_Link = "0";
  5246. $ChangedConstants_Link = "<a href='#Constants' style='color:Blue;'>".keys(%ConstantProblems)."</a>" if(keys(%ConstantProblems)>0);
  5247. $Problem_Summary .= "<tr><td class='table_header summary_item' colspan='2'>Constants Problems</td><td class='summary_item_value'>$ChangedConstants_Link</td></tr>";
  5248. $Problem_Summary .= "</table>\n";
  5249. return "<!--Summary-->\n".$Summary.$Problem_Summary."<!--Summary_End-->\n";
  5250. }
  5251. sub get_Report_ChangedConstants()
  5252. {
  5253. my ($CHANGED_CONSTANTS, %HeaderConstant);
  5254. foreach my $Name (keys(%ConstantProblems))
  5255. {
  5256. $HeaderConstant{$ConstantProblems{$Name}{"Header"}}{$Name} = 1;
  5257. }
  5258. my $Constants_Number = 0;
  5259. foreach my $HeaderName (sort {lc($a) cmp lc($b)} keys(%HeaderConstant))
  5260. {
  5261. $CHANGED_CONSTANTS .= "<span class='header_name'>$HeaderName</span><br/>\n";
  5262. foreach my $Name (sort {lc($a) cmp lc($b)} keys(%{$HeaderConstant{$HeaderName}}))
  5263. {
  5264. $Constants_Number += 1;
  5265. my $Old_Value = htmlSpecChars($ConstantProblems{$Name}{"Old_Value"});
  5266. my $New_Value = htmlSpecChars($ConstantProblems{$Name}{"New_Value"});
  5267. my $Incompatibility = "The value of constant <b>$Name</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.";
  5268. my $Effect = "If application uses this constant as a parameter of some interface than its execution may change.";
  5269. my $ConstantProblemsReport = "<tr><td align='center' valign='top' class='table_header'><span class='problem_num'>1</span></td><td align='left' valign='top'><span class='problem_body'>".$Incompatibility."</span></td><td align='left' valign='top'><span class='problem_body'>$Effect</span></td></tr>\n";
  5270. $CHANGED_CONSTANTS .= $ContentSpanStart."<span class='extension'>[+]</span> ".$Name.$ContentSpanEnd."<br/>\n$ContentDivStart<table width='900px' cellpadding='3' cellspacing='0' class='problems_table'><tr><td align='center' width='2%' class='table_header'><span class='problem_title' style='white-space:nowrap;'></span></td><td width='47%' align='center' class='table_header'><span class='problem_sub_title'>Incompatibility</span></td><td align='center' class='table_header'><span class='problem_sub_title'>Effect</span></td></tr>$ConstantProblemsReport</table><br/>$ContentDivEnd\n";
  5271. $CHANGED_CONSTANTS = insertIDs($CHANGED_CONSTANTS);
  5272. }
  5273. $CHANGED_CONSTANTS .= "<br/>\n";
  5274. }
  5275. if($CHANGED_CONSTANTS)
  5276. {
  5277. $CHANGED_CONSTANTS = "<a name='Constants'></a><h2 style='margin-bottom:0px;padding-bottom:0px;'>Constants Problems ($Constants_Number)</h2><hr/>\n"."<!--Changed_Constants-->\n".$CHANGED_CONSTANTS."<!--Changed_Constants_End-->\n"."<input id='Changed_Constants_Count' type='hidden' value=\'$Constants_Number\' /><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
  5278. }
  5279. return $CHANGED_CONSTANTS;
  5280. }
  5281. sub get_Report_Added()
  5282. {
  5283. my $ADDED_INTERFACES;
  5284. #added interfaces
  5285. my %FuncAddedInHeaderLib;
  5286. foreach my $Interface (sort keys(%CompatProblems))
  5287. {
  5288. foreach my $Kind (sort keys(%{$CompatProblems{$Interface}}))
  5289. {
  5290. foreach my $Location (sort keys(%{$CompatProblems{$Interface}{$Kind}}))
  5291. {
  5292. if($Kind eq "Added_Interface")
  5293. {
  5294. $FuncAddedInHeaderLib{$CompatProblems{$Interface}{$Kind}{$Location}{"Header"}}{$CompatProblems{$Interface}{$Kind}{$Location}{"New_SoName"}}{$Interface} = 1;
  5295. last;
  5296. }
  5297. }
  5298. }
  5299. }
  5300. my $Added_Number = 0;
  5301. foreach my $HeaderName (sort {lc($a) cmp lc($b)} keys(%FuncAddedInHeaderLib))
  5302. {
  5303. foreach my $SoName (sort {lc($a) cmp lc($b)} keys(%{$FuncAddedInHeaderLib{$HeaderName}}))
  5304. {
  5305. if($HeaderName)
  5306. {
  5307. $ADDED_INTERFACES .= "<span class='header_name'>$HeaderName</span>, <span class='solib_name'>$SoName</span><br/>\n";
  5308. }
  5309. else
  5310. {
  5311. $ADDED_INTERFACES .= "<span class='solib_name'>$SoName</span><br/>\n";
  5312. }
  5313. foreach my $Interface (sort {lc($CompatProblems{$a}{"Added_Interface"}{"SharedLibrary"}{"Signature"}) cmp lc($CompatProblems{$b}{"Added_Interface"}{"SharedLibrary"}{"Signature"})} keys(%{$FuncAddedInHeaderLib{$HeaderName}{$SoName}}))
  5314. {
  5315. $Added_Number += 1;
  5316. my $SubReport = "";
  5317. my $Signature = $CompatProblems{$Interface}{"Added_Interface"}{"SharedLibrary"}{"Signature"};
  5318. if($Interface =~ /\A_Z/)
  5319. {
  5320. if($Signature)
  5321. {
  5322. $SubReport = insertIDs($ContentSpanStart.highLight_Signature_Italic_Color(htmlSpecChars($Signature)).$ContentSpanEnd."<br/>\n".$ContentDivStart."<span class='mangled'>[ symbol: <b>$Interface</b> ]</span><br/><br/>".$ContentDivEnd."\n");
  5323. }
  5324. else
  5325. {
  5326. $SubReport = "<span class=\"interface_name\">".$Interface."</span>"."<br/>\n";
  5327. }
  5328. }
  5329. else
  5330. {
  5331. if($Signature)
  5332. {
  5333. $SubReport = "<span class=\"interface_name\">".highLight_Signature_Italic_Color($Signature)."</span>"."<br/>\n";
  5334. }
  5335. else
  5336. {
  5337. $SubReport = "<span class=\"interface_name\">".$Interface."</span>"."<br/>\n";
  5338. }
  5339. }
  5340. $ADDED_INTERFACES .= $SubReport;
  5341. }
  5342. $ADDED_INTERFACES .= "<br/>\n";
  5343. }
  5344. }
  5345. if($ADDED_INTERFACES)
  5346. {
  5347. $ADDED_INTERFACES = "<a name='Added'></a><h2 style='margin-bottom:0px;padding-bottom:0px;'>Added Interfaces ($Added_Number)</h2><hr/>\n"."<!--Added_Interfaces-->\n".$ADDED_INTERFACES."<!--Added_Interfaces_End-->\n"."<input id='Added_Interfaces_Count' type='hidden' value=\'$Added_Number\' /><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
  5348. }
  5349. return $ADDED_INTERFACES;
  5350. }
  5351. sub get_Report_Withdrawn()
  5352. {
  5353. my $WITHDRAWN_INTERFACES;
  5354. #withdrawn interfaces
  5355. my %FuncWithdrawnFromHeaderLib;
  5356. foreach my $Interface (sort keys(%CompatProblems))
  5357. {
  5358. foreach my $Kind (sort keys(%{$CompatProblems{$Interface}}))
  5359. {
  5360. foreach my $Location (sort keys(%{$CompatProblems{$Interface}{$Kind}}))
  5361. {
  5362. if($Kind eq "Withdrawn_Interface")
  5363. {
  5364. $FuncWithdrawnFromHeaderLib{$CompatProblems{$Interface}{$Kind}{$Location}{"Header"}}{$CompatProblems{$Interface}{$Kind}{$Location}{"Old_SoName"}}{$Interface} = 1;
  5365. last;
  5366. }
  5367. }
  5368. }
  5369. }
  5370. my $Withdrawn_Number = 0;
  5371. foreach my $HeaderName (sort {lc($a) cmp lc($b)} keys(%FuncWithdrawnFromHeaderLib))
  5372. {
  5373. foreach my $SoName (sort {lc($a) cmp lc($b)} keys(%{$FuncWithdrawnFromHeaderLib{$HeaderName}}))
  5374. {
  5375. if($HeaderName)
  5376. {
  5377. $WITHDRAWN_INTERFACES .= "<span class='header_name'>$HeaderName</span>, <span class='solib_name'>$SoName</span><br/>\n";
  5378. }
  5379. else
  5380. {
  5381. $WITHDRAWN_INTERFACES .= "<span class='solib_name'>$SoName</span><br/>\n";
  5382. }
  5383. foreach my $Interface (sort {lc($CompatProblems{$a}{"Withdrawn_Interface"}{"SharedLibrary"}{"Signature"}) cmp lc($CompatProblems{$b}{"Withdrawn_Interface"}{"SharedLibrary"}{"Signature"})} keys(%{$FuncWithdrawnFromHeaderLib{$HeaderName}{$SoName}}))
  5384. {
  5385. $Withdrawn_Number += 1;
  5386. my $SubReport = "";
  5387. my $Signature = $CompatProblems{$Interface}{"Withdrawn_Interface"}{"SharedLibrary"}{"Signature"};
  5388. if($Interface =~ /\A_Z/)
  5389. {
  5390. if($Signature)
  5391. {
  5392. $SubReport = insertIDs($ContentSpanStart.highLight_Signature_Italic_Color(htmlSpecChars($Signature)).$ContentSpanEnd."<br/>\n".$ContentDivStart."<span class='mangled'>[ symbol: <b>$Interface</b> ]</span><br/><br/>".$ContentDivEnd."\n");
  5393. }
  5394. else
  5395. {
  5396. $SubReport = "<span class=\"interface_name\">".$Interface."</span>"."<br/>\n";
  5397. }
  5398. }
  5399. else
  5400. {
  5401. if($Signature)
  5402. {
  5403. $SubReport = "<span class=\"interface_name\">".highLight_Signature_Italic_Color($Signature)."</span>"."<br/>\n";
  5404. }
  5405. else
  5406. {
  5407. $SubReport = "<span class=\"interface_name\">".$Interface."</span>"."<br/>\n";
  5408. }
  5409. }
  5410. $WITHDRAWN_INTERFACES .= $SubReport;
  5411. }
  5412. $WITHDRAWN_INTERFACES .= "<br/>\n";
  5413. }
  5414. }
  5415. if($WITHDRAWN_INTERFACES)
  5416. {
  5417. $WITHDRAWN_INTERFACES = "<a name='Withdrawn'></a><h2 style='margin-bottom:0px;padding-bottom:0px;'>Withdrawn Interfaces ($Withdrawn_Number)</h2><hr/>\n"."<!--Withdrawn_Interfaces-->\n".$WITHDRAWN_INTERFACES."<!--Withdrawn_Interfaces_End-->\n"."<input id='Withdrawn_Interfaces_Count' type='hidden' value=\'$Withdrawn_Number\' /><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
  5418. }
  5419. return $WITHDRAWN_INTERFACES;
  5420. }
  5421. sub get_Report_InterfaceProblems($)
  5422. {
  5423. my $TargetPriority = $_[0];
  5424. my ($INTERFACE_PROBLEMS, %FuncHeaderLib);
  5425. foreach my $Interface (sort keys(%CompatProblems))
  5426. {
  5427. foreach my $Kind (sort keys(%{$CompatProblems{$Interface}}))
  5428. {
  5429. if($InterfaceProblems_Kind{$Kind} and ($Kind ne "Added_Interface") and ($Kind ne "Withdrawn_Interface"))
  5430. {
  5431. foreach my $Location (sort keys(%{$CompatProblems{$Interface}{$Kind}}))
  5432. {
  5433. my $SoName = $CompatProblems{$Interface}{$Kind}{$Location}{"Old_SoName"};
  5434. my $HeaderName = $CompatProblems{$Interface}{$Kind}{$Location}{"Header"};
  5435. $FuncHeaderLib{$HeaderName}{$SoName}{$Interface} = 1;
  5436. last;
  5437. }
  5438. }
  5439. }
  5440. }
  5441. my $Problems_Number = 0;
  5442. #interface problems
  5443. foreach my $HeaderName (sort {lc($a) cmp lc($b)} keys(%FuncHeaderLib))
  5444. {
  5445. foreach my $SoName (sort {lc($a) cmp lc($b)} keys(%{$FuncHeaderLib{$HeaderName}}))
  5446. {
  5447. my $HEADER_LIB_REPORT = "";
  5448. foreach my $Interface (sort {lc($tr_name{$a}) cmp lc($tr_name{$b})} keys(%{$FuncHeaderLib{$HeaderName}{$SoName}}))
  5449. {
  5450. my $Signature = "";
  5451. my $InterfaceProblemsReport = "";
  5452. my $ProblemNum = 1;
  5453. foreach my $Kind (keys(%{$CompatProblems{$Interface}}))
  5454. {
  5455. foreach my $Location (keys(%{$CompatProblems{$Interface}{$Kind}}))
  5456. {
  5457. my $Incompatibility = "";
  5458. my $Effect = "";
  5459. my $Old_Value = htmlSpecChars($CompatProblems{$Interface}{$Kind}{$Location}{"Old_Value"});
  5460. my $New_Value = htmlSpecChars($CompatProblems{$Interface}{$Kind}{$Location}{"New_Value"});
  5461. my $Priority = $CompatProblems{$Interface}{$Kind}{$Location}{"Priority"};
  5462. my $Target = $CompatProblems{$Interface}{$Kind}{$Location}{"Target"};
  5463. my $Old_Size = $CompatProblems{$Interface}{$Kind}{$Location}{"Old_Size"};
  5464. my $New_Size = $CompatProblems{$Interface}{$Kind}{$Location}{"New_Size"};
  5465. my $InitialType_Type = $CompatProblems{$Interface}{$Kind}{$Location}{"InitialType_Type"};
  5466. my $Parameter_Position = $CompatProblems{$Interface}{$Kind}{$Location}{"Parameter_Position"};
  5467. my $Parameter_Position_Str = num_to_str($Parameter_Position + 1);
  5468. $Signature = $CompatProblems{$Interface}{$Kind}{$Location}{"Signature"} if(not $Signature);
  5469. next if($Priority ne $TargetPriority);
  5470. if($Kind eq "Function_Become_Static")
  5471. {
  5472. $Incompatibility = "Function become <b>static</b>.\n";
  5473. $Effect = "Layout of parameter's stack has been changed and therefore parameters in higher positions in the stack may be incorrectly initialized by applications.";
  5474. }
  5475. elsif($Kind eq "Function_Become_NonStatic")
  5476. {
  5477. $Incompatibility = "Function become <b>non-static</b>.\n";
  5478. $Effect = "Layout of parameter's stack has been changed and therefore parameters in higher positions in the stack may be incorrectly initialized by applications.";
  5479. }
  5480. elsif($Kind eq "Parameter_Type_And_Size")
  5481. {
  5482. $Incompatibility = "Type of $Parameter_Position_Str parameter <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.\n";
  5483. $Effect = "Layout of parameter's stack has been changed and therefore parameters in higher positions in the stack may be incorrectly initialized by applications.";
  5484. }
  5485. elsif($Kind eq "Parameter_Type")
  5486. {
  5487. $Incompatibility = "Type of $Parameter_Position_Str parameter <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.\n";
  5488. $Effect = "Replacement of parameter data type may indicate a change in the semantic meaning of this parameter.";
  5489. }
  5490. elsif($Kind eq "Withdrawn_Parameter")
  5491. {
  5492. $Incompatibility = "$Parameter_Position_Str parameter <b>$Target</b> has been withdrawn from the interface signature.\n";
  5493. $Effect = "This parameter will be ignored by the interface.";
  5494. }
  5495. elsif($Kind eq "Added_Parameter")
  5496. {
  5497. $Incompatibility = "$Parameter_Position_Str parameter <b>$Target</b> has been added to the interface signature.\n";
  5498. $Effect = "This parameter will not be initialized by applications.";
  5499. }
  5500. elsif($Kind eq "Parameter_BaseType_And_Size")
  5501. {
  5502. if($InitialType_Type eq "Pointer")
  5503. {
  5504. $Incompatibility = "Base type of $Parameter_Position_Str parameter <b>$Target</b> (pointer) has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.\n";
  5505. $Effect = "Memory stored by pointer may be incorrectly initialized by applications.";
  5506. }
  5507. else
  5508. {
  5509. $Incompatibility = "Base type of $Parameter_Position_Str parameter <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.\n";
  5510. $Effect = "Layout of parameter's stack has been changed and therefore parameters in higher positions in the stack may be incorrectly initialized by applications.";
  5511. }
  5512. }
  5513. elsif($Kind eq "Parameter_BaseType")
  5514. {
  5515. if($InitialType_Type eq "Pointer")
  5516. {
  5517. $Incompatibility = "Base type of $Parameter_Position_Str parameter <b>$Target</b> (pointer) has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.\n";
  5518. $Effect = "Memory stored by pointer may be incorrectly initialized by applications.";
  5519. }
  5520. else
  5521. {
  5522. $Incompatibility = "Base type of $Parameter_Position_Str parameter <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.\n";
  5523. $Effect = "Replacement of parameter base type may indicate a change in the semantic meaning of this parameter.";
  5524. }
  5525. }
  5526. elsif($Kind eq "Parameter_PointerLevel")
  5527. {
  5528. $Incompatibility = "Type pointer level of $Parameter_Position_Str parameter <b>$Target</b> has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.\n";
  5529. $Effect = "Possible incorrect initialization of $Parameter_Position_Str parameter <b>$Target</b> by applications.";
  5530. }
  5531. elsif($Kind eq "Return_Type_And_Size")
  5532. {
  5533. $Incompatibility = "Type of return value has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.\n";
  5534. $Effect = "Applications will get a different return value and execution may change.";
  5535. }
  5536. elsif($Kind eq "Return_Type")
  5537. {
  5538. $Incompatibility = "Type of return value has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.\n";
  5539. $Effect = "Replacement of return type may indicate a change in its semantic meaning.";
  5540. }
  5541. elsif($Kind eq "Return_BaseType_And_Size")
  5542. {
  5543. $Incompatibility = "Base type of return value has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.\n";
  5544. $Effect = "Applications will get a different return value and execution may change.";
  5545. }
  5546. elsif($Kind eq "Return_BaseType")
  5547. {
  5548. $Incompatibility = "Base type of return value has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.\n";
  5549. $Effect = "Replacement of return base type may indicate a change in its semantic meaning.";
  5550. }
  5551. elsif($Kind eq "Return_PointerLevel")
  5552. {
  5553. $Incompatibility = "Type pointer level of return value has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.\n";
  5554. $Effect = "Applications will get a different return value and execution may change.";
  5555. }
  5556. if($Incompatibility)
  5557. {
  5558. $InterfaceProblemsReport .= "<tr><td align='center' class='table_header'><span class='problem_num'>$ProblemNum</span></td><td align='left' valign='top'><span class='problem_body'>".$Incompatibility."</span></td><td align='left' valign='top'><span class='problem_body'>".$Effect."</span></td></tr>\n";
  5559. $ProblemNum += 1;
  5560. $Problems_Number += 1;
  5561. }
  5562. }
  5563. }
  5564. $ProblemNum -= 1;
  5565. if($InterfaceProblemsReport)
  5566. {
  5567. if($Interface =~ /\A_Z/)
  5568. {
  5569. if($Signature)
  5570. {
  5571. $HEADER_LIB_REPORT .= $ContentSpanStart."<span class='extension'>[+]</span> ".highLight_Signature_Italic_Color(htmlSpecChars($Signature))." ($ProblemNum)".$ContentSpanEnd."<br/>\n$ContentDivStart<span class='mangled'>[ symbol: <b>$Interface</b> ]</span><br/>\n";
  5572. }
  5573. else
  5574. {
  5575. $HEADER_LIB_REPORT .= $ContentSpanStart."<span class='extension'>[+]</span> ".$Interface." ($ProblemNum)".$ContentSpanEnd."<br/>\n$ContentDivStart\n";
  5576. }
  5577. }
  5578. else
  5579. {
  5580. if($Signature)
  5581. {
  5582. $HEADER_LIB_REPORT .= $ContentSpanStart."<span class='extension'>[+]</span> ".highLight_Signature_Italic_Color(htmlSpecChars($Signature))." ($ProblemNum)".$ContentSpanEnd."<br/>\n$ContentDivStart\n";
  5583. }
  5584. else
  5585. {
  5586. $HEADER_LIB_REPORT .= $ContentSpanStart."<span class='extension'>[+]</span> ".$Interface." ($ProblemNum)".$ContentSpanEnd."<br/>\n$ContentDivStart\n";
  5587. }
  5588. }
  5589. $HEADER_LIB_REPORT .= "<table width='900px' cellpadding='3' cellspacing='0' class='problems_table'><tr><td align='center' width='2%' class='table_header'><span class='problem_title' style='white-space:nowrap;'></span></td><td width='47%' align='center' class='table_header'><span class='problem_sub_title'>Incompatibility</span></td><td align='center' class='table_header'><span class='problem_sub_title'>Effect</span></td></tr>$InterfaceProblemsReport</table><br/>$ContentDivEnd\n";
  5590. $HEADER_LIB_REPORT = insertIDs($HEADER_LIB_REPORT);
  5591. }
  5592. }
  5593. if($HEADER_LIB_REPORT)
  5594. {
  5595. $INTERFACE_PROBLEMS .= "<span class='header_name'>$HeaderName</span>, <span class='solib_name'>$SoName</span><br/>\n".$HEADER_LIB_REPORT."<br/>";
  5596. }
  5597. }
  5598. }
  5599. if($INTERFACE_PROBLEMS)
  5600. {
  5601. $INTERFACE_PROBLEMS = "<a name=\'Interface_Problems_$TargetPriority\'></a>\n<h2 style='margin-bottom:0px;padding-bottom:0px;'>Interface problems, $TargetPriority risk ($Problems_Number)</h2><hr/>\n"."<!--Interface_Problems_".$TargetPriority."-->\n".$INTERFACE_PROBLEMS."<!--Interface_Problems_".$TargetPriority."_End-->\n"."<input id=\'Interface_Problems_$TargetPriority"."_Count"."\' type='hidden' value=\'$Problems_Number\' /><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
  5602. }
  5603. return $INTERFACE_PROBLEMS;
  5604. }
  5605. sub get_Report_TypeProblems($)
  5606. {
  5607. my $TargetPriority = $_[0];
  5608. my ($TYPE_PROBLEMS, %TypeHeader, %TypeChanges, %Type_MaxPriority) = ();
  5609. foreach my $Interface (sort keys(%CompatProblems))
  5610. {
  5611. foreach my $Kind (keys(%{$CompatProblems{$Interface}}))
  5612. {
  5613. if($TypeProblems_Kind{$Kind})
  5614. {
  5615. foreach my $Location (keys(%{$CompatProblems{$Interface}{$Kind}}))
  5616. {
  5617. my $Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Type_Name"};
  5618. my $Priority = $CompatProblems{$Interface}{$Kind}{$Location}{"Priority"};
  5619. my $Type_Header = $CompatProblems{$Interface}{$Kind}{$Location}{"Header"};
  5620. %{$TypeChanges{$Type_Name}{$Kind}{$Location}} = %{$CompatProblems{$Interface}{$Kind}{$Location}};
  5621. $TypeHeader{$Type_Header}{$Type_Name} = 1;
  5622. $Type_MaxPriority{$Type_Name}{$Kind} = max_priority($Type_MaxPriority{$Type_Name}{$Kind}, $Priority);
  5623. }
  5624. }
  5625. }
  5626. }
  5627. foreach my $Type_Name (keys(%TypeChanges))
  5628. {
  5629. foreach my $Kind (keys(%{$TypeChanges{$Type_Name}}))
  5630. {
  5631. foreach my $Location (keys(%{$TypeChanges{$Type_Name}{$Kind}}))
  5632. {
  5633. my $Priority = $TypeChanges{$Type_Name}{$Kind}{$Location}{"Priority"};
  5634. if(cmp_priority($Type_MaxPriority{$Type_Name}{$Kind}, $Priority))
  5635. {
  5636. delete($TypeChanges{$Type_Name}{$Kind}{$Location});
  5637. }
  5638. }
  5639. }
  5640. }
  5641. my $Problems_Number = 0;
  5642. foreach my $HeaderName (sort {lc($a) cmp lc($b)} keys(%TypeHeader))
  5643. {
  5644. my $HEADER_REPORT = "";
  5645. foreach my $TypeName (sort {lc($a) cmp lc($b)} keys(%{$TypeHeader{$HeaderName}}))
  5646. {
  5647. my $ProblemNum = 1;
  5648. my $TypeProblemsReport = "";
  5649. my %Kinds_Locations = ();
  5650. my %Kinds_Target = ();
  5651. foreach my $Kind (keys(%{$TypeChanges{$TypeName}}))
  5652. {
  5653. foreach my $Location (keys(%{$TypeChanges{$TypeName}{$Kind}}))
  5654. {
  5655. my $Priority = $TypeChanges{$TypeName}{$Kind}{$Location}{"Priority"};
  5656. next if($Priority ne $TargetPriority);
  5657. $Kinds_Locations{$Kind}{$Location} = 1;
  5658. my $Incompatibility = "";
  5659. my $Effect = "";
  5660. my $Target = $TypeChanges{$TypeName}{$Kind}{$Location}{"Target"};
  5661. next if($Kinds_Target{$Kind}{$Target});
  5662. $Kinds_Target{$Kind}{$Target} = 1;
  5663. my $Old_Value = htmlSpecChars($TypeChanges{$TypeName}{$Kind}{$Location}{"Old_Value"});
  5664. my $New_Value = htmlSpecChars($TypeChanges{$TypeName}{$Kind}{$Location}{"New_Value"});
  5665. my $Old_Size = $TypeChanges{$TypeName}{$Kind}{$Location}{"Old_Size"};
  5666. my $New_Size = $TypeChanges{$TypeName}{$Kind}{$Location}{"New_Size"};
  5667. my $Type_Type = $TypeChanges{$TypeName}{$Kind}{$Location}{"Type_Type"};
  5668. my $InitialType_Type = $TypeChanges{$TypeName}{$Kind}{$Location}{"InitialType_Type"};
  5669. if($Kind eq "Added_Virtual_Function")
  5670. {
  5671. $Incompatibility = "Virtual method "."<span class='interface_name_black'>".highLight_Signature(htmlSpecChars($Target))."</span>"." has been added to this class and therefore the layout of virtual table has been changed.";
  5672. $Effect = "Call of any virtual method in this class or its subclasses will result in crash of application.";
  5673. }
  5674. elsif($Kind eq "Withdrawn_Virtual_Function")
  5675. {
  5676. $Incompatibility = "Virtual method "."<span class='interface_name_black'>".highLight_Signature(htmlSpecChars($Target))."</span>"." has been withdrawn from this class and therefore the layout of virtual table has been changed.";
  5677. $Effect = "Call of any virtual method in this class or its subclasses will result in crash of application.";
  5678. }
  5679. elsif($Kind eq "Virtual_Function_Position")
  5680. {
  5681. $Incompatibility = "The relative position of virtual method "."<span class='interface_name_black'>".highLight_Signature(htmlSpecChars($Target))."</span>"." has been changed from <b>$Old_Value</b> to <b>$New_Value</b> and therefore the layout of virtual table has been changed.";
  5682. $Effect = "Call of this virtual method will result in crash of application.";
  5683. }
  5684. elsif($Kind eq "Virtual_Function_Redefinition")
  5685. {
  5686. $Incompatibility = "Virtual method "."<span class='interface_name_black'>".highLight_Signature(htmlSpecChars($Old_Value))."</span>"." has been redefined by "."<span class='interface_name_black'>".highLight_Signature(htmlSpecChars($New_Value))."</span>";
  5687. $Effect = "Method <span class='interface_name_black'>".highLight_Signature(htmlSpecChars($New_Value))."</span> will be called instead of <span class='interface_name_black'>".highLight_Signature(htmlSpecChars($Old_Value))."</span>";
  5688. }
  5689. elsif($Kind eq "Virtual_Function_Redefinition_B")
  5690. {
  5691. $Incompatibility = "Virtual method "."<span class='interface_name_black'>".highLight_Signature(htmlSpecChars($New_Value))."</span>"." has been redefined by "."<span class='interface_name_black'>".highLight_Signature(htmlSpecChars($Old_Value))."</span>";
  5692. $Effect = "Method <span class='interface_name_black'>".highLight_Signature(htmlSpecChars($Old_Value))."</span> will be called instead of <span class='interface_name_black'>".highLight_Signature(htmlSpecChars($New_Value))."</span>";
  5693. }
  5694. elsif($Kind eq "Size")
  5695. {
  5696. $Incompatibility = "Size of this type has been changed from <b>$Old_Value</b> to <b>$New_Value</b> bytes.";
  5697. $Effect = "Change of type size may lead to different effects in different contexts. $ContentSpanStart"."<span style='color:Black'>[+] ...</span>"."$ContentSpanEnd <label id=\"CONTENT_ID\" style=\"display:none;\"> In the context of function parameters, this change affects the parameter's stack layout and may lead to incorrect initialization of parameters in higher positions in the stack. In the context of structure members, this change affects the member's layout and may lead to incorrect attempts to access members in higher positions. Other effects are possible.</label>";
  5698. }
  5699. elsif($Kind eq "BaseType")
  5700. {
  5701. $Incompatibility = "Base of this type has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.";
  5702. $Effect = "Possible incorrect initialization of interface parameters by applications.";
  5703. }
  5704. elsif($Kind eq "Added_Member_And_Size")
  5705. {
  5706. $Incompatibility = "Member <b>$Target</b> has been added to this type.";
  5707. $Effect = "The size of the inclusive type has been changed.";
  5708. }
  5709. elsif($Kind eq "Added_Middle_Member_And_Size")
  5710. {
  5711. $Incompatibility = "Member <b>$Target</b> has been added between the first member and the last member of this structural type.";
  5712. $Effect = "1) Layout of structure members has been changed and therefore members in higher positions in the structure definition may be incorrectly accessed by applications.<br/>2) The size of the inclusive type will also be affected.";
  5713. }
  5714. elsif($Kind eq "Member_Rename")
  5715. {
  5716. $Incompatibility = "Member <b>$Target</b> has been renamed to <b>$New_Value</b>.";
  5717. $Effect = "Renaming of a member in a structural data type may indicate a change in the semantic meaning of the member.";
  5718. }
  5719. elsif($Kind eq "Withdrawn_Member_And_Size")
  5720. {
  5721. $Incompatibility = "Member <b>$Target</b> has been withdrawn from this type.";
  5722. $Effect = "1) Applications will access incorrect memory when attempting to access this member.<br/>2) The size of the inclusive type will also be affected.";
  5723. }
  5724. elsif($Kind eq "Withdrawn_Member")
  5725. {
  5726. $Incompatibility = "Member <b>$Target</b> has been withdrawn from this type.";
  5727. $Effect = "Applications will access incorrect memory when attempting to access this member.";
  5728. }
  5729. elsif($Kind eq "Withdrawn_Middle_Member_And_Size")
  5730. {
  5731. $Incompatibility = "Member <b>$Target</b> has been withdrawn from this structural type between the first member and the last member.";
  5732. $Effect = "1) Layout of structure members has been changed and therefore members in higher positions in the structure definition may be incorrectly accessed by applications.<br/>2) Previous accesses of applications to the withdrawn member will be incorrect.";
  5733. }
  5734. elsif($Kind eq "Withdrawn_Middle_Member")
  5735. {
  5736. $Incompatibility = "Member <b>$Target</b> has been withdrawn from this structural type between the first member and the last member.";
  5737. $Effect = "1) Layout of structure members has been changed and therefore members in higher positions in the structure definition may be incorrectly accessed by applications.<br/>2) Applications will access incorrect memory when attempting to access this member.";
  5738. }
  5739. elsif($Kind eq "Enum_Member_Value")
  5740. {
  5741. $Incompatibility = "Value of member <b>$Target</b> has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.";
  5742. $Effect = "Applications may execute another branch of library code.";
  5743. }
  5744. elsif($Kind eq "Enum_Member_Name")
  5745. {
  5746. $Incompatibility = "Name of member with value <b>$Target</b> has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.";
  5747. $Effect = "Applications may execute another branch of library code.";
  5748. }
  5749. elsif($Kind eq "Member_Type_And_Size")
  5750. {
  5751. $Incompatibility = "Type of member <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.";
  5752. $Effect = "Layout of structure members has been changed and therefore members in higher positions in the structure definition may be incorrectly accessed by applications.";
  5753. }
  5754. elsif($Kind eq "Member_Type")
  5755. {
  5756. $Incompatibility = "Type of member <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.";
  5757. $Effect = "Replacement of the member data type may indicate a change in the semantic meaning of the member.";
  5758. }
  5759. elsif($Kind eq "Member_BaseType_And_Size")
  5760. {
  5761. if($InitialType_Type eq "Pointer")
  5762. {
  5763. $Incompatibility = "Base type of member <b>$Target</b> (pointer) has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.";
  5764. $Effect = "Possible access of applications to incorrect memory via member pointer.";
  5765. }
  5766. else
  5767. {
  5768. $Incompatibility = "Base type of member <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.";
  5769. $Effect = "Layout of structure members has been changed and therefore members in higher positions in structure definition may be incorrectly accessed by applications.";
  5770. }
  5771. }
  5772. elsif($Kind eq "Member_BaseType")
  5773. {
  5774. if($InitialType_Type eq "Pointer")
  5775. {
  5776. $Incompatibility = "Base type of member <b>$Target</b> (pointer) has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.";
  5777. $Effect = "Possible access of applications to incorrect memory via member pointer.";
  5778. }
  5779. else
  5780. {
  5781. $Incompatibility = "Base type of member <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.";
  5782. $Effect = "Replacement of member base type may indicate a change in the semantic meaning of this member.";
  5783. }
  5784. }
  5785. elsif($Kind eq "Member_PointerLevel")
  5786. {
  5787. $Incompatibility = "Type pointer level of member <b>$Target</b> has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.";
  5788. $Effect = "Possible incorrect initialization of member <b>$Target</b> by applications.";
  5789. }
  5790. if($Incompatibility)
  5791. {
  5792. $TypeProblemsReport .= "<tr><td align='center' valign='top' class='table_header'><span class='problem_num'>$ProblemNum</span></td><td align='left' valign='top'><span class='problem_body'>".$Incompatibility."</span></td><td align='left' valign='top'><span class='problem_body'>$Effect</span></td></tr>\n";
  5793. $ProblemNum += 1;
  5794. $Problems_Number += 1;
  5795. $Kinds_Locations{$Kind}{$Location} = 1;
  5796. }
  5797. }
  5798. }
  5799. $ProblemNum -= 1;
  5800. if($TypeProblemsReport)
  5801. {
  5802. my ($Affected_Interfaces_Header, $Affected_Interfaces) = getAffectedInterfaces($TypeName, \%Kinds_Locations);
  5803. $HEADER_REPORT .= $ContentSpanStart."<span class='extension'>[+]</span> ".htmlSpecChars($TypeName)." ($ProblemNum)".$ContentSpanEnd."<br/>\n$ContentDivStart<table width='900px' cellpadding='3' cellspacing='0' class='problems_table'><tr><td align='center' width='2%' class='table_header'><span class='problem_title' style='white-space:nowrap;'></span></td><td width='47%' align='center' class='table_header'><span class='problem_sub_title'>Incompatibility</span></td><td align='center' class='table_header'><span class='problem_sub_title'>Effect</span></td></tr>$TypeProblemsReport</table>"."<span style='padding-left:10px'>$Affected_Interfaces_Header</span>$Affected_Interfaces<br/><br/>$ContentDivEnd\n";
  5804. $HEADER_REPORT = insertIDs($HEADER_REPORT);
  5805. }
  5806. }
  5807. if($HEADER_REPORT)
  5808. {
  5809. $TYPE_PROBLEMS .= "<span class='header_name'>$HeaderName</span><br/>\n".$HEADER_REPORT."<br/>";
  5810. }
  5811. }
  5812. if($TYPE_PROBLEMS)
  5813. {
  5814. my $Notations = "";
  5815. if($TYPE_PROBLEMS =~ /'RetVal|'Obj/)
  5816. {
  5817. my @Notations_Array = ();
  5818. if($TYPE_PROBLEMS =~ /'RetVal/)
  5819. {
  5820. @Notations_Array = (@Notations_Array, "<span style='color:#444444;padding-left:5px;'><b>RetVal</b></span> - function's return value");
  5821. }
  5822. if($TYPE_PROBLEMS =~ /'Obj/)
  5823. {
  5824. @Notations_Array = (@Notations_Array, "<span style='color:#444444;'><b>Obj</b></span> - method's object (C++)");
  5825. }
  5826. $Notations = "Shorthand notations: ".join("; ", @Notations_Array).".<br/>\n";
  5827. }
  5828. $TYPE_PROBLEMS = "<a name=\'Type_Problems_$TargetPriority\'></a>\n<h2 style='margin-bottom:0px;padding-bottom:0px;'>Problems in Data Types, $TargetPriority risk ($Problems_Number)</h2><hr/>\n".$Notations."<!--Type_Problems_".$TargetPriority."-->\n".$TYPE_PROBLEMS."<!--Type_Problems_".$TargetPriority."_End-->\n"."<input id=\'Type_Problems_$TargetPriority"."_Count"."\' type='hidden' value=\'$Problems_Number\' /><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
  5829. }
  5830. return $TYPE_PROBLEMS;
  5831. }
  5832. my $ContentSpanStart_2 = "<span style='line-height:25px;' class=\"section_2\" onclick=\"javascript:showContent(this, 'CONTENT_ID')\">\n";
  5833. sub getAffectedInterfaces($$)
  5834. {
  5835. my ($Target_TypeName, $Kinds_Locations) = @_;
  5836. my ($Affected_Interfaces_Header, $Affected_Interfaces, %FunctionNumber) = ();
  5837. foreach my $Interface (sort {lc($tr_name{$a}) cmp lc($tr_name{$b})} keys(%CompatProblems))
  5838. {
  5839. next if(($Interface =~ /C2/) or ($Interface =~ /D2/) or ($Interface =~ /D0/));
  5840. next if(keys(%FunctionNumber)>1000);
  5841. my $FunctionProblem = "";
  5842. my $MinPath_Length = "";
  5843. my $MaxPriority = 0;
  5844. my $Location_Last = "";
  5845. foreach my $Kind (keys(%{$CompatProblems{$Interface}}))
  5846. {
  5847. foreach my $Location (keys(%{$CompatProblems{$Interface}{$Kind}}))
  5848. {
  5849. next if(not $Kinds_Locations->{$Kind}{$Location});
  5850. my $Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Type_Name"};
  5851. my $Signature = $CompatProblems{$Interface}{$Kind}{$Location}{"Signature"};
  5852. my $Parameter_Position = $CompatProblems{$Interface}{$Kind}{$Location}{"Parameter_Position"};
  5853. my $Priority = $CompatProblems{$Interface}{$Kind}{$Location}{"Priority"};
  5854. if($Type_Name eq $Target_TypeName)
  5855. {
  5856. $FunctionNumber{$Interface} = 1;
  5857. my $Path_Length = 0;
  5858. while($Location =~ /\-\>/g){$Path_Length += 1;}
  5859. if(($MinPath_Length eq "") or ($Path_Length<$MinPath_Length and $Priority_Value{$Priority}>$MaxPriority) or (($Location_Last =~ /RetVal/ or $Location_Last =~ /Obj/) and $Location !~ /RetVal|Obj/ and $Location !~ /\-\>/) or ($Location_Last =~ /RetVal|Obj/ and $Location_Last =~ /\-\>/ and $Location !~ /RetVal|Obj/ and $Location =~ /\-\>/))
  5860. {
  5861. $MinPath_Length = $Path_Length;
  5862. $MaxPriority = $Priority_Value{$Priority};
  5863. $Location_Last = $Location;
  5864. my $Description = get_AffectDescription($Interface, $Kind, $Location);
  5865. $FunctionProblem = "<span class='interface_name_black' style='padding-left:20px;'>".highLight_Signature_PPos_Italic(htmlSpecChars($Signature), $Parameter_Position, 1, 0)."</span>:<br/>"."<span class='affect_description'>".addArrows($Description)."</span><br/><div style='height:4px;'>&nbsp;</div>\n";
  5866. }
  5867. }
  5868. }
  5869. }
  5870. $Affected_Interfaces .= $FunctionProblem;
  5871. }
  5872. $Affected_Interfaces .= "and other...<br/>" if(keys(%FunctionNumber)>5000);
  5873. if($Affected_Interfaces)
  5874. {
  5875. $Affected_Interfaces_Header = $ContentSpanStart_2."[+] affected interfaces (".keys(%FunctionNumber).")".$ContentSpanEnd;
  5876. $Affected_Interfaces = $ContentDivStart.$Affected_Interfaces.$ContentDivEnd;
  5877. }
  5878. return ($Affected_Interfaces_Header, $Affected_Interfaces);
  5879. }
  5880. my %Kind_TypeStructureChanged=(
  5881. "Size"=>1,
  5882. "Added_Member_And_Size"=>1,
  5883. "Added_Middle_Member_And_Size"=>1,
  5884. "Member_Rename"=>1,
  5885. "Withdrawn_Member_And_Size"=>1,
  5886. "Withdrawn_Member"=>1,
  5887. "Withdrawn_Middle_Member_And_Size"=>1,
  5888. "Enum_Member_Value"=>1,
  5889. "Enum_Member_Name"=>1,
  5890. "Member_Type_And_Size"=>1,
  5891. "Member_Type"=>1,
  5892. "Member_BaseType_And_Size"=>1,
  5893. "Member_BaseType"=>1,
  5894. "Member_PointerLevel"=>1,
  5895. "BaseType"=>1
  5896. );
  5897. my %Kind_VirtualTableChanged=(
  5898. "Added_Virtual_Function"=>1,
  5899. "Withdrawn_Virtual_Function"=>1,
  5900. "Virtual_Function_Position"=>1,
  5901. "Virtual_Function_Redefinition"=>1,
  5902. "Virtual_Function_Redefinition_B"=>1
  5903. );
  5904. sub get_AffectDescription($$$)
  5905. {
  5906. my ($Interface, $Kind, $Location) = @_;
  5907. my $Target = $CompatProblems{$Interface}{$Kind}{$Location}{"Target"};
  5908. my $Old_Value = $CompatProblems{$Interface}{$Kind}{$Location}{"Old_Value"};
  5909. my $New_Value = $CompatProblems{$Interface}{$Kind}{$Location}{"New_Value"};
  5910. my $Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Type_Name"};
  5911. my $Parameter_Position = $CompatProblems{$Interface}{$Kind}{$Location}{"Parameter_Position"};
  5912. my $Parameter_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Parameter_Name"};
  5913. my $Parameter_Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Parameter_Type_Name"};
  5914. my $Member_Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Member_Type_Name"};
  5915. my $Object_Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Object_Type_Name"};
  5916. my $Return_Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Return_Type_Name"};
  5917. my $Start_Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Start_Type_Name"};
  5918. my $InitialType_Type = $CompatProblems{$Interface}{$Kind}{$Location}{"InitialType_Type"};
  5919. my $Parameter_Position_Str = num_to_str($Parameter_Position + 1);
  5920. my @Sentence_Parts = ();
  5921. my $Location_To_Type = $Location;
  5922. $Location_To_Type =~ s/\-\>[^>]+?\Z//;
  5923. if($Kind_VirtualTableChanged{$Kind})
  5924. {
  5925. if($Kind eq "Virtual_Function_Redefinition")
  5926. {
  5927. @Sentence_Parts = (@Sentence_Parts, "This method become virtual and will be called instead of redefined method '".highLight_Signature(htmlSpecChars($Old_Value))."'.");
  5928. }
  5929. elsif($Kind eq "Virtual_Function_Redefinition_B")
  5930. {
  5931. @Sentence_Parts = (@Sentence_Parts, "This method become non-virtual and redefined method '".highLight_Signature(htmlSpecChars($Old_Value))."' will be called instead of it.");
  5932. }
  5933. else
  5934. {
  5935. @Sentence_Parts = (@Sentence_Parts, "Call of this virtual method will result in crash of application because the layout of virtual table has been changed.");
  5936. }
  5937. }
  5938. elsif($Kind_TypeStructureChanged{$Kind})
  5939. {
  5940. if($Location_To_Type =~ /RetVal/)
  5941. {#return value
  5942. if($Location_To_Type =~ /\-\>/)
  5943. {
  5944. @Sentence_Parts = (@Sentence_Parts, "Member \'$Location_To_Type\' in return value");
  5945. }
  5946. else
  5947. {
  5948. @Sentence_Parts = (@Sentence_Parts, "Return value");
  5949. }
  5950. }
  5951. elsif($Location_To_Type =~ /Obj/)
  5952. {#object
  5953. if($Location_To_Type =~ /\-\>/)
  5954. {
  5955. @Sentence_Parts = (@Sentence_Parts, "Member \'$Location_To_Type\' in the object of this method");
  5956. }
  5957. else
  5958. {
  5959. @Sentence_Parts = (@Sentence_Parts, "Object");
  5960. }
  5961. }
  5962. else
  5963. {#parameters
  5964. if($Location_To_Type =~ /\-\>/)
  5965. {
  5966. @Sentence_Parts = (@Sentence_Parts, "Member \'$Location_To_Type\' of $Parameter_Position_Str parameter");
  5967. }
  5968. else
  5969. {
  5970. @Sentence_Parts = (@Sentence_Parts, "$Parameter_Position_Str parameter");
  5971. }
  5972. if($Parameter_Name)
  5973. {
  5974. @Sentence_Parts = (@Sentence_Parts, "\'$Parameter_Name\'");
  5975. }
  5976. if($InitialType_Type eq "Pointer")
  5977. {
  5978. @Sentence_Parts = (@Sentence_Parts, "(pointer)");
  5979. }
  5980. }
  5981. if($Start_Type_Name eq $Type_Name)
  5982. {
  5983. @Sentence_Parts = (@Sentence_Parts, "has type \'$Type_Name\'.");
  5984. }
  5985. else
  5986. {
  5987. @Sentence_Parts = (@Sentence_Parts, "has base type \'$Type_Name\'.");
  5988. }
  5989. }
  5990. return join(" ", @Sentence_Parts);
  5991. }
  5992. sub create_HtmlReport()
  5993. {
  5994. my $CssStyles = "<style type=\"text/css\">
  5995. body{font-family:Arial;}
  5996. hr{color:Black;background-color:Black;height:1px;border:0;}
  5997. span.section{font-weight:bold;cursor:pointer;margin-left:7px;font-size:16px;font-family:Arial;color:#003E69;}
  5998. span:hover.section{color:#336699;}
  5999. span.section_2{cursor:pointer;margin-left:7px;font-size:14px;font-family:Arial;color:#cc3300;}
  6000. span.extension{font-weight:100;font-size:16px;}
  6001. span.problem_exact_location{color:Red;font-size:14px;}
  6002. span.header_name{color:#cc3300;font-size:14px;font-family:Arial;font-weight:bold;}
  6003. span.header_list_elem{padding-left:10px;color:#333333;font-size:15px;font-family:Arial;}
  6004. span.solib_list_elem{padding-left:10px;color:#333333;font-size:15px;font-family:Arial;}
  6005. span.solib_name{color:Green;font-size:14px;font-family:Arial;font-weight:bold;}
  6006. span.interface_name{font-weight:bold;font-size:16px;font-family:Arial;color:#003E69;margin-left:7px;}
  6007. span.interface_name_black{font-weight:bold;font-size:15px;font-family:Arial;color:#333333;}
  6008. span.problem_title{color:#333333;font-weight:bold;font-size:13px;font-family:Verdana;}
  6009. span.problem_sub_title{color:#333333;text-decoration:none;font-weight:bold;font-size:13px;font-family:Verdana;}
  6010. span.problem_body{color:Black;font-size:14px;}
  6011. span.int_p{font-weight:normal;}
  6012. span.affect_description{padding-left:30px;font-size:14px;font-style:italic;line-height:13px;}
  6013. table.problems_table{line-height:16px;margin-left:15px;margin-top:3px;border-collapse:collapse;}
  6014. table.problems_table td{border-style:solid;border-color:Gray;border-width:1px;}
  6015. td.table_header{background-color:#eeeeee;}
  6016. td.summary_item{font-size:15px;font-family:Arial;text-align:left;}
  6017. td.summary_item_value{padding-left:5px;padding-right:5px;width:35px;text-align:right;}
  6018. span.problem_num{color:#333333;font-weight:bold;font-size:13px;font-family:Verdana;}
  6019. span.mangled{padding-left:15px;font-size:13px;cursor:text;color:#444444;}
  6020. span.symver{color:#555555;font-size:13px;white-space:nowrap;}
  6021. span.color_param{font-style:italic;color:Brown;}
  6022. span.focus_param{font-style:italic;color:Red;}</style>";
  6023. my $JScripts = "<script type=\"text/javascript\" language=\"JavaScript\">
  6024. function showContent(header, id) {
  6025. e = document.getElementById(id);
  6026. if(e.style.display == 'none')
  6027. {
  6028. e.style.display = '';
  6029. e.style.visibility = 'visible';
  6030. header.innerHTML = header.innerHTML.replace(/\\\[[^0-9 ]\\\]/gi,\"[&minus;]\");
  6031. }
  6032. else
  6033. {
  6034. e.style.display = 'none';
  6035. e.style.visibility = 'hidden';
  6036. header.innerHTML = header.innerHTML.replace(/\\\[[^0-9 ]\\\]/gi,\"[+]\");
  6037. }
  6038. }</script>";
  6039. writeFile("$REPORT_PATH/abi_compat_report.html", "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />
  6040. <title>ABI compliance report for the library $TargetLibraryName from version ".$Descriptor{1}{"Version"}." to ".$Descriptor{2}{"Version"}." on ".getArch()."\n</title>\n<!--Styles-->\n".$CssStyles."\n<!--Styles_End-->\n"."<!--JScripts-->\n".$JScripts."\n<!--JScripts_End-->\n</head>\n<body>\n<div><a name='Top'></a>\n".get_Report_Header()."<br/>\n".get_Summary()."<br/>\n".get_Report_Added().get_Report_Withdrawn().get_Report_TypeProblems("High").get_Report_TypeProblems("Medium").get_Report_TypeProblems("Low").get_Report_InterfaceProblems("High").get_Report_InterfaceProblems("Medium").get_Report_InterfaceProblems("Low").get_Report_ChangedConstants().get_SourceInfo()."</div>\n"."<br/><br/><br/><hr/><div style='width:100%;font-family:Arial;font-size:11px;' align='right'><i>Generated on ".(localtime time)." for <span style='font-weight:bold'>$TargetLibraryName</span> by <a href='http://ispras.linux-foundation.org/index.php/ABI_compliance_checker'>ABI-compliance-checker</a> $ABI_COMPLIANCE_CHECKER_VERSION &nbsp;</i></div>\n<div style='height:999px;'></div>\n</body></html>");
  6041. }
  6042. sub trivialCmp($$)
  6043. {
  6044. if(int($_[0]) > int($_[1]))
  6045. {
  6046. return 1;
  6047. }
  6048. elsif($_[0] eq $_[1])
  6049. {
  6050. return 0;
  6051. }
  6052. else
  6053. {
  6054. return -1;
  6055. }
  6056. }
  6057. sub addArrows($)
  6058. {
  6059. my $Text = $_[0];
  6060. #$Text =~ s/\-\>/&#8594;/g;
  6061. $Text =~ s/\-\>/&minus;&gt;/g;
  6062. return $Text;
  6063. }
  6064. sub insertIDs($)
  6065. {
  6066. my $Text = $_[0];
  6067. while($Text =~ /CONTENT_ID/)
  6068. {
  6069. if(int($Content_Counter)%2)
  6070. {
  6071. $ContentID -= 1;
  6072. }
  6073. $Text =~ s/CONTENT_ID/c_$ContentID/;
  6074. $ContentID += 1;
  6075. $Content_Counter += 1;
  6076. }
  6077. return $Text;
  6078. }
  6079. sub restrict_num_decimal_digits
  6080. {
  6081. my $num=shift;
  6082. my $digs_to_cut=shift;
  6083. if ($num=~/\d+\.(\d){$digs_to_cut,}/)
  6084. {
  6085. $num=sprintf("%.".($digs_to_cut-1)."f", $num);
  6086. }
  6087. return $num;
  6088. }
  6089. sub parse_constants()
  6090. {
  6091. my $CurHeader = "";
  6092. foreach my $String (split("\n", $ConstantsSrc{$Version}))
  6093. {#detecting public and private constants using sources
  6094. if($String=~/#[ \t]+\d+[ \t]+\"(.+)\"/)
  6095. {
  6096. $CurHeader=$1;
  6097. }
  6098. if($String=~/\#[ \t]*define[ \t]+([_A-Z]+)[ \t]+(.*)[ \t]*\Z/)
  6099. {
  6100. my ($Name, $Value) = ($1, $2);
  6101. if(not $Constants{$Version}{$Name}{"Access"})
  6102. {
  6103. $Constants{$Version}{$Name}{"Access"} = "public";
  6104. $Constants{$Version}{$Name}{"Value"} = $Value;
  6105. $Constants{$Version}{$Name}{"Header"} = get_FileName($CurHeader);
  6106. }
  6107. }
  6108. elsif($String=~/\#[ \t]*undef[ \t]+([_A-Z]+)[ \t]*/)
  6109. {
  6110. my $Name = $1;
  6111. $Constants{$Version}{$Name}{"Access"} = "private";
  6112. }
  6113. }
  6114. foreach my $Constant (keys(%{$Constants{$Version}}))
  6115. {
  6116. if(($Constants{$Version}{$Constant}{"Access"} eq "private") or not $Constants{$Version}{$Constant}{"Value"}
  6117. or $Constant=~/_h\Z/i)
  6118. {
  6119. delete($Constants{$Version}{$Constant});
  6120. }
  6121. else
  6122. {
  6123. delete($Constants{$Version}{$Constant}{"Access"});
  6124. }
  6125. }
  6126. }
  6127. sub mergeConstants()
  6128. {
  6129. return if(defined $AppPath);
  6130. foreach my $Constant (keys(%{$Constants{1}}))
  6131. {
  6132. my $Old_Value = $Constants{1}{$Constant}{"Value"};
  6133. my $New_Value = $Constants{2}{$Constant}{"Value"};
  6134. my $Header = $Constants{1}{$Constant}{"Header"};
  6135. if($New_Value and $Old_Value and ($New_Value ne $Old_Value))
  6136. {
  6137. %{$ConstantProblems{$Constant}} = (
  6138. "Old_Value"=>$Old_Value,
  6139. "New_Value"=>$New_Value,
  6140. "Header"=>$Header
  6141. );
  6142. }
  6143. }
  6144. }
  6145. sub mergeHeaders_Separately()
  6146. {
  6147. system("mkdir", "-p", "header_compile_errors/".$TargetLibraryName);
  6148. system("rm", "-fr", $ERR_PATH{1}, $ERR_PATH{2});
  6149. my ($Header_Num, $Prev_Header_Length) = (0, 0);
  6150. my $All_Count = keys(%{$Headers{1}});
  6151. foreach my $Header_Dest (sort {int($Headers{1}{$a}{"Position"})<=>int($Headers{1}{$b}{"Position"})} keys(%{$Headers{1}}))
  6152. {
  6153. my $Header_Name = $Headers{1}{$Header_Dest}{"Name"};
  6154. my $Dest_Count = keys(%{$HeaderName_Destinations{1}{$Header_Name}});
  6155. my $Identity = $Headers{1}{$Header_Dest}{"Identity"};
  6156. my $Dest_Comment = ($Dest_Count>1 and $Identity=~/\//)?" ($Identity)":"";
  6157. print get_one_step_title($Header_Name.$Dest_Comment, $Header_Num, $All_Count, $Prev_Header_Length, 1)."\r";
  6158. %TypeDescr = ();
  6159. %FuncDescr = ();
  6160. %ClassFunc = ();
  6161. %ClassVirtFunc = ();
  6162. %LibInfo = ();
  6163. %CompleteSignature = ();
  6164. %Cache = ();
  6165. $Version = 1;
  6166. parseHeader($Header_Dest);
  6167. $Version = 2;
  6168. my $PairHeaderDest = find_pair_header($Header_Dest);
  6169. if(not $PairHeaderDest)
  6170. {
  6171. $Header_Num += 1;
  6172. next;
  6173. }
  6174. parseHeader($PairHeaderDest);
  6175. mergeSignatures();
  6176. mergeConstants();
  6177. $Header_Num += 1;
  6178. $Prev_Header_Length = length($Header_Name.$Dest_Comment);
  6179. }
  6180. print get_one_step_title("", $All_Count, $All_Count, $Prev_Header_Length, 0)."\n";
  6181. }
  6182. sub get_one_step_title($$$$$)
  6183. {
  6184. my ($Header_Name, $Num, $All_Count, $SpacesAtTheEnd, $ShowCurrent) = @_;
  6185. my ($Spaces_1, $Spaces_2, $Title) = ();
  6186. my $Title_1 = "checking headers: $Num/$All_Count [".restrict_num_decimal_digits($Num*100/$All_Count, 3)."%]".(($ShowCurrent)?",":"");
  6187. foreach (0 .. length("checking headers: ")+length($All_Count)*2+11 - length($Title_1))
  6188. {
  6189. $Spaces_1 .= " ";
  6190. }
  6191. $Title .= $Title_1.$Spaces_1;
  6192. if($ShowCurrent)
  6193. {
  6194. my $Title_2 = "current: $Header_Name";
  6195. foreach (0 .. $SpacesAtTheEnd - length($Header_Name)-1)
  6196. {
  6197. $Spaces_2 .= " ";
  6198. }
  6199. $Title .= $Title_2.$Spaces_2;
  6200. }
  6201. else
  6202. {
  6203. foreach (0 .. $SpacesAtTheEnd + length(" current: ") - 1)
  6204. {
  6205. $Title .= " ";
  6206. }
  6207. }
  6208. return $Title."\r";
  6209. }
  6210. sub find_pair_header($)
  6211. {
  6212. my $Header_Dest = $_[0];
  6213. my $Header_Name = $Headers{1}{$Header_Dest}{"Name"};
  6214. my $Identity = $Headers{1}{$Header_Dest}{"Identity"};
  6215. my @Pair_Dest = keys(%{$HeaderName_Destinations{2}{$Header_Name}});
  6216. if($#Pair_Dest==0)
  6217. {
  6218. return $Pair_Dest[0];
  6219. }
  6220. elsif($#Pair_Dest==-1)
  6221. {
  6222. return "";
  6223. }
  6224. else
  6225. {
  6226. foreach my $Pair_Dest (@Pair_Dest)
  6227. {
  6228. my $Pair_Identity = $Headers{2}{$Pair_Dest}{"Identity"};
  6229. if($Identity eq $Pair_Identity)
  6230. {
  6231. return $Pair_Dest;
  6232. }
  6233. }
  6234. return "";
  6235. }
  6236. }
  6237. sub getSymbols($)
  6238. {
  6239. my $LibVersion = $_[0];
  6240. my @SoLibPaths = getSoPaths($LibVersion);
  6241. if($#SoLibPaths eq -1 and not $CheckHeadersOnly)
  6242. {
  6243. print "ERROR: shared objects were not found\n";
  6244. exit(1);
  6245. }
  6246. foreach my $SoLibPath (@SoLibPaths)
  6247. {
  6248. getSymbols_Lib($LibVersion, $SoLibPath, 0);
  6249. }
  6250. }
  6251. sub separatePath($)
  6252. {
  6253. return ("", $_[0])if($_[0] !~ /\//);
  6254. if($_[0] =~ /\A(.*\/)([^\/]*)\Z/)
  6255. {
  6256. return ($1, $2);
  6257. }
  6258. else
  6259. {
  6260. return ("", $_[0]);
  6261. }
  6262. }
  6263. sub translateSymbols($)
  6264. {
  6265. my $LibVersion = $_[0];
  6266. my (@MnglNames, @UnMnglNames) = ();
  6267. foreach my $Interface (sort keys(%{$Interface_Library{$LibVersion}}))
  6268. {
  6269. if($Interface =~ /\A_Z/)
  6270. {
  6271. $Interface =~ s/[\@]+(.*)\Z//;
  6272. push(@MnglNames, $Interface);
  6273. }
  6274. else
  6275. {
  6276. $tr_name{$Interface} = $Interface;
  6277. $mangled_name{$tr_name{$Interface}} = $Interface;
  6278. }
  6279. }
  6280. if($#MnglNames > -1)
  6281. {
  6282. @UnMnglNames = reverse(unmangleArray(@MnglNames));
  6283. foreach my $Interface (sort keys(%{$Interface_Library{$LibVersion}}))
  6284. {
  6285. if($Interface =~ /\A_Z/)
  6286. {
  6287. $Interface =~ s/[\@]+(.*)\Z//;
  6288. $tr_name{$Interface} = pop(@UnMnglNames);
  6289. $mangled_name{correctName($tr_name{$Interface})} = $Interface;
  6290. }
  6291. }
  6292. }
  6293. }
  6294. sub detectAdded()
  6295. {
  6296. #detecting added
  6297. foreach my $Interface (keys(%{$Interface_Library{2}}))
  6298. {
  6299. if(not $Interface_Library{1}{$Interface})
  6300. {
  6301. $AddedInt{$Interface} = 1;
  6302. my ($MnglName, $SymbolVersion) = ($Interface, "");
  6303. if($Interface =~ /\A(.+)[\@]+(.+)\Z/)
  6304. {
  6305. ($MnglName, $SymbolVersion) = ($1, $2);
  6306. }
  6307. $FuncAttr{2}{$Interface}{"Signature"} = $tr_name{$MnglName}.(($SymbolVersion)?"\@".$SymbolVersion:"");
  6308. }
  6309. }
  6310. }
  6311. sub detectWithdrawn()
  6312. {
  6313. #detecting withdrawn
  6314. foreach my $Interface (keys(%{$Interface_Library{1}}))
  6315. {
  6316. if(not $Interface_Library{2}{$Interface} and not $Interface_Library{2}{$SymVer{2}{$Interface}})
  6317. {
  6318. next if($DepInterfaces{2}{$Interface});
  6319. $WithdrawnInt{$Interface} = 1;
  6320. my ($MnglName, $SymbolVersion) = ($Interface, "");
  6321. if($Interface =~ /\A(.+)[\@]+(.+)\Z/)
  6322. {
  6323. ($MnglName, $SymbolVersion) = ($1, $2);
  6324. }
  6325. $FuncAttr{1}{$Interface}{"Signature"} = $tr_name{$MnglName}.(($SymbolVersion)?"\@".$SymbolVersion:"");
  6326. }
  6327. }
  6328. }
  6329. sub isRecurLib($)
  6330. {
  6331. my $LibName = $_[0];
  6332. foreach my $LibNameInStack (@RecurLib)
  6333. {
  6334. if($LibName eq $LibNameInStack)
  6335. {
  6336. return 1;
  6337. }
  6338. }
  6339. return 0;
  6340. }
  6341. sub getSymbols_App($)
  6342. {
  6343. my $Path = $_[0];
  6344. return () if(not $Path or not -f $Path);
  6345. my @Ints = ();
  6346. open(APP, "readelf -WhlSsdA $Path |");
  6347. my $symtab=0;#indicates that we are processing 'symtab' section of 'readelf' output
  6348. while(<APP>)
  6349. {
  6350. if($symtab == 1) {
  6351. #do nothing with symtab (but there are some plans for the future)
  6352. next;
  6353. }
  6354. if( /'.dynsym'/ ) {
  6355. $symtab=0;
  6356. }
  6357. elsif( /'.symtab'/ ) {
  6358. $symtab=1;
  6359. }
  6360. elsif(my ($fullname, $idx, $Ndx) = readlile_ELF($_)) {
  6361. if( $Ndx eq "UND" ) {
  6362. #only exported interfaces
  6363. push(@Ints, $fullname);
  6364. }
  6365. }
  6366. }
  6367. close(APP);
  6368. return @Ints;
  6369. }
  6370. sub readlile_ELF($)
  6371. {
  6372. if($_[0]=~/\s*\d+:\s+(\w*)\s+\w+\s+(\w+)\s+(\w+)\s+(\w+)\s+(\w+)\s((\w|@|\.)+)/)
  6373. {#the line of 'readelf' output corresponding to the interface
  6374. my ($value, $type, $bind, $vis, $Ndx, $fullname)=($1, $2, $3, $4, $5, $6);
  6375. if(($bind ne "WEAK") and ($bind ne "GLOBAL")) {
  6376. return ();
  6377. }
  6378. if(($type ne "FUNC") and ($type ne "OBJECT") and ($type ne "COMMON")) {
  6379. return ();
  6380. }
  6381. if($vis ne "DEFAULT") {
  6382. return ();
  6383. }
  6384. if(($Ndx eq "ABS") and ($value !~ /\D|1|2|3|4|5|6|7|8|9/)) {
  6385. return ();
  6386. }
  6387. return ($fullname, $value, $Ndx);
  6388. }
  6389. else
  6390. {
  6391. return ();
  6392. }
  6393. }
  6394. sub getSymbols_Lib($$$)
  6395. {
  6396. my ($LibVersion, $Lib_Path, $IsNeededLib) = @_;
  6397. return if(not $Lib_Path or not -f $Lib_Path);
  6398. my ($Lib_Dir, $Lib_SoName) = separatePath($Lib_Path);
  6399. return if($CheckedSoLib{$LibVersion}{$Lib_SoName} and $IsNeededLib);
  6400. return if(isRecurLib($Lib_SoName) or $#RecurLib>=1);
  6401. $CheckedSoLib{$LibVersion}{$Lib_SoName} = 1;
  6402. push(@RecurLib, $Lib_SoName);
  6403. my (%Value_Interface, %Interface_Value, %NeededLib) = ();
  6404. if(not $IsNeededLib)
  6405. {
  6406. $SoNames_All{$LibVersion}{$Lib_SoName} = 1;
  6407. }
  6408. open(SOLIB, "readelf -WhlSsdA $Lib_Path |");
  6409. my $symtab=0;#indicates that we are processing 'symtab' section of 'readelf' output
  6410. while(<SOLIB>)
  6411. {
  6412. if($symtab == 1) {
  6413. #do nothing with symtab (but there are some plans for the future)
  6414. next;
  6415. }
  6416. if(/'.dynsym'/) {
  6417. $symtab=0;
  6418. }
  6419. elsif(/'.symtab'/) {
  6420. $symtab=1;
  6421. }
  6422. elsif(/NEEDED.+\[([^\[\]]+)\]/)
  6423. {
  6424. $NeededLib{$1} = 1;
  6425. }
  6426. elsif(my ($fullname, $idx, $Ndx) = readlile_ELF($_)) {
  6427. if( $Ndx eq "UND" ) {
  6428. #ignore interfaces that are exported form somewhere else
  6429. next;
  6430. }
  6431. my ($realname, $version) = ($fullname, "");
  6432. if($fullname =~ /\A([^@]+)[\@]+([^@]+)\Z/)
  6433. {
  6434. ($realname, $version) = ($1, $2);
  6435. }
  6436. next if(defined $InterfacesListPath and not $InterfacesList{$realname});
  6437. next if(defined $AppPath and not $InterfacesList_App{$realname});
  6438. if($IsNeededLib)
  6439. {
  6440. $DepInterfaces{$LibVersion}{$fullname} = 1;
  6441. }
  6442. if(not $IsNeededLib or (defined $InterfacesListPath and $InterfacesList{$realname}) or (defined $AppPath and $InterfacesList_App{$realname}))
  6443. {
  6444. $Interface_Library{$LibVersion}{$fullname} = $Lib_SoName;
  6445. $Library_Interface{$LibVersion}{$Lib_SoName}{$fullname} = 1;
  6446. $Interface_Value{$LibVersion}{$fullname} = $idx;
  6447. $Value_Interface{$LibVersion}{$idx}{$fullname} = 1;
  6448. if(not $Language{$LibVersion}{$Lib_SoName})
  6449. {
  6450. if($fullname =~ /\A_Z[A-Z]*[0-9]+/)
  6451. {
  6452. $Language{$LibVersion}{$Lib_SoName} = "C++";
  6453. }
  6454. }
  6455. }
  6456. }
  6457. }
  6458. close(SOLIB);
  6459. if(not $IsNeededLib)
  6460. {
  6461. foreach my $Interface_Name (keys(%{$Interface_Library{$LibVersion}}))
  6462. {
  6463. next if($Interface_Name !~ /\@/);
  6464. my $Interface_SymName = "";
  6465. foreach my $InterfaceName_SameValue (keys(%{$Value_Interface{$LibVersion}{$Interface_Value{$LibVersion}{$Interface_Name}}}))
  6466. {
  6467. if($InterfaceName_SameValue ne $Interface_Name)
  6468. {
  6469. $SymVer{$LibVersion}{$InterfaceName_SameValue} = $Interface_Name;
  6470. $Interface_SymName = $InterfaceName_SameValue;
  6471. last;
  6472. }
  6473. }
  6474. if(not $Interface_SymName)
  6475. {
  6476. if($Interface_Name =~ /\A([^@]*)[\@]+([^@]*)\Z/ and not $SymVer{$LibVersion}{$1})
  6477. {
  6478. $SymVer{$LibVersion}{$1} = $Interface_Name;
  6479. }
  6480. }
  6481. }
  6482. }
  6483. foreach my $SoLib (keys(%NeededLib))
  6484. {
  6485. getSymbols_Lib($LibVersion, find_solib_path($Lib_Dir, $SoLib), 1);
  6486. }
  6487. pop(@RecurLib);
  6488. }
  6489. sub find_solib_path($$)
  6490. {
  6491. my ($Dir, $SoName) = @_;
  6492. $Dir=~s/\/\Z//g;
  6493. if(-f $Dir."/".$SoName)
  6494. {
  6495. return $Dir."/".$SoName;
  6496. }
  6497. else
  6498. {
  6499. return $SoLib_DefaultPath{$SoName};
  6500. }
  6501. }
  6502. sub symbols_Preparation($)
  6503. {#recreate %SoNames and %Language using info from *.abi file
  6504. my $LibVersion = $_[0];
  6505. foreach my $Lib_SoName (keys(%{$Library_Interface{$LibVersion}}))
  6506. {
  6507. foreach my $Interface_Name (keys(%{$Library_Interface{$LibVersion}{$Lib_SoName}}))
  6508. {
  6509. $Interface_Library{$LibVersion}{$Interface_Name} = $Lib_SoName;
  6510. $SoNames_All{$LibVersion}{$Lib_SoName} = 1;
  6511. if(not $Language{$LibVersion}{$Lib_SoName})
  6512. {
  6513. if($Interface_Name =~ /\A_Z[A-Z]*[0-9]+/)
  6514. {
  6515. $Language{$LibVersion}{$Lib_SoName} = "C++";
  6516. }
  6517. }
  6518. }
  6519. }
  6520. }
  6521. sub getSoPaths($)
  6522. {
  6523. my $LibVersion = $_[0];
  6524. my @SoPaths = ();
  6525. foreach my $Dest (split("\n", $Descriptor{$LibVersion}{"Libs"}))
  6526. {
  6527. $Dest =~ s/\A\s+|\s+\Z//g;
  6528. next if(not $Dest);
  6529. if(not -e $Dest)
  6530. {
  6531. print "ERROR: can't access \'$Dest\'\n";
  6532. }
  6533. my @SoPaths_Dest = getSOPaths_Dest($Dest);
  6534. foreach (@SoPaths_Dest)
  6535. {
  6536. push(@SoPaths, $_);
  6537. }
  6538. }
  6539. return @SoPaths;
  6540. }
  6541. sub getSOPaths_Dest($)
  6542. {
  6543. my $Dest = $_[0];
  6544. if(-f $Dest)
  6545. {
  6546. return $Dest;
  6547. }
  6548. my @AllObjects = cmd_find($Dest,"f","*\.so*");
  6549. my @SOPaths = ();
  6550. foreach my $SharedObject (@AllObjects)
  6551. {
  6552. if(cmd_file($SharedObject) =~ /shared object/)
  6553. {
  6554. @SOPaths = (@SOPaths, $SharedObject);
  6555. }
  6556. }
  6557. return @SOPaths;
  6558. }
  6559. sub genDescriptorTemplate()
  6560. {
  6561. writeFile("library-descriptor.xml", $Descriptor_Template."\n");
  6562. print "descriptor template named 'library-descriptor.xml' has been generated in the current directory\n";
  6563. }
  6564. sub detectPointerSize()
  6565. {
  6566. `mkdir -p temp`;
  6567. writeFile("temp/get_pointer_size.c", "#include <stdio.h>
  6568. int main()
  6569. {
  6570. printf(\"\%d\", sizeof(int*));
  6571. return 0;
  6572. }\n");
  6573. system("gcc temp/get_pointer_size.c -o temp/get_pointer_size");
  6574. $POINTER_SIZE = `./temp/get_pointer_size`;
  6575. `rm -fr temp`;
  6576. }
  6577. sub data_Preparation($)
  6578. {
  6579. my $LibVersion = $_[0];
  6580. if($Descriptor{$LibVersion}{"Path"} =~ /\.abi\.tar\.gz/)
  6581. {
  6582. my $FileName = cmd_tar($Descriptor{$LibVersion}{"Path"});
  6583. if($FileName =~ /\.abi/)
  6584. {
  6585. chomp($FileName);
  6586. my $LibraryABI = eval readFile($FileName);
  6587. system("rm", "-f", $FileName);
  6588. $TypeDescr{$LibVersion} = $LibraryABI->{"TypeDescr"};
  6589. $FuncDescr{$LibVersion} = $LibraryABI->{"FuncDescr"};
  6590. $Library_Interface{$LibVersion} = $LibraryABI->{"Interfaces"};
  6591. $SymVer{$LibVersion} = $LibraryABI->{"SymVer"};
  6592. $Tid_TDid{$LibVersion} = $LibraryABI->{"Tid_TDid"};
  6593. $Descriptor{$LibVersion}{"Version"} = $LibraryABI->{"LibraryVersion"};
  6594. $OpaqueTypes{$LibVersion} = $LibraryABI->{"OpaqueTypes"};
  6595. $InternalInterfaces{$LibVersion} = $LibraryABI->{"InternalInterfaces"};
  6596. $Headers{$LibVersion} = $LibraryABI->{"Headers"};
  6597. $SoNames_All{$LibVersion} = $LibraryABI->{"SharedObjects"};
  6598. $Constants{$LibVersion} = $LibraryABI->{"Constants"};
  6599. if($LibraryABI->{"ABI_COMPLIANCE_CHECKER_VERSION"} ne $ABI_COMPLIANCE_CHECKER_VERSION)
  6600. {
  6601. print "ERROR: incompatible version of specified ABI dump (allowed only $ABI_COMPLIANCE_CHECKER_VERSION)\n";
  6602. exit(1);
  6603. }
  6604. foreach my $Destination (keys(%{$Headers{$LibVersion}}))
  6605. {
  6606. my $Header = get_FileName($Destination);
  6607. $HeaderName_Destinations{$LibVersion}{$Header}{$Destination} = 1;
  6608. }
  6609. symbols_Preparation($LibVersion);
  6610. }
  6611. }
  6612. elsif($Descriptor{$LibVersion}{"Path"} =~ /\.tar\.gz\Z/)
  6613. {
  6614. print "ERROR: descriptor must be an XML file or '*.abi.tar.gz' ABI dump\n";
  6615. exit(1);
  6616. }
  6617. else
  6618. {
  6619. readDescriptor($LibVersion);
  6620. if(not $CheckHeadersOnly)
  6621. {
  6622. getSymbols($LibVersion);
  6623. }
  6624. headerSearch($LibVersion);
  6625. }
  6626. }
  6627. sub dump_sorting($)
  6628. {
  6629. my $hash = $_[0];
  6630. if((keys(%{$hash}))[0] =~ /\A[0-9]+\Z/)
  6631. {
  6632. return [sort {int($a) <=> int($b)} keys %{$hash}];
  6633. }
  6634. else
  6635. {
  6636. return [sort {$a cmp $b} keys %{$hash}];
  6637. }
  6638. }
  6639. sub get_solib_default_paths()
  6640. {
  6641. foreach my $Line (split("\n", `ldconfig -p`))
  6642. {
  6643. if($Line=~/\A[ \t]*([^ \t]+) .* \=\> (.+)\Z/)
  6644. {
  6645. $SoLib_DefaultPath{$1} = $2;
  6646. }
  6647. }
  6648. }
  6649. sub scenario()
  6650. {
  6651. if(defined $Help)
  6652. {
  6653. HELP_MESSAGE();
  6654. exit(0);
  6655. }
  6656. if(defined $ShowVersion)
  6657. {
  6658. print "ABI Compliance Checker $ABI_COMPLIANCE_CHECKER_VERSION\nCopyright (C) The Linux Foundation\nCopyright (C) Institute for System Programming, RAS\nLicense GPLv2: GNU GPL version 2 <http://www.gnu.org/licenses/>\nThis program is free software: you can redistribute it and/or modify it.\n\nWritten by Andrey Ponomarenko.\n";
  6659. exit(0);
  6660. }
  6661. $Data::Dumper::Sortkeys = \&dump_sorting;
  6662. if(defined $TestSystem)
  6663. {
  6664. testSystem_cpp();
  6665. testSystem_c();
  6666. exit(0);
  6667. }
  6668. if($GenerateDescriptor)
  6669. {
  6670. genDescriptorTemplate();
  6671. exit(0);
  6672. }
  6673. if(not defined $TargetLibraryName)
  6674. {
  6675. print "select library name (option -l <name>)\n";
  6676. exit(1);
  6677. }
  6678. if(defined $InterfacesListPath)
  6679. {
  6680. if(not -f $InterfacesListPath)
  6681. {
  6682. print "ERROR: can't access file $InterfacesListPath\n";
  6683. exit(1);
  6684. }
  6685. foreach my $Interface (split("\n", readFile($InterfacesListPath)))
  6686. {
  6687. $InterfacesList{$Interface} = 1;
  6688. }
  6689. }
  6690. if($AppPath)
  6691. {
  6692. if(-f $AppPath)
  6693. {
  6694. foreach my $Interface (getSymbols_App($AppPath))
  6695. {
  6696. $InterfacesList_App{$Interface} = 1;
  6697. }
  6698. }
  6699. else
  6700. {
  6701. print "ERROR: can't access file \'$AppPath\'\n";
  6702. exit(1);
  6703. }
  6704. }
  6705. get_solib_default_paths();
  6706. if($DumpInfo_DescriptorPath)
  6707. {
  6708. if(not -f $DumpInfo_DescriptorPath)
  6709. {
  6710. print "ERROR: can't access file \'$DumpInfo_DescriptorPath\'\n";
  6711. exit(1);
  6712. }
  6713. $Descriptor{1}{"Path"} = $DumpInfo_DescriptorPath;
  6714. readDescriptor(1);
  6715. detectPointerSize();
  6716. getSymbols(1);
  6717. translateSymbols(1);
  6718. headerSearch(1);
  6719. parseHeaders_AllInOne(1);
  6720. cleanData(1);
  6721. my %LibraryABI = ();
  6722. print "creating library ABI info dump ...\n";
  6723. $LibraryABI{"TypeDescr"} = $TypeDescr{1};
  6724. $LibraryABI{"FuncDescr"} = $FuncDescr{1};
  6725. $LibraryABI{"Interfaces"} = $Library_Interface{1};
  6726. $LibraryABI{"SymVer"} = $SymVer{1};
  6727. $LibraryABI{"LibraryVersion"} = $Descriptor{1}{"Version"};
  6728. $LibraryABI{"Library"} = $TargetLibraryName;
  6729. $LibraryABI{"SharedObjects"} = $SoNames_All{1};
  6730. $LibraryABI{"Tid_TDid"} = $Tid_TDid{1};
  6731. $LibraryABI{"OpaqueTypes"} = $OpaqueTypes{1};
  6732. $LibraryABI{"InternalInterfaces"} = $InternalInterfaces{1};
  6733. $LibraryABI{"Headers"} = $Headers{1};
  6734. $LibraryABI{"Constants"} = $Constants{1};
  6735. $LibraryABI{"ABI_COMPLIANCE_CHECKER_VERSION"} = $ABI_COMPLIANCE_CHECKER_VERSION;
  6736. my $InfoDump_FilePath = "abi_dumps/$TargetLibraryName";
  6737. my $InfoDump_FileName = $TargetLibraryName."_".$Descriptor{1}{"Version"}.".abi";
  6738. system("mkdir", "-p", $InfoDump_FilePath);
  6739. system("rm", "-f", $InfoDump_FilePath."/".$InfoDump_FileName.".tar.gz");
  6740. writeFile("$InfoDump_FilePath/$InfoDump_FileName", Dumper(\%LibraryABI));
  6741. system("cd ".esc($InfoDump_FilePath)." && tar -cf ".esc($InfoDump_FileName).".tar ".esc($InfoDump_FileName));
  6742. system("cd ".esc($InfoDump_FilePath)." && gzip ".esc($InfoDump_FileName).".tar --best");
  6743. system("rm", "-f", $InfoDump_FilePath."/".$InfoDump_FileName);
  6744. if($?)
  6745. {
  6746. print "ERROR: can't create library ABI info dump\n";
  6747. exit(1);
  6748. }
  6749. else
  6750. {
  6751. print "see library ABI info dump in \'$InfoDump_FilePath/$InfoDump_FileName\.tar\.gz\': use it instead of library version descriptor on other machine\n";
  6752. exit(0);
  6753. }
  6754. }
  6755. if(not $Descriptor{1}{"Path"})
  6756. {
  6757. print "select 1st library descriptor (option -d1 <path>)\n";
  6758. exit(1);
  6759. }
  6760. if(not -f $Descriptor{1}{"Path"})
  6761. {
  6762. print "ERROR: descriptor d1 does not exist, incorrect file path '".$Descriptor{1}{"Path"}."'\n";
  6763. exit(1);
  6764. }
  6765. if(not $Descriptor{2}{"Path"})
  6766. {
  6767. print "select 2nd library descriptor (option -d2 <path>)\n";
  6768. exit(1);
  6769. }
  6770. if(not -f $Descriptor{2}{"Path"})
  6771. {
  6772. print "ERROR: descriptor d2 does not exist, incorrect file path '".$Descriptor{2}{"Path"}."'\n";
  6773. exit(1);
  6774. }
  6775. $StartTime = localtime time;
  6776. print "preparation...\n";
  6777. data_Preparation(1);
  6778. data_Preparation(2);
  6779. if($AppPath and not keys(%{$Interface_Library{1}}))
  6780. {
  6781. print "WARNING: symbols from the specified application were not found in the specified library shared objects\n";
  6782. }
  6783. $REPORT_PATH = "compat_reports/$TargetLibraryName/".$Descriptor{1}{"Version"}."_to_".$Descriptor{2}{"Version"};
  6784. system("mkdir", "-p", $REPORT_PATH);
  6785. system("rm", "-f", $REPORT_PATH."/abi_compat_report.html");
  6786. detectPointerSize();
  6787. translateSymbols(1);
  6788. translateSymbols(2);
  6789. if(not $CheckHeadersOnly)
  6790. {
  6791. detectAdded();
  6792. detectWithdrawn();
  6793. }
  6794. #headers merging
  6795. if($HeaderCheckingMode_Separately and $Descriptor{1}{"Path"} !~ /\.abi\.tar\.gz/ and $Descriptor{2}{"Path"} !~ /\.abi\.tar\.gz/)
  6796. {
  6797. mergeHeaders_Separately();
  6798. }
  6799. else
  6800. {
  6801. if($Descriptor{1}{"Path"} !~ /\.abi\.tar\.gz/)
  6802. {
  6803. parseHeaders_AllInOne(1);
  6804. }
  6805. if($Descriptor{2}{"Path"} !~ /\.abi\.tar\.gz/)
  6806. {
  6807. parseHeaders_AllInOne(2);
  6808. }
  6809. print "comparing headers ...\n";
  6810. mergeSignatures();
  6811. mergeConstants();
  6812. }
  6813. #libraries merging
  6814. if(not $CheckHeadersOnly)
  6815. {
  6816. print "comparing shared objects ...\n";
  6817. mergeLibs();
  6818. }
  6819. print "creating ABI compliance report ...\n";
  6820. create_HtmlReport();
  6821. if($HeaderCheckingMode_Separately)
  6822. {
  6823. if(keys(%HeaderCompileError))
  6824. {
  6825. print "\nWARNING: compilation errors in following headers:\n";
  6826. foreach my $Header (keys(%HeaderCompileError))
  6827. {
  6828. print $Header." ";
  6829. }
  6830. print "\nyou can see compilation errors in the following files:\n '$ERR_PATH{1}'\n '$ERR_PATH{2}'\n";
  6831. }
  6832. }
  6833. `rm -fr temp`;
  6834. print "\nstarted: $StartTime, finished: ".(localtime time)."\n" if($ShowExpendTime);
  6835. print "see the ABI compliance report in the file '$REPORT_PATH/abi_compat_report.html'\n";
  6836. exit(0);
  6837. }
  6838. scenario();