stb.h 455 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457
  1. /* stb.h - v2.37 - Sean's Tool Box -- public domain -- http://nothings.org/stb.h
  2. no warranty is offered or implied; use this code at your own risk
  3. This is a single header file with a bunch of useful utilities
  4. for getting stuff done in C/C++.
  5. Documentation: http://nothings.org/stb/stb_h.html
  6. Unit tests: http://nothings.org/stb/stb.c
  7. ============================================================================
  8. You MUST
  9. #define STB_DEFINE
  10. in EXACTLY _one_ C or C++ file that includes this header, BEFORE the
  11. include, like this:
  12. #define STB_DEFINE
  13. #include "stb.h"
  14. All other files should just #include "stb.h" without the #define.
  15. ============================================================================
  16. Version History
  17. 2.36 various fixes
  18. 2.35 fix clang-cl issues with swprintf
  19. 2.34 fix warnings
  20. 2.33 more fixes to random numbers
  21. 2.32 stb_intcmprev, stb_uidict, fix random numbers on Linux
  22. 2.31 stb_ucharcmp
  23. 2.30 MinGW fix
  24. 2.29 attempt to fix use of swprintf()
  25. 2.28 various new functionality
  26. 2.27 test _WIN32 not WIN32 in STB_THREADS
  27. 2.26 various warning & bugfixes
  28. 2.25 various warning & bugfixes
  29. 2.24 various warning & bugfixes
  30. 2.23 fix 2.22
  31. 2.22 64-bit fixes from '!='; fix stb_sdict_copy() to have preferred name
  32. 2.21 utf-8 decoder rejects "overlong" encodings; attempted 64-bit improvements
  33. 2.20 fix to hash "copy" function--reported by someone with handle "!="
  34. 2.19 ???
  35. 2.18 stb_readdir_subdirs_mask
  36. 2.17 stb_cfg_dir
  37. 2.16 fix stb_bgio_, add stb_bgio_stat(); begin a streaming wrapper
  38. 2.15 upgraded hash table template to allow:
  39. - aggregate keys (explicit comparison func for EMPTY and DEL keys)
  40. - "static" implementations (so they can be culled if unused)
  41. 2.14 stb_mprintf
  42. 2.13 reduce identifiable strings in STB_NO_STB_STRINGS
  43. 2.12 fix STB_ONLY -- lots of uint32s, TRUE/FALSE things had crept in
  44. 2.11 fix bug in stb_dirtree_get() which caused "c://path" sorts of stuff
  45. 2.10 STB_F(), STB_I() inline constants (also KI,KU,KF,KD)
  46. 2.09 stb_box_face_vertex_axis_side
  47. 2.08 bugfix stb_trimwhite()
  48. 2.07 colored printing in windows (why are we in 1985?)
  49. 2.06 comparison functions are now functions-that-return-functions and
  50. accept a struct-offset as a parameter (not thread-safe)
  51. 2.05 compile and pass tests under Linux (but no threads); thread cleanup
  52. 2.04 stb_cubic_bezier_1d, smoothstep, avoid dependency on registry
  53. 2.03 ?
  54. 2.02 remove integrated documentation
  55. 2.01 integrate various fixes; stb_force_uniprocessor
  56. 2.00 revised stb_dupe to use multiple hashes
  57. 1.99 stb_charcmp
  58. 1.98 stb_arr_deleten, stb_arr_insertn
  59. 1.97 fix stb_newell_normal()
  60. 1.96 stb_hash_number()
  61. 1.95 hack stb__rec_max; clean up recursion code to use new functions
  62. 1.94 stb_dirtree; rename stb_extra to stb_ptrmap
  63. 1.93 stb_sem_new() API cleanup (no blockflag-starts blocked; use 'extra')
  64. 1.92 stb_threadqueue--multi reader/writer queue, fixed size or resizeable
  65. 1.91 stb_bgio_* for reading disk asynchronously
  66. 1.90 stb_mutex uses CRITICAL_REGION; new stb_sync primitive for thread
  67. joining; workqueue supports stb_sync instead of stb_semaphore
  68. 1.89 support ';' in constant-string wildcards; stb_mutex wrapper (can
  69. implement with EnterCriticalRegion eventually)
  70. 1.88 portable threading API (only for win32 so far); worker thread queue
  71. 1.87 fix wildcard handling in stb_readdir_recursive
  72. 1.86 support ';' in wildcards
  73. 1.85 make stb_regex work with non-constant strings;
  74. beginnings of stb_introspect()
  75. 1.84 (forgot to make notes)
  76. 1.83 whoops, stb_keep_if_different wasn't deleting the temp file
  77. 1.82 bring back stb_compress from stb_file.h for cmirror
  78. 1.81 various bugfixes, STB_FASTMALLOC_INIT inits FASTMALLOC in release
  79. 1.80 stb_readdir returns utf8; write own utf8-utf16 because lib was wrong
  80. 1.79 stb_write
  81. 1.78 calloc() support for malloc wrapper, STB_FASTMALLOC
  82. 1.77 STB_FASTMALLOC
  83. 1.76 STB_STUA - Lua-like language; (stb_image, stb_csample, stb_bilinear)
  84. 1.75 alloc/free array of blocks; stb_hheap bug; a few stb_ps_ funcs;
  85. hash*getkey, hash*copy; stb_bitset; stb_strnicmp; bugfix stb_bst
  86. 1.74 stb_replaceinplace; use stdlib C function to convert utf8 to UTF-16
  87. 1.73 fix performance bug & leak in stb_ischar (C++ port lost a 'static')
  88. 1.72 remove stb_block, stb_block_manager, stb_decompress (to stb_file.h)
  89. 1.71 stb_trimwhite, stb_tokens_nested, etc.
  90. 1.70 back out 1.69 because it might problemize mixed builds; stb_filec()
  91. 1.69 (stb_file returns 'char *' in C++)
  92. 1.68 add a special 'tree root' data type for stb_bst; stb_arr_end
  93. 1.67 full C++ port. (stb_block_manager)
  94. 1.66 stb_newell_normal
  95. 1.65 stb_lex_item_wild -- allow wildcard items which MUST match entirely
  96. 1.64 stb_data
  97. 1.63 stb_log_name
  98. 1.62 stb_define_sort; C++ cleanup
  99. 1.61 stb_hash_fast -- Paul Hsieh's hash function (beats Bob Jenkins'?)
  100. 1.60 stb_delete_directory_recursive
  101. 1.59 stb_readdir_recursive
  102. 1.58 stb_bst variant with parent pointer for O(1) iteration, not O(log N)
  103. 1.57 replace LCG random with Mersenne Twister (found a public domain one)
  104. 1.56 stb_perfect_hash, stb_ischar, stb_regex
  105. 1.55 new stb_bst API allows multiple BSTs per node (e.g. secondary keys)
  106. 1.54 bugfix: stb_define_hash, stb_wildmatch, regexp
  107. 1.53 stb_define_hash; recoded stb_extra, stb_sdict use it
  108. 1.52 stb_rand_define, stb_bst, stb_reverse
  109. 1.51 fix 'stb_arr_setlen(NULL, 0)'
  110. 1.50 stb_wordwrap
  111. 1.49 minor improvements to enable the scripting language
  112. 1.48 better approach for stb_arr using stb_malloc; more invasive, clearer
  113. 1.47 stb_lex (lexes stb.h at 1.5ML/s on 3Ghz P4; 60/70% of optimal/flex)
  114. 1.46 stb_wrapper_*, STB_MALLOC_WRAPPER
  115. 1.45 lightly tested DFA acceleration of regexp searching
  116. 1.44 wildcard matching & searching; regexp matching & searching
  117. 1.43 stb_temp
  118. 1.42 allow stb_arr to use stb_malloc/realloc; note this is global
  119. 1.41 make it compile in C++; (disable stb_arr in C++)
  120. 1.40 stb_dupe tweak; stb_swap; stb_substr
  121. 1.39 stb_dupe; improve stb_file_max to be less stupid
  122. 1.38 stb_sha1_file: generate sha1 for file, even > 4GB
  123. 1.37 stb_file_max; partial support for utf8 filenames in Windows
  124. 1.36 remove STB__NO_PREFIX - poor interaction with IDE, not worth it
  125. streamline stb_arr to make it separately publishable
  126. 1.35 bugfixes for stb_sdict, stb_malloc(0), stristr
  127. 1.34 (streaming interfaces for stb_compress)
  128. 1.33 stb_alloc; bug in stb_getopt; remove stb_overflow
  129. 1.32 (stb_compress returns, smaller&faster; encode window & 64-bit len)
  130. 1.31 stb_prefix_count
  131. 1.30 (STB__NO_PREFIX - remove stb_ prefixes for personal projects)
  132. 1.29 stb_fput_varlen64, etc.
  133. 1.28 stb_sha1
  134. 1.27 ?
  135. 1.26 stb_extra
  136. 1.25 ?
  137. 1.24 stb_copyfile
  138. 1.23 stb_readdir
  139. 1.22 ?
  140. 1.21 ?
  141. 1.20 ?
  142. 1.19 ?
  143. 1.18 ?
  144. 1.17 ?
  145. 1.16 ?
  146. 1.15 stb_fixpath, stb_splitpath, stb_strchr2
  147. 1.14 stb_arr
  148. 1.13 ?stb, stb_log, stb_fatal
  149. 1.12 ?stb_hash2
  150. 1.11 miniML
  151. 1.10 stb_crc32, stb_adler32
  152. 1.09 stb_sdict
  153. 1.08 stb_bitreverse, stb_ispow2, stb_big32
  154. stb_fopen, stb_fput_varlen, stb_fput_ranged
  155. stb_fcmp, stb_feq
  156. 1.07 (stb_encompress)
  157. 1.06 stb_compress
  158. 1.05 stb_tokens, (stb_hheap)
  159. 1.04 stb_rand
  160. 1.03 ?(s-strings)
  161. 1.02 ?stb_filelen, stb_tokens
  162. 1.01 stb_tolower
  163. 1.00 stb_hash, stb_intcmp
  164. stb_file, stb_stringfile, stb_fgets
  165. stb_prefix, stb_strlower, stb_strtok
  166. stb_image
  167. (stb_array), (stb_arena)
  168. Parenthesized items have since been removed.
  169. LICENSE
  170. See end of file for license information.
  171. CREDITS
  172. Written by Sean Barrett.
  173. Fixes:
  174. Philipp Wiesemann
  175. Robert Nix
  176. r-lyeh
  177. blackpawn
  178. github:Mojofreem
  179. Ryan Whitworth
  180. Vincent Isambart
  181. Mike Sartain
  182. Eugene Opalev
  183. Tim Sjostrand
  184. github:infatum
  185. Dave Butler (Croepha)
  186. Ethan Lee (flibitijibibo)
  187. Brian Collins
  188. Kyle Langley
  189. */
  190. #include <stdarg.h>
  191. #ifndef STB__INCLUDE_STB_H
  192. #define STB__INCLUDE_STB_H
  193. #define STB_VERSION 1
  194. #ifdef STB_INTROSPECT
  195. #define STB_DEFINE
  196. #endif
  197. #ifdef STB_DEFINE_THREADS
  198. #ifndef STB_DEFINE
  199. #define STB_DEFINE
  200. #endif
  201. #ifndef STB_THREADS
  202. #define STB_THREADS
  203. #endif
  204. #endif
  205. #if defined(_WIN32) && !defined(__MINGW32__)
  206. #ifndef _CRT_SECURE_NO_WARNINGS
  207. #define _CRT_SECURE_NO_WARNINGS
  208. #endif
  209. #ifndef _CRT_NONSTDC_NO_DEPRECATE
  210. #define _CRT_NONSTDC_NO_DEPRECATE
  211. #endif
  212. #ifndef _CRT_NON_CONFORMING_SWPRINTFS
  213. #define _CRT_NON_CONFORMING_SWPRINTFS
  214. #endif
  215. #if !defined(_MSC_VER) || _MSC_VER > 1700
  216. #include <intrin.h> // _BitScanReverse
  217. #endif
  218. #endif
  219. #include <stdlib.h> // stdlib could have min/max
  220. #include <stdio.h> // need FILE
  221. #include <string.h> // stb_define_hash needs memcpy/memset
  222. #include <time.h> // stb_dirtree
  223. #ifdef __MINGW32__
  224. #include <fcntl.h> // O_RDWR
  225. #endif
  226. #ifdef STB_PERSONAL
  227. typedef int Bool;
  228. #define False 0
  229. #define True 1
  230. #endif
  231. #ifdef STB_MALLOC_WRAPPER_PAGED
  232. #define STB_MALLOC_WRAPPER_DEBUG
  233. #endif
  234. #ifdef STB_MALLOC_WRAPPER_DEBUG
  235. #define STB_MALLOC_WRAPPER
  236. #endif
  237. #ifdef STB_MALLOC_WRAPPER_FASTMALLOC
  238. #define STB_FASTMALLOC
  239. #define STB_MALLOC_WRAPPER
  240. #endif
  241. #ifdef STB_FASTMALLOC
  242. #ifndef _WIN32
  243. #undef STB_FASTMALLOC
  244. #endif
  245. #endif
  246. #ifdef STB_DEFINE
  247. #include <assert.h>
  248. #include <stdarg.h>
  249. #include <stddef.h>
  250. #include <ctype.h>
  251. #include <math.h>
  252. #ifndef _WIN32
  253. #include <unistd.h>
  254. #else
  255. #include <io.h> // _mktemp
  256. #include <direct.h> // _rmdir
  257. #endif
  258. #include <sys/types.h> // stat()/_stat()
  259. #include <sys/stat.h> // stat()/_stat()
  260. #endif
  261. #define stb_min(a,b) ((a) < (b) ? (a) : (b))
  262. #define stb_max(a,b) ((a) > (b) ? (a) : (b))
  263. #ifndef STB_ONLY
  264. #if !defined(__cplusplus) && !defined(min) && !defined(max)
  265. #define min(x,y) stb_min(x,y)
  266. #define max(x,y) stb_max(x,y)
  267. #endif
  268. #ifndef M_PI
  269. #define M_PI 3.14159265358979323846f
  270. #endif
  271. #ifndef TRUE
  272. #define TRUE 1
  273. #define FALSE 0
  274. #endif
  275. #ifndef deg2rad
  276. #define deg2rad(a) ((a)*(M_PI/180))
  277. #endif
  278. #ifndef rad2deg
  279. #define rad2deg(a) ((a)*(180/M_PI))
  280. #endif
  281. #ifndef swap
  282. #ifndef __cplusplus
  283. #define swap(TYPE,a,b) \
  284. do { TYPE stb__t; stb__t = (a); (a) = (b); (b) = stb__t; } while (0)
  285. #endif
  286. #endif
  287. typedef unsigned char uint8 ;
  288. typedef signed char int8 ;
  289. typedef unsigned short uint16;
  290. typedef signed short int16;
  291. #if defined(STB_USE_LONG_FOR_32_BIT_INT) || defined(STB_LONG32)
  292. typedef unsigned long uint32;
  293. typedef signed long int32;
  294. #else
  295. typedef unsigned int uint32;
  296. typedef signed int int32;
  297. #endif
  298. typedef unsigned char uchar ;
  299. typedef unsigned short ushort;
  300. typedef unsigned int uint ;
  301. typedef unsigned long ulong ;
  302. // produce compile errors if the sizes aren't right
  303. typedef char stb__testsize16[sizeof(int16)==2];
  304. typedef char stb__testsize32[sizeof(int32)==4];
  305. #endif
  306. #ifndef STB_TRUE
  307. #define STB_TRUE 1
  308. #define STB_FALSE 0
  309. #endif
  310. // if we're STB_ONLY, can't rely on uint32 or even uint, so all the
  311. // variables we'll use herein need typenames prefixed with 'stb':
  312. typedef unsigned char stb_uchar;
  313. typedef unsigned char stb_uint8;
  314. typedef unsigned int stb_uint;
  315. typedef unsigned short stb_uint16;
  316. typedef short stb_int16;
  317. typedef signed char stb_int8;
  318. #if defined(STB_USE_LONG_FOR_32_BIT_INT) || defined(STB_LONG32)
  319. typedef unsigned long stb_uint32;
  320. typedef long stb_int32;
  321. #else
  322. typedef unsigned int stb_uint32;
  323. typedef int stb_int32;
  324. #endif
  325. typedef char stb__testsize2_16[sizeof(stb_uint16)==2 ? 1 : -1];
  326. typedef char stb__testsize2_32[sizeof(stb_uint32)==4 ? 1 : -1];
  327. #ifdef _MSC_VER
  328. typedef unsigned __int64 stb_uint64;
  329. typedef __int64 stb_int64;
  330. #define STB_IMM_UINT64(literalui64) (literalui64##ui64)
  331. #define STB_IMM_INT64(literali64) (literali64##i64)
  332. #else
  333. // ??
  334. typedef unsigned long long stb_uint64;
  335. typedef long long stb_int64;
  336. #define STB_IMM_UINT64(literalui64) (literalui64##ULL)
  337. #define STB_IMM_INT64(literali64) (literali64##LL)
  338. #endif
  339. typedef char stb__testsize2_64[sizeof(stb_uint64)==8 ? 1 : -1];
  340. // add platform-specific ways of checking for sizeof(char*) == 8,
  341. // and make those define STB_PTR64
  342. #if defined(_WIN64) || defined(__x86_64__) || defined(__ia64__) || defined(__LP64__)
  343. #define STB_PTR64
  344. #endif
  345. #ifdef STB_PTR64
  346. typedef char stb__testsize2_ptr[sizeof(char *) == 8];
  347. typedef stb_uint64 stb_uinta;
  348. typedef stb_int64 stb_inta;
  349. #else
  350. typedef char stb__testsize2_ptr[sizeof(char *) == 4];
  351. typedef stb_uint32 stb_uinta;
  352. typedef stb_int32 stb_inta;
  353. #endif
  354. typedef char stb__testsize2_uinta[sizeof(stb_uinta)==sizeof(char*) ? 1 : -1];
  355. // if so, we should define an int type that is the pointer size. until then,
  356. // we'll have to make do with this (which is not the same at all!)
  357. typedef union
  358. {
  359. unsigned int i;
  360. void * p;
  361. } stb_uintptr;
  362. #ifdef __cplusplus
  363. #define STB_EXTERN extern "C"
  364. #else
  365. #define STB_EXTERN extern
  366. #endif
  367. // check for well-known debug defines
  368. #if defined(DEBUG) || defined(_DEBUG) || defined(DBG)
  369. #ifndef NDEBUG
  370. #define STB_DEBUG
  371. #endif
  372. #endif
  373. #ifdef STB_DEBUG
  374. #include <assert.h>
  375. #endif
  376. //////////////////////////////////////////////////////////////////////////////
  377. //
  378. // C library function platform handling
  379. //
  380. #ifdef STB_DEFINE
  381. #if defined(_WIN32) && defined(__STDC_WANT_SECURE_LIB__)
  382. static FILE * stb_p_fopen(const char *filename, const char *mode)
  383. {
  384. FILE *f;
  385. if (0 == fopen_s(&f, filename, mode))
  386. return f;
  387. else
  388. return NULL;
  389. }
  390. static FILE * stb_p_wfopen(const wchar_t *filename, const wchar_t *mode)
  391. {
  392. FILE *f;
  393. if (0 == _wfopen_s(&f, filename, mode))
  394. return f;
  395. else
  396. return NULL;
  397. }
  398. static char *stb_p_strcpy_s(char *a, size_t size, const char *b)
  399. {
  400. strcpy_s(a,size,b);
  401. return a;
  402. }
  403. static char *stb_p_strncpy_s(char *a, size_t size, const char *b, size_t count)
  404. {
  405. strncpy_s(a,size,b,count);
  406. return a;
  407. }
  408. #define stb_p_mktemp(s) (_mktemp_s(s, strlen(s)+1) == 0)
  409. #define stb_p_sprintf sprintf_s
  410. #define stb_p_size(x) ,(x)
  411. #else
  412. #define stb_p_fopen fopen
  413. #define stb_p_wfopen _wfopen
  414. #define stb_p_strcpy_s(a,s,b) strcpy(a,b)
  415. #define stb_p_strncpy_s(a,s,b,c) strncpy(a,b,c)
  416. #define stb_p_mktemp(s) (mktemp(s) != NULL)
  417. #define stb_p_sprintf sprintf
  418. #define stb_p_size(x)
  419. #endif
  420. #if defined(_WIN32)
  421. #define stb_p_vsnprintf _vsnprintf
  422. #else
  423. #define stb_p_vsnprintf vsnprintf
  424. #endif
  425. #endif // STB_DEFINE
  426. #if defined(_WIN32) && (_MSC_VER >= 1300)
  427. #define stb_p_stricmp _stricmp
  428. #define stb_p_strnicmp _strnicmp
  429. #define stb_p_strdup _strdup
  430. #else
  431. #define stb_p_strdup strdup
  432. #define stb_p_stricmp stricmp
  433. #define stb_p_strnicmp strnicmp
  434. #endif
  435. STB_EXTERN void stb_wrapper_malloc(void *newp, size_t sz, char *file, int line);
  436. STB_EXTERN void stb_wrapper_free(void *oldp, char *file, int line);
  437. STB_EXTERN void stb_wrapper_realloc(void *oldp, void *newp, size_t sz, char *file, int line);
  438. STB_EXTERN void stb_wrapper_calloc(size_t num, size_t sz, char *file, int line);
  439. STB_EXTERN void stb_wrapper_listall(void (*func)(void *ptr, size_t sz, char *file, int line));
  440. STB_EXTERN void stb_wrapper_dump(char *filename);
  441. STB_EXTERN size_t stb_wrapper_allocsize(void *oldp);
  442. STB_EXTERN void stb_wrapper_check(void *oldp);
  443. #ifdef STB_DEFINE
  444. // this is a special function used inside malloc wrapper
  445. // to do allocations that aren't tracked (to avoid
  446. // reentrancy). Of course if someone _else_ wraps realloc,
  447. // this breaks, but if they're doing that AND the malloc
  448. // wrapper they need to explicitly check for reentrancy.
  449. //
  450. // only define realloc_raw() and we do realloc(NULL,sz)
  451. // for malloc() and realloc(p,0) for free().
  452. static void * stb__realloc_raw(void *p, int sz)
  453. {
  454. if (p == NULL) return malloc(sz);
  455. if (sz == 0) { free(p); return NULL; }
  456. return realloc(p,sz);
  457. }
  458. #endif
  459. #ifdef _WIN32
  460. STB_EXTERN void * stb_smalloc(size_t sz);
  461. STB_EXTERN void stb_sfree(void *p);
  462. STB_EXTERN void * stb_srealloc(void *p, size_t sz);
  463. STB_EXTERN void * stb_scalloc(size_t n, size_t sz);
  464. STB_EXTERN char * stb_sstrdup(char *s);
  465. #endif
  466. #ifdef STB_FASTMALLOC
  467. #define malloc stb_smalloc
  468. #define free stb_sfree
  469. #define realloc stb_srealloc
  470. #define strdup stb_sstrdup
  471. #define calloc stb_scalloc
  472. #endif
  473. #ifndef STB_MALLOC_ALLCHECK
  474. #define stb__check(p) 1
  475. #else
  476. #ifndef STB_MALLOC_WRAPPER
  477. #error STB_MALLOC_ALLCHECK requires STB_MALLOC_WRAPPER
  478. #else
  479. #define stb__check(p) stb_mcheck(p)
  480. #endif
  481. #endif
  482. #ifdef STB_MALLOC_WRAPPER
  483. STB_EXTERN void * stb__malloc(size_t, char *, int);
  484. STB_EXTERN void * stb__realloc(void *, size_t, char *, int);
  485. STB_EXTERN void * stb__calloc(size_t n, size_t s, char *, int);
  486. STB_EXTERN void stb__free(void *, char *file, int);
  487. STB_EXTERN char * stb__strdup(char *s, char *file, int);
  488. STB_EXTERN void stb_malloc_checkall(void);
  489. STB_EXTERN void stb_malloc_check_counter(int init_delay, int rep_delay);
  490. #ifndef STB_MALLOC_WRAPPER_DEBUG
  491. #define stb_mcheck(p) 1
  492. #else
  493. STB_EXTERN int stb_mcheck(void *);
  494. #endif
  495. #ifdef STB_DEFINE
  496. #ifdef STB_MALLOC_WRAPPER_DEBUG
  497. #define STB__PAD 32
  498. #define STB__BIAS 16
  499. #define STB__SIG 0x51b01234
  500. #define STB__FIXSIZE(sz) (((sz+3) & ~3) + STB__PAD)
  501. #define STB__ptr(x,y) ((char *) (x) + (y))
  502. #else
  503. #define STB__ptr(x,y) (x)
  504. #define STB__FIXSIZE(sz) (sz)
  505. #endif
  506. #ifdef STB_MALLOC_WRAPPER_DEBUG
  507. int stb_mcheck(void *p)
  508. {
  509. unsigned int sz;
  510. if (p == NULL) return 1;
  511. p = ((char *) p) - STB__BIAS;
  512. sz = * (unsigned int *) p;
  513. assert(* (unsigned int *) STB__ptr(p,4) == STB__SIG);
  514. assert(* (unsigned int *) STB__ptr(p,8) == STB__SIG);
  515. assert(* (unsigned int *) STB__ptr(p,12) == STB__SIG);
  516. assert(* (unsigned int *) STB__ptr(p,sz-4) == STB__SIG+1);
  517. assert(* (unsigned int *) STB__ptr(p,sz-8) == STB__SIG+1);
  518. assert(* (unsigned int *) STB__ptr(p,sz-12) == STB__SIG+1);
  519. assert(* (unsigned int *) STB__ptr(p,sz-16) == STB__SIG+1);
  520. stb_wrapper_check(STB__ptr(p, STB__BIAS));
  521. return 1;
  522. }
  523. static void stb__check2(void *p, size_t sz, char *file, int line)
  524. {
  525. stb_mcheck(p);
  526. }
  527. void stb_malloc_checkall(void)
  528. {
  529. stb_wrapper_listall(stb__check2);
  530. }
  531. #else
  532. void stb_malloc_checkall(void) { }
  533. #endif
  534. static int stb__malloc_wait=(1 << 30), stb__malloc_next_wait = (1 << 30), stb__malloc_iter;
  535. void stb_malloc_check_counter(int init_delay, int rep_delay)
  536. {
  537. stb__malloc_wait = init_delay;
  538. stb__malloc_next_wait = rep_delay;
  539. }
  540. void stb_mcheck_all(void)
  541. {
  542. #ifdef STB_MALLOC_WRAPPER_DEBUG
  543. ++stb__malloc_iter;
  544. if (--stb__malloc_wait <= 0) {
  545. stb_malloc_checkall();
  546. stb__malloc_wait = stb__malloc_next_wait;
  547. }
  548. #endif
  549. }
  550. #ifdef STB_MALLOC_WRAPPER_PAGED
  551. #define STB__WINDOWS_PAGE (1 << 12)
  552. #ifndef _WINDOWS_
  553. STB_EXTERN __declspec(dllimport) void * __stdcall VirtualAlloc(void *p, unsigned long size, unsigned long type, unsigned long protect);
  554. STB_EXTERN __declspec(dllimport) int __stdcall VirtualFree(void *p, unsigned long size, unsigned long freetype);
  555. #endif
  556. #endif
  557. static void *stb__malloc_final(size_t sz)
  558. {
  559. #ifdef STB_MALLOC_WRAPPER_PAGED
  560. size_t aligned = (sz + STB__WINDOWS_PAGE - 1) & ~(STB__WINDOWS_PAGE-1);
  561. char *p = VirtualAlloc(NULL, aligned + STB__WINDOWS_PAGE, 0x2000, 0x04); // RESERVE, READWRITE
  562. if (p == NULL) return p;
  563. VirtualAlloc(p, aligned, 0x1000, 0x04); // COMMIT, READWRITE
  564. return p;
  565. #else
  566. return malloc(sz);
  567. #endif
  568. }
  569. static void stb__free_final(void *p)
  570. {
  571. #ifdef STB_MALLOC_WRAPPER_PAGED
  572. VirtualFree(p, 0, 0x8000); // RELEASE
  573. #else
  574. free(p);
  575. #endif
  576. }
  577. int stb__malloc_failure;
  578. #ifdef STB_MALLOC_WRAPPER_PAGED
  579. static void *stb__realloc_final(void *p, size_t sz, size_t old_sz)
  580. {
  581. void *q = stb__malloc_final(sz);
  582. if (q == NULL)
  583. return ++stb__malloc_failure, q;
  584. // @TODO: deal with p being smaller!
  585. memcpy(q, p, sz < old_sz ? sz : old_sz);
  586. stb__free_final(p);
  587. return q;
  588. }
  589. #endif
  590. void stb__free(void *p, char *file, int line)
  591. {
  592. stb_mcheck_all();
  593. if (!p) return;
  594. #ifdef STB_MALLOC_WRAPPER_DEBUG
  595. stb_mcheck(p);
  596. #endif
  597. stb_wrapper_free(p,file,line);
  598. #ifdef STB_MALLOC_WRAPPER_DEBUG
  599. p = STB__ptr(p,-STB__BIAS);
  600. * (unsigned int *) STB__ptr(p,0) = 0xdeadbeef;
  601. * (unsigned int *) STB__ptr(p,4) = 0xdeadbeef;
  602. * (unsigned int *) STB__ptr(p,8) = 0xdeadbeef;
  603. * (unsigned int *) STB__ptr(p,12) = 0xdeadbeef;
  604. #endif
  605. stb__free_final(p);
  606. }
  607. void * stb__malloc(size_t sz, char *file, int line)
  608. {
  609. void *p;
  610. stb_mcheck_all();
  611. if (sz == 0) return NULL;
  612. p = stb__malloc_final(STB__FIXSIZE(sz));
  613. if (p == NULL) p = stb__malloc_final(STB__FIXSIZE(sz));
  614. if (p == NULL) p = stb__malloc_final(STB__FIXSIZE(sz));
  615. if (p == NULL) {
  616. ++stb__malloc_failure;
  617. #ifdef STB_MALLOC_WRAPPER_DEBUG
  618. stb_malloc_checkall();
  619. #endif
  620. return p;
  621. }
  622. #ifdef STB_MALLOC_WRAPPER_DEBUG
  623. * (int *) STB__ptr(p,0) = STB__FIXSIZE(sz);
  624. * (unsigned int *) STB__ptr(p,4) = STB__SIG;
  625. * (unsigned int *) STB__ptr(p,8) = STB__SIG;
  626. * (unsigned int *) STB__ptr(p,12) = STB__SIG;
  627. * (unsigned int *) STB__ptr(p,STB__FIXSIZE(sz)-4) = STB__SIG+1;
  628. * (unsigned int *) STB__ptr(p,STB__FIXSIZE(sz)-8) = STB__SIG+1;
  629. * (unsigned int *) STB__ptr(p,STB__FIXSIZE(sz)-12) = STB__SIG+1;
  630. * (unsigned int *) STB__ptr(p,STB__FIXSIZE(sz)-16) = STB__SIG+1;
  631. p = STB__ptr(p, STB__BIAS);
  632. #endif
  633. stb_wrapper_malloc(p,sz,file,line);
  634. return p;
  635. }
  636. void * stb__realloc(void *p, size_t sz, char *file, int line)
  637. {
  638. void *q;
  639. stb_mcheck_all();
  640. if (p == NULL) return stb__malloc(sz,file,line);
  641. if (sz == 0 ) { stb__free(p,file,line); return NULL; }
  642. #ifdef STB_MALLOC_WRAPPER_DEBUG
  643. stb_mcheck(p);
  644. p = STB__ptr(p,-STB__BIAS);
  645. #endif
  646. #ifdef STB_MALLOC_WRAPPER_PAGED
  647. {
  648. size_t n = stb_wrapper_allocsize(STB__ptr(p,STB__BIAS));
  649. if (!n)
  650. stb_wrapper_check(STB__ptr(p,STB__BIAS));
  651. q = stb__realloc_final(p, STB__FIXSIZE(sz), STB__FIXSIZE(n));
  652. }
  653. #else
  654. q = realloc(p, STB__FIXSIZE(sz));
  655. #endif
  656. if (q == NULL)
  657. return ++stb__malloc_failure, q;
  658. #ifdef STB_MALLOC_WRAPPER_DEBUG
  659. * (int *) STB__ptr(q,0) = STB__FIXSIZE(sz);
  660. * (unsigned int *) STB__ptr(q,4) = STB__SIG;
  661. * (unsigned int *) STB__ptr(q,8) = STB__SIG;
  662. * (unsigned int *) STB__ptr(q,12) = STB__SIG;
  663. * (unsigned int *) STB__ptr(q,STB__FIXSIZE(sz)-4) = STB__SIG+1;
  664. * (unsigned int *) STB__ptr(q,STB__FIXSIZE(sz)-8) = STB__SIG+1;
  665. * (unsigned int *) STB__ptr(q,STB__FIXSIZE(sz)-12) = STB__SIG+1;
  666. * (unsigned int *) STB__ptr(q,STB__FIXSIZE(sz)-16) = STB__SIG+1;
  667. q = STB__ptr(q, STB__BIAS);
  668. p = STB__ptr(p, STB__BIAS);
  669. #endif
  670. stb_wrapper_realloc(p,q,sz,file,line);
  671. return q;
  672. }
  673. STB_EXTERN int stb_log2_ceil(size_t);
  674. static void *stb__calloc(size_t n, size_t sz, char *file, int line)
  675. {
  676. void *q;
  677. stb_mcheck_all();
  678. if (n == 0 || sz == 0) return NULL;
  679. if (stb_log2_ceil(n) + stb_log2_ceil(sz) >= 32) return NULL;
  680. q = stb__malloc(n*sz, file, line);
  681. if (q) memset(q, 0, n*sz);
  682. return q;
  683. }
  684. char * stb__strdup(char *s, char *file, int line)
  685. {
  686. char *p;
  687. stb_mcheck_all();
  688. p = stb__malloc(strlen(s)+1, file, line);
  689. if (!p) return p;
  690. stb_p_strcpy_s(p, strlen(s)+1, s);
  691. return p;
  692. }
  693. #endif // STB_DEFINE
  694. #ifdef STB_FASTMALLOC
  695. #undef malloc
  696. #undef realloc
  697. #undef free
  698. #undef strdup
  699. #undef calloc
  700. #endif
  701. // include everything that might define these, BEFORE making macros
  702. #include <stdlib.h>
  703. #include <string.h>
  704. #include <malloc.h>
  705. #define malloc(s) stb__malloc ( s, __FILE__, __LINE__)
  706. #define realloc(p,s) stb__realloc(p,s, __FILE__, __LINE__)
  707. #define calloc(n,s) stb__calloc (n,s, __FILE__, __LINE__)
  708. #define free(p) stb__free (p, __FILE__, __LINE__)
  709. #define strdup(p) stb__strdup (p, __FILE__, __LINE__)
  710. #endif
  711. //////////////////////////////////////////////////////////////////////////////
  712. //
  713. // Windows pretty display
  714. //
  715. STB_EXTERN void stbprint(const char *fmt, ...);
  716. STB_EXTERN char *stb_sprintf(const char *fmt, ...);
  717. STB_EXTERN char *stb_mprintf(const char *fmt, ...);
  718. STB_EXTERN int stb_snprintf(char *s, size_t n, const char *fmt, ...);
  719. STB_EXTERN int stb_vsnprintf(char *s, size_t n, const char *fmt, va_list v);
  720. #ifdef STB_DEFINE
  721. int stb_vsnprintf(char *s, size_t n, const char *fmt, va_list v)
  722. {
  723. int res;
  724. #ifdef _WIN32
  725. #ifdef __STDC_WANT_SECURE_LIB__
  726. res = _vsnprintf_s(s, n, _TRUNCATE, fmt, v);
  727. #else
  728. res = stb_p_vsnprintf(s,n,fmt,v);
  729. #endif
  730. #else
  731. res = vsnprintf(s,n,fmt,v);
  732. #endif
  733. if (n) s[n-1] = 0;
  734. // Unix returns length output would require, Windows returns negative when truncated.
  735. return (res >= (int) n || res < 0) ? -1 : res;
  736. }
  737. int stb_snprintf(char *s, size_t n, const char *fmt, ...)
  738. {
  739. int res;
  740. va_list v;
  741. va_start(v,fmt);
  742. res = stb_vsnprintf(s, n, fmt, v);
  743. va_end(v);
  744. return res;
  745. }
  746. char *stb_sprintf(const char *fmt, ...)
  747. {
  748. static char buffer[1024];
  749. va_list v;
  750. va_start(v,fmt);
  751. stb_vsnprintf(buffer,1024,fmt,v);
  752. va_end(v);
  753. return buffer;
  754. }
  755. char *stb_mprintf(const char *fmt, ...)
  756. {
  757. static char buffer[1024];
  758. va_list v;
  759. va_start(v,fmt);
  760. stb_vsnprintf(buffer,1024,fmt,v);
  761. va_end(v);
  762. return stb_p_strdup(buffer);
  763. }
  764. #ifdef _WIN32
  765. #ifndef _WINDOWS_
  766. STB_EXTERN __declspec(dllimport) int __stdcall WriteConsoleA(void *, const void *, unsigned int, unsigned int *, void *);
  767. STB_EXTERN __declspec(dllimport) void * __stdcall GetStdHandle(unsigned int);
  768. STB_EXTERN __declspec(dllimport) int __stdcall SetConsoleTextAttribute(void *, unsigned short);
  769. #endif
  770. static void stb__print_one(void *handle, char *s, ptrdiff_t len)
  771. {
  772. if (len)
  773. if (0==WriteConsoleA(handle, s, (unsigned) len, NULL,NULL))
  774. // if it fails, maybe redirected, so output normally...
  775. // but it's supriously reporting failure now on Win7 and later
  776. {}//fwrite(s, 1, (unsigned) len, stdout);
  777. }
  778. static void stb__print(char *s)
  779. {
  780. void *handle = GetStdHandle((unsigned int) -11); // STD_OUTPUT_HANDLE
  781. int pad=0; // number of padding characters to add
  782. char *t = s;
  783. while (*s) {
  784. int lpad;
  785. while (*s && *s != '{') {
  786. if (pad) {
  787. if (*s == '\r' || *s == '\n')
  788. pad = 0;
  789. else if (s[0] == ' ' && s[1] == ' ') {
  790. stb__print_one(handle, t, s-t);
  791. t = s;
  792. while (pad) {
  793. stb__print_one(handle, t, 1);
  794. --pad;
  795. }
  796. }
  797. }
  798. ++s;
  799. }
  800. if (!*s) break;
  801. stb__print_one(handle, t, s-t);
  802. if (s[1] == '{') {
  803. ++s;
  804. continue;
  805. }
  806. if (s[1] == '#') {
  807. t = s+3;
  808. if (isxdigit(s[2]))
  809. if (isdigit(s[2]))
  810. SetConsoleTextAttribute(handle, s[2] - '0');
  811. else
  812. SetConsoleTextAttribute(handle, tolower(s[2]) - 'a' + 10);
  813. else {
  814. SetConsoleTextAttribute(handle, 0x0f);
  815. t=s+2;
  816. }
  817. } else if (s[1] == '!') {
  818. SetConsoleTextAttribute(handle, 0x0c);
  819. t = s+2;
  820. } else if (s[1] == '@') {
  821. SetConsoleTextAttribute(handle, 0x09);
  822. t = s+2;
  823. } else if (s[1] == '$') {
  824. SetConsoleTextAttribute(handle, 0x0a);
  825. t = s+2;
  826. } else {
  827. SetConsoleTextAttribute(handle, 0x08); // 0,7,8,15 => shades of grey
  828. t = s+1;
  829. }
  830. lpad = (int) (t-s);
  831. s = t;
  832. while (*s && *s != '}') ++s;
  833. if (!*s) break;
  834. stb__print_one(handle, t, s-t);
  835. if (s[1] == '}') {
  836. t = s+2;
  837. } else {
  838. pad += 1+lpad;
  839. t = s+1;
  840. }
  841. s=t;
  842. SetConsoleTextAttribute(handle, 0x07);
  843. }
  844. stb__print_one(handle, t, s-t);
  845. SetConsoleTextAttribute(handle, 0x07);
  846. }
  847. void stbprint(const char *fmt, ...)
  848. {
  849. int res;
  850. char buffer[1024];
  851. char *tbuf = buffer;
  852. va_list v;
  853. va_start(v,fmt);
  854. res = stb_vsnprintf(buffer, sizeof(buffer), fmt, v);
  855. va_end(v);
  856. if (res < 0) {
  857. tbuf = (char *) malloc(16384);
  858. va_start(v,fmt);
  859. res = stb_vsnprintf(tbuf,16384, fmt, v);
  860. va_end(v);
  861. tbuf[16383] = 0;
  862. }
  863. stb__print(tbuf);
  864. if (tbuf != buffer)
  865. free(tbuf);
  866. }
  867. #else // _WIN32
  868. void stbprint(const char *fmt, ...)
  869. {
  870. va_list v;
  871. va_start(v,fmt);
  872. vprintf(fmt,v);
  873. va_end(v);
  874. }
  875. #endif // _WIN32
  876. #endif // STB_DEFINE
  877. //////////////////////////////////////////////////////////////////////////////
  878. //
  879. // Windows UTF8 filename handling
  880. //
  881. // Windows stupidly treats 8-bit filenames as some dopey code page,
  882. // rather than utf-8. If we want to use utf8 filenames, we have to
  883. // convert them to WCHAR explicitly and call WCHAR versions of the
  884. // file functions. So, ok, we do.
  885. #ifdef _WIN32
  886. #define stb__fopen(x,y) stb_p_wfopen((const wchar_t *)stb__from_utf8(x), (const wchar_t *)stb__from_utf8_alt(y))
  887. #define stb__windows(x,y) x
  888. #else
  889. #define stb__fopen(x,y) stb_p_fopen(x,y)
  890. #define stb__windows(x,y) y
  891. #endif
  892. typedef unsigned short stb__wchar;
  893. STB_EXTERN stb__wchar * stb_from_utf8(stb__wchar *buffer, const char *str, int n);
  894. STB_EXTERN char * stb_to_utf8 (char *buffer, const stb__wchar *str, int n);
  895. STB_EXTERN stb__wchar *stb__from_utf8(const char *str);
  896. STB_EXTERN stb__wchar *stb__from_utf8_alt(const char *str);
  897. STB_EXTERN char *stb__to_utf8(const stb__wchar *str);
  898. #ifdef STB_DEFINE
  899. stb__wchar * stb_from_utf8(stb__wchar *buffer, const char *ostr, int n)
  900. {
  901. unsigned char *str = (unsigned char *) ostr;
  902. stb_uint32 c;
  903. int i=0;
  904. --n;
  905. while (*str) {
  906. if (i >= n)
  907. return NULL;
  908. if (!(*str & 0x80))
  909. buffer[i++] = *str++;
  910. else if ((*str & 0xe0) == 0xc0) {
  911. if (*str < 0xc2) return NULL;
  912. c = (*str++ & 0x1f) << 6;
  913. if ((*str & 0xc0) != 0x80) return NULL;
  914. buffer[i++] = c + (*str++ & 0x3f);
  915. } else if ((*str & 0xf0) == 0xe0) {
  916. if (*str == 0xe0 && (str[1] < 0xa0 || str[1] > 0xbf)) return NULL;
  917. if (*str == 0xed && str[1] > 0x9f) return NULL; // str[1] < 0x80 is checked below
  918. c = (*str++ & 0x0f) << 12;
  919. if ((*str & 0xc0) != 0x80) return NULL;
  920. c += (*str++ & 0x3f) << 6;
  921. if ((*str & 0xc0) != 0x80) return NULL;
  922. buffer[i++] = c + (*str++ & 0x3f);
  923. } else if ((*str & 0xf8) == 0xf0) {
  924. if (*str > 0xf4) return NULL;
  925. if (*str == 0xf0 && (str[1] < 0x90 || str[1] > 0xbf)) return NULL;
  926. if (*str == 0xf4 && str[1] > 0x8f) return NULL; // str[1] < 0x80 is checked below
  927. c = (*str++ & 0x07) << 18;
  928. if ((*str & 0xc0) != 0x80) return NULL;
  929. c += (*str++ & 0x3f) << 12;
  930. if ((*str & 0xc0) != 0x80) return NULL;
  931. c += (*str++ & 0x3f) << 6;
  932. if ((*str & 0xc0) != 0x80) return NULL;
  933. c += (*str++ & 0x3f);
  934. // utf-8 encodings of values used in surrogate pairs are invalid
  935. if ((c & 0xFFFFF800) == 0xD800) return NULL;
  936. if (c >= 0x10000) {
  937. c -= 0x10000;
  938. if (i + 2 > n) return NULL;
  939. buffer[i++] = 0xD800 | (0x3ff & (c >> 10));
  940. buffer[i++] = 0xDC00 | (0x3ff & (c ));
  941. }
  942. } else
  943. return NULL;
  944. }
  945. buffer[i] = 0;
  946. return buffer;
  947. }
  948. char * stb_to_utf8(char *buffer, const stb__wchar *str, int n)
  949. {
  950. int i=0;
  951. --n;
  952. while (*str) {
  953. if (*str < 0x80) {
  954. if (i+1 > n) return NULL;
  955. buffer[i++] = (char) *str++;
  956. } else if (*str < 0x800) {
  957. if (i+2 > n) return NULL;
  958. buffer[i++] = 0xc0 + (*str >> 6);
  959. buffer[i++] = 0x80 + (*str & 0x3f);
  960. str += 1;
  961. } else if (*str >= 0xd800 && *str < 0xdc00) {
  962. stb_uint32 c;
  963. if (i+4 > n) return NULL;
  964. c = ((str[0] - 0xd800) << 10) + ((str[1]) - 0xdc00) + 0x10000;
  965. buffer[i++] = 0xf0 + (c >> 18);
  966. buffer[i++] = 0x80 + ((c >> 12) & 0x3f);
  967. buffer[i++] = 0x80 + ((c >> 6) & 0x3f);
  968. buffer[i++] = 0x80 + ((c ) & 0x3f);
  969. str += 2;
  970. } else if (*str >= 0xdc00 && *str < 0xe000) {
  971. return NULL;
  972. } else {
  973. if (i+3 > n) return NULL;
  974. buffer[i++] = 0xe0 + (*str >> 12);
  975. buffer[i++] = 0x80 + ((*str >> 6) & 0x3f);
  976. buffer[i++] = 0x80 + ((*str ) & 0x3f);
  977. str += 1;
  978. }
  979. }
  980. buffer[i] = 0;
  981. return buffer;
  982. }
  983. stb__wchar *stb__from_utf8(const char *str)
  984. {
  985. static stb__wchar buffer[4096];
  986. return stb_from_utf8(buffer, str, 4096);
  987. }
  988. stb__wchar *stb__from_utf8_alt(const char *str)
  989. {
  990. static stb__wchar buffer[4096];
  991. return stb_from_utf8(buffer, str, 4096);
  992. }
  993. char *stb__to_utf8(const stb__wchar *str)
  994. {
  995. static char buffer[4096];
  996. return stb_to_utf8(buffer, str, 4096);
  997. }
  998. #endif
  999. //////////////////////////////////////////////////////////////////////////////
  1000. //
  1001. // Miscellany
  1002. //
  1003. STB_EXTERN void stb_fatal(const char *fmt, ...);
  1004. STB_EXTERN void stb_(char *fmt, ...);
  1005. STB_EXTERN void stb_append_to_file(char *file, char *fmt, ...);
  1006. STB_EXTERN void stb_log(int active);
  1007. STB_EXTERN void stb_log_fileline(int active);
  1008. STB_EXTERN void stb_log_name(char *filename);
  1009. STB_EXTERN void stb_swap(void *p, void *q, size_t sz);
  1010. STB_EXTERN void *stb_copy(void *p, size_t sz);
  1011. STB_EXTERN void stb_pointer_array_free(void *p, int len);
  1012. STB_EXTERN void **stb_array_block_alloc(int count, int blocksize);
  1013. #define stb_arrcount(x) (sizeof(x)/sizeof((x)[0]))
  1014. STB_EXTERN int stb__record_fileline(const char *f, int n);
  1015. #ifdef STB_DEFINE
  1016. static char *stb__file;
  1017. static int stb__line;
  1018. int stb__record_fileline(const char *f, int n)
  1019. {
  1020. stb__file = (char*) f;
  1021. stb__line = n;
  1022. return 0;
  1023. }
  1024. void stb_fatal(const char *s, ...)
  1025. {
  1026. va_list a;
  1027. if (stb__file)
  1028. fprintf(stderr, "[%s:%d] ", stb__file, stb__line);
  1029. va_start(a,s);
  1030. fputs("Fatal error: ", stderr);
  1031. vfprintf(stderr, s, a);
  1032. va_end(a);
  1033. fputs("\n", stderr);
  1034. #ifdef STB_DEBUG
  1035. #ifdef _MSC_VER
  1036. #ifndef STB_PTR64
  1037. __asm int 3; // trap to debugger!
  1038. #else
  1039. __debugbreak();
  1040. #endif
  1041. #else
  1042. __builtin_trap();
  1043. #endif
  1044. #endif
  1045. exit(1);
  1046. }
  1047. static int stb__log_active=1, stb__log_fileline=1;
  1048. void stb_log(int active)
  1049. {
  1050. stb__log_active = active;
  1051. }
  1052. void stb_log_fileline(int active)
  1053. {
  1054. stb__log_fileline = active;
  1055. }
  1056. #ifdef STB_NO_STB_STRINGS
  1057. const char *stb__log_filename = "temp.log";
  1058. #else
  1059. const char *stb__log_filename = "stb.log";
  1060. #endif
  1061. void stb_log_name(char *s)
  1062. {
  1063. stb__log_filename = s;
  1064. }
  1065. void stb_(char *s, ...)
  1066. {
  1067. if (stb__log_active) {
  1068. FILE *f = stb_p_fopen(stb__log_filename, "a");
  1069. if (f) {
  1070. va_list a;
  1071. if (stb__log_fileline && stb__file)
  1072. fprintf(f, "[%s:%4d] ", stb__file, stb__line);
  1073. va_start(a,s);
  1074. vfprintf(f, s, a);
  1075. va_end(a);
  1076. fputs("\n", f);
  1077. fclose(f);
  1078. }
  1079. }
  1080. }
  1081. void stb_append_to_file(char *filename, char *s, ...)
  1082. {
  1083. FILE *f = stb_p_fopen(filename, "a");
  1084. if (f) {
  1085. va_list a;
  1086. va_start(a,s);
  1087. vfprintf(f, s, a);
  1088. va_end(a);
  1089. fputs("\n", f);
  1090. fclose(f);
  1091. }
  1092. }
  1093. typedef struct { char d[4]; } stb__4;
  1094. typedef struct { char d[8]; } stb__8;
  1095. // optimize the small cases, though you shouldn't be calling this for those!
  1096. void stb_swap(void *p, void *q, size_t sz)
  1097. {
  1098. char buffer[256];
  1099. if (p == q) return;
  1100. if (sz == 4) {
  1101. stb__4 temp = * ( stb__4 *) p;
  1102. * (stb__4 *) p = * ( stb__4 *) q;
  1103. * (stb__4 *) q = temp;
  1104. return;
  1105. } else if (sz == 8) {
  1106. stb__8 temp = * ( stb__8 *) p;
  1107. * (stb__8 *) p = * ( stb__8 *) q;
  1108. * (stb__8 *) q = temp;
  1109. return;
  1110. }
  1111. while (sz > sizeof(buffer)) {
  1112. stb_swap(p, q, sizeof(buffer));
  1113. p = (char *) p + sizeof(buffer);
  1114. q = (char *) q + sizeof(buffer);
  1115. sz -= sizeof(buffer);
  1116. }
  1117. memcpy(buffer, p , sz);
  1118. memcpy(p , q , sz);
  1119. memcpy(q , buffer, sz);
  1120. }
  1121. void *stb_copy(void *p, size_t sz)
  1122. {
  1123. void *q = malloc(sz);
  1124. memcpy(q, p, sz);
  1125. return q;
  1126. }
  1127. void stb_pointer_array_free(void *q, int len)
  1128. {
  1129. void **p = (void **) q;
  1130. int i;
  1131. for (i=0; i < len; ++i)
  1132. free(p[i]);
  1133. }
  1134. void **stb_array_block_alloc(int count, int blocksize)
  1135. {
  1136. int i;
  1137. char *p = (char *) malloc(sizeof(void *) * count + count * blocksize);
  1138. void **q;
  1139. if (p == NULL) return NULL;
  1140. q = (void **) p;
  1141. p += sizeof(void *) * count;
  1142. for (i=0; i < count; ++i)
  1143. q[i] = p + i * blocksize;
  1144. return q;
  1145. }
  1146. #endif
  1147. #ifdef STB_DEBUG
  1148. // tricky hack to allow recording FILE,LINE even in varargs functions
  1149. #define STB__RECORD_FILE(x) (stb__record_fileline(__FILE__, __LINE__),(x))
  1150. #define stb_log STB__RECORD_FILE(stb_log)
  1151. #define stb_ STB__RECORD_FILE(stb_)
  1152. #ifndef STB_FATAL_CLEAN
  1153. #define stb_fatal STB__RECORD_FILE(stb_fatal)
  1154. #endif
  1155. #define STB__DEBUG(x) x
  1156. #else
  1157. #define STB__DEBUG(x)
  1158. #endif
  1159. //////////////////////////////////////////////////////////////////////////////
  1160. //
  1161. // stb_temp
  1162. //
  1163. #define stb_temp(block, sz) stb__temp(block, sizeof(block), (sz))
  1164. STB_EXTERN void * stb__temp(void *b, int b_sz, int want_sz);
  1165. STB_EXTERN void stb_tempfree(void *block, void *ptr);
  1166. #ifdef STB_DEFINE
  1167. void * stb__temp(void *b, int b_sz, int want_sz)
  1168. {
  1169. if (b_sz >= want_sz)
  1170. return b;
  1171. else
  1172. return malloc(want_sz);
  1173. }
  1174. void stb_tempfree(void *b, void *p)
  1175. {
  1176. if (p != b)
  1177. free(p);
  1178. }
  1179. #endif
  1180. //////////////////////////////////////////////////////////////////////////////
  1181. //
  1182. // math/sampling operations
  1183. //
  1184. #define stb_lerp(t,a,b) ( (a) + (t) * (float) ((b)-(a)) )
  1185. #define stb_unlerp(t,a,b) ( ((t) - (a)) / (float) ((b) - (a)) )
  1186. #define stb_clamp(x,xmin,xmax) ((x) < (xmin) ? (xmin) : (x) > (xmax) ? (xmax) : (x))
  1187. STB_EXTERN void stb_newell_normal(float *normal, int num_vert, float **vert, int normalize);
  1188. STB_EXTERN int stb_box_face_vertex_axis_side(int face_number, int vertex_number, int axis);
  1189. STB_EXTERN void stb_linear_controller(float *curpos, float target_pos, float acc, float deacc, float dt);
  1190. STB_EXTERN int stb_float_eq(float x, float y, float delta, int max_ulps);
  1191. STB_EXTERN int stb_is_prime(unsigned int m);
  1192. STB_EXTERN unsigned int stb_power_of_two_nearest_prime(int n);
  1193. STB_EXTERN float stb_smoothstep(float t);
  1194. STB_EXTERN float stb_cubic_bezier_1d(float t, float p0, float p1, float p2, float p3);
  1195. STB_EXTERN double stb_linear_remap(double x, double a, double b,
  1196. double c, double d);
  1197. #ifdef STB_DEFINE
  1198. float stb_smoothstep(float t)
  1199. {
  1200. return (3 - 2*t)*(t*t);
  1201. }
  1202. float stb_cubic_bezier_1d(float t, float p0, float p1, float p2, float p3)
  1203. {
  1204. float it = 1-t;
  1205. return it*it*it*p0 + 3*it*it*t*p1 + 3*it*t*t*p2 + t*t*t*p3;
  1206. }
  1207. void stb_newell_normal(float *normal, int num_vert, float **vert, int normalize)
  1208. {
  1209. int i,j;
  1210. float p;
  1211. normal[0] = normal[1] = normal[2] = 0;
  1212. for (i=num_vert-1,j=0; j < num_vert; i=j++) {
  1213. float *u = vert[i];
  1214. float *v = vert[j];
  1215. normal[0] += (u[1] - v[1]) * (u[2] + v[2]);
  1216. normal[1] += (u[2] - v[2]) * (u[0] + v[0]);
  1217. normal[2] += (u[0] - v[0]) * (u[1] + v[1]);
  1218. }
  1219. if (normalize) {
  1220. p = normal[0]*normal[0] + normal[1]*normal[1] + normal[2]*normal[2];
  1221. p = (float) (1.0 / sqrt(p));
  1222. normal[0] *= p;
  1223. normal[1] *= p;
  1224. normal[2] *= p;
  1225. }
  1226. }
  1227. int stb_box_face_vertex_axis_side(int face_number, int vertex_number, int axis)
  1228. {
  1229. static int box_vertices[6][4][3] =
  1230. {
  1231. { { 1,1,1 }, { 1,0,1 }, { 1,0,0 }, { 1,1,0 } },
  1232. { { 0,0,0 }, { 0,0,1 }, { 0,1,1 }, { 0,1,0 } },
  1233. { { 0,0,0 }, { 0,1,0 }, { 1,1,0 }, { 1,0,0 } },
  1234. { { 0,0,0 }, { 1,0,0 }, { 1,0,1 }, { 0,0,1 } },
  1235. { { 1,1,1 }, { 0,1,1 }, { 0,0,1 }, { 1,0,1 } },
  1236. { { 1,1,1 }, { 1,1,0 }, { 0,1,0 }, { 0,1,1 } },
  1237. };
  1238. assert(face_number >= 0 && face_number < 6);
  1239. assert(vertex_number >= 0 && vertex_number < 4);
  1240. assert(axis >= 0 && axis < 3);
  1241. return box_vertices[face_number][vertex_number][axis];
  1242. }
  1243. void stb_linear_controller(float *curpos, float target_pos, float acc, float deacc, float dt)
  1244. {
  1245. float sign = 1, p, cp = *curpos;
  1246. if (cp == target_pos) return;
  1247. if (target_pos < cp) {
  1248. target_pos = -target_pos;
  1249. cp = -cp;
  1250. sign = -1;
  1251. }
  1252. // first decelerate
  1253. if (cp < 0) {
  1254. p = cp + deacc * dt;
  1255. if (p > 0) {
  1256. p = 0;
  1257. dt = dt - cp / deacc;
  1258. if (dt < 0) dt = 0;
  1259. } else {
  1260. dt = 0;
  1261. }
  1262. cp = p;
  1263. }
  1264. // now accelerate
  1265. p = cp + acc*dt;
  1266. if (p > target_pos) p = target_pos;
  1267. *curpos = p * sign;
  1268. // @TODO: testing
  1269. }
  1270. float stb_quadratic_controller(float target_pos, float curpos, float maxvel, float maxacc, float dt, float *curvel)
  1271. {
  1272. return 0; // @TODO
  1273. }
  1274. int stb_float_eq(float x, float y, float delta, int max_ulps)
  1275. {
  1276. if (fabs(x-y) <= delta) return 1;
  1277. if (abs(*(int *)&x - *(int *)&y) <= max_ulps) return 1;
  1278. return 0;
  1279. }
  1280. int stb_is_prime(unsigned int m)
  1281. {
  1282. unsigned int i,j;
  1283. if (m < 2) return 0;
  1284. if (m == 2) return 1;
  1285. if (!(m & 1)) return 0;
  1286. if (m % 3 == 0) return (m == 3);
  1287. for (i=5; (j=i*i), j <= m && j > i; i += 6) {
  1288. if (m % i == 0) return 0;
  1289. if (m % (i+2) == 0) return 0;
  1290. }
  1291. return 1;
  1292. }
  1293. unsigned int stb_power_of_two_nearest_prime(int n)
  1294. {
  1295. static signed char tab[32] = { 0,0,0,0,1,0,-1,0,1,-1,-1,3,-1,0,-1,2,1,
  1296. 0,2,0,-1,-4,-1,5,-1,18,-2,15,2,-1,2,0 };
  1297. if (!tab[0]) {
  1298. int i;
  1299. for (i=0; i < 32; ++i)
  1300. tab[i] = (1 << i) + 2*tab[i] - 1;
  1301. tab[1] = 2;
  1302. tab[0] = 1;
  1303. }
  1304. if (n >= 32) return 0xfffffffb;
  1305. return tab[n];
  1306. }
  1307. double stb_linear_remap(double x, double x_min, double x_max,
  1308. double out_min, double out_max)
  1309. {
  1310. return stb_lerp(stb_unlerp(x,x_min,x_max),out_min,out_max);
  1311. }
  1312. #endif
  1313. // create a macro so it's faster, but you can get at the function pointer
  1314. #define stb_linear_remap(t,a,b,c,d) stb_lerp(stb_unlerp(t,a,b),c,d)
  1315. //////////////////////////////////////////////////////////////////////////////
  1316. //
  1317. // bit operations
  1318. //
  1319. #define stb_big32(c) (((c)[0]<<24) + (c)[1]*65536 + (c)[2]*256 + (c)[3])
  1320. #define stb_little32(c) (((c)[3]<<24) + (c)[2]*65536 + (c)[1]*256 + (c)[0])
  1321. #define stb_big16(c) ((c)[0]*256 + (c)[1])
  1322. #define stb_little16(c) ((c)[1]*256 + (c)[0])
  1323. STB_EXTERN int stb_bitcount(unsigned int a);
  1324. STB_EXTERN unsigned int stb_bitreverse8(unsigned char n);
  1325. STB_EXTERN unsigned int stb_bitreverse(unsigned int n);
  1326. STB_EXTERN int stb_is_pow2(size_t);
  1327. STB_EXTERN int stb_log2_ceil(size_t);
  1328. STB_EXTERN int stb_log2_floor(size_t);
  1329. STB_EXTERN int stb_lowbit8(unsigned int n);
  1330. STB_EXTERN int stb_highbit8(unsigned int n);
  1331. #ifdef STB_DEFINE
  1332. int stb_bitcount(unsigned int a)
  1333. {
  1334. a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2
  1335. a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4
  1336. a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits
  1337. a = (a + (a >> 8)); // max 16 per 8 bits
  1338. a = (a + (a >> 16)); // max 32 per 8 bits
  1339. return a & 0xff;
  1340. }
  1341. unsigned int stb_bitreverse8(unsigned char n)
  1342. {
  1343. n = ((n & 0xAA) >> 1) + ((n & 0x55) << 1);
  1344. n = ((n & 0xCC) >> 2) + ((n & 0x33) << 2);
  1345. return (unsigned char) ((n >> 4) + (n << 4));
  1346. }
  1347. unsigned int stb_bitreverse(unsigned int n)
  1348. {
  1349. n = ((n & 0xAAAAAAAA) >> 1) | ((n & 0x55555555) << 1);
  1350. n = ((n & 0xCCCCCCCC) >> 2) | ((n & 0x33333333) << 2);
  1351. n = ((n & 0xF0F0F0F0) >> 4) | ((n & 0x0F0F0F0F) << 4);
  1352. n = ((n & 0xFF00FF00) >> 8) | ((n & 0x00FF00FF) << 8);
  1353. return (n >> 16) | (n << 16);
  1354. }
  1355. int stb_is_pow2(size_t n)
  1356. {
  1357. return (n & (n-1)) == 0;
  1358. }
  1359. // tricky use of 4-bit table to identify 5 bit positions (note the '-1')
  1360. // 3-bit table would require another tree level; 5-bit table wouldn't save one
  1361. #if defined(_WIN32) && !defined(__MINGW32__)
  1362. #pragma warning(push)
  1363. #pragma warning(disable: 4035) // disable warning about no return value
  1364. int stb_log2_floor(size_t n)
  1365. {
  1366. #if _MSC_VER > 1700
  1367. unsigned long i;
  1368. #ifdef STB_PTR64
  1369. _BitScanReverse64(&i, n);
  1370. #else
  1371. _BitScanReverse(&i, n);
  1372. #endif
  1373. return i != 0 ? i : -1;
  1374. #else
  1375. __asm {
  1376. bsr eax,n
  1377. jnz done
  1378. mov eax,-1
  1379. }
  1380. done:;
  1381. #endif
  1382. }
  1383. #pragma warning(pop)
  1384. #else
  1385. int stb_log2_floor(size_t n)
  1386. {
  1387. static signed char log2_4[16] = { -1,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3 };
  1388. #ifdef STB_PTR64
  1389. if (n >= ((size_t) 1u << 32))
  1390. return stb_log2_floor(n >> 32);
  1391. #endif
  1392. // 2 compares if n < 16, 3 compares otherwise
  1393. if (n < (1U << 14))
  1394. if (n < (1U << 4)) return 0 + log2_4[n ];
  1395. else if (n < (1U << 9)) return 5 + log2_4[n >> 5];
  1396. else return 10 + log2_4[n >> 10];
  1397. else if (n < (1U << 24))
  1398. if (n < (1U << 19)) return 15 + log2_4[n >> 15];
  1399. else return 20 + log2_4[n >> 20];
  1400. else if (n < (1U << 29)) return 25 + log2_4[n >> 25];
  1401. else return 30 + log2_4[n >> 30];
  1402. }
  1403. #endif
  1404. // define ceil from floor
  1405. int stb_log2_ceil(size_t n)
  1406. {
  1407. if (stb_is_pow2(n)) return stb_log2_floor(n);
  1408. else return 1 + stb_log2_floor(n);
  1409. }
  1410. int stb_highbit8(unsigned int n)
  1411. {
  1412. return stb_log2_ceil(n&255);
  1413. }
  1414. int stb_lowbit8(unsigned int n)
  1415. {
  1416. static signed char lowbit4[16] = { -1,0,1,0, 2,0,1,0, 3,0,1,0, 2,0,1,0 };
  1417. int k = lowbit4[n & 15];
  1418. if (k >= 0) return k;
  1419. k = lowbit4[(n >> 4) & 15];
  1420. if (k >= 0) return k+4;
  1421. return k;
  1422. }
  1423. #endif
  1424. //////////////////////////////////////////////////////////////////////////////
  1425. //
  1426. // qsort Compare Routines
  1427. //
  1428. #ifdef _WIN32
  1429. #define stb_stricmp(a,b) stb_p_stricmp(a,b)
  1430. #define stb_strnicmp(a,b,n) stb_p_strnicmp(a,b,n)
  1431. #else
  1432. #define stb_stricmp(a,b) strcasecmp(a,b)
  1433. #define stb_strnicmp(a,b,n) strncasecmp(a,b,n)
  1434. #endif
  1435. STB_EXTERN int (*stb_intcmp(int offset))(const void *a, const void *b);
  1436. STB_EXTERN int (*stb_intcmprev(int offset))(const void *a, const void *b);
  1437. STB_EXTERN int (*stb_qsort_strcmp(int offset))(const void *a, const void *b);
  1438. STB_EXTERN int (*stb_qsort_stricmp(int offset))(const void *a, const void *b);
  1439. STB_EXTERN int (*stb_floatcmp(int offset))(const void *a, const void *b);
  1440. STB_EXTERN int (*stb_doublecmp(int offset))(const void *a, const void *b);
  1441. STB_EXTERN int (*stb_charcmp(int offset))(const void *a, const void *b);
  1442. #ifdef STB_DEFINE
  1443. static int stb__intcmpoffset, stb__ucharcmpoffset, stb__strcmpoffset;
  1444. static int stb__floatcmpoffset, stb__doublecmpoffset;
  1445. static int stb__memcmpoffset, stb__memcmpsize;
  1446. int stb__intcmp(const void *a, const void *b)
  1447. {
  1448. const int p = *(const int *) ((const char *) a + stb__intcmpoffset);
  1449. const int q = *(const int *) ((const char *) b + stb__intcmpoffset);
  1450. return p < q ? -1 : p > q;
  1451. }
  1452. int stb__intcmprev(const void *a, const void *b)
  1453. {
  1454. const int p = *(const int *) ((const char *) a + stb__intcmpoffset);
  1455. const int q = *(const int *) ((const char *) b + stb__intcmpoffset);
  1456. return q < p ? -1 : q > p;
  1457. }
  1458. int stb__ucharcmp(const void *a, const void *b)
  1459. {
  1460. const int p = *(const unsigned char *) ((const char *) a + stb__ucharcmpoffset);
  1461. const int q = *(const unsigned char *) ((const char *) b + stb__ucharcmpoffset);
  1462. return p < q ? -1 : p > q;
  1463. }
  1464. int stb__floatcmp(const void *a, const void *b)
  1465. {
  1466. const float p = *(const float *) ((const char *) a + stb__floatcmpoffset);
  1467. const float q = *(const float *) ((const char *) b + stb__floatcmpoffset);
  1468. return p < q ? -1 : p > q;
  1469. }
  1470. int stb__doublecmp(const void *a, const void *b)
  1471. {
  1472. const double p = *(const double *) ((const char *) a + stb__doublecmpoffset);
  1473. const double q = *(const double *) ((const char *) b + stb__doublecmpoffset);
  1474. return p < q ? -1 : p > q;
  1475. }
  1476. int stb__qsort_strcmp(const void *a, const void *b)
  1477. {
  1478. const char *p = *(const char **) ((const char *) a + stb__strcmpoffset);
  1479. const char *q = *(const char **) ((const char *) b + stb__strcmpoffset);
  1480. return strcmp(p,q);
  1481. }
  1482. int stb__qsort_stricmp(const void *a, const void *b)
  1483. {
  1484. const char *p = *(const char **) ((const char *) a + stb__strcmpoffset);
  1485. const char *q = *(const char **) ((const char *) b + stb__strcmpoffset);
  1486. return stb_stricmp(p,q);
  1487. }
  1488. int stb__memcmp(const void *a, const void *b)
  1489. {
  1490. return memcmp((char *) a + stb__memcmpoffset, (char *) b + stb__memcmpoffset, stb__memcmpsize);
  1491. }
  1492. int (*stb_intcmp(int offset))(const void *, const void *)
  1493. {
  1494. stb__intcmpoffset = offset;
  1495. return &stb__intcmp;
  1496. }
  1497. int (*stb_intcmprev(int offset))(const void *, const void *)
  1498. {
  1499. stb__intcmpoffset = offset;
  1500. return &stb__intcmprev;
  1501. }
  1502. int (*stb_ucharcmp(int offset))(const void *, const void *)
  1503. {
  1504. stb__ucharcmpoffset = offset;
  1505. return &stb__ucharcmp;
  1506. }
  1507. int (*stb_qsort_strcmp(int offset))(const void *, const void *)
  1508. {
  1509. stb__strcmpoffset = offset;
  1510. return &stb__qsort_strcmp;
  1511. }
  1512. int (*stb_qsort_stricmp(int offset))(const void *, const void *)
  1513. {
  1514. stb__strcmpoffset = offset;
  1515. return &stb__qsort_stricmp;
  1516. }
  1517. int (*stb_floatcmp(int offset))(const void *, const void *)
  1518. {
  1519. stb__floatcmpoffset = offset;
  1520. return &stb__floatcmp;
  1521. }
  1522. int (*stb_doublecmp(int offset))(const void *, const void *)
  1523. {
  1524. stb__doublecmpoffset = offset;
  1525. return &stb__doublecmp;
  1526. }
  1527. int (*stb_memcmp(int offset, int size))(const void *, const void *)
  1528. {
  1529. stb__memcmpoffset = offset;
  1530. stb__memcmpsize = size;
  1531. return &stb__memcmp;
  1532. }
  1533. #endif
  1534. //////////////////////////////////////////////////////////////////////////////
  1535. //
  1536. // Binary Search Toolkit
  1537. //
  1538. typedef struct
  1539. {
  1540. int minval, maxval, guess;
  1541. int mode, step;
  1542. } stb_search;
  1543. STB_EXTERN int stb_search_binary(stb_search *s, int minv, int maxv, int find_smallest);
  1544. STB_EXTERN int stb_search_open(stb_search *s, int minv, int find_smallest);
  1545. STB_EXTERN int stb_probe(stb_search *s, int compare, int *result); // return 0 when done
  1546. #ifdef STB_DEFINE
  1547. enum
  1548. {
  1549. STB_probe_binary_smallest,
  1550. STB_probe_binary_largest,
  1551. STB_probe_open_smallest,
  1552. STB_probe_open_largest,
  1553. };
  1554. static int stb_probe_guess(stb_search *s, int *result)
  1555. {
  1556. switch(s->mode) {
  1557. case STB_probe_binary_largest:
  1558. if (s->minval == s->maxval) {
  1559. *result = s->minval;
  1560. return 0;
  1561. }
  1562. assert(s->minval < s->maxval);
  1563. // if a < b, then a < p <= b
  1564. s->guess = s->minval + (((unsigned) s->maxval - s->minval + 1) >> 1);
  1565. break;
  1566. case STB_probe_binary_smallest:
  1567. if (s->minval == s->maxval) {
  1568. *result = s->minval;
  1569. return 0;
  1570. }
  1571. assert(s->minval < s->maxval);
  1572. // if a < b, then a <= p < b
  1573. s->guess = s->minval + (((unsigned) s->maxval - s->minval) >> 1);
  1574. break;
  1575. case STB_probe_open_smallest:
  1576. case STB_probe_open_largest:
  1577. s->guess = s->maxval; // guess the current maxval
  1578. break;
  1579. }
  1580. *result = s->guess;
  1581. return 1;
  1582. }
  1583. int stb_probe(stb_search *s, int compare, int *result)
  1584. {
  1585. switch(s->mode) {
  1586. case STB_probe_open_smallest:
  1587. case STB_probe_open_largest: {
  1588. if (compare <= 0) {
  1589. // then it lies within minval & maxval
  1590. if (s->mode == STB_probe_open_smallest)
  1591. s->mode = STB_probe_binary_smallest;
  1592. else
  1593. s->mode = STB_probe_binary_largest;
  1594. } else {
  1595. // otherwise, we need to probe larger
  1596. s->minval = s->maxval + 1;
  1597. s->maxval = s->minval + s->step;
  1598. s->step += s->step;
  1599. }
  1600. break;
  1601. }
  1602. case STB_probe_binary_smallest: {
  1603. // if compare < 0, then s->minval <= a < p
  1604. // if compare = 0, then s->minval <= a <= p
  1605. // if compare > 0, then p < a <= s->maxval
  1606. if (compare <= 0)
  1607. s->maxval = s->guess;
  1608. else
  1609. s->minval = s->guess+1;
  1610. break;
  1611. }
  1612. case STB_probe_binary_largest: {
  1613. // if compare < 0, then s->minval <= a < p
  1614. // if compare = 0, then p <= a <= s->maxval
  1615. // if compare > 0, then p < a <= s->maxval
  1616. if (compare < 0)
  1617. s->maxval = s->guess-1;
  1618. else
  1619. s->minval = s->guess;
  1620. break;
  1621. }
  1622. }
  1623. return stb_probe_guess(s, result);
  1624. }
  1625. int stb_search_binary(stb_search *s, int minv, int maxv, int find_smallest)
  1626. {
  1627. int r;
  1628. if (maxv < minv) return minv-1;
  1629. s->minval = minv;
  1630. s->maxval = maxv;
  1631. s->mode = find_smallest ? STB_probe_binary_smallest : STB_probe_binary_largest;
  1632. stb_probe_guess(s, &r);
  1633. return r;
  1634. }
  1635. int stb_search_open(stb_search *s, int minv, int find_smallest)
  1636. {
  1637. int r;
  1638. s->step = 4;
  1639. s->minval = minv;
  1640. s->maxval = minv+s->step;
  1641. s->mode = find_smallest ? STB_probe_open_smallest : STB_probe_open_largest;
  1642. stb_probe_guess(s, &r);
  1643. return r;
  1644. }
  1645. #endif
  1646. //////////////////////////////////////////////////////////////////////////////
  1647. //
  1648. // String Processing
  1649. //
  1650. #define stb_prefixi(s,t) (0==stb_strnicmp((s),(t),strlen(t)))
  1651. enum stb_splitpath_flag
  1652. {
  1653. STB_PATH = 1,
  1654. STB_FILE = 2,
  1655. STB_EXT = 4,
  1656. STB_PATH_FILE = STB_PATH + STB_FILE,
  1657. STB_FILE_EXT = STB_FILE + STB_EXT,
  1658. STB_EXT_NO_PERIOD = 8,
  1659. };
  1660. STB_EXTERN char * stb_skipwhite(char *s);
  1661. STB_EXTERN char * stb_trimwhite(char *s);
  1662. STB_EXTERN char * stb_skipnewline(char *s);
  1663. STB_EXTERN char * stb_strncpy(char *s, char *t, int n);
  1664. STB_EXTERN char * stb_substr(char *t, int n);
  1665. STB_EXTERN char * stb_duplower(char *s);
  1666. STB_EXTERN void stb_tolower (char *s);
  1667. STB_EXTERN char * stb_strchr2 (char *s, char p1, char p2);
  1668. STB_EXTERN char * stb_strrchr2(char *s, char p1, char p2);
  1669. STB_EXTERN char * stb_strtok(char *output, char *src, char *delimit);
  1670. STB_EXTERN char * stb_strtok_keep(char *output, char *src, char *delimit);
  1671. STB_EXTERN char * stb_strtok_invert(char *output, char *src, char *allowed);
  1672. STB_EXTERN char * stb_dupreplace(char *s, char *find, char *replace);
  1673. STB_EXTERN void stb_replaceinplace(char *s, char *find, char *replace);
  1674. STB_EXTERN char * stb_splitpath(char *output, char *src, int flag);
  1675. STB_EXTERN char * stb_splitpathdup(char *src, int flag);
  1676. STB_EXTERN char * stb_replacedir(char *output, char *src, char *dir);
  1677. STB_EXTERN char * stb_replaceext(char *output, char *src, char *ext);
  1678. STB_EXTERN void stb_fixpath(char *path);
  1679. STB_EXTERN char * stb_shorten_path_readable(char *path, int max_len);
  1680. STB_EXTERN int stb_suffix (char *s, char *t);
  1681. STB_EXTERN int stb_suffixi(char *s, char *t);
  1682. STB_EXTERN int stb_prefix (char *s, char *t);
  1683. STB_EXTERN char * stb_strichr(char *s, char t);
  1684. STB_EXTERN char * stb_stristr(char *s, char *t);
  1685. STB_EXTERN int stb_prefix_count(char *s, char *t);
  1686. STB_EXTERN const char * stb_plural(int n); // "s" or ""
  1687. STB_EXTERN size_t stb_strscpy(char *d, const char *s, size_t n);
  1688. STB_EXTERN char **stb_tokens(char *src, char *delimit, int *count);
  1689. STB_EXTERN char **stb_tokens_nested(char *src, char *delimit, int *count, char *nest_in, char *nest_out);
  1690. STB_EXTERN char **stb_tokens_nested_empty(char *src, char *delimit, int *count, char *nest_in, char *nest_out);
  1691. STB_EXTERN char **stb_tokens_allowempty(char *src, char *delimit, int *count);
  1692. STB_EXTERN char **stb_tokens_stripwhite(char *src, char *delimit, int *count);
  1693. STB_EXTERN char **stb_tokens_withdelim(char *src, char *delimit, int *count);
  1694. STB_EXTERN char **stb_tokens_quoted(char *src, char *delimit, int *count);
  1695. // with 'quoted', allow delimiters to appear inside quotation marks, and don't
  1696. // strip whitespace inside them (and we delete the quotation marks unless they
  1697. // appear back to back, in which case they're considered escaped)
  1698. #ifdef STB_DEFINE
  1699. size_t stb_strscpy(char *d, const char *s, size_t n)
  1700. {
  1701. size_t len = strlen(s);
  1702. if (len >= n) {
  1703. if (n) d[0] = 0;
  1704. return 0;
  1705. }
  1706. stb_p_strcpy_s(d,n,s);
  1707. return len;
  1708. }
  1709. const char *stb_plural(int n)
  1710. {
  1711. return n == 1 ? "" : "s";
  1712. }
  1713. int stb_prefix(char *s, char *t)
  1714. {
  1715. while (*t)
  1716. if (*s++ != *t++)
  1717. return STB_FALSE;
  1718. return STB_TRUE;
  1719. }
  1720. int stb_prefix_count(char *s, char *t)
  1721. {
  1722. int c=0;
  1723. while (*t) {
  1724. if (*s++ != *t++)
  1725. break;
  1726. ++c;
  1727. }
  1728. return c;
  1729. }
  1730. int stb_suffix(char *s, char *t)
  1731. {
  1732. size_t n = strlen(s);
  1733. size_t m = strlen(t);
  1734. if (m <= n)
  1735. return 0 == strcmp(s+n-m, t);
  1736. else
  1737. return 0;
  1738. }
  1739. int stb_suffixi(char *s, char *t)
  1740. {
  1741. size_t n = strlen(s);
  1742. size_t m = strlen(t);
  1743. if (m <= n)
  1744. return 0 == stb_stricmp(s+n-m, t);
  1745. else
  1746. return 0;
  1747. }
  1748. // originally I was using this table so that I could create known sentinel
  1749. // values--e.g. change whitetable[0] to be true if I was scanning for whitespace,
  1750. // and false if I was scanning for nonwhite. I don't appear to be using that
  1751. // functionality anymore (I do for tokentable, though), so just replace it
  1752. // with isspace()
  1753. char *stb_skipwhite(char *s)
  1754. {
  1755. while (isspace((unsigned char) *s)) ++s;
  1756. return s;
  1757. }
  1758. char *stb_skipnewline(char *s)
  1759. {
  1760. if (s[0] == '\r' || s[0] == '\n') {
  1761. if (s[0]+s[1] == '\r' + '\n') ++s;
  1762. ++s;
  1763. }
  1764. return s;
  1765. }
  1766. char *stb_trimwhite(char *s)
  1767. {
  1768. int i,n;
  1769. s = stb_skipwhite(s);
  1770. n = (int) strlen(s);
  1771. for (i=n-1; i >= 0; --i)
  1772. if (!isspace(s[i]))
  1773. break;
  1774. s[i+1] = 0;
  1775. return s;
  1776. }
  1777. char *stb_strncpy(char *s, char *t, int n)
  1778. {
  1779. stb_p_strncpy_s(s,n+1,t,n);
  1780. s[n] = 0;
  1781. return s;
  1782. }
  1783. char *stb_substr(char *t, int n)
  1784. {
  1785. char *a;
  1786. int z = (int) strlen(t);
  1787. if (z < n) n = z;
  1788. a = (char *) malloc(n+1);
  1789. stb_p_strncpy_s(a,n+1,t,n);
  1790. a[n] = 0;
  1791. return a;
  1792. }
  1793. char *stb_duplower(char *s)
  1794. {
  1795. char *p = stb_p_strdup(s), *q = p;
  1796. while (*q) {
  1797. *q = tolower(*q);
  1798. ++q;
  1799. }
  1800. return p;
  1801. }
  1802. void stb_tolower(char *s)
  1803. {
  1804. while (*s) {
  1805. *s = tolower(*s);
  1806. ++s;
  1807. }
  1808. }
  1809. char *stb_strchr2(char *s, char x, char y)
  1810. {
  1811. for(; *s; ++s)
  1812. if (*s == x || *s == y)
  1813. return s;
  1814. return NULL;
  1815. }
  1816. char *stb_strrchr2(char *s, char x, char y)
  1817. {
  1818. char *r = NULL;
  1819. for(; *s; ++s)
  1820. if (*s == x || *s == y)
  1821. r = s;
  1822. return r;
  1823. }
  1824. char *stb_strichr(char *s, char t)
  1825. {
  1826. if (tolower(t) == toupper(t))
  1827. return strchr(s,t);
  1828. return stb_strchr2(s, (char) tolower(t), (char) toupper(t));
  1829. }
  1830. char *stb_stristr(char *s, char *t)
  1831. {
  1832. size_t n = strlen(t);
  1833. char *z;
  1834. if (n==0) return s;
  1835. while ((z = stb_strichr(s, *t)) != NULL) {
  1836. if (0==stb_strnicmp(z, t, n))
  1837. return z;
  1838. s = z+1;
  1839. }
  1840. return NULL;
  1841. }
  1842. static char *stb_strtok_raw(char *output, char *src, char *delimit, int keep, int invert)
  1843. {
  1844. if (invert) {
  1845. while (*src && strchr(delimit, *src) != NULL) {
  1846. *output++ = *src++;
  1847. }
  1848. } else {
  1849. while (*src && strchr(delimit, *src) == NULL) {
  1850. *output++ = *src++;
  1851. }
  1852. }
  1853. *output = 0;
  1854. if (keep)
  1855. return src;
  1856. else
  1857. return *src ? src+1 : src;
  1858. }
  1859. char *stb_strtok(char *output, char *src, char *delimit)
  1860. {
  1861. return stb_strtok_raw(output, src, delimit, 0, 0);
  1862. }
  1863. char *stb_strtok_keep(char *output, char *src, char *delimit)
  1864. {
  1865. return stb_strtok_raw(output, src, delimit, 1, 0);
  1866. }
  1867. char *stb_strtok_invert(char *output, char *src, char *delimit)
  1868. {
  1869. return stb_strtok_raw(output, src, delimit, 1,1);
  1870. }
  1871. static char **stb_tokens_raw(char *src_, char *delimit, int *count,
  1872. int stripwhite, int allow_empty, char *start, char *end)
  1873. {
  1874. int nested = 0;
  1875. unsigned char *src = (unsigned char *) src_;
  1876. static char stb_tokentable[256]; // rely on static initializion to 0
  1877. static char stable[256],etable[256];
  1878. char *out;
  1879. char **result;
  1880. int num=0;
  1881. unsigned char *s;
  1882. s = (unsigned char *) delimit; while (*s) stb_tokentable[*s++] = 1;
  1883. if (start) {
  1884. s = (unsigned char *) start; while (*s) stable[*s++] = 1;
  1885. s = (unsigned char *) end; if (s) while (*s) stable[*s++] = 1;
  1886. s = (unsigned char *) end; if (s) while (*s) etable[*s++] = 1;
  1887. }
  1888. stable[0] = 1;
  1889. // two passes through: the first time, counting how many
  1890. s = (unsigned char *) src;
  1891. while (*s) {
  1892. // state: just found delimiter
  1893. // skip further delimiters
  1894. if (!allow_empty) {
  1895. stb_tokentable[0] = 0;
  1896. while (stb_tokentable[*s])
  1897. ++s;
  1898. if (!*s) break;
  1899. }
  1900. ++num;
  1901. // skip further non-delimiters
  1902. stb_tokentable[0] = 1;
  1903. if (stripwhite == 2) { // quoted strings
  1904. while (!stb_tokentable[*s]) {
  1905. if (*s != '"')
  1906. ++s;
  1907. else {
  1908. ++s;
  1909. if (*s == '"')
  1910. ++s; // "" -> ", not start a string
  1911. else {
  1912. // begin a string
  1913. while (*s) {
  1914. if (s[0] == '"') {
  1915. if (s[1] == '"') s += 2; // "" -> "
  1916. else { ++s; break; } // terminating "
  1917. } else
  1918. ++s;
  1919. }
  1920. }
  1921. }
  1922. }
  1923. } else
  1924. while (nested || !stb_tokentable[*s]) {
  1925. if (stable[*s]) {
  1926. if (!*s) break;
  1927. if (end ? etable[*s] : nested)
  1928. --nested;
  1929. else
  1930. ++nested;
  1931. }
  1932. ++s;
  1933. }
  1934. if (allow_empty) {
  1935. if (*s) ++s;
  1936. }
  1937. }
  1938. // now num has the actual count... malloc our output structure
  1939. // need space for all the strings: strings won't be any longer than
  1940. // original input, since for every '\0' there's at least one delimiter
  1941. result = (char **) malloc(sizeof(*result) * (num+1) + (s-src+1));
  1942. if (result == NULL) return result;
  1943. out = (char *) (result + (num+1));
  1944. // second pass: copy out the data
  1945. s = (unsigned char *) src;
  1946. num = 0;
  1947. nested = 0;
  1948. while (*s) {
  1949. char *last_nonwhite;
  1950. // state: just found delimiter
  1951. // skip further delimiters
  1952. if (!allow_empty) {
  1953. stb_tokentable[0] = 0;
  1954. if (stripwhite)
  1955. while (stb_tokentable[*s] || isspace(*s))
  1956. ++s;
  1957. else
  1958. while (stb_tokentable[*s])
  1959. ++s;
  1960. } else if (stripwhite) {
  1961. while (isspace(*s)) ++s;
  1962. }
  1963. if (!*s) break;
  1964. // we're past any leading delimiters and whitespace
  1965. result[num] = out;
  1966. ++num;
  1967. // copy non-delimiters
  1968. stb_tokentable[0] = 1;
  1969. last_nonwhite = out-1;
  1970. if (stripwhite == 2) {
  1971. while (!stb_tokentable[*s]) {
  1972. if (*s != '"') {
  1973. if (!isspace(*s)) last_nonwhite = out;
  1974. *out++ = *s++;
  1975. } else {
  1976. ++s;
  1977. if (*s == '"') {
  1978. if (!isspace(*s)) last_nonwhite = out;
  1979. *out++ = *s++; // "" -> ", not start string
  1980. } else {
  1981. // begin a quoted string
  1982. while (*s) {
  1983. if (s[0] == '"') {
  1984. if (s[1] == '"') { *out++ = *s; s += 2; }
  1985. else { ++s; break; } // terminating "
  1986. } else
  1987. *out++ = *s++;
  1988. }
  1989. last_nonwhite = out-1; // all in quotes counts as non-white
  1990. }
  1991. }
  1992. }
  1993. } else {
  1994. while (nested || !stb_tokentable[*s]) {
  1995. if (!isspace(*s)) last_nonwhite = out;
  1996. if (stable[*s]) {
  1997. if (!*s) break;
  1998. if (end ? etable[*s] : nested)
  1999. --nested;
  2000. else
  2001. ++nested;
  2002. }
  2003. *out++ = *s++;
  2004. }
  2005. }
  2006. if (stripwhite) // rewind to last non-whitespace char
  2007. out = last_nonwhite+1;
  2008. *out++ = '\0';
  2009. if (*s) ++s; // skip delimiter
  2010. }
  2011. s = (unsigned char *) delimit; while (*s) stb_tokentable[*s++] = 0;
  2012. if (start) {
  2013. s = (unsigned char *) start; while (*s) stable[*s++] = 1;
  2014. s = (unsigned char *) end; if (s) while (*s) stable[*s++] = 1;
  2015. s = (unsigned char *) end; if (s) while (*s) etable[*s++] = 1;
  2016. }
  2017. if (count != NULL) *count = num;
  2018. result[num] = 0;
  2019. return result;
  2020. }
  2021. char **stb_tokens(char *src, char *delimit, int *count)
  2022. {
  2023. return stb_tokens_raw(src,delimit,count,0,0,0,0);
  2024. }
  2025. char **stb_tokens_nested(char *src, char *delimit, int *count, char *nest_in, char *nest_out)
  2026. {
  2027. return stb_tokens_raw(src,delimit,count,0,0,nest_in,nest_out);
  2028. }
  2029. char **stb_tokens_nested_empty(char *src, char *delimit, int *count, char *nest_in, char *nest_out)
  2030. {
  2031. return stb_tokens_raw(src,delimit,count,0,1,nest_in,nest_out);
  2032. }
  2033. char **stb_tokens_allowempty(char *src, char *delimit, int *count)
  2034. {
  2035. return stb_tokens_raw(src,delimit,count,0,1,0,0);
  2036. }
  2037. char **stb_tokens_stripwhite(char *src, char *delimit, int *count)
  2038. {
  2039. return stb_tokens_raw(src,delimit,count,1,1,0,0);
  2040. }
  2041. char **stb_tokens_quoted(char *src, char *delimit, int *count)
  2042. {
  2043. return stb_tokens_raw(src,delimit,count,2,1,0,0);
  2044. }
  2045. char *stb_dupreplace(char *src, char *find, char *replace)
  2046. {
  2047. size_t len_find = strlen(find);
  2048. size_t len_replace = strlen(replace);
  2049. int count = 0;
  2050. char *s,*p,*q;
  2051. s = strstr(src, find);
  2052. if (s == NULL) return stb_p_strdup(src);
  2053. do {
  2054. ++count;
  2055. s = strstr(s + len_find, find);
  2056. } while (s != NULL);
  2057. p = (char *) malloc(strlen(src) + count * (len_replace - len_find) + 1);
  2058. if (p == NULL) return p;
  2059. q = p;
  2060. s = src;
  2061. for (;;) {
  2062. char *t = strstr(s, find);
  2063. if (t == NULL) {
  2064. stb_p_strcpy_s(q,strlen(src)+count*(len_replace-len_find)+1,s);
  2065. assert(strlen(p) == strlen(src) + count*(len_replace-len_find));
  2066. return p;
  2067. }
  2068. memcpy(q, s, t-s);
  2069. q += t-s;
  2070. memcpy(q, replace, len_replace);
  2071. q += len_replace;
  2072. s = t + len_find;
  2073. }
  2074. }
  2075. void stb_replaceinplace(char *src, char *find, char *replace)
  2076. {
  2077. size_t len_find = strlen(find);
  2078. size_t len_replace = strlen(replace);
  2079. int delta;
  2080. char *s,*p,*q;
  2081. delta = (int) (len_replace - len_find);
  2082. assert(delta <= 0);
  2083. if (delta > 0) return;
  2084. p = strstr(src, find);
  2085. if (p == NULL) return;
  2086. s = q = p;
  2087. while (*s) {
  2088. memcpy(q, replace, len_replace);
  2089. p += len_find;
  2090. q += len_replace;
  2091. s = strstr(p, find);
  2092. if (s == NULL) s = p + strlen(p);
  2093. memmove(q, p, s-p);
  2094. q += s-p;
  2095. p = s;
  2096. }
  2097. *q = 0;
  2098. }
  2099. void stb_fixpath(char *path)
  2100. {
  2101. for(; *path; ++path)
  2102. if (*path == '\\')
  2103. *path = '/';
  2104. }
  2105. void stb__add_section(char *buffer, char *data, ptrdiff_t curlen, ptrdiff_t newlen)
  2106. {
  2107. if (newlen < curlen) {
  2108. ptrdiff_t z1 = newlen >> 1, z2 = newlen-z1;
  2109. memcpy(buffer, data, z1-1);
  2110. buffer[z1-1] = '.';
  2111. buffer[z1-0] = '.';
  2112. memcpy(buffer+z1+1, data+curlen-z2+1, z2-1);
  2113. } else
  2114. memcpy(buffer, data, curlen);
  2115. }
  2116. char * stb_shorten_path_readable(char *path, int len)
  2117. {
  2118. static char buffer[1024];
  2119. ptrdiff_t n = strlen(path),n1,n2,r1,r2;
  2120. char *s;
  2121. if (n <= len) return path;
  2122. if (len > 1024) return path;
  2123. s = stb_strrchr2(path, '/', '\\');
  2124. if (s) {
  2125. n1 = s - path + 1;
  2126. n2 = n - n1;
  2127. ++s;
  2128. } else {
  2129. n1 = 0;
  2130. n2 = n;
  2131. s = path;
  2132. }
  2133. // now we need to reduce r1 and r2 so that they fit in len
  2134. if (n1 < len>>1) {
  2135. r1 = n1;
  2136. r2 = len - r1;
  2137. } else if (n2 < len >> 1) {
  2138. r2 = n2;
  2139. r1 = len - r2;
  2140. } else {
  2141. r1 = n1 * len / n;
  2142. r2 = n2 * len / n;
  2143. if (r1 < len>>2) r1 = len>>2, r2 = len-r1;
  2144. if (r2 < len>>2) r2 = len>>2, r1 = len-r2;
  2145. }
  2146. assert(r1 <= n1 && r2 <= n2);
  2147. if (n1)
  2148. stb__add_section(buffer, path, n1, r1);
  2149. stb__add_section(buffer+r1, s, n2, r2);
  2150. buffer[len] = 0;
  2151. return buffer;
  2152. }
  2153. static char *stb__splitpath_raw(char *buffer, char *path, int flag)
  2154. {
  2155. ptrdiff_t len=0,x,y, n = (int) strlen(path), f1,f2;
  2156. char *s = stb_strrchr2(path, '/', '\\');
  2157. char *t = strrchr(path, '.');
  2158. if (s && t && t < s) t = NULL;
  2159. if (s) ++s;
  2160. if (flag == STB_EXT_NO_PERIOD)
  2161. flag |= STB_EXT;
  2162. if (!(flag & (STB_PATH | STB_FILE | STB_EXT))) return NULL;
  2163. f1 = s == NULL ? 0 : s-path; // start of filename
  2164. f2 = t == NULL ? n : t-path; // just past end of filename
  2165. if (flag & STB_PATH) {
  2166. x = 0; if (f1 == 0 && flag == STB_PATH) len=2;
  2167. } else if (flag & STB_FILE) {
  2168. x = f1;
  2169. } else {
  2170. x = f2;
  2171. if (flag & STB_EXT_NO_PERIOD)
  2172. if (path[x] == '.')
  2173. ++x;
  2174. }
  2175. if (flag & STB_EXT)
  2176. y = n;
  2177. else if (flag & STB_FILE)
  2178. y = f2;
  2179. else
  2180. y = f1;
  2181. if (buffer == NULL) {
  2182. buffer = (char *) malloc(y-x + len + 1);
  2183. if (!buffer) return NULL;
  2184. }
  2185. if (len) { stb_p_strcpy_s(buffer, 3, "./"); return buffer; }
  2186. stb_strncpy(buffer, path+(int)x, (int)(y-x));
  2187. return buffer;
  2188. }
  2189. char *stb_splitpath(char *output, char *src, int flag)
  2190. {
  2191. return stb__splitpath_raw(output, src, flag);
  2192. }
  2193. char *stb_splitpathdup(char *src, int flag)
  2194. {
  2195. return stb__splitpath_raw(NULL, src, flag);
  2196. }
  2197. char *stb_replacedir(char *output, char *src, char *dir)
  2198. {
  2199. char buffer[4096];
  2200. stb_splitpath(buffer, src, STB_FILE | STB_EXT);
  2201. if (dir)
  2202. stb_p_sprintf(output stb_p_size(9999), "%s/%s", dir, buffer);
  2203. else
  2204. stb_p_strcpy_s(output, sizeof(buffer), buffer); // @UNSAFE
  2205. return output;
  2206. }
  2207. char *stb_replaceext(char *output, char *src, char *ext)
  2208. {
  2209. char buffer[4096];
  2210. stb_splitpath(buffer, src, STB_PATH | STB_FILE);
  2211. if (ext)
  2212. stb_p_sprintf(output stb_p_size(9999), "%s.%s", buffer, ext[0] == '.' ? ext+1 : ext);
  2213. else
  2214. stb_p_strcpy_s(output, sizeof(buffer), buffer); // @UNSAFE
  2215. return output;
  2216. }
  2217. #endif
  2218. //////////////////////////////////////////////////////////////////////////////
  2219. //
  2220. // stb_alloc - hierarchical allocator
  2221. //
  2222. // inspired by http://swapped.cc/halloc
  2223. //
  2224. //
  2225. // When you alloc a given block through stb_alloc, you have these choices:
  2226. //
  2227. // 1. does it have a parent?
  2228. // 2. can it have children?
  2229. // 3. can it be freed directly?
  2230. // 4. is it transferrable?
  2231. // 5. what is its alignment?
  2232. //
  2233. // Here are interesting combinations of those:
  2234. //
  2235. // children free transfer alignment
  2236. // arena Y Y N n/a
  2237. // no-overhead, chunked N N N normal
  2238. // string pool alloc N N N 1
  2239. // parent-ptr, chunked Y N N normal
  2240. // low-overhead, unchunked N Y Y normal
  2241. // general purpose alloc Y Y Y normal
  2242. //
  2243. // Unchunked allocations will probably return 16-aligned pointers. If
  2244. // we 16-align the results, we have room for 4 pointers. For smaller
  2245. // allocations that allow finer alignment, we can reduce the pointers.
  2246. //
  2247. // The strategy is that given a pointer, assuming it has a header (only
  2248. // the no-overhead allocations have no header), we can determine the
  2249. // type of the header fields, and the number of them, by stepping backwards
  2250. // through memory and looking at the tags in the bottom bits.
  2251. //
  2252. // Implementation strategy:
  2253. // chunked allocations come from the middle of chunks, and can't
  2254. // be freed. thefore they do not need to be on a sibling chain.
  2255. // they may need child pointers if they have children.
  2256. //
  2257. // chunked, with-children
  2258. // void *parent;
  2259. //
  2260. // unchunked, no-children -- reduced storage
  2261. // void *next_sibling;
  2262. // void *prev_sibling_nextp;
  2263. //
  2264. // unchunked, general
  2265. // void *first_child;
  2266. // void *next_sibling;
  2267. // void *prev_sibling_nextp;
  2268. // void *chunks;
  2269. //
  2270. // so, if we code each of these fields with different bit patterns
  2271. // (actually same one for next/prev/child), then we can identify which
  2272. // each one is from the last field.
  2273. STB_EXTERN void stb_free(void *p);
  2274. STB_EXTERN void *stb_malloc_global(size_t size);
  2275. STB_EXTERN void *stb_malloc(void *context, size_t size);
  2276. STB_EXTERN void *stb_malloc_nofree(void *context, size_t size);
  2277. STB_EXTERN void *stb_malloc_leaf(void *context, size_t size);
  2278. STB_EXTERN void *stb_malloc_raw(void *context, size_t size);
  2279. STB_EXTERN void *stb_realloc(void *ptr, size_t newsize);
  2280. STB_EXTERN void stb_reassign(void *new_context, void *ptr);
  2281. STB_EXTERN void stb_malloc_validate(void *p, void *parent);
  2282. extern int stb_alloc_chunk_size ;
  2283. extern int stb_alloc_count_free ;
  2284. extern int stb_alloc_count_alloc;
  2285. extern int stb_alloc_alignment ;
  2286. #ifdef STB_DEFINE
  2287. int stb_alloc_chunk_size = 65536;
  2288. int stb_alloc_count_free = 0;
  2289. int stb_alloc_count_alloc = 0;
  2290. int stb_alloc_alignment = -16;
  2291. typedef struct stb__chunk
  2292. {
  2293. struct stb__chunk *next;
  2294. int data_left;
  2295. int alloc;
  2296. } stb__chunk;
  2297. typedef struct
  2298. {
  2299. void * next;
  2300. void ** prevn;
  2301. } stb__nochildren;
  2302. typedef struct
  2303. {
  2304. void ** prevn;
  2305. void * child;
  2306. void * next;
  2307. stb__chunk *chunks;
  2308. } stb__alloc;
  2309. typedef struct
  2310. {
  2311. stb__alloc *parent;
  2312. } stb__chunked;
  2313. #define STB__PARENT 1
  2314. #define STB__CHUNKS 2
  2315. typedef enum
  2316. {
  2317. STB__nochildren = 0,
  2318. STB__chunked = STB__PARENT,
  2319. STB__alloc = STB__CHUNKS,
  2320. STB__chunk_raw = 4,
  2321. } stb__alloc_type;
  2322. // these functions set the bottom bits of a pointer efficiently
  2323. #define STB__DECODE(x,v) ((void *) ((char *) (x) - (v)))
  2324. #define STB__ENCODE(x,v) ((void *) ((char *) (x) + (v)))
  2325. #define stb__parent(z) (stb__alloc *) STB__DECODE((z)->parent, STB__PARENT)
  2326. #define stb__chunks(z) (stb__chunk *) STB__DECODE((z)->chunks, STB__CHUNKS)
  2327. #define stb__setparent(z,p) (z)->parent = (stb__alloc *) STB__ENCODE((p), STB__PARENT)
  2328. #define stb__setchunks(z,c) (z)->chunks = (stb__chunk *) STB__ENCODE((c), STB__CHUNKS)
  2329. static stb__alloc stb__alloc_global =
  2330. {
  2331. NULL,
  2332. NULL,
  2333. NULL,
  2334. (stb__chunk *) STB__ENCODE(NULL, STB__CHUNKS)
  2335. };
  2336. static stb__alloc_type stb__identify(void *p)
  2337. {
  2338. void **q = (void **) p;
  2339. return (stb__alloc_type) ((stb_uinta) q[-1] & 3);
  2340. }
  2341. static void *** stb__prevn(void *p)
  2342. {
  2343. if (stb__identify(p) == STB__alloc) {
  2344. stb__alloc *s = (stb__alloc *) p - 1;
  2345. return &s->prevn;
  2346. } else {
  2347. stb__nochildren *s = (stb__nochildren *) p - 1;
  2348. return &s->prevn;
  2349. }
  2350. }
  2351. void stb_free(void *p)
  2352. {
  2353. if (p == NULL) return;
  2354. // count frees so that unit tests can see what's happening
  2355. ++stb_alloc_count_free;
  2356. switch(stb__identify(p)) {
  2357. case STB__chunked:
  2358. // freeing a chunked-block with children does nothing;
  2359. // they only get freed when the parent does
  2360. // surely this is wrong, and it should free them immediately?
  2361. // otherwise how are they getting put on the right chain?
  2362. return;
  2363. case STB__nochildren: {
  2364. stb__nochildren *s = (stb__nochildren *) p - 1;
  2365. // unlink from sibling chain
  2366. *(s->prevn) = s->next;
  2367. if (s->next)
  2368. *stb__prevn(s->next) = s->prevn;
  2369. free(s);
  2370. return;
  2371. }
  2372. case STB__alloc: {
  2373. stb__alloc *s = (stb__alloc *) p - 1;
  2374. stb__chunk *c, *n;
  2375. void *q;
  2376. // unlink from sibling chain, if any
  2377. *(s->prevn) = s->next;
  2378. if (s->next)
  2379. *stb__prevn(s->next) = s->prevn;
  2380. // first free chunks
  2381. c = (stb__chunk *) stb__chunks(s);
  2382. while (c != NULL) {
  2383. n = c->next;
  2384. stb_alloc_count_free += c->alloc;
  2385. free(c);
  2386. c = n;
  2387. }
  2388. // validating
  2389. stb__setchunks(s,NULL);
  2390. s->prevn = NULL;
  2391. s->next = NULL;
  2392. // now free children
  2393. while ((q = s->child) != NULL) {
  2394. stb_free(q);
  2395. }
  2396. // now free self
  2397. free(s);
  2398. return;
  2399. }
  2400. default:
  2401. assert(0); /* NOTREACHED */
  2402. }
  2403. }
  2404. void stb_malloc_validate(void *p, void *parent)
  2405. {
  2406. if (p == NULL) return;
  2407. switch(stb__identify(p)) {
  2408. case STB__chunked:
  2409. return;
  2410. case STB__nochildren: {
  2411. stb__nochildren *n = (stb__nochildren *) p - 1;
  2412. if (n->prevn)
  2413. assert(*n->prevn == p);
  2414. if (n->next) {
  2415. assert(*stb__prevn(n->next) == &n->next);
  2416. stb_malloc_validate(n, parent);
  2417. }
  2418. return;
  2419. }
  2420. case STB__alloc: {
  2421. stb__alloc *s = (stb__alloc *) p - 1;
  2422. if (s->prevn)
  2423. assert(*s->prevn == p);
  2424. if (s->child) {
  2425. assert(*stb__prevn(s->child) == &s->child);
  2426. stb_malloc_validate(s->child, p);
  2427. }
  2428. if (s->next) {
  2429. assert(*stb__prevn(s->next) == &s->next);
  2430. stb_malloc_validate(s->next, parent);
  2431. }
  2432. return;
  2433. }
  2434. default:
  2435. assert(0); /* NOTREACHED */
  2436. }
  2437. }
  2438. static void * stb__try_chunk(stb__chunk *c, int size, int align, int pre_align)
  2439. {
  2440. char *memblock = (char *) (c+1), *q;
  2441. stb_inta iq;
  2442. int start_offset;
  2443. // we going to allocate at the end of the chunk, not the start. confusing,
  2444. // but it means we don't need both a 'limit' and a 'cur', just a 'cur'.
  2445. // the block ends at: p + c->data_left
  2446. // then we move back by size
  2447. start_offset = c->data_left - size;
  2448. // now we need to check the alignment of that
  2449. q = memblock + start_offset;
  2450. iq = (stb_inta) q;
  2451. assert(sizeof(q) == sizeof(iq));
  2452. // suppose align = 2
  2453. // then we need to retreat iq far enough that (iq & (2-1)) == 0
  2454. // to get (iq & (align-1)) = 0 requires subtracting (iq & (align-1))
  2455. start_offset -= iq & (align-1);
  2456. assert(((stb_uinta) (memblock+start_offset) & (align-1)) == 0);
  2457. // now, if that + pre_align works, go for it!
  2458. start_offset -= pre_align;
  2459. if (start_offset >= 0) {
  2460. c->data_left = start_offset;
  2461. return memblock + start_offset;
  2462. }
  2463. return NULL;
  2464. }
  2465. static void stb__sort_chunks(stb__alloc *src)
  2466. {
  2467. // of the first two chunks, put the chunk with more data left in it first
  2468. stb__chunk *c = stb__chunks(src), *d;
  2469. if (c == NULL) return;
  2470. d = c->next;
  2471. if (d == NULL) return;
  2472. if (c->data_left > d->data_left) return;
  2473. c->next = d->next;
  2474. d->next = c;
  2475. stb__setchunks(src, d);
  2476. }
  2477. static void * stb__alloc_chunk(stb__alloc *src, int size, int align, int pre_align)
  2478. {
  2479. void *p;
  2480. stb__chunk *c = stb__chunks(src);
  2481. if (c && size <= stb_alloc_chunk_size) {
  2482. p = stb__try_chunk(c, size, align, pre_align);
  2483. if (p) { ++c->alloc; return p; }
  2484. // try a second chunk to reduce wastage
  2485. if (c->next) {
  2486. p = stb__try_chunk(c->next, size, align, pre_align);
  2487. if (p) { ++c->alloc; return p; }
  2488. // put the bigger chunk first, since the second will get buried
  2489. // the upshot of this is that, until it gets allocated from, chunk #2
  2490. // is always the largest remaining chunk. (could formalize
  2491. // this with a heap!)
  2492. stb__sort_chunks(src);
  2493. c = stb__chunks(src);
  2494. }
  2495. }
  2496. // allocate a new chunk
  2497. {
  2498. stb__chunk *n;
  2499. int chunk_size = stb_alloc_chunk_size;
  2500. // we're going to allocate a new chunk to put this in
  2501. if (size > chunk_size)
  2502. chunk_size = size;
  2503. assert(sizeof(*n) + pre_align <= 16);
  2504. // loop trying to allocate a large enough chunk
  2505. // the loop is because the alignment may cause problems if it's big...
  2506. // and we don't know what our chunk alignment is going to be
  2507. while (1) {
  2508. n = (stb__chunk *) malloc(16 + chunk_size);
  2509. if (n == NULL) return NULL;
  2510. n->data_left = chunk_size - sizeof(*n);
  2511. p = stb__try_chunk(n, size, align, pre_align);
  2512. if (p != NULL) {
  2513. n->next = c;
  2514. stb__setchunks(src, n);
  2515. // if we just used up the whole block immediately,
  2516. // move the following chunk up
  2517. n->alloc = 1;
  2518. if (size == chunk_size)
  2519. stb__sort_chunks(src);
  2520. return p;
  2521. }
  2522. free(n);
  2523. chunk_size += 16+align;
  2524. }
  2525. }
  2526. }
  2527. static stb__alloc * stb__get_context(void *context)
  2528. {
  2529. if (context == NULL) {
  2530. return &stb__alloc_global;
  2531. } else {
  2532. int u = stb__identify(context);
  2533. // if context is chunked, grab parent
  2534. if (u == STB__chunked) {
  2535. stb__chunked *s = (stb__chunked *) context - 1;
  2536. return stb__parent(s);
  2537. } else {
  2538. return (stb__alloc *) context - 1;
  2539. }
  2540. }
  2541. }
  2542. static void stb__insert_alloc(stb__alloc *src, stb__alloc *s)
  2543. {
  2544. s->prevn = &src->child;
  2545. s->next = src->child;
  2546. src->child = s+1;
  2547. if (s->next)
  2548. *stb__prevn(s->next) = &s->next;
  2549. }
  2550. static void stb__insert_nochild(stb__alloc *src, stb__nochildren *s)
  2551. {
  2552. s->prevn = &src->child;
  2553. s->next = src->child;
  2554. src->child = s+1;
  2555. if (s->next)
  2556. *stb__prevn(s->next) = &s->next;
  2557. }
  2558. static void * malloc_base(void *context, size_t size, stb__alloc_type t, int align)
  2559. {
  2560. void *p;
  2561. stb__alloc *src = stb__get_context(context);
  2562. if (align <= 0) {
  2563. // compute worst-case C packed alignment
  2564. // e.g. a 24-byte struct is 8-aligned
  2565. int align_proposed = 1 << stb_lowbit8((unsigned int) size);
  2566. if (align_proposed < 0)
  2567. align_proposed = 4;
  2568. if (align_proposed == 0) {
  2569. if (size == 0)
  2570. align_proposed = 1;
  2571. else
  2572. align_proposed = 256;
  2573. }
  2574. // a negative alignment means 'don't align any larger
  2575. // than this'; so -16 means we align 1,2,4,8, or 16
  2576. if (align < 0) {
  2577. if (align_proposed > -align)
  2578. align_proposed = -align;
  2579. }
  2580. align = align_proposed;
  2581. }
  2582. assert(stb_is_pow2(align));
  2583. // don't cause misalignment when allocating nochildren
  2584. if (t == STB__nochildren && align > 8)
  2585. t = STB__alloc;
  2586. switch (t) {
  2587. case STB__alloc: {
  2588. stb__alloc *s = (stb__alloc *) malloc(size + sizeof(*s));
  2589. if (s == NULL) return NULL;
  2590. p = s+1;
  2591. s->child = NULL;
  2592. stb__insert_alloc(src, s);
  2593. stb__setchunks(s,NULL);
  2594. break;
  2595. }
  2596. case STB__nochildren: {
  2597. stb__nochildren *s = (stb__nochildren *) malloc(size + sizeof(*s));
  2598. if (s == NULL) return NULL;
  2599. p = s+1;
  2600. stb__insert_nochild(src, s);
  2601. break;
  2602. }
  2603. case STB__chunk_raw: {
  2604. p = stb__alloc_chunk(src, (int) size, align, 0);
  2605. if (p == NULL) return NULL;
  2606. break;
  2607. }
  2608. case STB__chunked: {
  2609. stb__chunked *s;
  2610. if (align < sizeof(stb_uintptr)) align = sizeof(stb_uintptr);
  2611. s = (stb__chunked *) stb__alloc_chunk(src, (int) size, align, sizeof(*s));
  2612. if (s == NULL) return NULL;
  2613. stb__setparent(s, src);
  2614. p = s+1;
  2615. break;
  2616. }
  2617. default: p = NULL; assert(0); /* NOTREACHED */
  2618. }
  2619. ++stb_alloc_count_alloc;
  2620. return p;
  2621. }
  2622. void *stb_malloc_global(size_t size)
  2623. {
  2624. return malloc_base(NULL, size, STB__alloc, stb_alloc_alignment);
  2625. }
  2626. void *stb_malloc(void *context, size_t size)
  2627. {
  2628. return malloc_base(context, size, STB__alloc, stb_alloc_alignment);
  2629. }
  2630. void *stb_malloc_nofree(void *context, size_t size)
  2631. {
  2632. return malloc_base(context, size, STB__chunked, stb_alloc_alignment);
  2633. }
  2634. void *stb_malloc_leaf(void *context, size_t size)
  2635. {
  2636. return malloc_base(context, size, STB__nochildren, stb_alloc_alignment);
  2637. }
  2638. void *stb_malloc_raw(void *context, size_t size)
  2639. {
  2640. return malloc_base(context, size, STB__chunk_raw, stb_alloc_alignment);
  2641. }
  2642. char *stb_malloc_string(void *context, size_t size)
  2643. {
  2644. return (char *) malloc_base(context, size, STB__chunk_raw, 1);
  2645. }
  2646. void *stb_realloc(void *ptr, size_t newsize)
  2647. {
  2648. stb__alloc_type t;
  2649. if (ptr == NULL) return stb_malloc(NULL, newsize);
  2650. if (newsize == 0) { stb_free(ptr); return NULL; }
  2651. t = stb__identify(ptr);
  2652. assert(t == STB__alloc || t == STB__nochildren);
  2653. if (t == STB__alloc) {
  2654. stb__alloc *s = (stb__alloc *) ptr - 1;
  2655. s = (stb__alloc *) realloc(s, newsize + sizeof(*s));
  2656. if (s == NULL) return NULL;
  2657. ptr = s+1;
  2658. // update pointers
  2659. (*s->prevn) = ptr;
  2660. if (s->next)
  2661. *stb__prevn(s->next) = &s->next;
  2662. if (s->child)
  2663. *stb__prevn(s->child) = &s->child;
  2664. return ptr;
  2665. } else {
  2666. stb__nochildren *s = (stb__nochildren *) ptr - 1;
  2667. s = (stb__nochildren *) realloc(ptr, newsize + sizeof(s));
  2668. if (s == NULL) return NULL;
  2669. // update pointers
  2670. (*s->prevn) = s+1;
  2671. if (s->next)
  2672. *stb__prevn(s->next) = &s->next;
  2673. return s+1;
  2674. }
  2675. }
  2676. void *stb_realloc_c(void *context, void *ptr, size_t newsize)
  2677. {
  2678. if (ptr == NULL) return stb_malloc(context, newsize);
  2679. if (newsize == 0) { stb_free(ptr); return NULL; }
  2680. // @TODO: verify you haven't changed contexts
  2681. return stb_realloc(ptr, newsize);
  2682. }
  2683. void stb_reassign(void *new_context, void *ptr)
  2684. {
  2685. stb__alloc *src = stb__get_context(new_context);
  2686. stb__alloc_type t = stb__identify(ptr);
  2687. assert(t == STB__alloc || t == STB__nochildren);
  2688. if (t == STB__alloc) {
  2689. stb__alloc *s = (stb__alloc *) ptr - 1;
  2690. // unlink from old
  2691. *(s->prevn) = s->next;
  2692. if (s->next)
  2693. *stb__prevn(s->next) = s->prevn;
  2694. stb__insert_alloc(src, s);
  2695. } else {
  2696. stb__nochildren *s = (stb__nochildren *) ptr - 1;
  2697. // unlink from old
  2698. *(s->prevn) = s->next;
  2699. if (s->next)
  2700. *stb__prevn(s->next) = s->prevn;
  2701. stb__insert_nochild(src, s);
  2702. }
  2703. }
  2704. #endif
  2705. //////////////////////////////////////////////////////////////////////////////
  2706. //
  2707. // stb_arr
  2708. //
  2709. // An stb_arr is directly useable as a pointer (use the actual type in your
  2710. // definition), but when it resizes, it returns a new pointer and you can't
  2711. // use the old one, so you have to be careful to copy-in-out as necessary.
  2712. //
  2713. // Use a NULL pointer as a 0-length array.
  2714. //
  2715. // float *my_array = NULL, *temp;
  2716. //
  2717. // // add elements on the end one at a time
  2718. // stb_arr_push(my_array, 0.0f);
  2719. // stb_arr_push(my_array, 1.0f);
  2720. // stb_arr_push(my_array, 2.0f);
  2721. //
  2722. // assert(my_array[1] == 2.0f);
  2723. //
  2724. // // add an uninitialized element at the end, then assign it
  2725. // *stb_arr_add(my_array) = 3.0f;
  2726. //
  2727. // // add three uninitialized elements at the end
  2728. // temp = stb_arr_addn(my_array,3);
  2729. // temp[0] = 4.0f;
  2730. // temp[1] = 5.0f;
  2731. // temp[2] = 6.0f;
  2732. //
  2733. // assert(my_array[5] == 5.0f);
  2734. //
  2735. // // remove the last one
  2736. // stb_arr_pop(my_array);
  2737. //
  2738. // assert(stb_arr_len(my_array) == 6);
  2739. #ifdef STB_MALLOC_WRAPPER
  2740. #define STB__PARAMS , char *file, int line
  2741. #define STB__ARGS , file, line
  2742. #else
  2743. #define STB__PARAMS
  2744. #define STB__ARGS
  2745. #endif
  2746. // calling this function allocates an empty stb_arr attached to p
  2747. // (whereas NULL isn't attached to anything)
  2748. STB_EXTERN void stb_arr_malloc(void **target, void *context);
  2749. // call this function with a non-NULL value to have all successive
  2750. // stbs that are created be attached to the associated parent. Note
  2751. // that once a given stb_arr is non-empty, it stays attached to its
  2752. // current parent, even if you call this function again.
  2753. // it turns the previous value, so you can restore it
  2754. STB_EXTERN void* stb_arr_malloc_parent(void *p);
  2755. // simple functions written on top of other functions
  2756. #define stb_arr_empty(a) ( stb_arr_len(a) == 0 )
  2757. #define stb_arr_add(a) ( stb_arr_addn((a),1) )
  2758. #define stb_arr_push(a,v) ( *stb_arr_add(a)=(v) )
  2759. typedef struct
  2760. {
  2761. int len, limit;
  2762. int stb_malloc;
  2763. unsigned int signature;
  2764. } stb__arr;
  2765. #define stb_arr_signature 0x51bada7b // ends with 0123 in decimal
  2766. // access the header block stored before the data
  2767. #define stb_arrhead(a) /*lint --e(826)*/ (((stb__arr *) (a)) - 1)
  2768. #define stb_arrhead2(a) /*lint --e(826)*/ (((stb__arr *) (a)) - 1)
  2769. #ifdef STB_DEBUG
  2770. #define stb_arr_check(a) assert(!a || stb_arrhead(a)->signature == stb_arr_signature)
  2771. #define stb_arr_check2(a) assert(!a || stb_arrhead2(a)->signature == stb_arr_signature)
  2772. #else
  2773. #define stb_arr_check(a) ((void) 0)
  2774. #define stb_arr_check2(a) ((void) 0)
  2775. #endif
  2776. // ARRAY LENGTH
  2777. // get the array length; special case if pointer is NULL
  2778. #define stb_arr_len(a) (a ? stb_arrhead(a)->len : 0)
  2779. #define stb_arr_len2(a) ((stb__arr *) (a) ? stb_arrhead2(a)->len : 0)
  2780. #define stb_arr_lastn(a) (stb_arr_len(a)-1)
  2781. // check whether a given index is valid -- tests 0 <= i < stb_arr_len(a)
  2782. #define stb_arr_valid(a,i) (a ? (int) (i) < stb_arrhead(a)->len : 0)
  2783. // change the array length so is is exactly N entries long, creating
  2784. // uninitialized entries as needed
  2785. #define stb_arr_setlen(a,n) \
  2786. (stb__arr_setlen((void **) &(a), sizeof(a[0]), (n)))
  2787. // change the array length so that N is a valid index (that is, so
  2788. // it is at least N entries long), creating uninitialized entries as needed
  2789. #define stb_arr_makevalid(a,n) \
  2790. (stb_arr_len(a) < (n)+1 ? stb_arr_setlen(a,(n)+1),(a) : (a))
  2791. // remove the last element of the array, returning it
  2792. #define stb_arr_pop(a) ((stb_arr_check(a), (a))[--stb_arrhead(a)->len])
  2793. // access the last element in the array
  2794. #define stb_arr_last(a) ((stb_arr_check(a), (a))[stb_arr_len(a)-1])
  2795. // is iterator at end of list?
  2796. #define stb_arr_end(a,i) ((i) >= &(a)[stb_arr_len(a)])
  2797. // (internal) change the allocated length of the array
  2798. #define stb_arr__grow(a,n) (stb_arr_check(a), stb_arrhead(a)->len += (n))
  2799. // add N new uninitialized elements to the end of the array
  2800. #define stb_arr__addn(a,n) /*lint --e(826)*/ \
  2801. ((stb_arr_len(a)+(n) > stb_arrcurmax(a)) \
  2802. ? (stb__arr_addlen((void **) &(a),sizeof(*a),(n)),0) \
  2803. : ((stb_arr__grow(a,n), 0)))
  2804. // add N new uninitialized elements to the end of the array, and return
  2805. // a pointer to the first new one
  2806. #define stb_arr_addn(a,n) (stb_arr__addn((a),n),(a)+stb_arr_len(a)-(n))
  2807. // add N new uninitialized elements starting at index 'i'
  2808. #define stb_arr_insertn(a,i,n) (stb__arr_insertn((void **) &(a), sizeof(*a), (i), (n)))
  2809. // insert an element at i
  2810. #define stb_arr_insert(a,i,v) (stb__arr_insertn((void **) &(a), sizeof(*a), (i), (1)), ((a)[i] = v))
  2811. // delete N elements from the middle starting at index 'i'
  2812. #define stb_arr_deleten(a,i,n) (stb__arr_deleten((void **) &(a), sizeof(*a), (i), (n)))
  2813. // delete the i'th element
  2814. #define stb_arr_delete(a,i) stb_arr_deleten(a,i,1)
  2815. // delete the i'th element, swapping down from the end
  2816. #define stb_arr_fastdelete(a,i) \
  2817. (stb_swap(&a[i], &a[stb_arrhead(a)->len-1], sizeof(*a)), stb_arr_pop(a))
  2818. // ARRAY STORAGE
  2819. // get the array maximum storage; special case if NULL
  2820. #define stb_arrcurmax(a) (a ? stb_arrhead(a)->limit : 0)
  2821. #define stb_arrcurmax2(a) (a ? stb_arrhead2(a)->limit : 0)
  2822. // set the maxlength of the array to n in anticipation of further growth
  2823. #define stb_arr_setsize(a,n) (stb_arr_check(a), stb__arr_setsize((void **) &(a),sizeof((a)[0]),n))
  2824. // make sure maxlength is large enough for at least N new allocations
  2825. #define stb_arr_atleast(a,n) (stb_arr_len(a)+(n) > stb_arrcurmax(a) \
  2826. ? stb_arr_setsize((a), (n)) : 0)
  2827. // make a copy of a given array (copies contents via 'memcpy'!)
  2828. #define stb_arr_copy(a) stb__arr_copy(a, sizeof((a)[0]))
  2829. // compute the storage needed to store all the elements of the array
  2830. #define stb_arr_storage(a) (stb_arr_len(a) * sizeof((a)[0]))
  2831. #define stb_arr_for(v,arr) for((v)=(arr); (v) < (arr)+stb_arr_len(arr); ++(v))
  2832. // IMPLEMENTATION
  2833. STB_EXTERN void stb_arr_free_(void **p);
  2834. STB_EXTERN void *stb__arr_copy_(void *p, int elem_size);
  2835. STB_EXTERN void stb__arr_setsize_(void **p, int size, int limit STB__PARAMS);
  2836. STB_EXTERN void stb__arr_setlen_(void **p, int size, int newlen STB__PARAMS);
  2837. STB_EXTERN void stb__arr_addlen_(void **p, int size, int addlen STB__PARAMS);
  2838. STB_EXTERN void stb__arr_deleten_(void **p, int size, int loc, int n STB__PARAMS);
  2839. STB_EXTERN void stb__arr_insertn_(void **p, int size, int loc, int n STB__PARAMS);
  2840. #define stb_arr_free(p) stb_arr_free_((void **) &(p))
  2841. #define stb__arr_copy stb__arr_copy_
  2842. #ifndef STB_MALLOC_WRAPPER
  2843. #define stb__arr_setsize stb__arr_setsize_
  2844. #define stb__arr_setlen stb__arr_setlen_
  2845. #define stb__arr_addlen stb__arr_addlen_
  2846. #define stb__arr_deleten stb__arr_deleten_
  2847. #define stb__arr_insertn stb__arr_insertn_
  2848. #else
  2849. #define stb__arr_addlen(p,s,n) stb__arr_addlen_(p,s,n,__FILE__,__LINE__)
  2850. #define stb__arr_setlen(p,s,n) stb__arr_setlen_(p,s,n,__FILE__,__LINE__)
  2851. #define stb__arr_setsize(p,s,n) stb__arr_setsize_(p,s,n,__FILE__,__LINE__)
  2852. #define stb__arr_deleten(p,s,i,n) stb__arr_deleten_(p,s,i,n,__FILE__,__LINE__)
  2853. #define stb__arr_insertn(p,s,i,n) stb__arr_insertn_(p,s,i,n,__FILE__,__LINE__)
  2854. #endif
  2855. #ifdef STB_DEFINE
  2856. static void *stb__arr_context;
  2857. void *stb_arr_malloc_parent(void *p)
  2858. {
  2859. void *q = stb__arr_context;
  2860. stb__arr_context = p;
  2861. return q;
  2862. }
  2863. void stb_arr_malloc(void **target, void *context)
  2864. {
  2865. stb__arr *q = (stb__arr *) stb_malloc(context, sizeof(*q));
  2866. q->len = q->limit = 0;
  2867. q->stb_malloc = 1;
  2868. q->signature = stb_arr_signature;
  2869. *target = (void *) (q+1);
  2870. }
  2871. static void * stb__arr_malloc(int size)
  2872. {
  2873. if (stb__arr_context)
  2874. return stb_malloc(stb__arr_context, size);
  2875. return malloc(size);
  2876. }
  2877. void * stb__arr_copy_(void *p, int elem_size)
  2878. {
  2879. stb__arr *q;
  2880. if (p == NULL) return p;
  2881. q = (stb__arr *) stb__arr_malloc(sizeof(*q) + elem_size * stb_arrhead2(p)->limit);
  2882. stb_arr_check2(p);
  2883. memcpy(q, stb_arrhead2(p), sizeof(*q) + elem_size * stb_arrhead2(p)->len);
  2884. q->stb_malloc = !!stb__arr_context;
  2885. return q+1;
  2886. }
  2887. void stb_arr_free_(void **pp)
  2888. {
  2889. void *p = *pp;
  2890. stb_arr_check2(p);
  2891. if (p) {
  2892. stb__arr *q = stb_arrhead2(p);
  2893. if (q->stb_malloc)
  2894. stb_free(q);
  2895. else
  2896. free(q);
  2897. }
  2898. *pp = NULL;
  2899. }
  2900. static void stb__arrsize_(void **pp, int size, int limit, int len STB__PARAMS)
  2901. {
  2902. void *p = *pp;
  2903. stb__arr *a;
  2904. stb_arr_check2(p);
  2905. if (p == NULL) {
  2906. if (len == 0 && size == 0) return;
  2907. a = (stb__arr *) stb__arr_malloc(sizeof(*a) + size*limit);
  2908. a->limit = limit;
  2909. a->len = len;
  2910. a->stb_malloc = !!stb__arr_context;
  2911. a->signature = stb_arr_signature;
  2912. } else {
  2913. a = stb_arrhead2(p);
  2914. a->len = len;
  2915. if (a->limit < limit) {
  2916. void *p;
  2917. if (a->limit >= 4 && limit < a->limit * 2)
  2918. limit = a->limit * 2;
  2919. if (a->stb_malloc)
  2920. p = stb_realloc(a, sizeof(*a) + limit*size);
  2921. else
  2922. #ifdef STB_MALLOC_WRAPPER
  2923. p = stb__realloc(a, sizeof(*a) + limit*size, file, line);
  2924. #else
  2925. p = realloc(a, sizeof(*a) + limit*size);
  2926. #endif
  2927. if (p) {
  2928. a = (stb__arr *) p;
  2929. a->limit = limit;
  2930. } else {
  2931. // throw an error!
  2932. }
  2933. }
  2934. }
  2935. a->len = stb_min(a->len, a->limit);
  2936. *pp = a+1;
  2937. }
  2938. void stb__arr_setsize_(void **pp, int size, int limit STB__PARAMS)
  2939. {
  2940. void *p = *pp;
  2941. stb_arr_check2(p);
  2942. stb__arrsize_(pp, size, limit, stb_arr_len2(p) STB__ARGS);
  2943. }
  2944. void stb__arr_setlen_(void **pp, int size, int newlen STB__PARAMS)
  2945. {
  2946. void *p = *pp;
  2947. stb_arr_check2(p);
  2948. if (stb_arrcurmax2(p) < newlen || p == NULL) {
  2949. stb__arrsize_(pp, size, newlen, newlen STB__ARGS);
  2950. } else {
  2951. stb_arrhead2(p)->len = newlen;
  2952. }
  2953. }
  2954. void stb__arr_addlen_(void **p, int size, int addlen STB__PARAMS)
  2955. {
  2956. stb__arr_setlen_(p, size, stb_arr_len2(*p) + addlen STB__ARGS);
  2957. }
  2958. void stb__arr_insertn_(void **pp, int size, int i, int n STB__PARAMS)
  2959. {
  2960. void *p = *pp;
  2961. if (n) {
  2962. int z;
  2963. if (p == NULL) {
  2964. stb__arr_addlen_(pp, size, n STB__ARGS);
  2965. return;
  2966. }
  2967. z = stb_arr_len2(p);
  2968. stb__arr_addlen_(&p, size, n STB__ARGS);
  2969. memmove((char *) p + (i+n)*size, (char *) p + i*size, size * (z-i));
  2970. }
  2971. *pp = p;
  2972. }
  2973. void stb__arr_deleten_(void **pp, int size, int i, int n STB__PARAMS)
  2974. {
  2975. void *p = *pp;
  2976. if (n) {
  2977. memmove((char *) p + i*size, (char *) p + (i+n)*size, size * (stb_arr_len2(p)-(i+n)));
  2978. stb_arrhead2(p)->len -= n;
  2979. }
  2980. *pp = p;
  2981. }
  2982. #endif
  2983. //////////////////////////////////////////////////////////////////////////////
  2984. //
  2985. // Hashing
  2986. //
  2987. // typical use for this is to make a power-of-two hash table.
  2988. //
  2989. // let N = size of table (2^n)
  2990. // let H = stb_hash(str)
  2991. // let S = stb_rehash(H) | 1
  2992. //
  2993. // then hash probe sequence P(i) for i=0..N-1
  2994. // P(i) = (H + S*i) & (N-1)
  2995. //
  2996. // the idea is that H has 32 bits of hash information, but the
  2997. // table has only, say, 2^20 entries so only uses 20 of the bits.
  2998. // then by rehashing the original H we get 2^12 different probe
  2999. // sequences for a given initial probe location. (So it's optimal
  3000. // for 64K tables and its optimality decreases past that.)
  3001. //
  3002. // ok, so I've added something that generates _two separate_
  3003. // 32-bit hashes simultaneously which should scale better to
  3004. // very large tables.
  3005. STB_EXTERN unsigned int stb_hash(char *str);
  3006. STB_EXTERN unsigned int stb_hashptr(void *p);
  3007. STB_EXTERN unsigned int stb_hashlen(char *str, int len);
  3008. STB_EXTERN unsigned int stb_rehash_improved(unsigned int v);
  3009. STB_EXTERN unsigned int stb_hash_fast(void *p, int len);
  3010. STB_EXTERN unsigned int stb_hash2(char *str, unsigned int *hash2_ptr);
  3011. STB_EXTERN unsigned int stb_hash_number(unsigned int hash);
  3012. #define stb_rehash(x) ((x) + ((x) >> 6) + ((x) >> 19))
  3013. #ifdef STB_DEFINE
  3014. unsigned int stb_hash(char *str)
  3015. {
  3016. unsigned int hash = 0;
  3017. while (*str)
  3018. hash = (hash << 7) + (hash >> 25) + *str++;
  3019. return hash + (hash >> 16);
  3020. }
  3021. unsigned int stb_hashlen(char *str, int len)
  3022. {
  3023. unsigned int hash = 0;
  3024. while (len-- > 0 && *str)
  3025. hash = (hash << 7) + (hash >> 25) + *str++;
  3026. return hash + (hash >> 16);
  3027. }
  3028. unsigned int stb_hashptr(void *p)
  3029. {
  3030. unsigned int x = (unsigned int)(size_t) p;
  3031. // typically lacking in low bits and high bits
  3032. x = stb_rehash(x);
  3033. x += x << 16;
  3034. // pearson's shuffle
  3035. x ^= x << 3;
  3036. x += x >> 5;
  3037. x ^= x << 2;
  3038. x += x >> 15;
  3039. x ^= x << 10;
  3040. return stb_rehash(x);
  3041. }
  3042. unsigned int stb_rehash_improved(unsigned int v)
  3043. {
  3044. return stb_hashptr((void *)(size_t) v);
  3045. }
  3046. unsigned int stb_hash2(char *str, unsigned int *hash2_ptr)
  3047. {
  3048. unsigned int hash1 = 0x3141592c;
  3049. unsigned int hash2 = 0x77f044ed;
  3050. while (*str) {
  3051. hash1 = (hash1 << 7) + (hash1 >> 25) + *str;
  3052. hash2 = (hash2 << 11) + (hash2 >> 21) + *str;
  3053. ++str;
  3054. }
  3055. *hash2_ptr = hash2 + (hash1 >> 16);
  3056. return hash1 + (hash2 >> 16);
  3057. }
  3058. // Paul Hsieh hash
  3059. #define stb__get16(p) ((p)[0] | ((p)[1] << 8))
  3060. unsigned int stb_hash_fast(void *p, int len)
  3061. {
  3062. unsigned char *q = (unsigned char *) p;
  3063. unsigned int hash = len;
  3064. if (len <= 0 || q == NULL) return 0;
  3065. /* Main loop */
  3066. for (;len > 3; len -= 4) {
  3067. unsigned int val;
  3068. hash += stb__get16(q);
  3069. val = (stb__get16(q+2) << 11);
  3070. hash = (hash << 16) ^ hash ^ val;
  3071. q += 4;
  3072. hash += hash >> 11;
  3073. }
  3074. /* Handle end cases */
  3075. switch (len) {
  3076. case 3: hash += stb__get16(q);
  3077. hash ^= hash << 16;
  3078. hash ^= q[2] << 18;
  3079. hash += hash >> 11;
  3080. break;
  3081. case 2: hash += stb__get16(q);
  3082. hash ^= hash << 11;
  3083. hash += hash >> 17;
  3084. break;
  3085. case 1: hash += q[0];
  3086. hash ^= hash << 10;
  3087. hash += hash >> 1;
  3088. break;
  3089. case 0: break;
  3090. }
  3091. /* Force "avalanching" of final 127 bits */
  3092. hash ^= hash << 3;
  3093. hash += hash >> 5;
  3094. hash ^= hash << 4;
  3095. hash += hash >> 17;
  3096. hash ^= hash << 25;
  3097. hash += hash >> 6;
  3098. return hash;
  3099. }
  3100. unsigned int stb_hash_number(unsigned int hash)
  3101. {
  3102. hash ^= hash << 3;
  3103. hash += hash >> 5;
  3104. hash ^= hash << 4;
  3105. hash += hash >> 17;
  3106. hash ^= hash << 25;
  3107. hash += hash >> 6;
  3108. return hash;
  3109. }
  3110. #endif
  3111. #ifdef STB_PERFECT_HASH
  3112. //////////////////////////////////////////////////////////////////////////////
  3113. //
  3114. // Perfect hashing for ints/pointers
  3115. //
  3116. // This is mainly useful for making faster pointer-indexed tables
  3117. // that don't change frequently. E.g. for stb_ischar().
  3118. //
  3119. typedef struct
  3120. {
  3121. stb_uint32 addend;
  3122. stb_uint multiplicand;
  3123. stb_uint b_mask;
  3124. stb_uint8 small_bmap[16];
  3125. stb_uint16 *large_bmap;
  3126. stb_uint table_mask;
  3127. stb_uint32 *table;
  3128. } stb_perfect;
  3129. STB_EXTERN int stb_perfect_create(stb_perfect *,unsigned int*,int n);
  3130. STB_EXTERN void stb_perfect_destroy(stb_perfect *);
  3131. STB_EXTERN int stb_perfect_hash(stb_perfect *, unsigned int x);
  3132. extern int stb_perfect_hash_max_failures;
  3133. #ifdef STB_DEFINE
  3134. int stb_perfect_hash_max_failures;
  3135. int stb_perfect_hash(stb_perfect *p, unsigned int x)
  3136. {
  3137. stb_uint m = x * p->multiplicand;
  3138. stb_uint y = x >> 16;
  3139. stb_uint bv = (m >> 24) + y;
  3140. stb_uint av = (m + y) >> 12;
  3141. if (p->table == NULL) return -1; // uninitialized table fails
  3142. bv &= p->b_mask;
  3143. av &= p->table_mask;
  3144. if (p->large_bmap)
  3145. av ^= p->large_bmap[bv];
  3146. else
  3147. av ^= p->small_bmap[bv];
  3148. return p->table[av] == x ? av : -1;
  3149. }
  3150. static void stb__perfect_prehash(stb_perfect *p, stb_uint x, stb_uint16 *a, stb_uint16 *b)
  3151. {
  3152. stb_uint m = x * p->multiplicand;
  3153. stb_uint y = x >> 16;
  3154. stb_uint bv = (m >> 24) + y;
  3155. stb_uint av = (m + y) >> 12;
  3156. bv &= p->b_mask;
  3157. av &= p->table_mask;
  3158. *b = bv;
  3159. *a = av;
  3160. }
  3161. static unsigned long stb__perfect_rand(void)
  3162. {
  3163. static unsigned long stb__rand;
  3164. stb__rand = stb__rand * 2147001325 + 715136305;
  3165. return 0x31415926 ^ ((stb__rand >> 16) + (stb__rand << 16));
  3166. }
  3167. typedef struct {
  3168. unsigned short count;
  3169. unsigned short b;
  3170. unsigned short map;
  3171. unsigned short *entries;
  3172. } stb__slot;
  3173. static int stb__slot_compare(const void *p, const void *q)
  3174. {
  3175. stb__slot *a = (stb__slot *) p;
  3176. stb__slot *b = (stb__slot *) q;
  3177. return a->count > b->count ? -1 : a->count < b->count; // sort large to small
  3178. }
  3179. int stb_perfect_create(stb_perfect *p, unsigned int *v, int n)
  3180. {
  3181. unsigned int buffer1[64], buffer2[64], buffer3[64], buffer4[64], buffer5[32];
  3182. unsigned short *as = (unsigned short *) stb_temp(buffer1, sizeof(*v)*n);
  3183. unsigned short *bs = (unsigned short *) stb_temp(buffer2, sizeof(*v)*n);
  3184. unsigned short *entries = (unsigned short *) stb_temp(buffer4, sizeof(*entries) * n);
  3185. int size = 1 << stb_log2_ceil(n), bsize=8;
  3186. int failure = 0,i,j,k;
  3187. assert(n <= 32768);
  3188. p->large_bmap = NULL;
  3189. for(;;) {
  3190. stb__slot *bcount = (stb__slot *) stb_temp(buffer3, sizeof(*bcount) * bsize);
  3191. unsigned short *bloc = (unsigned short *) stb_temp(buffer5, sizeof(*bloc) * bsize);
  3192. unsigned short *e;
  3193. int bad=0;
  3194. p->addend = stb__perfect_rand();
  3195. p->multiplicand = stb__perfect_rand() | 1;
  3196. p->table_mask = size-1;
  3197. p->b_mask = bsize-1;
  3198. p->table = (stb_uint32 *) malloc(size * sizeof(*p->table));
  3199. for (i=0; i < bsize; ++i) {
  3200. bcount[i].b = i;
  3201. bcount[i].count = 0;
  3202. bcount[i].map = 0;
  3203. }
  3204. for (i=0; i < n; ++i) {
  3205. stb__perfect_prehash(p, v[i], as+i, bs+i);
  3206. ++bcount[bs[i]].count;
  3207. }
  3208. qsort(bcount, bsize, sizeof(*bcount), stb__slot_compare);
  3209. e = entries; // now setup up their entries index
  3210. for (i=0; i < bsize; ++i) {
  3211. bcount[i].entries = e;
  3212. e += bcount[i].count;
  3213. bcount[i].count = 0;
  3214. bloc[bcount[i].b] = i;
  3215. }
  3216. // now fill them out
  3217. for (i=0; i < n; ++i) {
  3218. int b = bs[i];
  3219. int w = bloc[b];
  3220. bcount[w].entries[bcount[w].count++] = i;
  3221. }
  3222. stb_tempfree(buffer5,bloc);
  3223. // verify
  3224. for (i=0; i < bsize; ++i)
  3225. for (j=0; j < bcount[i].count; ++j)
  3226. assert(bs[bcount[i].entries[j]] == bcount[i].b);
  3227. memset(p->table, 0, size*sizeof(*p->table));
  3228. // check if any b has duplicate a
  3229. for (i=0; i < bsize; ++i) {
  3230. if (bcount[i].count > 1) {
  3231. for (j=0; j < bcount[i].count; ++j) {
  3232. if (p->table[as[bcount[i].entries[j]]])
  3233. bad = 1;
  3234. p->table[as[bcount[i].entries[j]]] = 1;
  3235. }
  3236. for (j=0; j < bcount[i].count; ++j) {
  3237. p->table[as[bcount[i].entries[j]]] = 0;
  3238. }
  3239. if (bad) break;
  3240. }
  3241. }
  3242. if (!bad) {
  3243. // go through the bs and populate the table, first fit
  3244. for (i=0; i < bsize; ++i) {
  3245. if (bcount[i].count) {
  3246. // go through the candidate table[b] values
  3247. for (j=0; j < size; ++j) {
  3248. // go through the a values and see if they fit
  3249. for (k=0; k < bcount[i].count; ++k) {
  3250. int a = as[bcount[i].entries[k]];
  3251. if (p->table[(a^j)&p->table_mask]) {
  3252. break; // fails
  3253. }
  3254. }
  3255. // if succeeded, accept
  3256. if (k == bcount[i].count) {
  3257. bcount[i].map = j;
  3258. for (k=0; k < bcount[i].count; ++k) {
  3259. int a = as[bcount[i].entries[k]];
  3260. p->table[(a^j)&p->table_mask] = 1;
  3261. }
  3262. break;
  3263. }
  3264. }
  3265. if (j == size)
  3266. break; // no match for i'th entry, so break out in failure
  3267. }
  3268. }
  3269. if (i == bsize) {
  3270. // success... fill out map
  3271. if (bsize <= 16 && size <= 256) {
  3272. p->large_bmap = NULL;
  3273. for (i=0; i < bsize; ++i)
  3274. p->small_bmap[bcount[i].b] = (stb_uint8) bcount[i].map;
  3275. } else {
  3276. p->large_bmap = (unsigned short *) malloc(sizeof(*p->large_bmap) * bsize);
  3277. for (i=0; i < bsize; ++i)
  3278. p->large_bmap[bcount[i].b] = bcount[i].map;
  3279. }
  3280. // initialize table to v[0], so empty slots will fail
  3281. for (i=0; i < size; ++i)
  3282. p->table[i] = v[0];
  3283. for (i=0; i < n; ++i)
  3284. if (p->large_bmap)
  3285. p->table[as[i] ^ p->large_bmap[bs[i]]] = v[i];
  3286. else
  3287. p->table[as[i] ^ p->small_bmap[bs[i]]] = v[i];
  3288. // and now validate that none of them collided
  3289. for (i=0; i < n; ++i)
  3290. assert(stb_perfect_hash(p, v[i]) >= 0);
  3291. stb_tempfree(buffer3, bcount);
  3292. break;
  3293. }
  3294. }
  3295. free(p->table);
  3296. p->table = NULL;
  3297. stb_tempfree(buffer3, bcount);
  3298. ++failure;
  3299. if (failure >= 4 && bsize < size) bsize *= 2;
  3300. if (failure >= 8 && (failure & 3) == 0 && size < 4*n) {
  3301. size *= 2;
  3302. bsize *= 2;
  3303. }
  3304. if (failure == 6) {
  3305. // make sure the input data is unique, so we don't infinite loop
  3306. unsigned int *data = (unsigned int *) stb_temp(buffer3, n * sizeof(*data));
  3307. memcpy(data, v, sizeof(*data) * n);
  3308. qsort(data, n, sizeof(*data), stb_intcmp(0));
  3309. for (i=1; i < n; ++i) {
  3310. if (data[i] == data[i-1])
  3311. size = 0; // size is return value, so 0 it
  3312. }
  3313. stb_tempfree(buffer3, data);
  3314. if (!size) break;
  3315. }
  3316. }
  3317. if (failure > stb_perfect_hash_max_failures)
  3318. stb_perfect_hash_max_failures = failure;
  3319. stb_tempfree(buffer1, as);
  3320. stb_tempfree(buffer2, bs);
  3321. stb_tempfree(buffer4, entries);
  3322. return size;
  3323. }
  3324. void stb_perfect_destroy(stb_perfect *p)
  3325. {
  3326. if (p->large_bmap) free(p->large_bmap);
  3327. if (p->table ) free(p->table);
  3328. p->large_bmap = NULL;
  3329. p->table = NULL;
  3330. p->b_mask = 0;
  3331. p->table_mask = 0;
  3332. }
  3333. #endif
  3334. //////////////////////////////////////////////////////////////////////////////
  3335. //
  3336. // Perfect hash clients
  3337. STB_EXTERN int stb_ischar(char s, char *set);
  3338. #ifdef STB_DEFINE
  3339. int stb_ischar(char c, char *set)
  3340. {
  3341. static unsigned char bit[8] = { 1,2,4,8,16,32,64,128 };
  3342. static stb_perfect p;
  3343. static unsigned char (*tables)[256];
  3344. static char ** sets = NULL;
  3345. int z = stb_perfect_hash(&p, (int)(size_t) set);
  3346. if (z < 0) {
  3347. int i,k,n,j,f;
  3348. // special code that means free all existing data
  3349. if (set == NULL) {
  3350. stb_arr_free(sets);
  3351. free(tables);
  3352. tables = NULL;
  3353. stb_perfect_destroy(&p);
  3354. return 0;
  3355. }
  3356. stb_arr_push(sets, set);
  3357. stb_perfect_destroy(&p);
  3358. n = stb_perfect_create(&p, (unsigned int *) (char **) sets, stb_arr_len(sets));
  3359. assert(n != 0);
  3360. k = (n+7) >> 3;
  3361. tables = (unsigned char (*)[256]) realloc(tables, sizeof(*tables) * k);
  3362. memset(tables, 0, sizeof(*tables) * k);
  3363. for (i=0; i < stb_arr_len(sets); ++i) {
  3364. k = stb_perfect_hash(&p, (int)(size_t) sets[i]);
  3365. assert(k >= 0);
  3366. n = k >> 3;
  3367. f = bit[k&7];
  3368. for (j=0; !j || sets[i][j]; ++j) {
  3369. tables[n][(unsigned char) sets[i][j]] |= f;
  3370. }
  3371. }
  3372. z = stb_perfect_hash(&p, (int)(size_t) set);
  3373. }
  3374. return tables[z >> 3][(unsigned char) c] & bit[z & 7];
  3375. }
  3376. #endif
  3377. #endif
  3378. //////////////////////////////////////////////////////////////////////////////
  3379. //
  3380. // Instantiated data structures
  3381. //
  3382. // This is an attempt to implement a templated data structure.
  3383. //
  3384. // Hash table: call stb_define_hash(TYPE,N,KEY,K1,K2,HASH,VALUE)
  3385. // TYPE -- will define a structure type containing the hash table
  3386. // N -- the name, will prefix functions named:
  3387. // N create
  3388. // N destroy
  3389. // N get
  3390. // N set, N add, N update,
  3391. // N remove
  3392. // KEY -- the type of the key. 'x == y' must be valid
  3393. // K1,K2 -- keys never used by the app, used as flags in the hashtable
  3394. // HASH -- a piece of code ending with 'return' that hashes key 'k'
  3395. // VALUE -- the type of the value. 'x = y' must be valid
  3396. //
  3397. // Note that stb_define_hash_base can be used to define more sophisticated
  3398. // hash tables, e.g. those that make copies of the key or use special
  3399. // comparisons (e.g. strcmp).
  3400. #define STB_(prefix,name) stb__##prefix##name
  3401. #define STB__(prefix,name) prefix##name
  3402. #define STB__use(x) x
  3403. #define STB__skip(x)
  3404. #define stb_declare_hash(PREFIX,TYPE,N,KEY,VALUE) \
  3405. typedef struct stb__st_##TYPE TYPE;\
  3406. PREFIX int STB__(N, init)(TYPE *h, int count);\
  3407. PREFIX int STB__(N, memory_usage)(TYPE *h);\
  3408. PREFIX TYPE * STB__(N, create)(void);\
  3409. PREFIX TYPE * STB__(N, copy)(TYPE *h);\
  3410. PREFIX void STB__(N, destroy)(TYPE *h);\
  3411. PREFIX int STB__(N,get_flag)(TYPE *a, KEY k, VALUE *v);\
  3412. PREFIX VALUE STB__(N,get)(TYPE *a, KEY k);\
  3413. PREFIX int STB__(N, set)(TYPE *a, KEY k, VALUE v);\
  3414. PREFIX int STB__(N, add)(TYPE *a, KEY k, VALUE v);\
  3415. PREFIX int STB__(N, update)(TYPE*a,KEY k,VALUE v);\
  3416. PREFIX int STB__(N, remove)(TYPE *a, KEY k, VALUE *v);
  3417. #define STB_nocopy(x) (x)
  3418. #define STB_nodelete(x) 0
  3419. #define STB_nofields
  3420. #define STB_nonullvalue(x)
  3421. #define STB_nullvalue(x) x
  3422. #define STB_safecompare(x) x
  3423. #define STB_nosafe(x)
  3424. #define STB_noprefix
  3425. #ifdef __GNUC__
  3426. #define STB__nogcc(x)
  3427. #else
  3428. #define STB__nogcc(x) x
  3429. #endif
  3430. #define stb_define_hash_base(PREFIX,TYPE,FIELDS,N,NC,LOAD_FACTOR, \
  3431. KEY,EMPTY,DEL,COPY,DISPOSE,SAFE, \
  3432. VCOMPARE,CCOMPARE,HASH, \
  3433. VALUE,HASVNULL,VNULL) \
  3434. \
  3435. typedef struct \
  3436. { \
  3437. KEY k; \
  3438. VALUE v; \
  3439. } STB_(N,_hashpair); \
  3440. \
  3441. STB__nogcc( typedef struct stb__st_##TYPE TYPE; ) \
  3442. struct stb__st_##TYPE { \
  3443. FIELDS \
  3444. STB_(N,_hashpair) *table; \
  3445. unsigned int mask; \
  3446. int count, limit; \
  3447. int deleted; \
  3448. \
  3449. int delete_threshhold; \
  3450. int grow_threshhold; \
  3451. int shrink_threshhold; \
  3452. unsigned char alloced, has_empty, has_del; \
  3453. VALUE ev; VALUE dv; \
  3454. }; \
  3455. \
  3456. static unsigned int STB_(N, hash)(KEY k) \
  3457. { \
  3458. HASH \
  3459. } \
  3460. \
  3461. PREFIX int STB__(N, init)(TYPE *h, int count) \
  3462. { \
  3463. int i; \
  3464. if (count < 4) count = 4; \
  3465. h->limit = count; \
  3466. h->count = 0; \
  3467. h->mask = count-1; \
  3468. h->deleted = 0; \
  3469. h->grow_threshhold = (int) (count * LOAD_FACTOR); \
  3470. h->has_empty = h->has_del = 0; \
  3471. h->alloced = 0; \
  3472. if (count <= 64) \
  3473. h->shrink_threshhold = 0; \
  3474. else \
  3475. h->shrink_threshhold = (int) (count * (LOAD_FACTOR/2.25)); \
  3476. h->delete_threshhold = (int) (count * (1-LOAD_FACTOR)/2); \
  3477. h->table = (STB_(N,_hashpair)*) malloc(sizeof(h->table[0]) * count); \
  3478. if (h->table == NULL) return 0; \
  3479. /* ideally this gets turned into a memset32 automatically */ \
  3480. for (i=0; i < count; ++i) \
  3481. h->table[i].k = EMPTY; \
  3482. return 1; \
  3483. } \
  3484. \
  3485. PREFIX int STB__(N, memory_usage)(TYPE *h) \
  3486. { \
  3487. return sizeof(*h) + h->limit * sizeof(h->table[0]); \
  3488. } \
  3489. \
  3490. PREFIX TYPE * STB__(N, create)(void) \
  3491. { \
  3492. TYPE *h = (TYPE *) malloc(sizeof(*h)); \
  3493. if (h) { \
  3494. if (STB__(N, init)(h, 16)) \
  3495. h->alloced = 1; \
  3496. else { free(h); h=NULL; } \
  3497. } \
  3498. return h; \
  3499. } \
  3500. \
  3501. PREFIX void STB__(N, destroy)(TYPE *a) \
  3502. { \
  3503. int i; \
  3504. for (i=0; i < a->limit; ++i) \
  3505. if (!CCOMPARE(a->table[i].k,EMPTY) && !CCOMPARE(a->table[i].k, DEL)) \
  3506. DISPOSE(a->table[i].k); \
  3507. free(a->table); \
  3508. if (a->alloced) \
  3509. free(a); \
  3510. } \
  3511. \
  3512. static void STB_(N, rehash)(TYPE *a, int count); \
  3513. \
  3514. PREFIX int STB__(N,get_flag)(TYPE *a, KEY k, VALUE *v) \
  3515. { \
  3516. unsigned int h = STB_(N, hash)(k); \
  3517. unsigned int n = h & a->mask, s; \
  3518. if (CCOMPARE(k,EMPTY)){ if (a->has_empty) *v = a->ev; return a->has_empty;}\
  3519. if (CCOMPARE(k,DEL)) { if (a->has_del ) *v = a->dv; return a->has_del; }\
  3520. if (CCOMPARE(a->table[n].k,EMPTY)) return 0; \
  3521. SAFE(if (!CCOMPARE(a->table[n].k,DEL))) \
  3522. if (VCOMPARE(a->table[n].k,k)) { *v = a->table[n].v; return 1; } \
  3523. s = stb_rehash(h) | 1; \
  3524. for(;;) { \
  3525. n = (n + s) & a->mask; \
  3526. if (CCOMPARE(a->table[n].k,EMPTY)) return 0; \
  3527. SAFE(if (CCOMPARE(a->table[n].k,DEL)) continue;) \
  3528. if (VCOMPARE(a->table[n].k,k)) \
  3529. { *v = a->table[n].v; return 1; } \
  3530. } \
  3531. } \
  3532. \
  3533. HASVNULL( \
  3534. PREFIX VALUE STB__(N,get)(TYPE *a, KEY k) \
  3535. { \
  3536. VALUE v; \
  3537. if (STB__(N,get_flag)(a,k,&v)) return v; \
  3538. else return VNULL; \
  3539. } \
  3540. ) \
  3541. \
  3542. PREFIX int STB__(N,getkey)(TYPE *a, KEY k, KEY *kout) \
  3543. { \
  3544. unsigned int h = STB_(N, hash)(k); \
  3545. unsigned int n = h & a->mask, s; \
  3546. if (CCOMPARE(k,EMPTY)||CCOMPARE(k,DEL)) return 0; \
  3547. if (CCOMPARE(a->table[n].k,EMPTY)) return 0; \
  3548. SAFE(if (!CCOMPARE(a->table[n].k,DEL))) \
  3549. if (VCOMPARE(a->table[n].k,k)) { *kout = a->table[n].k; return 1; } \
  3550. s = stb_rehash(h) | 1; \
  3551. for(;;) { \
  3552. n = (n + s) & a->mask; \
  3553. if (CCOMPARE(a->table[n].k,EMPTY)) return 0; \
  3554. SAFE(if (CCOMPARE(a->table[n].k,DEL)) continue;) \
  3555. if (VCOMPARE(a->table[n].k,k)) \
  3556. { *kout = a->table[n].k; return 1; } \
  3557. } \
  3558. } \
  3559. \
  3560. static int STB_(N,addset)(TYPE *a, KEY k, VALUE v, \
  3561. int allow_new, int allow_old, int copy) \
  3562. { \
  3563. unsigned int h = STB_(N, hash)(k); \
  3564. unsigned int n = h & a->mask; \
  3565. int b = -1; \
  3566. if (CCOMPARE(k,EMPTY)) { \
  3567. if (a->has_empty ? allow_old : allow_new) { \
  3568. n=a->has_empty; a->ev = v; a->has_empty = 1; return !n; \
  3569. } else return 0; \
  3570. } \
  3571. if (CCOMPARE(k,DEL)) { \
  3572. if (a->has_del ? allow_old : allow_new) { \
  3573. n=a->has_del; a->dv = v; a->has_del = 1; return !n; \
  3574. } else return 0; \
  3575. } \
  3576. if (!CCOMPARE(a->table[n].k, EMPTY)) { \
  3577. unsigned int s; \
  3578. if (CCOMPARE(a->table[n].k, DEL)) \
  3579. b = n; \
  3580. else if (VCOMPARE(a->table[n].k,k)) { \
  3581. if (allow_old) \
  3582. a->table[n].v = v; \
  3583. return !allow_new; \
  3584. } \
  3585. s = stb_rehash(h) | 1; \
  3586. for(;;) { \
  3587. n = (n + s) & a->mask; \
  3588. if (CCOMPARE(a->table[n].k, EMPTY)) break; \
  3589. if (CCOMPARE(a->table[n].k, DEL)) { \
  3590. if (b < 0) b = n; \
  3591. } else if (VCOMPARE(a->table[n].k,k)) { \
  3592. if (allow_old) \
  3593. a->table[n].v = v; \
  3594. return !allow_new; \
  3595. } \
  3596. } \
  3597. } \
  3598. if (!allow_new) return 0; \
  3599. if (b < 0) b = n; else --a->deleted; \
  3600. a->table[b].k = copy ? COPY(k) : k; \
  3601. a->table[b].v = v; \
  3602. ++a->count; \
  3603. if (a->count > a->grow_threshhold) \
  3604. STB_(N,rehash)(a, a->limit*2); \
  3605. return 1; \
  3606. } \
  3607. \
  3608. PREFIX int STB__(N, set)(TYPE *a, KEY k, VALUE v){return STB_(N,addset)(a,k,v,1,1,1);}\
  3609. PREFIX int STB__(N, add)(TYPE *a, KEY k, VALUE v){return STB_(N,addset)(a,k,v,1,0,1);}\
  3610. PREFIX int STB__(N, update)(TYPE*a,KEY k,VALUE v){return STB_(N,addset)(a,k,v,0,1,1);}\
  3611. \
  3612. PREFIX int STB__(N, remove)(TYPE *a, KEY k, VALUE *v) \
  3613. { \
  3614. unsigned int h = STB_(N, hash)(k); \
  3615. unsigned int n = h & a->mask, s; \
  3616. if (CCOMPARE(k,EMPTY)) { if (a->has_empty) { if(v)*v = a->ev; a->has_empty=0; return 1; } return 0; } \
  3617. if (CCOMPARE(k,DEL)) { if (a->has_del ) { if(v)*v = a->dv; a->has_del =0; return 1; } return 0; } \
  3618. if (CCOMPARE(a->table[n].k,EMPTY)) return 0; \
  3619. if (SAFE(CCOMPARE(a->table[n].k,DEL) || ) !VCOMPARE(a->table[n].k,k)) { \
  3620. s = stb_rehash(h) | 1; \
  3621. for(;;) { \
  3622. n = (n + s) & a->mask; \
  3623. if (CCOMPARE(a->table[n].k,EMPTY)) return 0; \
  3624. SAFE(if (CCOMPARE(a->table[n].k, DEL)) continue;) \
  3625. if (VCOMPARE(a->table[n].k,k)) break; \
  3626. } \
  3627. } \
  3628. DISPOSE(a->table[n].k); \
  3629. a->table[n].k = DEL; \
  3630. --a->count; \
  3631. ++a->deleted; \
  3632. if (v != NULL) \
  3633. *v = a->table[n].v; \
  3634. if (a->count < a->shrink_threshhold) \
  3635. STB_(N, rehash)(a, a->limit >> 1); \
  3636. else if (a->deleted > a->delete_threshhold) \
  3637. STB_(N, rehash)(a, a->limit); \
  3638. return 1; \
  3639. } \
  3640. \
  3641. PREFIX TYPE * STB__(NC, copy)(TYPE *a) \
  3642. { \
  3643. int i; \
  3644. TYPE *h = (TYPE *) malloc(sizeof(*h)); \
  3645. if (!h) return NULL; \
  3646. if (!STB__(N, init)(h, a->limit)) { free(h); return NULL; } \
  3647. h->count = a->count; \
  3648. h->deleted = a->deleted; \
  3649. h->alloced = 1; \
  3650. h->ev = a->ev; h->dv = a->dv; \
  3651. h->has_empty = a->has_empty; h->has_del = a->has_del; \
  3652. memcpy(h->table, a->table, h->limit * sizeof(h->table[0])); \
  3653. for (i=0; i < a->limit; ++i) \
  3654. if (!CCOMPARE(h->table[i].k,EMPTY) && !CCOMPARE(h->table[i].k,DEL)) \
  3655. h->table[i].k = COPY(h->table[i].k); \
  3656. return h; \
  3657. } \
  3658. \
  3659. static void STB_(N, rehash)(TYPE *a, int count) \
  3660. { \
  3661. int i; \
  3662. TYPE b; \
  3663. STB__(N, init)(&b, count); \
  3664. for (i=0; i < a->limit; ++i) \
  3665. if (!CCOMPARE(a->table[i].k,EMPTY) && !CCOMPARE(a->table[i].k,DEL)) \
  3666. STB_(N,addset)(&b, a->table[i].k, a->table[i].v,1,1,0); \
  3667. free(a->table); \
  3668. a->table = b.table; \
  3669. a->mask = b.mask; \
  3670. a->count = b.count; \
  3671. a->limit = b.limit; \
  3672. a->deleted = b.deleted; \
  3673. a->delete_threshhold = b.delete_threshhold; \
  3674. a->grow_threshhold = b.grow_threshhold; \
  3675. a->shrink_threshhold = b.shrink_threshhold; \
  3676. }
  3677. #define STB_equal(a,b) ((a) == (b))
  3678. #define stb_define_hash(TYPE,N,KEY,EMPTY,DEL,HASH,VALUE) \
  3679. stb_define_hash_base(STB_noprefix, TYPE,STB_nofields,N,NC,0.85f, \
  3680. KEY,EMPTY,DEL,STB_nocopy,STB_nodelete,STB_nosafe, \
  3681. STB_equal,STB_equal,HASH, \
  3682. VALUE,STB_nonullvalue,0)
  3683. #define stb_define_hash_vnull(TYPE,N,KEY,EMPTY,DEL,HASH,VALUE,VNULL) \
  3684. stb_define_hash_base(STB_noprefix, TYPE,STB_nofields,N,NC,0.85f, \
  3685. KEY,EMPTY,DEL,STB_nocopy,STB_nodelete,STB_nosafe, \
  3686. STB_equal,STB_equal,HASH, \
  3687. VALUE,STB_nullvalue,VNULL)
  3688. //////////////////////////////////////////////////////////////////////////////
  3689. //
  3690. // stb_ptrmap
  3691. //
  3692. // An stb_ptrmap data structure is an O(1) hash table between pointers. One
  3693. // application is to let you store "extra" data associated with pointers,
  3694. // which is why it was originally called stb_extra.
  3695. stb_declare_hash(STB_EXTERN, stb_ptrmap, stb_ptrmap_, void *, void *)
  3696. stb_declare_hash(STB_EXTERN, stb_idict, stb_idict_, stb_int32, stb_int32)
  3697. stb_declare_hash(STB_EXTERN, stb_uidict, stbi_uidict_, stb_uint32, stb_uint32)
  3698. STB_EXTERN void stb_ptrmap_delete(stb_ptrmap *e, void (*free_func)(void *));
  3699. STB_EXTERN stb_ptrmap *stb_ptrmap_new(void);
  3700. STB_EXTERN stb_idict * stb_idict_new_size(int size);
  3701. STB_EXTERN void stb_idict_remove_all(stb_idict *e);
  3702. STB_EXTERN void stb_uidict_reset(stb_uidict *e);
  3703. #ifdef STB_DEFINE
  3704. #define STB_EMPTY ((void *) 2)
  3705. #define STB_EDEL ((void *) 6)
  3706. stb_define_hash_base(STB_noprefix,stb_ptrmap, STB_nofields, stb_ptrmap_,stb_ptrmap_,0.85f,
  3707. void *,STB_EMPTY,STB_EDEL,STB_nocopy,STB_nodelete,STB_nosafe,
  3708. STB_equal,STB_equal,return stb_hashptr(k);,
  3709. void *,STB_nullvalue,NULL)
  3710. stb_ptrmap *stb_ptrmap_new(void)
  3711. {
  3712. return stb_ptrmap_create();
  3713. }
  3714. void stb_ptrmap_delete(stb_ptrmap *e, void (*free_func)(void *))
  3715. {
  3716. int i;
  3717. if (free_func)
  3718. for (i=0; i < e->limit; ++i)
  3719. if (e->table[i].k != STB_EMPTY && e->table[i].k != STB_EDEL) {
  3720. if (free_func == free)
  3721. free(e->table[i].v); // allow STB_MALLOC_WRAPPER to operate
  3722. else
  3723. free_func(e->table[i].v);
  3724. }
  3725. stb_ptrmap_destroy(e);
  3726. }
  3727. // extra fields needed for stua_dict
  3728. #define STB_IEMPTY ((int) 1)
  3729. #define STB_IDEL ((int) 3)
  3730. stb_define_hash_base(STB_noprefix, stb_idict, short type; short gc; STB_nofields, stb_idict_,stb_idict_,0.95f,
  3731. stb_int32,STB_IEMPTY,STB_IDEL,STB_nocopy,STB_nodelete,STB_nosafe,
  3732. STB_equal,STB_equal,
  3733. return stb_rehash_improved(k);,stb_int32,STB_nonullvalue,0)
  3734. stb_idict * stb_idict_new_size(int size)
  3735. {
  3736. stb_idict *e = (stb_idict *) malloc(sizeof(*e));
  3737. if (e) {
  3738. if (!stb_is_pow2(size))
  3739. size = 1 << stb_log2_ceil(size);
  3740. stb_idict_init(e, size);
  3741. e->alloced = 1;
  3742. }
  3743. return e;
  3744. }
  3745. void stb_idict_remove_all(stb_idict *e)
  3746. {
  3747. int n;
  3748. for (n=0; n < e->limit; ++n)
  3749. e->table[n].k = STB_IEMPTY;
  3750. e->has_empty = e->has_del = 0;
  3751. e->count = 0;
  3752. e->deleted = 0;
  3753. }
  3754. stb_define_hash_base(STB_noprefix, stb_uidict, STB_nofields, stb_uidict_,stb_uidict_,0.85f,
  3755. stb_int32,0xffffffff,0xfffffffe,STB_nocopy,STB_nodelete,STB_nosafe,
  3756. STB_equal,STB_equal,
  3757. return stb_rehash_improved(k);,stb_uint32,STB_nonullvalue,0)
  3758. void stb_uidict_reset(stb_uidict *e)
  3759. {
  3760. int n;
  3761. for (n=0; n < e->limit; ++n)
  3762. e->table[n].k = 0xffffffff;
  3763. e->has_empty = e->has_del = 0;
  3764. e->count = 0;
  3765. e->deleted = 0;
  3766. }
  3767. #endif
  3768. //////////////////////////////////////////////////////////////////////////////
  3769. //
  3770. // stb_sparse_ptr_matrix
  3771. //
  3772. // An stb_ptrmap data structure is an O(1) hash table storing an arbitrary
  3773. // block of data for a given pair of pointers.
  3774. //
  3775. // If create=0, returns
  3776. typedef struct stb__st_stb_spmatrix stb_spmatrix;
  3777. STB_EXTERN stb_spmatrix * stb_sparse_ptr_matrix_new(int val_size);
  3778. STB_EXTERN void stb_sparse_ptr_matrix_free(stb_spmatrix *z);
  3779. STB_EXTERN void * stb_sparse_ptr_matrix_get(stb_spmatrix *z, void *a, void *b, int create);
  3780. #ifdef STB_DEFINE
  3781. typedef struct
  3782. {
  3783. void *a;
  3784. void *b;
  3785. } stb__ptrpair;
  3786. static stb__ptrpair stb__ptrpair_empty = { (void *) 1, (void *) 1 };
  3787. static stb__ptrpair stb__ptrpair_del = { (void *) 2, (void *) 2 };
  3788. #define STB__equal_ptrpair(x,y) ((x).a == (y).a && (x).b == (y).b)
  3789. stb_define_hash_base(STB_noprefix, stb_spmatrix, int val_size; void *arena;, stb__spmatrix_,stb__spmatrix_, 0.85,
  3790. stb__ptrpair, stb__ptrpair_empty, stb__ptrpair_del,
  3791. STB_nocopy, STB_nodelete, STB_nosafe,
  3792. STB__equal_ptrpair, STB__equal_ptrpair, return stb_rehash(stb_hashptr(k.a))+stb_hashptr(k.b);,
  3793. void *, STB_nullvalue, 0)
  3794. stb_spmatrix *stb_sparse_ptr_matrix_new(int val_size)
  3795. {
  3796. stb_spmatrix *m = stb__spmatrix_create();
  3797. if (m) m->val_size = val_size;
  3798. if (m) m->arena = stb_malloc_global(1);
  3799. return m;
  3800. }
  3801. void stb_sparse_ptr_matrix_free(stb_spmatrix *z)
  3802. {
  3803. if (z->arena) stb_free(z->arena);
  3804. stb__spmatrix_destroy(z);
  3805. }
  3806. void *stb_sparse_ptr_matrix_get(stb_spmatrix *z, void *a, void *b, int create)
  3807. {
  3808. stb__ptrpair t = { a,b };
  3809. void *data = stb__spmatrix_get(z, t);
  3810. if (!data && create) {
  3811. data = stb_malloc_raw(z->arena, z->val_size);
  3812. if (!data) return NULL;
  3813. memset(data, 0, z->val_size);
  3814. stb__spmatrix_add(z, t, data);
  3815. }
  3816. return data;
  3817. }
  3818. #endif
  3819. //////////////////////////////////////////////////////////////////////////////
  3820. //
  3821. // SDICT: Hash Table for Strings (symbol table)
  3822. //
  3823. // if "use_arena=1", then strings will be copied
  3824. // into blocks and never freed until the sdict is freed;
  3825. // otherwise they're malloc()ed and free()d on the fly.
  3826. // (specify use_arena=1 if you never stb_sdict_remove)
  3827. stb_declare_hash(STB_EXTERN, stb_sdict, stb_sdict_, char *, void *)
  3828. STB_EXTERN stb_sdict * stb_sdict_new(int use_arena);
  3829. STB_EXTERN stb_sdict * stb_sdict_copy(stb_sdict*);
  3830. STB_EXTERN void stb_sdict_delete(stb_sdict *);
  3831. STB_EXTERN void * stb_sdict_change(stb_sdict *, char *str, void *p);
  3832. STB_EXTERN int stb_sdict_count(stb_sdict *d);
  3833. STB_EXTERN int stb_sdict_internal_limit(stb_sdict *d);
  3834. STB_EXTERN char * stb_sdict_internal_key(stb_sdict *d, int n);
  3835. STB_EXTERN void * stb_sdict_internal_value(stb_sdict *d, int n);
  3836. #define stb_sdict_for(d,i,q,z) \
  3837. for(i=0; i < stb_sdict_internal_limit(d) ? (q=stb_sdict_internal_key(d,i),z=stb_sdict_internal_value(d,i),1) : 0; ++i) \
  3838. if (q==NULL||q==(void *) 1);else // reversed makes macro friendly
  3839. #ifdef STB_DEFINE
  3840. // if in same translation unit, for speed, don't call accessors
  3841. #undef stb_sdict_for
  3842. #define stb_sdict_for(d,i,q,z) \
  3843. for(i=0; i < (d)->limit ? (q=(d)->table[i].k,z=(d)->table[i].v,1) : 0; ++i) \
  3844. if (q==NULL||q==(void *) 1);else // reversed makes macro friendly
  3845. #define STB_DEL ((void *) 1)
  3846. #define STB_SDEL ((char *) 1)
  3847. #define stb_sdict__copy(x) \
  3848. stb_p_strcpy_s(a->arena ? stb_malloc_string(a->arena, strlen(x)+1) \
  3849. : (char *) malloc(strlen(x)+1), strlen(x)+1, x)
  3850. #define stb_sdict__dispose(x) if (!a->arena) free(x)
  3851. stb_define_hash_base(STB_noprefix, stb_sdict, void*arena;, stb_sdict_,stb_sdictinternal_, 0.85f,
  3852. char *, NULL, STB_SDEL, stb_sdict__copy, stb_sdict__dispose,
  3853. STB_safecompare, !strcmp, STB_equal, return stb_hash(k);,
  3854. void *, STB_nullvalue, NULL)
  3855. int stb_sdict_count(stb_sdict *a)
  3856. {
  3857. return a->count;
  3858. }
  3859. int stb_sdict_internal_limit(stb_sdict *a)
  3860. {
  3861. return a->limit;
  3862. }
  3863. char* stb_sdict_internal_key(stb_sdict *a, int n)
  3864. {
  3865. return a->table[n].k;
  3866. }
  3867. void* stb_sdict_internal_value(stb_sdict *a, int n)
  3868. {
  3869. return a->table[n].v;
  3870. }
  3871. stb_sdict * stb_sdict_new(int use_arena)
  3872. {
  3873. stb_sdict *d = stb_sdict_create();
  3874. if (d == NULL) return NULL;
  3875. d->arena = use_arena ? stb_malloc_global(1) : NULL;
  3876. return d;
  3877. }
  3878. stb_sdict* stb_sdict_copy(stb_sdict *old)
  3879. {
  3880. stb_sdict *n;
  3881. void *old_arena = old->arena;
  3882. void *new_arena = old_arena ? stb_malloc_global(1) : NULL;
  3883. old->arena = new_arena;
  3884. n = stb_sdictinternal_copy(old);
  3885. old->arena = old_arena;
  3886. if (n)
  3887. n->arena = new_arena;
  3888. else if (new_arena)
  3889. stb_free(new_arena);
  3890. return n;
  3891. }
  3892. void stb_sdict_delete(stb_sdict *d)
  3893. {
  3894. if (d->arena)
  3895. stb_free(d->arena);
  3896. stb_sdict_destroy(d);
  3897. }
  3898. void * stb_sdict_change(stb_sdict *d, char *str, void *p)
  3899. {
  3900. void *q = stb_sdict_get(d, str);
  3901. stb_sdict_set(d, str, p);
  3902. return q;
  3903. }
  3904. #endif
  3905. //////////////////////////////////////////////////////////////////////////////
  3906. //
  3907. // Instantiated data structures
  3908. //
  3909. // This is an attempt to implement a templated data structure.
  3910. // What you do is define a struct foo, and then include several
  3911. // pointer fields to struct foo in your struct. Then you call
  3912. // the instantiator, which creates the functions that implement
  3913. // the data structure. This requires massive undebuggable #defines,
  3914. // so we limit the cases where we do this.
  3915. //
  3916. // AA tree is an encoding of a 2-3 tree whereas RB trees encode a 2-3-4 tree;
  3917. // much simpler code due to fewer cases.
  3918. #define stb__bst_parent(x) x
  3919. #define stb__bst_noparent(x)
  3920. #define stb_bst_fields(N) \
  3921. *STB_(N,left), *STB_(N,right); \
  3922. unsigned char STB_(N,level)
  3923. #define stb_bst_fields_parent(N) \
  3924. *STB_(N,left), *STB_(N,right), *STB_(N,parent); \
  3925. unsigned char STB_(N,level)
  3926. #define STB__level(N,x) ((x) ? (x)->STB_(N,level) : 0)
  3927. #define stb_bst_base(TYPE, N, TREE, M, compare, PAR) \
  3928. \
  3929. static int STB_(N,_compare)(TYPE *p, TYPE *q) \
  3930. { \
  3931. compare \
  3932. } \
  3933. \
  3934. static void STB_(N,setleft)(TYPE *q, TYPE *v) \
  3935. { \
  3936. q->STB_(N,left) = v; \
  3937. PAR(if (v) v->STB_(N,parent) = q;) \
  3938. } \
  3939. \
  3940. static void STB_(N,setright)(TYPE *q, TYPE *v) \
  3941. { \
  3942. q->STB_(N,right) = v; \
  3943. PAR(if (v) v->STB_(N,parent) = q;) \
  3944. } \
  3945. \
  3946. static TYPE *STB_(N,skew)(TYPE *q) \
  3947. { \
  3948. if (q == NULL) return q; \
  3949. if (q->STB_(N,left) \
  3950. && q->STB_(N,left)->STB_(N,level) == q->STB_(N,level)) { \
  3951. TYPE *p = q->STB_(N,left); \
  3952. STB_(N,setleft)(q, p->STB_(N,right)); \
  3953. STB_(N,setright)(p, q); \
  3954. return p; \
  3955. } \
  3956. return q; \
  3957. } \
  3958. \
  3959. static TYPE *STB_(N,split)(TYPE *p) \
  3960. { \
  3961. TYPE *q = p->STB_(N,right); \
  3962. if (q && q->STB_(N,right) \
  3963. && q->STB_(N,right)->STB_(N,level) == p->STB_(N,level)) { \
  3964. STB_(N,setright)(p, q->STB_(N,left)); \
  3965. STB_(N,setleft)(q,p); \
  3966. ++q->STB_(N,level); \
  3967. return q; \
  3968. } \
  3969. return p; \
  3970. } \
  3971. \
  3972. TYPE *STB__(N,insert)(TYPE *tree, TYPE *item) \
  3973. { \
  3974. int c; \
  3975. if (tree == NULL) { \
  3976. item->STB_(N,left) = NULL; \
  3977. item->STB_(N,right) = NULL; \
  3978. item->STB_(N,level) = 1; \
  3979. PAR(item->STB_(N,parent) = NULL;) \
  3980. return item; \
  3981. } \
  3982. c = STB_(N,_compare)(item,tree); \
  3983. if (c == 0) { \
  3984. if (item != tree) { \
  3985. STB_(N,setleft)(item, tree->STB_(N,left)); \
  3986. STB_(N,setright)(item, tree->STB_(N,right)); \
  3987. item->STB_(N,level) = tree->STB_(N,level); \
  3988. PAR(item->STB_(N,parent) = NULL;) \
  3989. } \
  3990. return item; \
  3991. } \
  3992. if (c < 0) \
  3993. STB_(N,setleft )(tree, STB__(N,insert)(tree->STB_(N,left), item)); \
  3994. else \
  3995. STB_(N,setright)(tree, STB__(N,insert)(tree->STB_(N,right), item)); \
  3996. tree = STB_(N,skew)(tree); \
  3997. tree = STB_(N,split)(tree); \
  3998. PAR(tree->STB_(N,parent) = NULL;) \
  3999. return tree; \
  4000. } \
  4001. \
  4002. TYPE *STB__(N,remove)(TYPE *tree, TYPE *item) \
  4003. { \
  4004. static TYPE *delnode, *leaf, *restore; \
  4005. if (tree == NULL) return NULL; \
  4006. leaf = tree; \
  4007. if (STB_(N,_compare)(item, tree) < 0) { \
  4008. STB_(N,setleft)(tree, STB__(N,remove)(tree->STB_(N,left), item)); \
  4009. } else { \
  4010. TYPE *r; \
  4011. delnode = tree; \
  4012. r = STB__(N,remove)(tree->STB_(N,right), item); \
  4013. /* maybe move 'leaf' up to this location */ \
  4014. if (restore == tree) { tree = leaf; leaf = restore = NULL; } \
  4015. STB_(N,setright)(tree,r); \
  4016. assert(tree->STB_(N,right) != tree); \
  4017. } \
  4018. if (tree == leaf) { \
  4019. if (delnode == item) { \
  4020. tree = tree->STB_(N,right); \
  4021. assert(leaf->STB_(N,left) == NULL); \
  4022. /* move leaf (the right sibling) up to delnode */ \
  4023. STB_(N,setleft )(leaf, item->STB_(N,left )); \
  4024. STB_(N,setright)(leaf, item->STB_(N,right)); \
  4025. leaf->STB_(N,level) = item->STB_(N,level); \
  4026. if (leaf != item) \
  4027. restore = delnode; \
  4028. } \
  4029. delnode = NULL; \
  4030. } else { \
  4031. if (STB__level(N,tree->STB_(N,left) ) < tree->STB_(N,level)-1 || \
  4032. STB__level(N,tree->STB_(N,right)) < tree->STB_(N,level)-1) { \
  4033. --tree->STB_(N,level); \
  4034. if (STB__level(N,tree->STB_(N,right)) > tree->STB_(N,level)) \
  4035. tree->STB_(N,right)->STB_(N,level) = tree->STB_(N,level); \
  4036. tree = STB_(N,skew)(tree); \
  4037. STB_(N,setright)(tree, STB_(N,skew)(tree->STB_(N,right))); \
  4038. if (tree->STB_(N,right)) \
  4039. STB_(N,setright)(tree->STB_(N,right), \
  4040. STB_(N,skew)(tree->STB_(N,right)->STB_(N,right))); \
  4041. tree = STB_(N,split)(tree); \
  4042. if (tree->STB_(N,right)) \
  4043. STB_(N,setright)(tree, STB_(N,split)(tree->STB_(N,right))); \
  4044. } \
  4045. } \
  4046. PAR(if (tree) tree->STB_(N,parent) = NULL;) \
  4047. return tree; \
  4048. } \
  4049. \
  4050. TYPE *STB__(N,last)(TYPE *tree) \
  4051. { \
  4052. if (tree) \
  4053. while (tree->STB_(N,right)) tree = tree->STB_(N,right); \
  4054. return tree; \
  4055. } \
  4056. \
  4057. TYPE *STB__(N,first)(TYPE *tree) \
  4058. { \
  4059. if (tree) \
  4060. while (tree->STB_(N,left)) tree = tree->STB_(N,left); \
  4061. return tree; \
  4062. } \
  4063. \
  4064. TYPE *STB__(N,next)(TYPE *tree, TYPE *item) \
  4065. { \
  4066. TYPE *next = NULL; \
  4067. if (item->STB_(N,right)) \
  4068. return STB__(N,first)(item->STB_(N,right)); \
  4069. PAR( \
  4070. while(item->STB_(N,parent)) { \
  4071. TYPE *up = item->STB_(N,parent); \
  4072. if (up->STB_(N,left) == item) return up; \
  4073. item = up; \
  4074. } \
  4075. return NULL; \
  4076. ) \
  4077. while (tree != item) { \
  4078. if (STB_(N,_compare)(item, tree) < 0) { \
  4079. next = tree; \
  4080. tree = tree->STB_(N,left); \
  4081. } else { \
  4082. tree = tree->STB_(N,right); \
  4083. } \
  4084. } \
  4085. return next; \
  4086. } \
  4087. \
  4088. TYPE *STB__(N,prev)(TYPE *tree, TYPE *item) \
  4089. { \
  4090. TYPE *next = NULL; \
  4091. if (item->STB_(N,left)) \
  4092. return STB__(N,last)(item->STB_(N,left)); \
  4093. PAR( \
  4094. while(item->STB_(N,parent)) { \
  4095. TYPE *up = item->STB_(N,parent); \
  4096. if (up->STB_(N,right) == item) return up; \
  4097. item = up; \
  4098. } \
  4099. return NULL; \
  4100. ) \
  4101. while (tree != item) { \
  4102. if (STB_(N,_compare)(item, tree) < 0) { \
  4103. tree = tree->STB_(N,left); \
  4104. } else { \
  4105. next = tree; \
  4106. tree = tree->STB_(N,right); \
  4107. } \
  4108. } \
  4109. return next; \
  4110. } \
  4111. \
  4112. STB__DEBUG( \
  4113. void STB__(N,_validate)(TYPE *tree, int root) \
  4114. { \
  4115. if (tree == NULL) return; \
  4116. PAR(if(root) assert(tree->STB_(N,parent) == NULL);) \
  4117. assert(STB__level(N,tree->STB_(N,left) ) == tree->STB_(N,level)-1); \
  4118. assert(STB__level(N,tree->STB_(N,right)) <= tree->STB_(N,level)); \
  4119. assert(STB__level(N,tree->STB_(N,right)) >= tree->STB_(N,level)-1); \
  4120. if (tree->STB_(N,right)) { \
  4121. assert(STB__level(N,tree->STB_(N,right)->STB_(N,right)) \
  4122. != tree->STB_(N,level)); \
  4123. PAR(assert(tree->STB_(N,right)->STB_(N,parent) == tree);) \
  4124. } \
  4125. PAR(if(tree->STB_(N,left)) assert(tree->STB_(N,left)->STB_(N,parent) == tree);) \
  4126. STB__(N,_validate)(tree->STB_(N,left) ,0); \
  4127. STB__(N,_validate)(tree->STB_(N,right),0); \
  4128. } \
  4129. ) \
  4130. \
  4131. typedef struct \
  4132. { \
  4133. TYPE *root; \
  4134. } TREE; \
  4135. \
  4136. void STB__(M,Insert)(TREE *tree, TYPE *item) \
  4137. { tree->root = STB__(N,insert)(tree->root, item); } \
  4138. void STB__(M,Remove)(TREE *tree, TYPE *item) \
  4139. { tree->root = STB__(N,remove)(tree->root, item); } \
  4140. TYPE *STB__(M,Next)(TREE *tree, TYPE *item) \
  4141. { return STB__(N,next)(tree->root, item); } \
  4142. TYPE *STB__(M,Prev)(TREE *tree, TYPE *item) \
  4143. { return STB__(N,prev)(tree->root, item); } \
  4144. TYPE *STB__(M,First)(TREE *tree) { return STB__(N,first)(tree->root); } \
  4145. TYPE *STB__(M,Last) (TREE *tree) { return STB__(N,last) (tree->root); } \
  4146. void STB__(M,Init)(TREE *tree) { tree->root = NULL; }
  4147. #define stb_bst_find(N,tree,fcompare) \
  4148. { \
  4149. int c; \
  4150. while (tree != NULL) { \
  4151. fcompare \
  4152. if (c == 0) return tree; \
  4153. if (c < 0) tree = tree->STB_(N,left); \
  4154. else tree = tree->STB_(N,right); \
  4155. } \
  4156. return NULL; \
  4157. }
  4158. #define stb_bst_raw(TYPE,N,TREE,M,vfield,VTYPE,compare,PAR) \
  4159. stb_bst_base(TYPE,N,TREE,M, \
  4160. VTYPE a = p->vfield; VTYPE b = q->vfield; return (compare);, PAR ) \
  4161. \
  4162. TYPE *STB__(N,find)(TYPE *tree, VTYPE a) \
  4163. stb_bst_find(N,tree,VTYPE b = tree->vfield; c = (compare);) \
  4164. TYPE *STB__(M,Find)(TREE *tree, VTYPE a) \
  4165. { return STB__(N,find)(tree->root, a); }
  4166. #define stb_bst(TYPE,N,TREE,M,vfield,VTYPE,compare) \
  4167. stb_bst_raw(TYPE,N,TREE,M,vfield,VTYPE,compare,stb__bst_noparent)
  4168. #define stb_bst_parent(TYPE,N,TREE,M,vfield,VTYPE,compare) \
  4169. stb_bst_raw(TYPE,N,TREE,M,vfield,VTYPE,compare,stb__bst_parent)
  4170. //////////////////////////////////////////////////////////////////////////////
  4171. //
  4172. // Pointer Nulling
  4173. //
  4174. // This lets you automatically NULL dangling pointers to "registered"
  4175. // objects. Note that you have to make sure you call the appropriate
  4176. // functions when you free or realloc blocks of memory that contain
  4177. // pointers or pointer targets. stb.h can automatically do this for
  4178. // stb_arr, or for all frees/reallocs if it's wrapping them.
  4179. //
  4180. #ifdef STB_NPTR
  4181. STB_EXTERN void stb_nptr_set(void *address_of_pointer, void *value_to_write);
  4182. STB_EXTERN void stb_nptr_didset(void *address_of_pointer);
  4183. STB_EXTERN void stb_nptr_didfree(void *address_being_freed, int len);
  4184. STB_EXTERN void stb_nptr_free(void *address_being_freed, int len);
  4185. STB_EXTERN void stb_nptr_didrealloc(void *new_address, void *old_address, int len);
  4186. STB_EXTERN void stb_nptr_recache(void); // recache all known pointers
  4187. // do this after pointer sets outside your control, slow
  4188. #ifdef STB_DEFINE
  4189. // for fast updating on free/realloc, we need to be able to find
  4190. // all the objects (pointers and targets) within a given block;
  4191. // this precludes hashing
  4192. // we use a three-level hierarchy of memory to minimize storage:
  4193. // level 1: 65536 pointers to stb__memory_node (always uses 256 KB)
  4194. // level 2: each stb__memory_node represents a 64K block of memory
  4195. // with 256 stb__memory_leafs (worst case 64MB)
  4196. // level 3: each stb__memory_leaf represents 256 bytes of memory
  4197. // using a list of target locations and a list of pointers
  4198. // (which are hopefully fairly short normally!)
  4199. // this approach won't work in 64-bit, which has a much larger address
  4200. // space. need to redesign
  4201. #define STB__NPTR_ROOT_LOG2 16
  4202. #define STB__NPTR_ROOT_NUM (1 << STB__NPTR_ROOT_LOG2)
  4203. #define STB__NPTR_ROOT_SHIFT (32 - STB__NPTR_ROOT_LOG2)
  4204. #define STB__NPTR_NODE_LOG2 5
  4205. #define STB__NPTR_NODE_NUM (1 << STB__NPTR_NODE_LOG2)
  4206. #define STB__NPTR_NODE_MASK (STB__NPTR_NODE_NUM-1)
  4207. #define STB__NPTR_NODE_SHIFT (STB__NPTR_ROOT_SHIFT - STB__NPTR_NODE_LOG2)
  4208. #define STB__NPTR_NODE_OFFSET(x) (((x) >> STB__NPTR_NODE_SHIFT) & STB__NPTR_NODE_MASK)
  4209. typedef struct stb__st_nptr
  4210. {
  4211. void *ptr; // address of actual pointer
  4212. struct stb__st_nptr *next; // next pointer with same target
  4213. struct stb__st_nptr **prev; // prev pointer with same target, address of 'next' field (or first)
  4214. struct stb__st_nptr *next_in_block;
  4215. } stb__nptr;
  4216. typedef struct stb__st_nptr_target
  4217. {
  4218. void *ptr; // address of target
  4219. stb__nptr *first; // address of first nptr pointing to this
  4220. struct stb__st_nptr_target *next_in_block;
  4221. } stb__nptr_target;
  4222. typedef struct
  4223. {
  4224. stb__nptr *pointers;
  4225. stb__nptr_target *targets;
  4226. } stb__memory_leaf;
  4227. typedef struct
  4228. {
  4229. stb__memory_leaf *children[STB__NPTR_NODE_NUM];
  4230. } stb__memory_node;
  4231. stb__memory_node *stb__memtab_root[STB__NPTR_ROOT_NUM];
  4232. static stb__memory_leaf *stb__nptr_find_leaf(void *mem)
  4233. {
  4234. stb_uint32 address = (stb_uint32) mem;
  4235. stb__memory_node *z = stb__memtab_root[address >> STB__NPTR_ROOT_SHIFT];
  4236. if (z)
  4237. return z->children[STB__NPTR_NODE_OFFSET(address)];
  4238. else
  4239. return NULL;
  4240. }
  4241. static void * stb__nptr_alloc(int size)
  4242. {
  4243. return stb__realloc_raw(0,size);
  4244. }
  4245. static void stb__nptr_free(void *p)
  4246. {
  4247. stb__realloc_raw(p,0);
  4248. }
  4249. static stb__memory_leaf *stb__nptr_make_leaf(void *mem)
  4250. {
  4251. stb_uint32 address = (stb_uint32) mem;
  4252. stb__memory_node *z = stb__memtab_root[address >> STB__NPTR_ROOT_SHIFT];
  4253. stb__memory_leaf *f;
  4254. if (!z) {
  4255. int i;
  4256. z = (stb__memory_node *) stb__nptr_alloc(sizeof(*stb__memtab_root[0]));
  4257. stb__memtab_root[address >> STB__NPTR_ROOT_SHIFT] = z;
  4258. for (i=0; i < 256; ++i)
  4259. z->children[i] = 0;
  4260. }
  4261. f = (stb__memory_leaf *) stb__nptr_alloc(sizeof(*f));
  4262. z->children[STB__NPTR_NODE_OFFSET(address)] = f;
  4263. f->pointers = NULL;
  4264. f->targets = NULL;
  4265. return f;
  4266. }
  4267. static stb__nptr_target *stb__nptr_find_target(void *target, int force)
  4268. {
  4269. stb__memory_leaf *p = stb__nptr_find_leaf(target);
  4270. if (p) {
  4271. stb__nptr_target *t = p->targets;
  4272. while (t) {
  4273. if (t->ptr == target)
  4274. return t;
  4275. t = t->next_in_block;
  4276. }
  4277. }
  4278. if (force) {
  4279. stb__nptr_target *t = (stb__nptr_target*) stb__nptr_alloc(sizeof(*t));
  4280. if (!p) p = stb__nptr_make_leaf(target);
  4281. t->ptr = target;
  4282. t->first = NULL;
  4283. t->next_in_block = p->targets;
  4284. p->targets = t;
  4285. return t;
  4286. } else
  4287. return NULL;
  4288. }
  4289. static stb__nptr *stb__nptr_find_pointer(void *ptr, int force)
  4290. {
  4291. stb__memory_leaf *p = stb__nptr_find_leaf(ptr);
  4292. if (p) {
  4293. stb__nptr *t = p->pointers;
  4294. while (t) {
  4295. if (t->ptr == ptr)
  4296. return t;
  4297. t = t->next_in_block;
  4298. }
  4299. }
  4300. if (force) {
  4301. stb__nptr *t = (stb__nptr *) stb__nptr_alloc(sizeof(*t));
  4302. if (!p) p = stb__nptr_make_leaf(ptr);
  4303. t->ptr = ptr;
  4304. t->next = NULL;
  4305. t->prev = NULL;
  4306. t->next_in_block = p->pointers;
  4307. p->pointers = t;
  4308. return t;
  4309. } else
  4310. return NULL;
  4311. }
  4312. void stb_nptr_set(void *address_of_pointer, void *value_to_write)
  4313. {
  4314. if (*(void **)address_of_pointer != value_to_write) {
  4315. *(void **) address_of_pointer = value_to_write;
  4316. stb_nptr_didset(address_of_pointer);
  4317. }
  4318. }
  4319. void stb_nptr_didset(void *address_of_pointer)
  4320. {
  4321. // first unlink from old chain
  4322. void *new_address;
  4323. stb__nptr *p = stb__nptr_find_pointer(address_of_pointer, 1); // force building if doesn't exist
  4324. if (p->prev) { // if p->prev is NULL, we just built it, or it was NULL
  4325. *(p->prev) = p->next;
  4326. if (p->next) p->next->prev = p->prev;
  4327. }
  4328. // now add to new chain
  4329. new_address = *(void **)address_of_pointer;
  4330. if (new_address != NULL) {
  4331. stb__nptr_target *t = stb__nptr_find_target(new_address, 1);
  4332. p->next = t->first;
  4333. if (p->next) p->next->prev = &p->next;
  4334. p->prev = &t->first;
  4335. t->first = p;
  4336. } else {
  4337. p->prev = NULL;
  4338. p->next = NULL;
  4339. }
  4340. }
  4341. void stb__nptr_block(void *address, int len, void (*function)(stb__memory_leaf *f, int datum, void *start, void *end), int datum)
  4342. {
  4343. void *end_address = (void *) ((char *) address + len - 1);
  4344. stb__memory_node *n;
  4345. stb_uint32 start = (stb_uint32) address;
  4346. stb_uint32 end = start + len - 1;
  4347. int b0 = start >> STB__NPTR_ROOT_SHIFT;
  4348. int b1 = end >> STB__NPTR_ROOT_SHIFT;
  4349. int b=b0,i,e0,e1;
  4350. e0 = STB__NPTR_NODE_OFFSET(start);
  4351. if (datum <= 0) {
  4352. // first block
  4353. n = stb__memtab_root[b0];
  4354. if (n) {
  4355. if (b0 != b1)
  4356. e1 = STB__NPTR_NODE_NUM-1;
  4357. else
  4358. e1 = STB__NPTR_NODE_OFFSET(end);
  4359. for (i=e0; i <= e1; ++i)
  4360. if (n->children[i])
  4361. function(n->children[i], datum, address, end_address);
  4362. }
  4363. if (b1 > b0) {
  4364. // blocks other than the first and last block
  4365. for (b=b0+1; b < b1; ++b) {
  4366. n = stb__memtab_root[b];
  4367. if (n)
  4368. for (i=0; i <= STB__NPTR_NODE_NUM-1; ++i)
  4369. if (n->children[i])
  4370. function(n->children[i], datum, address, end_address);
  4371. }
  4372. // last block
  4373. n = stb__memtab_root[b1];
  4374. if (n) {
  4375. e1 = STB__NPTR_NODE_OFFSET(end);
  4376. for (i=0; i <= e1; ++i)
  4377. if (n->children[i])
  4378. function(n->children[i], datum, address, end_address);
  4379. }
  4380. }
  4381. } else {
  4382. if (b1 > b0) {
  4383. // last block
  4384. n = stb__memtab_root[b1];
  4385. if (n) {
  4386. e1 = STB__NPTR_NODE_OFFSET(end);
  4387. for (i=e1; i >= 0; --i)
  4388. if (n->children[i])
  4389. function(n->children[i], datum, address, end_address);
  4390. }
  4391. // blocks other than the first and last block
  4392. for (b=b1-1; b > b0; --b) {
  4393. n = stb__memtab_root[b];
  4394. if (n)
  4395. for (i=STB__NPTR_NODE_NUM-1; i >= 0; --i)
  4396. if (n->children[i])
  4397. function(n->children[i], datum, address, end_address);
  4398. }
  4399. }
  4400. // first block
  4401. n = stb__memtab_root[b0];
  4402. if (n) {
  4403. if (b0 != b1)
  4404. e1 = STB__NPTR_NODE_NUM-1;
  4405. else
  4406. e1 = STB__NPTR_NODE_OFFSET(end);
  4407. for (i=e1; i >= e0; --i)
  4408. if (n->children[i])
  4409. function(n->children[i], datum, address, end_address);
  4410. }
  4411. }
  4412. }
  4413. static void stb__nptr_delete_pointers(stb__memory_leaf *f, int offset, void *start, void *end)
  4414. {
  4415. stb__nptr **p = &f->pointers;
  4416. while (*p) {
  4417. stb__nptr *n = *p;
  4418. if (n->ptr >= start && n->ptr <= end) {
  4419. // unlink
  4420. if (n->prev) {
  4421. *(n->prev) = n->next;
  4422. if (n->next) n->next->prev = n->prev;
  4423. }
  4424. *p = n->next_in_block;
  4425. stb__nptr_free(n);
  4426. } else
  4427. p = &(n->next_in_block);
  4428. }
  4429. }
  4430. static void stb__nptr_delete_targets(stb__memory_leaf *f, int offset, void *start, void *end)
  4431. {
  4432. stb__nptr_target **p = &f->targets;
  4433. while (*p) {
  4434. stb__nptr_target *n = *p;
  4435. if (n->ptr >= start && n->ptr <= end) {
  4436. // null pointers
  4437. stb__nptr *z = n->first;
  4438. while (z) {
  4439. stb__nptr *y = z->next;
  4440. z->prev = NULL;
  4441. z->next = NULL;
  4442. *(void **) z->ptr = NULL;
  4443. z = y;
  4444. }
  4445. // unlink this target
  4446. *p = n->next_in_block;
  4447. stb__nptr_free(n);
  4448. } else
  4449. p = &(n->next_in_block);
  4450. }
  4451. }
  4452. void stb_nptr_didfree(void *address_being_freed, int len)
  4453. {
  4454. // step one: delete all pointers in this block
  4455. stb__nptr_block(address_being_freed, len, stb__nptr_delete_pointers, 0);
  4456. // step two: NULL all pointers to this block; do this second to avoid NULLing deleted pointers
  4457. stb__nptr_block(address_being_freed, len, stb__nptr_delete_targets, 0);
  4458. }
  4459. void stb_nptr_free(void *address_being_freed, int len)
  4460. {
  4461. free(address_being_freed);
  4462. stb_nptr_didfree(address_being_freed, len);
  4463. }
  4464. static void stb__nptr_move_targets(stb__memory_leaf *f, int offset, void *start, void *end)
  4465. {
  4466. stb__nptr_target **t = &f->targets;
  4467. while (*t) {
  4468. stb__nptr_target *n = *t;
  4469. if (n->ptr >= start && n->ptr <= end) {
  4470. stb__nptr *z;
  4471. stb__memory_leaf *f;
  4472. // unlink n
  4473. *t = n->next_in_block;
  4474. // update n to new address
  4475. n->ptr = (void *) ((char *) n->ptr + offset);
  4476. f = stb__nptr_find_leaf(n->ptr);
  4477. if (!f) f = stb__nptr_make_leaf(n->ptr);
  4478. n->next_in_block = f->targets;
  4479. f->targets = n;
  4480. // now go through all pointers and make them point here
  4481. z = n->first;
  4482. while (z) {
  4483. *(void**) z->ptr = n->ptr;
  4484. z = z->next;
  4485. }
  4486. } else
  4487. t = &(n->next_in_block);
  4488. }
  4489. }
  4490. static void stb__nptr_move_pointers(stb__memory_leaf *f, int offset, void *start, void *end)
  4491. {
  4492. stb__nptr **p = &f->pointers;
  4493. while (*p) {
  4494. stb__nptr *n = *p;
  4495. if (n->ptr >= start && n->ptr <= end) {
  4496. // unlink
  4497. *p = n->next_in_block;
  4498. n->ptr = (void *) ((int) n->ptr + offset);
  4499. // move to new block
  4500. f = stb__nptr_find_leaf(n->ptr);
  4501. if (!f) f = stb__nptr_make_leaf(n->ptr);
  4502. n->next_in_block = f->pointers;
  4503. f->pointers = n;
  4504. } else
  4505. p = &(n->next_in_block);
  4506. }
  4507. }
  4508. void stb_nptr_realloc(void *new_address, void *old_address, int len)
  4509. {
  4510. if (new_address == old_address) return;
  4511. // have to move the pointers first, because moving the targets
  4512. // requires writing to the pointers-to-the-targets, and if some of those moved too,
  4513. // we need to make sure we don't write to the old memory
  4514. // step one: move all pointers within the block
  4515. stb__nptr_block(old_address, len, stb__nptr_move_pointers, (char *) new_address - (char *) old_address);
  4516. // step two: move all targets within the block
  4517. stb__nptr_block(old_address, len, stb__nptr_move_targets, (char *) new_address - (char *) old_address);
  4518. }
  4519. void stb_nptr_move(void *new_address, void *old_address)
  4520. {
  4521. stb_nptr_realloc(new_address, old_address, 1);
  4522. }
  4523. void stb_nptr_recache(void)
  4524. {
  4525. int i,j;
  4526. for (i=0; i < STB__NPTR_ROOT_NUM; ++i)
  4527. if (stb__memtab_root[i])
  4528. for (j=0; j < STB__NPTR_NODE_NUM; ++j)
  4529. if (stb__memtab_root[i]->children[j]) {
  4530. stb__nptr *p = stb__memtab_root[i]->children[j]->pointers;
  4531. while (p) {
  4532. stb_nptr_didset(p->ptr);
  4533. p = p->next_in_block;
  4534. }
  4535. }
  4536. }
  4537. #endif // STB_DEFINE
  4538. #endif // STB_NPTR
  4539. //////////////////////////////////////////////////////////////////////////////
  4540. //
  4541. // File Processing
  4542. //
  4543. #ifdef _WIN32
  4544. #define stb_rename(x,y) _wrename((const wchar_t *)stb__from_utf8(x), (const wchar_t *)stb__from_utf8_alt(y))
  4545. #else
  4546. #define stb_rename rename
  4547. #endif
  4548. STB_EXTERN void stb_fput_varlen64(FILE *f, stb_uint64 v);
  4549. STB_EXTERN stb_uint64 stb_fget_varlen64(FILE *f);
  4550. STB_EXTERN int stb_size_varlen64(stb_uint64 v);
  4551. #define stb_filec (char *) stb_file
  4552. #define stb_fileu (unsigned char *) stb_file
  4553. STB_EXTERN void * stb_file(char *filename, size_t *length);
  4554. STB_EXTERN void * stb_file_max(char *filename, size_t *length);
  4555. STB_EXTERN size_t stb_filelen(FILE *f);
  4556. STB_EXTERN int stb_filewrite(char *filename, void *data, size_t length);
  4557. STB_EXTERN int stb_filewritestr(char *filename, char *data);
  4558. STB_EXTERN char ** stb_stringfile(char *filename, int *len);
  4559. STB_EXTERN char ** stb_stringfile_trimmed(char *name, int *len, char comm);
  4560. STB_EXTERN char * stb_fgets(char *buffer, int buflen, FILE *f);
  4561. STB_EXTERN char * stb_fgets_malloc(FILE *f);
  4562. STB_EXTERN int stb_fexists(char *filename);
  4563. STB_EXTERN int stb_fcmp(char *s1, char *s2);
  4564. STB_EXTERN int stb_feq(char *s1, char *s2);
  4565. STB_EXTERN time_t stb_ftimestamp(char *filename);
  4566. STB_EXTERN int stb_fullpath(char *abs, int abs_size, char *rel);
  4567. STB_EXTERN FILE * stb_fopen(char *filename, const char *mode);
  4568. STB_EXTERN int stb_fclose(FILE *f, int keep);
  4569. enum
  4570. {
  4571. stb_keep_no = 0,
  4572. stb_keep_yes = 1,
  4573. stb_keep_if_different = 2,
  4574. };
  4575. STB_EXTERN int stb_copyfile(char *src, char *dest);
  4576. STB_EXTERN void stb_fput_varlen64(FILE *f, stb_uint64 v);
  4577. STB_EXTERN stb_uint64 stb_fget_varlen64(FILE *f);
  4578. STB_EXTERN int stb_size_varlen64(stb_uint64 v);
  4579. STB_EXTERN void stb_fwrite32(FILE *f, stb_uint32 datum);
  4580. STB_EXTERN void stb_fput_varlen (FILE *f, int v);
  4581. STB_EXTERN void stb_fput_varlenu(FILE *f, unsigned int v);
  4582. STB_EXTERN int stb_fget_varlen (FILE *f);
  4583. STB_EXTERN stb_uint stb_fget_varlenu(FILE *f);
  4584. STB_EXTERN void stb_fput_ranged (FILE *f, int v, int b, stb_uint n);
  4585. STB_EXTERN int stb_fget_ranged (FILE *f, int b, stb_uint n);
  4586. STB_EXTERN int stb_size_varlen (int v);
  4587. STB_EXTERN int stb_size_varlenu(unsigned int v);
  4588. STB_EXTERN int stb_size_ranged (int b, stb_uint n);
  4589. STB_EXTERN int stb_fread(void *data, size_t len, size_t count, void *f);
  4590. STB_EXTERN int stb_fwrite(void *data, size_t len, size_t count, void *f);
  4591. #if 0
  4592. typedef struct
  4593. {
  4594. FILE *base_file;
  4595. char *buffer;
  4596. int buffer_size;
  4597. int buffer_off;
  4598. int buffer_left;
  4599. } STBF;
  4600. STB_EXTERN STBF *stb_tfopen(char *filename, char *mode);
  4601. STB_EXTERN int stb_tfread(void *data, size_t len, size_t count, STBF *f);
  4602. STB_EXTERN int stb_tfwrite(void *data, size_t len, size_t count, STBF *f);
  4603. #endif
  4604. #ifdef STB_DEFINE
  4605. #if 0
  4606. STBF *stb_tfopen(char *filename, char *mode)
  4607. {
  4608. STBF *z;
  4609. FILE *f = stb_p_fopen(filename, mode);
  4610. if (!f) return NULL;
  4611. z = (STBF *) malloc(sizeof(*z));
  4612. if (!z) { fclose(f); return NULL; }
  4613. z->base_file = f;
  4614. if (!strcmp(mode, "rb") || !strcmp(mode, "wb")) {
  4615. z->buffer_size = 4096;
  4616. z->buffer_off = z->buffer_size;
  4617. z->buffer_left = 0;
  4618. z->buffer = malloc(z->buffer_size);
  4619. if (!z->buffer) { free(z); fclose(f); return NULL; }
  4620. } else {
  4621. z->buffer = 0;
  4622. z->buffer_size = 0;
  4623. z->buffer_left = 0;
  4624. }
  4625. return z;
  4626. }
  4627. int stb_tfread(void *data, size_t len, size_t count, STBF *f)
  4628. {
  4629. int total = len*count, done=0;
  4630. if (!total) return 0;
  4631. if (total <= z->buffer_left) {
  4632. memcpy(data, z->buffer + z->buffer_off, total);
  4633. z->buffer_off += total;
  4634. z->buffer_left -= total;
  4635. return count;
  4636. } else {
  4637. char *out = (char *) data;
  4638. // consume all buffered data
  4639. memcpy(data, z->buffer + z->buffer_off, z->buffer_left);
  4640. done = z->buffer_left;
  4641. out += z->buffer_left;
  4642. z->buffer_left=0;
  4643. if (total-done > (z->buffer_size >> 1)) {
  4644. done += fread(out
  4645. }
  4646. }
  4647. }
  4648. #endif
  4649. void stb_fwrite32(FILE *f, stb_uint32 x)
  4650. {
  4651. fwrite(&x, 4, 1, f);
  4652. }
  4653. #if defined(_WIN32)
  4654. #define stb__stat _stat
  4655. #else
  4656. #define stb__stat stat
  4657. #endif
  4658. int stb_fexists(char *filename)
  4659. {
  4660. struct stb__stat buf;
  4661. return stb__windows(
  4662. _wstat((const wchar_t *)stb__from_utf8(filename), &buf),
  4663. stat(filename,&buf)
  4664. ) == 0;
  4665. }
  4666. time_t stb_ftimestamp(char *filename)
  4667. {
  4668. struct stb__stat buf;
  4669. if (stb__windows(
  4670. _wstat((const wchar_t *)stb__from_utf8(filename), &buf),
  4671. stat(filename,&buf)
  4672. ) == 0)
  4673. {
  4674. return buf.st_mtime;
  4675. } else {
  4676. return 0;
  4677. }
  4678. }
  4679. size_t stb_filelen(FILE *f)
  4680. {
  4681. long len, pos;
  4682. pos = ftell(f);
  4683. fseek(f, 0, SEEK_END);
  4684. len = ftell(f);
  4685. fseek(f, pos, SEEK_SET);
  4686. return (size_t) len;
  4687. }
  4688. void *stb_file(char *filename, size_t *length)
  4689. {
  4690. FILE *f = stb__fopen(filename, "rb");
  4691. char *buffer;
  4692. size_t len, len2;
  4693. if (!f) return NULL;
  4694. len = stb_filelen(f);
  4695. buffer = (char *) malloc(len+2); // nul + extra
  4696. len2 = fread(buffer, 1, len, f);
  4697. if (len2 == len) {
  4698. if (length) *length = len;
  4699. buffer[len] = 0;
  4700. } else {
  4701. free(buffer);
  4702. buffer = NULL;
  4703. }
  4704. fclose(f);
  4705. return buffer;
  4706. }
  4707. int stb_filewrite(char *filename, void *data, size_t length)
  4708. {
  4709. FILE *f = stb_fopen(filename, "wb");
  4710. if (f) {
  4711. unsigned char *data_ptr = (unsigned char *) data;
  4712. size_t remaining = length;
  4713. while (remaining > 0) {
  4714. size_t len2 = remaining > 65536 ? 65536 : remaining;
  4715. size_t len3 = fwrite(data_ptr, 1, len2, f);
  4716. if (len2 != len3) {
  4717. fprintf(stderr, "Failed while writing %s\n", filename);
  4718. break;
  4719. }
  4720. remaining -= len2;
  4721. data_ptr += len2;
  4722. }
  4723. stb_fclose(f, stb_keep_if_different);
  4724. }
  4725. return f != NULL;
  4726. }
  4727. int stb_filewritestr(char *filename, char *data)
  4728. {
  4729. return stb_filewrite(filename, data, strlen(data));
  4730. }
  4731. void * stb_file_max(char *filename, size_t *length)
  4732. {
  4733. FILE *f = stb__fopen(filename, "rb");
  4734. char *buffer;
  4735. size_t len, maxlen;
  4736. if (!f) return NULL;
  4737. maxlen = *length;
  4738. buffer = (char *) malloc(maxlen+1);
  4739. len = fread(buffer, 1, maxlen, f);
  4740. buffer[len] = 0;
  4741. fclose(f);
  4742. *length = len;
  4743. return buffer;
  4744. }
  4745. char ** stb_stringfile(char *filename, int *plen)
  4746. {
  4747. FILE *f = stb__fopen(filename, "rb");
  4748. char *buffer, **list=NULL, *s;
  4749. size_t len, count, i;
  4750. if (!f) return NULL;
  4751. len = stb_filelen(f);
  4752. buffer = (char *) malloc(len+1);
  4753. len = fread(buffer, 1, len, f);
  4754. buffer[len] = 0;
  4755. fclose(f);
  4756. // two passes through: first time count lines, second time set them
  4757. for (i=0; i < 2; ++i) {
  4758. s = buffer;
  4759. if (i == 1)
  4760. list[0] = s;
  4761. count = 1;
  4762. while (*s) {
  4763. if (*s == '\n' || *s == '\r') {
  4764. // detect if both cr & lf are together
  4765. int crlf = (s[0] + s[1]) == ('\n' + '\r');
  4766. if (i == 1) *s = 0;
  4767. if (crlf) ++s;
  4768. if (s[1]) { // it's not over yet
  4769. if (i == 1) list[count] = s+1;
  4770. ++count;
  4771. }
  4772. }
  4773. ++s;
  4774. }
  4775. if (i == 0) {
  4776. list = (char **) malloc(sizeof(*list) * (count+1) + len+1);
  4777. if (!list) return NULL;
  4778. list[count] = 0;
  4779. // recopy the file so there's just a single allocation to free
  4780. memcpy(&list[count+1], buffer, len+1);
  4781. free(buffer);
  4782. buffer = (char *) &list[count+1];
  4783. if (plen) *plen = (int) count;
  4784. }
  4785. }
  4786. return list;
  4787. }
  4788. char ** stb_stringfile_trimmed(char *name, int *len, char comment)
  4789. {
  4790. int i,n,o=0;
  4791. char **s = stb_stringfile(name, &n);
  4792. if (s == NULL) return NULL;
  4793. for (i=0; i < n; ++i) {
  4794. char *p = stb_skipwhite(s[i]);
  4795. if (*p && *p != comment)
  4796. s[o++] = p;
  4797. }
  4798. s[o] = NULL;
  4799. if (len) *len = o;
  4800. return s;
  4801. }
  4802. char * stb_fgets(char *buffer, int buflen, FILE *f)
  4803. {
  4804. char *p;
  4805. buffer[0] = 0;
  4806. p = fgets(buffer, buflen, f);
  4807. if (p) {
  4808. int n = (int) (strlen(p)-1);
  4809. if (n >= 0)
  4810. if (p[n] == '\n')
  4811. p[n] = 0;
  4812. }
  4813. return p;
  4814. }
  4815. char * stb_fgets_malloc(FILE *f)
  4816. {
  4817. // avoid reallocing for small strings
  4818. char quick_buffer[800];
  4819. quick_buffer[sizeof(quick_buffer)-2] = 0;
  4820. if (!fgets(quick_buffer, sizeof(quick_buffer), f))
  4821. return NULL;
  4822. if (quick_buffer[sizeof(quick_buffer)-2] == 0) {
  4823. size_t n = strlen(quick_buffer);
  4824. if (n > 0 && quick_buffer[n-1] == '\n')
  4825. quick_buffer[n-1] = 0;
  4826. return stb_p_strdup(quick_buffer);
  4827. } else {
  4828. char *p;
  4829. char *a = stb_p_strdup(quick_buffer);
  4830. size_t len = sizeof(quick_buffer)-1;
  4831. while (!feof(f)) {
  4832. if (a[len-1] == '\n') break;
  4833. a = (char *) realloc(a, len*2);
  4834. p = &a[len];
  4835. p[len-2] = 0;
  4836. if (!fgets(p, (int) len, f))
  4837. break;
  4838. if (p[len-2] == 0) {
  4839. len += strlen(p);
  4840. break;
  4841. }
  4842. len = len + (len-1);
  4843. }
  4844. if (a[len-1] == '\n')
  4845. a[len-1] = 0;
  4846. return a;
  4847. }
  4848. }
  4849. int stb_fullpath(char *abs, int abs_size, char *rel)
  4850. {
  4851. #ifdef _WIN32
  4852. return _fullpath(abs, rel, abs_size) != NULL;
  4853. #else
  4854. if (rel[0] == '/' || rel[0] == '~') {
  4855. if ((int) strlen(rel) >= abs_size)
  4856. return 0;
  4857. stb_p_strcpy_s(abs,65536,rel);
  4858. return STB_TRUE;
  4859. } else {
  4860. int n;
  4861. char* _c = getcwd(abs, abs_size);
  4862. n = strlen(abs);
  4863. if (n+(int) strlen(rel)+2 <= abs_size) {
  4864. abs[n] = '/';
  4865. stb_p_strcpy_s(abs+n+1, 65536,rel);
  4866. return STB_TRUE;
  4867. } else {
  4868. return STB_FALSE;
  4869. }
  4870. }
  4871. #endif
  4872. }
  4873. static int stb_fcmp_core(FILE *f, FILE *g)
  4874. {
  4875. char buf1[1024],buf2[1024];
  4876. int n1,n2, res=0;
  4877. while (1) {
  4878. n1 = (int) fread(buf1, 1, sizeof(buf1), f);
  4879. n2 = (int) fread(buf2, 1, sizeof(buf2), g);
  4880. res = memcmp(buf1,buf2,stb_min(n1,n2));
  4881. if (res)
  4882. break;
  4883. if (n1 != n2) {
  4884. res = n1 < n2 ? -1 : 1;
  4885. break;
  4886. }
  4887. if (n1 == 0)
  4888. break;
  4889. }
  4890. fclose(f);
  4891. fclose(g);
  4892. return res;
  4893. }
  4894. int stb_fcmp(char *s1, char *s2)
  4895. {
  4896. FILE *f = stb__fopen(s1, "rb");
  4897. FILE *g = stb__fopen(s2, "rb");
  4898. if (f == NULL || g == NULL) {
  4899. if (f) fclose(f);
  4900. if (g) {
  4901. fclose(g);
  4902. return STB_TRUE;
  4903. }
  4904. return f != NULL;
  4905. }
  4906. return stb_fcmp_core(f,g);
  4907. }
  4908. int stb_feq(char *s1, char *s2)
  4909. {
  4910. FILE *f = stb__fopen(s1, "rb");
  4911. FILE *g = stb__fopen(s2, "rb");
  4912. if (f == NULL || g == NULL) {
  4913. if (f) fclose(f);
  4914. if (g) fclose(g);
  4915. return f == g;
  4916. }
  4917. // feq is faster because it shortcuts if they're different length
  4918. if (stb_filelen(f) != stb_filelen(g)) {
  4919. fclose(f);
  4920. fclose(g);
  4921. return 0;
  4922. }
  4923. return !stb_fcmp_core(f,g);
  4924. }
  4925. static stb_ptrmap *stb__files;
  4926. typedef struct
  4927. {
  4928. char *temp_name;
  4929. char *name;
  4930. int errors;
  4931. } stb__file_data;
  4932. static FILE *stb__open_temp_file(char *temp_name, char *src_name, const char *mode)
  4933. {
  4934. size_t p;
  4935. #ifdef _MSC_VER
  4936. int j;
  4937. #endif
  4938. FILE *f;
  4939. // try to generate a temporary file in the same directory
  4940. p = strlen(src_name)-1;
  4941. while (p > 0 && src_name[p] != '/' && src_name[p] != '\\'
  4942. && src_name[p] != ':' && src_name[p] != '~')
  4943. --p;
  4944. ++p;
  4945. memcpy(temp_name, src_name, p);
  4946. #ifdef _MSC_VER
  4947. // try multiple times to make a temp file... just in
  4948. // case some other process makes the name first
  4949. for (j=0; j < 32; ++j) {
  4950. stb_p_strcpy_s(temp_name+p, 65536, "stmpXXXXXX");
  4951. if (!stb_p_mktemp(temp_name))
  4952. return 0;
  4953. f = stb_p_fopen(temp_name, mode);
  4954. if (f != NULL)
  4955. break;
  4956. }
  4957. #else
  4958. {
  4959. stb_p_strcpy_s(temp_name+p, 65536, "stmpXXXXXX");
  4960. #ifdef __MINGW32__
  4961. stb_p_mktemp(temp_name);
  4962. int fd = open(temp_name, O_RDWR);
  4963. #else
  4964. int fd = mkstemp(temp_name);
  4965. #endif
  4966. if (fd == -1) return NULL;
  4967. f = fdopen(fd, mode);
  4968. if (f == NULL) {
  4969. unlink(temp_name);
  4970. close(fd);
  4971. return NULL;
  4972. }
  4973. }
  4974. #endif
  4975. return f;
  4976. }
  4977. FILE * stb_fopen(char *filename, const char *mode)
  4978. {
  4979. FILE *f;
  4980. char name_full[4096];
  4981. char temp_full[sizeof(name_full) + 12];
  4982. // @TODO: if the file doesn't exist, we can also use the fastpath here
  4983. if (mode[0] != 'w' && !strchr(mode, '+'))
  4984. return stb__fopen(filename, mode);
  4985. // save away the full path to the file so if the program
  4986. // changes the cwd everything still works right! unix has
  4987. // better ways to do this, but we have to work in windows
  4988. name_full[0] = '\0'; // stb_fullpath reads name_full[0]
  4989. if (stb_fullpath(name_full, sizeof(name_full), filename)==0)
  4990. return 0;
  4991. f = stb__open_temp_file(temp_full, name_full, mode);
  4992. if (f != NULL) {
  4993. stb__file_data *d = (stb__file_data *) malloc(sizeof(*d));
  4994. if (!d) { assert(0); /* NOTREACHED */fclose(f); return NULL; }
  4995. if (stb__files == NULL) stb__files = stb_ptrmap_create();
  4996. d->temp_name = stb_p_strdup(temp_full);
  4997. d->name = stb_p_strdup(name_full);
  4998. d->errors = 0;
  4999. stb_ptrmap_add(stb__files, f, d);
  5000. return f;
  5001. }
  5002. return NULL;
  5003. }
  5004. int stb_fclose(FILE *f, int keep)
  5005. {
  5006. stb__file_data *d;
  5007. int ok = STB_FALSE;
  5008. if (f == NULL) return 0;
  5009. if (ferror(f))
  5010. keep = stb_keep_no;
  5011. fclose(f);
  5012. if (stb__files && stb_ptrmap_remove(stb__files, f, (void **) &d)) {
  5013. if (stb__files->count == 0) {
  5014. stb_ptrmap_destroy(stb__files);
  5015. stb__files = NULL;
  5016. }
  5017. } else
  5018. return STB_TRUE; // not special
  5019. if (keep == stb_keep_if_different) {
  5020. // check if the files are identical
  5021. if (stb_feq(d->name, d->temp_name)) {
  5022. keep = stb_keep_no;
  5023. ok = STB_TRUE; // report success if no change
  5024. }
  5025. }
  5026. if (keep == stb_keep_no) {
  5027. remove(d->temp_name);
  5028. } else {
  5029. if (!stb_fexists(d->name)) {
  5030. // old file doesn't exist, so just move the new file over it
  5031. stb_rename(d->temp_name, d->name);
  5032. } else {
  5033. // don't delete the old file yet in case there are troubles! First rename it!
  5034. char preserved_old_file[4096];
  5035. // generate a temp filename in the same directory (also creates it, which we don't need)
  5036. FILE *dummy = stb__open_temp_file(preserved_old_file, d->name, "wb");
  5037. if (dummy != NULL) {
  5038. // we don't actually want the open file
  5039. fclose(dummy);
  5040. // discard what we just created
  5041. remove(preserved_old_file); // if this fails, there's nothing we can do, and following logic handles it as best as possible anyway
  5042. // move the existing file to the preserved name
  5043. if (0 != stb_rename(d->name, preserved_old_file)) { // 0 on success
  5044. // failed, state is:
  5045. // filename -> old file
  5046. // tempname -> new file
  5047. // keep tempname around so we don't lose data
  5048. } else {
  5049. // state is:
  5050. // preserved -> old file
  5051. // tempname -> new file
  5052. // move the new file to the old name
  5053. if (0 == stb_rename(d->temp_name, d->name)) {
  5054. // state is:
  5055. // preserved -> old file
  5056. // filename -> new file
  5057. ok = STB_TRUE;
  5058. // 'filename -> new file' has always been the goal, so clean up
  5059. remove(preserved_old_file); // nothing to be done if it fails
  5060. } else {
  5061. // couldn't rename, so try renaming preserved file back
  5062. // state is:
  5063. // preserved -> old file
  5064. // tempname -> new file
  5065. stb_rename(preserved_old_file, d->name);
  5066. // if the rename failed, there's nothing more we can do
  5067. }
  5068. }
  5069. } else {
  5070. // we couldn't get a temp filename. do this the naive way; the worst case failure here
  5071. // leaves the filename pointing to nothing and the new file as a tempfile
  5072. remove(d->name);
  5073. stb_rename(d->temp_name, d->name);
  5074. }
  5075. }
  5076. }
  5077. free(d->temp_name);
  5078. free(d->name);
  5079. free(d);
  5080. return ok;
  5081. }
  5082. int stb_copyfile(char *src, char *dest)
  5083. {
  5084. char raw_buffer[1024];
  5085. char *buffer;
  5086. int buf_size = 65536;
  5087. FILE *f, *g;
  5088. // if file already exists at destination, do nothing
  5089. if (stb_feq(src, dest)) return STB_TRUE;
  5090. // open file
  5091. f = stb__fopen(src, "rb");
  5092. if (f == NULL) return STB_FALSE;
  5093. // open file for writing
  5094. g = stb__fopen(dest, "wb");
  5095. if (g == NULL) {
  5096. fclose(f);
  5097. return STB_FALSE;
  5098. }
  5099. buffer = (char *) malloc(buf_size);
  5100. if (buffer == NULL) {
  5101. buffer = raw_buffer;
  5102. buf_size = sizeof(raw_buffer);
  5103. }
  5104. while (!feof(f)) {
  5105. size_t n = fread(buffer, 1, buf_size, f);
  5106. if (n != 0)
  5107. fwrite(buffer, 1, n, g);
  5108. }
  5109. fclose(f);
  5110. if (buffer != raw_buffer)
  5111. free(buffer);
  5112. fclose(g);
  5113. return STB_TRUE;
  5114. }
  5115. // varlen:
  5116. // v' = (v >> 31) + (v < 0 ? ~v : v)<<1; // small abs(v) => small v'
  5117. // output v as big endian v'+k for v' <= k:
  5118. // 1 byte : v' <= 0x00000080 ( -64 <= v < 64) 7 bits
  5119. // 2 bytes: v' <= 0x00004000 (-8192 <= v < 8192) 14 bits
  5120. // 3 bytes: v' <= 0x00200000 21 bits
  5121. // 4 bytes: v' <= 0x10000000 28 bits
  5122. // the number of most significant 1-bits in the first byte
  5123. // equals the number of bytes after the first
  5124. #define stb__varlen_xform(v) (v<0 ? (~v << 1)+1 : (v << 1))
  5125. int stb_size_varlen(int v) { return stb_size_varlenu(stb__varlen_xform(v)); }
  5126. int stb_size_varlenu(unsigned int v)
  5127. {
  5128. if (v < 0x00000080) return 1;
  5129. if (v < 0x00004000) return 2;
  5130. if (v < 0x00200000) return 3;
  5131. if (v < 0x10000000) return 4;
  5132. return 5;
  5133. }
  5134. void stb_fput_varlen(FILE *f, int v) { stb_fput_varlenu(f, stb__varlen_xform(v)); }
  5135. void stb_fput_varlenu(FILE *f, unsigned int z)
  5136. {
  5137. if (z >= 0x10000000) fputc(0xF0,f);
  5138. if (z >= 0x00200000) fputc((z < 0x10000000 ? 0xE0 : 0)+(z>>24),f);
  5139. if (z >= 0x00004000) fputc((z < 0x00200000 ? 0xC0 : 0)+(z>>16),f);
  5140. if (z >= 0x00000080) fputc((z < 0x00004000 ? 0x80 : 0)+(z>> 8),f);
  5141. fputc(z,f);
  5142. }
  5143. #define stb_fgetc(f) ((unsigned char) fgetc(f))
  5144. int stb_fget_varlen(FILE *f)
  5145. {
  5146. unsigned int z = stb_fget_varlenu(f);
  5147. return (z & 1) ? ~(z>>1) : (z>>1);
  5148. }
  5149. unsigned int stb_fget_varlenu(FILE *f)
  5150. {
  5151. unsigned int z;
  5152. unsigned char d;
  5153. d = stb_fgetc(f);
  5154. if (d >= 0x80) {
  5155. if (d >= 0xc0) {
  5156. if (d >= 0xe0) {
  5157. if (d == 0xf0) z = stb_fgetc(f) << 24;
  5158. else z = (d - 0xe0) << 24;
  5159. z += stb_fgetc(f) << 16;
  5160. }
  5161. else
  5162. z = (d - 0xc0) << 16;
  5163. z += stb_fgetc(f) << 8;
  5164. } else
  5165. z = (d - 0x80) << 8;
  5166. z += stb_fgetc(f);
  5167. } else
  5168. z = d;
  5169. return z;
  5170. }
  5171. stb_uint64 stb_fget_varlen64(FILE *f)
  5172. {
  5173. stb_uint64 z;
  5174. unsigned char d;
  5175. d = stb_fgetc(f);
  5176. if (d >= 0x80) {
  5177. if (d >= 0xc0) {
  5178. if (d >= 0xe0) {
  5179. if (d >= 0xf0) {
  5180. if (d >= 0xf8) {
  5181. if (d >= 0xfc) {
  5182. if (d >= 0xfe) {
  5183. if (d >= 0xff)
  5184. z = (stb_uint64) stb_fgetc(f) << 56;
  5185. else
  5186. z = (stb_uint64) (d - 0xfe) << 56;
  5187. z |= (stb_uint64) stb_fgetc(f) << 48;
  5188. } else z = (stb_uint64) (d - 0xfc) << 48;
  5189. z |= (stb_uint64) stb_fgetc(f) << 40;
  5190. } else z = (stb_uint64) (d - 0xf8) << 40;
  5191. z |= (stb_uint64) stb_fgetc(f) << 32;
  5192. } else z = (stb_uint64) (d - 0xf0) << 32;
  5193. z |= (stb_uint) stb_fgetc(f) << 24;
  5194. } else z = (stb_uint) (d - 0xe0) << 24;
  5195. z |= (stb_uint) stb_fgetc(f) << 16;
  5196. } else z = (stb_uint) (d - 0xc0) << 16;
  5197. z |= (stb_uint) stb_fgetc(f) << 8;
  5198. } else z = (stb_uint) (d - 0x80) << 8;
  5199. z |= stb_fgetc(f);
  5200. } else
  5201. z = d;
  5202. return (z & 1) ? ~(z >> 1) : (z >> 1);
  5203. }
  5204. int stb_size_varlen64(stb_uint64 v)
  5205. {
  5206. if (v < 0x00000080) return 1;
  5207. if (v < 0x00004000) return 2;
  5208. if (v < 0x00200000) return 3;
  5209. if (v < 0x10000000) return 4;
  5210. if (v < STB_IMM_UINT64(0x0000000800000000)) return 5;
  5211. if (v < STB_IMM_UINT64(0x0000040000000000)) return 6;
  5212. if (v < STB_IMM_UINT64(0x0002000000000000)) return 7;
  5213. if (v < STB_IMM_UINT64(0x0100000000000000)) return 8;
  5214. return 9;
  5215. }
  5216. void stb_fput_varlen64(FILE *f, stb_uint64 v)
  5217. {
  5218. stb_uint64 z = stb__varlen_xform(v);
  5219. int first=1;
  5220. if (z >= STB_IMM_UINT64(0x100000000000000)) {
  5221. fputc(0xff,f);
  5222. first=0;
  5223. }
  5224. if (z >= STB_IMM_UINT64(0x02000000000000)) fputc((first ? 0xFE : 0)+(char)(z>>56),f), first=0;
  5225. if (z >= STB_IMM_UINT64(0x00040000000000)) fputc((first ? 0xFC : 0)+(char)(z>>48),f), first=0;
  5226. if (z >= STB_IMM_UINT64(0x00000800000000)) fputc((first ? 0xF8 : 0)+(char)(z>>40),f), first=0;
  5227. if (z >= STB_IMM_UINT64(0x00000010000000)) fputc((first ? 0xF0 : 0)+(char)(z>>32),f), first=0;
  5228. if (z >= STB_IMM_UINT64(0x00000000200000)) fputc((first ? 0xE0 : 0)+(char)(z>>24),f), first=0;
  5229. if (z >= STB_IMM_UINT64(0x00000000004000)) fputc((first ? 0xC0 : 0)+(char)(z>>16),f), first=0;
  5230. if (z >= STB_IMM_UINT64(0x00000000000080)) fputc((first ? 0x80 : 0)+(char)(z>> 8),f), first=0;
  5231. fputc((char)z,f);
  5232. }
  5233. void stb_fput_ranged(FILE *f, int v, int b, stb_uint n)
  5234. {
  5235. v -= b;
  5236. if (n <= (1 << 31))
  5237. assert((stb_uint) v < n);
  5238. if (n > (1 << 24)) fputc(v >> 24, f);
  5239. if (n > (1 << 16)) fputc(v >> 16, f);
  5240. if (n > (1 << 8)) fputc(v >> 8, f);
  5241. fputc(v,f);
  5242. }
  5243. int stb_fget_ranged(FILE *f, int b, stb_uint n)
  5244. {
  5245. unsigned int v=0;
  5246. if (n > (1 << 24)) v += stb_fgetc(f) << 24;
  5247. if (n > (1 << 16)) v += stb_fgetc(f) << 16;
  5248. if (n > (1 << 8)) v += stb_fgetc(f) << 8;
  5249. v += stb_fgetc(f);
  5250. return b+v;
  5251. }
  5252. int stb_size_ranged(int b, stb_uint n)
  5253. {
  5254. if (n > (1 << 24)) return 4;
  5255. if (n > (1 << 16)) return 3;
  5256. if (n > (1 << 8)) return 2;
  5257. return 1;
  5258. }
  5259. void stb_fput_string(FILE *f, char *s)
  5260. {
  5261. size_t len = strlen(s);
  5262. stb_fput_varlenu(f, (unsigned int) len);
  5263. fwrite(s, 1, len, f);
  5264. }
  5265. // inverse of the above algorithm
  5266. char *stb_fget_string(FILE *f, void *p)
  5267. {
  5268. char *s;
  5269. int len = stb_fget_varlenu(f);
  5270. if (len > 4096) return NULL;
  5271. s = p ? stb_malloc_string(p, len+1) : (char *) malloc(len+1);
  5272. size_t _s = fread(s, 1, len, f);
  5273. s[len] = 0;
  5274. return s;
  5275. }
  5276. char *stb_strdup(char *str, void *pool)
  5277. {
  5278. size_t len = strlen(str);
  5279. char *p = stb_malloc_string(pool, len+1);
  5280. stb_p_strcpy_s(p, len+1, str);
  5281. return p;
  5282. }
  5283. // strip the trailing '/' or '\\' from a directory so we can refer to it
  5284. // as a file for _stat()
  5285. char *stb_strip_final_slash(char *t)
  5286. {
  5287. if (t[0]) {
  5288. char *z = t + strlen(t) - 1;
  5289. // *z is the last character
  5290. if (*z == '\\' || *z == '/')
  5291. if (z != t+2 || t[1] != ':') // but don't strip it if it's e.g. "c:/"
  5292. *z = 0;
  5293. if (*z == '\\')
  5294. *z = '/'; // canonicalize to make sure it matches db
  5295. }
  5296. return t;
  5297. }
  5298. char *stb_strip_final_slash_regardless(char *t)
  5299. {
  5300. if (t[0]) {
  5301. char *z = t + strlen(t) - 1;
  5302. // *z is the last character
  5303. if (*z == '\\' || *z == '/')
  5304. *z = 0;
  5305. if (*z == '\\')
  5306. *z = '/'; // canonicalize to make sure it matches db
  5307. }
  5308. return t;
  5309. }
  5310. #endif
  5311. //////////////////////////////////////////////////////////////////////////////
  5312. //
  5313. // Options parsing
  5314. //
  5315. STB_EXTERN char **stb_getopt_param(int *argc, char **argv, char *param);
  5316. STB_EXTERN char **stb_getopt(int *argc, char **argv);
  5317. STB_EXTERN void stb_getopt_free(char **opts);
  5318. #ifdef STB_DEFINE
  5319. void stb_getopt_free(char **opts)
  5320. {
  5321. int i;
  5322. char ** o2 = opts;
  5323. for (i=0; i < stb_arr_len(o2); ++i)
  5324. free(o2[i]);
  5325. stb_arr_free(o2);
  5326. }
  5327. char **stb_getopt(int *argc, char **argv)
  5328. {
  5329. return stb_getopt_param(argc, argv, (char*) "");
  5330. }
  5331. char **stb_getopt_param(int *argc, char **argv, char *param)
  5332. {
  5333. char ** opts=NULL;
  5334. int i,j=1;
  5335. for (i=1; i < *argc; ++i) {
  5336. if (argv[i][0] != '-') {
  5337. argv[j++] = argv[i];
  5338. } else {
  5339. if (argv[i][1] == 0) { // plain - == don't parse further options
  5340. ++i;
  5341. while (i < *argc)
  5342. argv[j++] = argv[i++];
  5343. break;
  5344. } else if (argv[i][1] == '-') {
  5345. // copy argument through including initial '-' for clarity
  5346. stb_arr_push(opts, stb_p_strdup(argv[i]));
  5347. } else {
  5348. int k;
  5349. char *q = argv[i]; // traverse options list
  5350. for (k=1; q[k]; ++k) {
  5351. char *s;
  5352. if (strchr(param, q[k])) { // does it take a parameter?
  5353. char *t = &q[k+1], z = q[k];
  5354. size_t len=0;
  5355. if (*t == 0) {
  5356. if (i == *argc-1) { // takes a parameter, but none found
  5357. *argc = 0;
  5358. stb_getopt_free(opts);
  5359. return NULL;
  5360. }
  5361. t = argv[++i];
  5362. } else
  5363. k += (int) strlen(t);
  5364. len = strlen(t);
  5365. s = (char *) malloc(len+2);
  5366. if (!s) return NULL;
  5367. s[0] = z;
  5368. stb_p_strcpy_s(s+1, len+2, t);
  5369. } else {
  5370. // no parameter
  5371. s = (char *) malloc(2);
  5372. if (!s) return NULL;
  5373. s[0] = q[k];
  5374. s[1] = 0;
  5375. }
  5376. stb_arr_push(opts, s);
  5377. }
  5378. }
  5379. }
  5380. }
  5381. stb_arr_push(opts, NULL);
  5382. *argc = j;
  5383. return opts;
  5384. }
  5385. #endif
  5386. //////////////////////////////////////////////////////////////////////////////
  5387. //
  5388. // Portable directory reading
  5389. //
  5390. /*
  5391. STB_EXTERN char **stb_readdir_files (char *dir);
  5392. STB_EXTERN char **stb_readdir_files_mask(char *dir, char *wild);
  5393. STB_EXTERN char **stb_readdir_subdirs(char *dir);
  5394. STB_EXTERN char **stb_readdir_subdirs_mask(char *dir, char *wild);
  5395. STB_EXTERN void stb_readdir_free (char **files);
  5396. STB_EXTERN char **stb_readdir_recursive(char *dir, char *filespec);
  5397. STB_EXTERN void stb_delete_directory_recursive(char *dir);
  5398. #ifdef STB_DEFINE
  5399. #ifdef _MSC_VER
  5400. #include <io.h>
  5401. #else
  5402. #include <unistd.h>
  5403. #include <dirent.h>
  5404. #endif
  5405. void stb_readdir_free(char **files)
  5406. {
  5407. char **f2 = files;
  5408. int i;
  5409. for (i=0; i < stb_arr_len(f2); ++i)
  5410. free(f2[i]);
  5411. stb_arr_free(f2);
  5412. }
  5413. static int isdotdirname(char *name)
  5414. {
  5415. if (name[0] == '.')
  5416. return (name[1] == '.') ? !name[2] : !name[1];
  5417. return 0;
  5418. }
  5419. STB_EXTERN int stb_wildmatchi(char *expr, char *candidate);
  5420. static char **readdir_raw(char *dir, int return_subdirs, char *mask)
  5421. {
  5422. char **results = NULL;
  5423. char buffer[4096], with_slash[4096];
  5424. size_t n;
  5425. #ifdef _MSC_VER
  5426. stb__wchar *ws;
  5427. struct _wfinddata_t data;
  5428. #ifdef _WIN64
  5429. const intptr_t none = -1;
  5430. intptr_t z;
  5431. #else
  5432. const long none = -1;
  5433. long z;
  5434. #endif
  5435. #else // !_MSC_VER
  5436. const DIR *none = NULL;
  5437. DIR *z;
  5438. #endif
  5439. n = stb_strscpy(buffer,dir,sizeof(buffer));
  5440. if (!n || n >= sizeof(buffer))
  5441. return NULL;
  5442. stb_fixpath(buffer);
  5443. if (n > 0 && (buffer[n-1] != '/')) {
  5444. buffer[n++] = '/';
  5445. }
  5446. buffer[n] = 0;
  5447. if (!stb_strscpy(with_slash,buffer,sizeof(with_slash)))
  5448. return NULL;
  5449. #ifdef _MSC_VER
  5450. if (!stb_strscpy(buffer+n,"*.*",sizeof(buffer)-n))
  5451. return NULL;
  5452. ws = stb__from_utf8(buffer);
  5453. z = _wfindfirst((wchar_t *)ws, &data);
  5454. #else
  5455. z = opendir(dir);
  5456. #endif
  5457. if (z != none) {
  5458. int nonempty = STB_TRUE;
  5459. #ifndef _MSC_VER
  5460. struct dirent *data = readdir(z);
  5461. nonempty = (data != NULL);
  5462. #endif
  5463. if (nonempty) {
  5464. do {
  5465. int is_subdir;
  5466. #ifdef _MSC_VER
  5467. char *name = stb__to_utf8((stb__wchar *)data.name);
  5468. if (name == NULL) {
  5469. fprintf(stderr, "%s to convert '%S' to %s!\n", "Unable", data.name, "utf8");
  5470. continue;
  5471. }
  5472. is_subdir = !!(data.attrib & _A_SUBDIR);
  5473. #else
  5474. char *name = data->d_name;
  5475. if (!stb_strscpy(buffer+n,name,sizeof(buffer)-n))
  5476. break;
  5477. // Could follow DT_LNK, but would need to check for recursive links.
  5478. is_subdir = !!(data->d_name & DT_DIR);
  5479. #endif
  5480. if (is_subdir == return_subdirs) {
  5481. if (!is_subdir || !isdotdirname(name)) {
  5482. if (!mask || stb_wildmatchi(mask, name)) {
  5483. char buffer[4096],*p=buffer;
  5484. if ( stb_snprintf(buffer, sizeof(buffer), "%s%s", with_slash, name) < 0 )
  5485. break;
  5486. if (buffer[0] == '.' && buffer[1] == '/')
  5487. p = buffer+2;
  5488. stb_arr_push(results, stb_p_strdup(p));
  5489. }
  5490. }
  5491. }
  5492. }
  5493. #ifdef _MSC_VER
  5494. while (0 == _wfindnext(z, &data));
  5495. #else
  5496. while ((data = readdir(z)) != NULL);
  5497. #endif
  5498. }
  5499. #ifdef _MSC_VER
  5500. _findclose(z);
  5501. #else
  5502. closedir(z);
  5503. #endif
  5504. }
  5505. return results;
  5506. }
  5507. char **stb_readdir_files (char *dir) { return readdir_raw(dir, 0, NULL); }
  5508. char **stb_readdir_subdirs(char *dir) { return readdir_raw(dir, 1, NULL); }
  5509. char **stb_readdir_files_mask(char *dir, char *wild) { return readdir_raw(dir, 0, wild); }
  5510. char **stb_readdir_subdirs_mask(char *dir, char *wild) { return readdir_raw(dir, 1, wild); }
  5511. int stb__rec_max=0x7fffffff;
  5512. static char **stb_readdir_rec(char **sofar, char *dir, char *filespec)
  5513. {
  5514. char **files;
  5515. char ** dirs;
  5516. char **p;
  5517. if (stb_arr_len(sofar) >= stb__rec_max) return sofar;
  5518. files = stb_readdir_files_mask(dir, filespec);
  5519. stb_arr_for(p, files) {
  5520. stb_arr_push(sofar, stb_p_strdup(*p));
  5521. if (stb_arr_len(sofar) >= stb__rec_max) break;
  5522. }
  5523. stb_readdir_free(files);
  5524. if (stb_arr_len(sofar) >= stb__rec_max) return sofar;
  5525. dirs = stb_readdir_subdirs(dir);
  5526. stb_arr_for(p, dirs)
  5527. sofar = stb_readdir_rec(sofar, *p, filespec);
  5528. stb_readdir_free(dirs);
  5529. return sofar;
  5530. }
  5531. char **stb_readdir_recursive(char *dir, char *filespec)
  5532. {
  5533. return stb_readdir_rec(NULL, dir, filespec);
  5534. }
  5535. void stb_delete_directory_recursive(char *dir)
  5536. {
  5537. char **list = stb_readdir_subdirs(dir);
  5538. int i;
  5539. for (i=0; i < stb_arr_len(list); ++i)
  5540. stb_delete_directory_recursive(list[i]);
  5541. stb_arr_free(list);
  5542. list = stb_readdir_files(dir);
  5543. for (i=0; i < stb_arr_len(list); ++i)
  5544. if (!remove(list[i])) {
  5545. // on windows, try again after making it writeable; don't ALWAYS
  5546. // do this first since that would be slow in the normal case
  5547. #ifdef _MSC_VER
  5548. _chmod(list[i], _S_IWRITE);
  5549. remove(list[i]);
  5550. #endif
  5551. }
  5552. stb_arr_free(list);
  5553. stb__windows(_rmdir,rmdir)(dir);
  5554. }
  5555. #endif
  5556. */
  5557. //////////////////////////////////////////////////////////////////////////////
  5558. //
  5559. // construct trees from filenames; useful for cmirror summaries
  5560. typedef struct stb_dirtree2 stb_dirtree2;
  5561. struct stb_dirtree2
  5562. {
  5563. stb_dirtree2 **subdirs;
  5564. // make convenient for stb_summarize_tree
  5565. int num_subdir;
  5566. float weight;
  5567. // actual data
  5568. char *fullpath;
  5569. char *relpath;
  5570. char **files;
  5571. };
  5572. STB_EXTERN stb_dirtree2 *stb_dirtree2_from_files_relative(char *src, char **filelist, int count);
  5573. STB_EXTERN stb_dirtree2 *stb_dirtree2_from_files(char **filelist, int count);
  5574. STB_EXTERN int stb_dir_is_prefix(char *dir, int dirlen, char *file);
  5575. #ifdef STB_DEFINE
  5576. int stb_dir_is_prefix(char *dir, int dirlen, char *file)
  5577. {
  5578. if (dirlen == 0) return STB_TRUE;
  5579. if (stb_strnicmp(dir, file, dirlen)) return STB_FALSE;
  5580. if (file[dirlen] == '/' || file[dirlen] == '\\') return STB_TRUE;
  5581. return STB_FALSE;
  5582. }
  5583. stb_dirtree2 *stb_dirtree2_from_files_relative(char *src, char **filelist, int count)
  5584. {
  5585. char buffer1[1024];
  5586. int i;
  5587. int dlen = (int) strlen(src), elen;
  5588. stb_dirtree2 *d;
  5589. char ** descendents = NULL;
  5590. char ** files = NULL;
  5591. char *s;
  5592. if (!count) return NULL;
  5593. // first find all the ones that belong here... note this is will take O(NM) with N files and M subdirs
  5594. for (i=0; i < count; ++i) {
  5595. if (stb_dir_is_prefix(src, dlen, filelist[i])) {
  5596. stb_arr_push(descendents, filelist[i]);
  5597. }
  5598. }
  5599. if (descendents == NULL)
  5600. return NULL;
  5601. elen = dlen;
  5602. // skip a leading slash
  5603. if (elen == 0 && (descendents[0][0] == '/' || descendents[0][0] == '\\'))
  5604. ++elen;
  5605. else if (elen)
  5606. ++elen;
  5607. // now extract all the ones that have their root here
  5608. for (i=0; i < stb_arr_len(descendents);) {
  5609. if (!stb_strchr2(descendents[i]+elen, '/', '\\')) {
  5610. stb_arr_push(files, descendents[i]);
  5611. descendents[i] = descendents[stb_arr_len(descendents)-1];
  5612. stb_arr_pop(descendents);
  5613. } else
  5614. ++i;
  5615. }
  5616. // now create a record
  5617. d = (stb_dirtree2 *) malloc(sizeof(*d));
  5618. d->files = files;
  5619. d->subdirs = NULL;
  5620. d->fullpath = stb_p_strdup(src);
  5621. s = stb_strrchr2(d->fullpath, '/', '\\');
  5622. if (s)
  5623. ++s;
  5624. else
  5625. s = d->fullpath;
  5626. d->relpath = s;
  5627. // now create the children
  5628. qsort(descendents, stb_arr_len(descendents), sizeof(char *), stb_qsort_stricmp(0));
  5629. buffer1[0] = 0;
  5630. for (i=0; i < stb_arr_len(descendents); ++i) {
  5631. char buffer2[1024];
  5632. char *s = descendents[i] + elen, *t;
  5633. t = stb_strchr2(s, '/', '\\');
  5634. assert(t);
  5635. stb_strncpy(buffer2, descendents[i], (int) (t-descendents[i]+1));
  5636. if (stb_stricmp(buffer1, buffer2)) {
  5637. stb_dirtree2 *t = stb_dirtree2_from_files_relative(buffer2, descendents, stb_arr_len(descendents));
  5638. assert(t != NULL);
  5639. stb_p_strcpy_s(buffer1, sizeof(buffer1), buffer2);
  5640. stb_arr_push(d->subdirs, t);
  5641. }
  5642. }
  5643. d->num_subdir = stb_arr_len(d->subdirs);
  5644. d->weight = 0;
  5645. return d;
  5646. }
  5647. stb_dirtree2 *stb_dirtree2_from_files(char **filelist, int count)
  5648. {
  5649. return stb_dirtree2_from_files_relative((char*) "", filelist, count);
  5650. }
  5651. #endif
  5652. //////////////////////////////////////////////////////////////////////////////
  5653. //
  5654. // Checksums: CRC-32, ADLER32, SHA-1
  5655. //
  5656. // CRC-32 and ADLER32 allow streaming blocks
  5657. // SHA-1 requires either a complete buffer, max size 2^32 - 73
  5658. // or it can checksum directly from a file, max 2^61
  5659. #define STB_ADLER32_SEED 1
  5660. #define STB_CRC32_SEED 0 // note that we logical NOT this in the code
  5661. STB_EXTERN stb_uint
  5662. stb_adler32(stb_uint adler32, stb_uchar *buffer, stb_uint buflen);
  5663. STB_EXTERN stb_uint
  5664. stb_crc32_block(stb_uint crc32, stb_uchar *buffer, stb_uint len);
  5665. STB_EXTERN stb_uint stb_crc32(unsigned char *buffer, stb_uint len);
  5666. STB_EXTERN void stb_sha1(
  5667. unsigned char output[20], unsigned char *buffer, unsigned int len);
  5668. STB_EXTERN int stb_sha1_file(unsigned char output[20], char *file);
  5669. STB_EXTERN void stb_sha1_readable(char display[27], unsigned char sha[20]);
  5670. #ifdef STB_DEFINE
  5671. stb_uint stb_crc32_block(stb_uint crc, unsigned char *buffer, stb_uint len)
  5672. {
  5673. static stb_uint crc_table[256];
  5674. stb_uint i,j,s;
  5675. crc = ~crc;
  5676. if (crc_table[1] == 0)
  5677. for(i=0; i < 256; i++) {
  5678. for (s=i, j=0; j < 8; ++j)
  5679. s = (s >> 1) ^ (s & 1 ? 0xedb88320 : 0);
  5680. crc_table[i] = s;
  5681. }
  5682. for (i=0; i < len; ++i)
  5683. crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)];
  5684. return ~crc;
  5685. }
  5686. stb_uint stb_crc32(unsigned char *buffer, stb_uint len)
  5687. {
  5688. return stb_crc32_block(0, buffer, len);
  5689. }
  5690. stb_uint stb_adler32(stb_uint adler32, stb_uchar *buffer, stb_uint buflen)
  5691. {
  5692. const unsigned long ADLER_MOD = 65521;
  5693. unsigned long s1 = adler32 & 0xffff, s2 = adler32 >> 16;
  5694. unsigned long blocklen, i;
  5695. blocklen = buflen % 5552;
  5696. while (buflen) {
  5697. for (i=0; i + 7 < blocklen; i += 8) {
  5698. s1 += buffer[0], s2 += s1;
  5699. s1 += buffer[1], s2 += s1;
  5700. s1 += buffer[2], s2 += s1;
  5701. s1 += buffer[3], s2 += s1;
  5702. s1 += buffer[4], s2 += s1;
  5703. s1 += buffer[5], s2 += s1;
  5704. s1 += buffer[6], s2 += s1;
  5705. s1 += buffer[7], s2 += s1;
  5706. buffer += 8;
  5707. }
  5708. for (; i < blocklen; ++i)
  5709. s1 += *buffer++, s2 += s1;
  5710. s1 %= ADLER_MOD, s2 %= ADLER_MOD;
  5711. buflen -= blocklen;
  5712. blocklen = 5552;
  5713. }
  5714. return (s2 << 16) + s1;
  5715. }
  5716. static void stb__sha1(stb_uchar *chunk, stb_uint h[5])
  5717. {
  5718. int i;
  5719. stb_uint a,b,c,d,e;
  5720. stb_uint w[80];
  5721. for (i=0; i < 16; ++i)
  5722. w[i] = stb_big32(&chunk[i*4]);
  5723. for (i=16; i < 80; ++i) {
  5724. stb_uint t;
  5725. t = w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16];
  5726. w[i] = (t + t) | (t >> 31);
  5727. }
  5728. a = h[0];
  5729. b = h[1];
  5730. c = h[2];
  5731. d = h[3];
  5732. e = h[4];
  5733. #define STB__SHA1(k,f) \
  5734. { \
  5735. stb_uint temp = (a << 5) + (a >> 27) + (f) + e + (k) + w[i]; \
  5736. e = d; \
  5737. d = c; \
  5738. c = (b << 30) + (b >> 2); \
  5739. b = a; \
  5740. a = temp; \
  5741. }
  5742. i=0;
  5743. for (; i < 20; ++i) STB__SHA1(0x5a827999, d ^ (b & (c ^ d)) );
  5744. for (; i < 40; ++i) STB__SHA1(0x6ed9eba1, b ^ c ^ d );
  5745. for (; i < 60; ++i) STB__SHA1(0x8f1bbcdc, (b & c) + (d & (b ^ c)) );
  5746. for (; i < 80; ++i) STB__SHA1(0xca62c1d6, b ^ c ^ d );
  5747. #undef STB__SHA1
  5748. h[0] += a;
  5749. h[1] += b;
  5750. h[2] += c;
  5751. h[3] += d;
  5752. h[4] += e;
  5753. }
  5754. void stb_sha1(stb_uchar output[20], stb_uchar *buffer, stb_uint len)
  5755. {
  5756. unsigned char final_block[128];
  5757. stb_uint end_start, final_len, j;
  5758. int i;
  5759. stb_uint h[5];
  5760. h[0] = 0x67452301;
  5761. h[1] = 0xefcdab89;
  5762. h[2] = 0x98badcfe;
  5763. h[3] = 0x10325476;
  5764. h[4] = 0xc3d2e1f0;
  5765. // we need to write padding to the last one or two
  5766. // blocks, so build those first into 'final_block'
  5767. // we have to write one special byte, plus the 8-byte length
  5768. // compute the block where the data runs out
  5769. end_start = len & ~63;
  5770. // compute the earliest we can encode the length
  5771. if (((len+9) & ~63) == end_start) {
  5772. // it all fits in one block, so fill a second-to-last block
  5773. end_start -= 64;
  5774. }
  5775. final_len = end_start + 128;
  5776. // now we need to copy the data in
  5777. assert(end_start + 128 >= len+9);
  5778. assert(end_start < len || len < 64-9);
  5779. j = 0;
  5780. if (end_start > len)
  5781. j = (stb_uint) - (int) end_start;
  5782. for (; end_start + j < len; ++j)
  5783. final_block[j] = buffer[end_start + j];
  5784. final_block[j++] = 0x80;
  5785. while (j < 128-5) // 5 byte length, so write 4 extra padding bytes
  5786. final_block[j++] = 0;
  5787. // big-endian size
  5788. final_block[j++] = len >> 29;
  5789. final_block[j++] = len >> 21;
  5790. final_block[j++] = len >> 13;
  5791. final_block[j++] = len >> 5;
  5792. final_block[j++] = len << 3;
  5793. assert(j == 128 && end_start + j == final_len);
  5794. for (j=0; j < final_len; j += 64) { // 512-bit chunks
  5795. if (j+64 >= end_start+64)
  5796. stb__sha1(&final_block[j - end_start], h);
  5797. else
  5798. stb__sha1(&buffer[j], h);
  5799. }
  5800. for (i=0; i < 5; ++i) {
  5801. output[i*4 + 0] = h[i] >> 24;
  5802. output[i*4 + 1] = h[i] >> 16;
  5803. output[i*4 + 2] = h[i] >> 8;
  5804. output[i*4 + 3] = h[i] >> 0;
  5805. }
  5806. }
  5807. #ifdef _MSC_VER
  5808. int stb_sha1_file(stb_uchar output[20], char *file)
  5809. {
  5810. int i;
  5811. stb_uint64 length=0;
  5812. unsigned char buffer[128];
  5813. FILE *f = stb__fopen(file, "rb");
  5814. stb_uint h[5];
  5815. if (f == NULL) return 0; // file not found
  5816. h[0] = 0x67452301;
  5817. h[1] = 0xefcdab89;
  5818. h[2] = 0x98badcfe;
  5819. h[3] = 0x10325476;
  5820. h[4] = 0xc3d2e1f0;
  5821. for(;;) {
  5822. size_t n = fread(buffer, 1, 64, f);
  5823. if (n == 64) {
  5824. stb__sha1(buffer, h);
  5825. length += n;
  5826. } else {
  5827. int block = 64;
  5828. length += n;
  5829. buffer[n++] = 0x80;
  5830. // if there isn't enough room for the length, double the block
  5831. if (n + 8 > 64)
  5832. block = 128;
  5833. // pad to end
  5834. memset(buffer+n, 0, block-8-n);
  5835. i = block - 8;
  5836. buffer[i++] = (stb_uchar) (length >> 53);
  5837. buffer[i++] = (stb_uchar) (length >> 45);
  5838. buffer[i++] = (stb_uchar) (length >> 37);
  5839. buffer[i++] = (stb_uchar) (length >> 29);
  5840. buffer[i++] = (stb_uchar) (length >> 21);
  5841. buffer[i++] = (stb_uchar) (length >> 13);
  5842. buffer[i++] = (stb_uchar) (length >> 5);
  5843. buffer[i++] = (stb_uchar) (length << 3);
  5844. assert(i == block);
  5845. stb__sha1(buffer, h);
  5846. if (block == 128)
  5847. stb__sha1(buffer+64, h);
  5848. else
  5849. assert(block == 64);
  5850. break;
  5851. }
  5852. }
  5853. fclose(f);
  5854. for (i=0; i < 5; ++i) {
  5855. output[i*4 + 0] = h[i] >> 24;
  5856. output[i*4 + 1] = h[i] >> 16;
  5857. output[i*4 + 2] = h[i] >> 8;
  5858. output[i*4 + 3] = h[i] >> 0;
  5859. }
  5860. return 1;
  5861. }
  5862. #endif // _MSC_VER
  5863. // client can truncate this wherever they like
  5864. void stb_sha1_readable(char display[27], unsigned char sha[20])
  5865. {
  5866. char encoding[65] = "0123456789abcdefghijklmnopqrstuv"
  5867. "wxyzABCDEFGHIJKLMNOPQRSTUVWXYZ%$";
  5868. int num_bits = 0, acc=0;
  5869. int i=0,o=0;
  5870. while (o < 26) {
  5871. int v;
  5872. // expand the accumulator
  5873. if (num_bits < 6) {
  5874. assert(i != 20);
  5875. acc += sha[i++] << num_bits;
  5876. num_bits += 8;
  5877. }
  5878. v = acc & ((1 << 6) - 1);
  5879. display[o++] = encoding[v];
  5880. acc >>= 6;
  5881. num_bits -= 6;
  5882. }
  5883. assert(num_bits == 20*8 - 26*6);
  5884. display[o++] = encoding[acc];
  5885. }
  5886. #endif // STB_DEFINE
  5887. ///////////////////////////////////////////////////////////
  5888. //
  5889. // simplified WINDOWS registry interface... hopefully
  5890. // we'll never actually use this?
  5891. #if defined(_WIN32)
  5892. STB_EXTERN void * stb_reg_open(const char *mode, const char *where); // mode: "rHKLM" or "rHKCU" or "w.."
  5893. STB_EXTERN void stb_reg_close(void *reg);
  5894. STB_EXTERN int stb_reg_read(void *zreg, const char *str, void *data, unsigned long len);
  5895. STB_EXTERN int stb_reg_read_string(void *zreg, const char *str, char *data, int len);
  5896. STB_EXTERN void stb_reg_write(void *zreg, const char *str, const void *data, unsigned long len);
  5897. STB_EXTERN void stb_reg_write_string(void *zreg, const char *str, const char *data);
  5898. #if defined(STB_DEFINE) && !defined(STB_NO_REGISTRY)
  5899. #define STB_HAS_REGISTRY
  5900. #ifndef _WINDOWS_
  5901. #define HKEY void *
  5902. STB_EXTERN __declspec(dllimport) long __stdcall RegCloseKey ( HKEY hKey );
  5903. STB_EXTERN __declspec(dllimport) long __stdcall RegCreateKeyExA ( HKEY hKey, const char * lpSubKey,
  5904. int Reserved, char * lpClass, int dwOptions,
  5905. int samDesired, void *lpSecurityAttributes, HKEY * phkResult, int * lpdwDisposition );
  5906. STB_EXTERN __declspec(dllimport) long __stdcall RegDeleteKeyA ( HKEY hKey, const char * lpSubKey );
  5907. STB_EXTERN __declspec(dllimport) long __stdcall RegQueryValueExA ( HKEY hKey, const char * lpValueName,
  5908. int * lpReserved, unsigned long * lpType, unsigned char * lpData, unsigned long * lpcbData );
  5909. STB_EXTERN __declspec(dllimport) long __stdcall RegSetValueExA ( HKEY hKey, const char * lpValueName,
  5910. int Reserved, int dwType, const unsigned char* lpData, int cbData );
  5911. STB_EXTERN __declspec(dllimport) long __stdcall RegOpenKeyExA ( HKEY hKey, const char * lpSubKey,
  5912. int ulOptions, int samDesired, HKEY * phkResult );
  5913. #endif // _WINDOWS_
  5914. #define STB__REG_OPTION_NON_VOLATILE 0
  5915. #define STB__REG_KEY_ALL_ACCESS 0x000f003f
  5916. #define STB__REG_KEY_READ 0x00020019
  5917. #ifdef _M_AMD64
  5918. #define STB__HKEY_CURRENT_USER 0x80000001ull
  5919. #define STB__HKEY_LOCAL_MACHINE 0x80000002ull
  5920. #else
  5921. #define STB__HKEY_CURRENT_USER 0x80000001
  5922. #define STB__HKEY_LOCAL_MACHINE 0x80000002
  5923. #endif
  5924. void *stb_reg_open(const char *mode, const char *where)
  5925. {
  5926. long res;
  5927. HKEY base;
  5928. HKEY zreg;
  5929. if (!stb_stricmp(mode+1, "cu") || !stb_stricmp(mode+1, "hkcu"))
  5930. base = (HKEY) STB__HKEY_CURRENT_USER;
  5931. else if (!stb_stricmp(mode+1, "lm") || !stb_stricmp(mode+1, "hklm"))
  5932. base = (HKEY) STB__HKEY_LOCAL_MACHINE;
  5933. else
  5934. return NULL;
  5935. if (mode[0] == 'r')
  5936. res = RegOpenKeyExA(base, where, 0, STB__REG_KEY_READ, &zreg);
  5937. else if (mode[0] == 'w')
  5938. res = RegCreateKeyExA(base, where, 0, NULL, STB__REG_OPTION_NON_VOLATILE, STB__REG_KEY_ALL_ACCESS, NULL, &zreg, NULL);
  5939. else
  5940. return NULL;
  5941. return res ? NULL : zreg;
  5942. }
  5943. void stb_reg_close(void *reg)
  5944. {
  5945. RegCloseKey((HKEY) reg);
  5946. }
  5947. #define STB__REG_SZ 1
  5948. #define STB__REG_BINARY 3
  5949. #define STB__REG_DWORD 4
  5950. int stb_reg_read(void *zreg, const char *str, void *data, unsigned long len)
  5951. {
  5952. unsigned long type;
  5953. unsigned long alen = len;
  5954. if (0 == RegQueryValueExA((HKEY) zreg, str, 0, &type, (unsigned char *) data, &len))
  5955. if (type == STB__REG_BINARY || type == STB__REG_SZ || type == STB__REG_DWORD) {
  5956. if (len < alen)
  5957. *((char *) data + len) = 0;
  5958. return 1;
  5959. }
  5960. return 0;
  5961. }
  5962. void stb_reg_write(void *zreg, const char *str, const void *data, unsigned long len)
  5963. {
  5964. if (zreg)
  5965. RegSetValueExA((HKEY) zreg, str, 0, STB__REG_BINARY, (const unsigned char *) data, len);
  5966. }
  5967. int stb_reg_read_string(void *zreg, const char *str, char *data, int len)
  5968. {
  5969. if (!stb_reg_read(zreg, str, data, len)) return 0;
  5970. data[len-1] = 0; // force a 0 at the end of the string no matter what
  5971. return 1;
  5972. }
  5973. void stb_reg_write_string(void *zreg, const char *str, const char *data)
  5974. {
  5975. if (zreg)
  5976. RegSetValueExA((HKEY) zreg, str, 0, STB__REG_SZ, (const unsigned char *) data, (int) strlen(data)+1);
  5977. }
  5978. #endif // STB_DEFINE
  5979. #endif // _WIN32
  5980. //////////////////////////////////////////////////////////////////////////////
  5981. //
  5982. // stb_cfg - This is like the registry, but the config info
  5983. // is all stored in plain old files where we can
  5984. // backup and restore them easily. The LOCATION of
  5985. // the config files is gotten from... the registry!
  5986. #ifndef STB_NO_STB_STRINGS
  5987. typedef struct stb_cfg_st stb_cfg;
  5988. STB_EXTERN stb_cfg * stb_cfg_open(char *config, const char *mode); // mode = "r", "w"
  5989. STB_EXTERN void stb_cfg_close(stb_cfg *cfg);
  5990. STB_EXTERN int stb_cfg_read(stb_cfg *cfg, char *key, void *value, int len);
  5991. STB_EXTERN void stb_cfg_write(stb_cfg *cfg, char *key, void *value, int len);
  5992. STB_EXTERN int stb_cfg_read_string(stb_cfg *cfg, char *key, char *value, int len);
  5993. STB_EXTERN void stb_cfg_write_string(stb_cfg *cfg, char *key, char *value);
  5994. STB_EXTERN int stb_cfg_delete(stb_cfg *cfg, char *key);
  5995. STB_EXTERN void stb_cfg_set_directory(char *dir);
  5996. #ifdef STB_DEFINE
  5997. typedef struct
  5998. {
  5999. char *key;
  6000. void *value;
  6001. int value_len;
  6002. } stb__cfg_item;
  6003. struct stb_cfg_st
  6004. {
  6005. stb__cfg_item *data;
  6006. char *loaded_file; // this needs to be freed
  6007. FILE *f; // write the data to this file on close
  6008. };
  6009. static const char *stb__cfg_sig = "sTbCoNfIg!\0\0";
  6010. static char stb__cfg_dir[512];
  6011. STB_EXTERN void stb_cfg_set_directory(char *dir)
  6012. {
  6013. stb_p_strcpy_s(stb__cfg_dir, sizeof(stb__cfg_dir), dir);
  6014. }
  6015. STB_EXTERN stb_cfg * stb_cfg_open(char *config, const char *mode)
  6016. {
  6017. size_t len;
  6018. stb_cfg *z;
  6019. char file[512];
  6020. if (mode[0] != 'r' && mode[0] != 'w') return NULL;
  6021. if (!stb__cfg_dir[0]) {
  6022. #ifdef _WIN32
  6023. stb_p_strcpy_s(stb__cfg_dir, sizeof(stb__cfg_dir), "c:/stb");
  6024. #else
  6025. strcpy(stb__cfg_dir, "~/.stbconfig");
  6026. #endif
  6027. #ifdef STB_HAS_REGISTRY
  6028. {
  6029. void *reg = stb_reg_open("rHKLM", "Software\\SilverSpaceship\\stb");
  6030. if (reg) {
  6031. stb_reg_read_string(reg, "config_dir", stb__cfg_dir, sizeof(stb__cfg_dir));
  6032. stb_reg_close(reg);
  6033. }
  6034. }
  6035. #endif
  6036. }
  6037. stb_p_sprintf(file stb_p_size(sizeof(file)), "%s/%s.cfg", stb__cfg_dir, config);
  6038. z = (stb_cfg *) stb_malloc(0, sizeof(*z));
  6039. z->data = NULL;
  6040. z->loaded_file = stb_filec(file, &len);
  6041. if (z->loaded_file) {
  6042. char *s = z->loaded_file;
  6043. if (!memcmp(s, stb__cfg_sig, 12)) {
  6044. char *s = z->loaded_file + 12;
  6045. while (s < z->loaded_file + len) {
  6046. stb__cfg_item a;
  6047. int n = *(stb_int16 *) s;
  6048. a.key = s+2;
  6049. s = s+2 + n;
  6050. a.value_len = *(int *) s;
  6051. s += 4;
  6052. a.value = s;
  6053. s += a.value_len;
  6054. stb_arr_push(z->data, a);
  6055. }
  6056. assert(s == z->loaded_file + len);
  6057. }
  6058. }
  6059. if (mode[0] == 'w')
  6060. z->f = stb_p_fopen(file, "wb");
  6061. else
  6062. z->f = NULL;
  6063. return z;
  6064. }
  6065. void stb_cfg_close(stb_cfg *z)
  6066. {
  6067. if (z->f) {
  6068. int i;
  6069. // write the file out
  6070. fwrite(stb__cfg_sig, 12, 1, z->f);
  6071. for (i=0; i < stb_arr_len(z->data); ++i) {
  6072. stb_int16 n = (stb_int16) strlen(z->data[i].key)+1;
  6073. fwrite(&n, 2, 1, z->f);
  6074. fwrite(z->data[i].key, n, 1, z->f);
  6075. fwrite(&z->data[i].value_len, 4, 1, z->f);
  6076. fwrite(z->data[i].value, z->data[i].value_len, 1, z->f);
  6077. }
  6078. fclose(z->f);
  6079. }
  6080. stb_arr_free(z->data);
  6081. stb_free(z);
  6082. }
  6083. int stb_cfg_read(stb_cfg *z, char *key, void *value, int len)
  6084. {
  6085. int i;
  6086. for (i=0; i < stb_arr_len(z->data); ++i) {
  6087. if (!stb_stricmp(z->data[i].key, key)) {
  6088. int n = stb_min(len, z->data[i].value_len);
  6089. memcpy(value, z->data[i].value, n);
  6090. if (n < len)
  6091. *((char *) value + n) = 0;
  6092. return 1;
  6093. }
  6094. }
  6095. return 0;
  6096. }
  6097. void stb_cfg_write(stb_cfg *z, char *key, void *value, int len)
  6098. {
  6099. int i;
  6100. for (i=0; i < stb_arr_len(z->data); ++i)
  6101. if (!stb_stricmp(z->data[i].key, key))
  6102. break;
  6103. if (i == stb_arr_len(z->data)) {
  6104. stb__cfg_item p;
  6105. p.key = stb_strdup(key, z);
  6106. p.value = NULL;
  6107. p.value_len = 0;
  6108. stb_arr_push(z->data, p);
  6109. }
  6110. z->data[i].value = stb_malloc(z, len);
  6111. z->data[i].value_len = len;
  6112. memcpy(z->data[i].value, value, len);
  6113. }
  6114. int stb_cfg_delete(stb_cfg *z, char *key)
  6115. {
  6116. int i;
  6117. for (i=0; i < stb_arr_len(z->data); ++i)
  6118. if (!stb_stricmp(z->data[i].key, key)) {
  6119. stb_arr_fastdelete(z->data, i);
  6120. return 1;
  6121. }
  6122. return 0;
  6123. }
  6124. int stb_cfg_read_string(stb_cfg *z, char *key, char *value, int len)
  6125. {
  6126. if (!stb_cfg_read(z, key, value, len)) return 0;
  6127. value[len-1] = 0;
  6128. return 1;
  6129. }
  6130. void stb_cfg_write_string(stb_cfg *z, char *key, char *value)
  6131. {
  6132. stb_cfg_write(z, key, value, (int) strlen(value)+1);
  6133. }
  6134. #endif
  6135. //////////////////////////////////////////////////////////////////////////////
  6136. //
  6137. // stb_dirtree - load a description of a directory tree
  6138. // uses a cache and stat()s the directories for changes
  6139. // MUCH faster on NTFS, _wrong_ on FAT32, so should
  6140. // ignore the db on FAT32
  6141. #ifdef _WIN32
  6142. typedef struct
  6143. {
  6144. char * path; // full path from passed-in root
  6145. time_t last_modified;
  6146. int num_files;
  6147. int flag;
  6148. } stb_dirtree_dir;
  6149. typedef struct
  6150. {
  6151. char *name; // name relative to path
  6152. int dir; // index into dirs[] array
  6153. stb_int64 size; // size, max 4GB
  6154. time_t last_modified;
  6155. int flag;
  6156. } stb_dirtree_file;
  6157. typedef struct
  6158. {
  6159. stb_dirtree_dir *dirs;
  6160. stb_dirtree_file *files;
  6161. // internal use
  6162. void * string_pool; // used to free data en masse
  6163. } stb_dirtree;
  6164. extern void stb_dirtree_free ( stb_dirtree *d );
  6165. extern stb_dirtree *stb_dirtree_get ( char *dir);
  6166. extern stb_dirtree *stb_dirtree_get_dir ( char *dir, char *cache_dir);
  6167. extern stb_dirtree *stb_dirtree_get_with_file ( char *dir, char *cache_file);
  6168. // get a list of all the files recursively underneath 'dir'
  6169. //
  6170. // cache_file is used to store a copy of the directory tree to speed up
  6171. // later calls. It must be unique to 'dir' and the current working
  6172. // directory! Otherwise who knows what will happen (a good solution
  6173. // is to put it _in_ dir, but this API doesn't force that).
  6174. //
  6175. // Also, it might be possible to break this if you have two different processes
  6176. // do a call to stb_dirtree_get() with the same cache file at about the same
  6177. // time, but I _think_ it might just work.
  6178. // i needed to build an identical data structure representing the state of
  6179. // a mirrored copy WITHOUT bothering to rescan it (i.e. we're mirroring to
  6180. // it WITHOUT scanning it, e.g. it's over the net), so this requires access
  6181. // to all of the innards.
  6182. extern void stb_dirtree_db_add_dir(stb_dirtree *active, char *path, time_t last);
  6183. extern void stb_dirtree_db_add_file(stb_dirtree *active, char *name, int dir, stb_int64 size, time_t last);
  6184. extern void stb_dirtree_db_read(stb_dirtree *target, char *filename, char *dir);
  6185. extern void stb_dirtree_db_write(stb_dirtree *target, char *filename, char *dir);
  6186. #ifdef STB_DEFINE
  6187. static void stb__dirtree_add_dir(char *path, time_t last, stb_dirtree *active)
  6188. {
  6189. stb_dirtree_dir d;
  6190. d.last_modified = last;
  6191. d.num_files = 0;
  6192. d.path = stb_strdup(path, active->string_pool);
  6193. stb_arr_push(active->dirs, d);
  6194. }
  6195. static void stb__dirtree_add_file(char *name, int dir, stb_int64 size, time_t last, stb_dirtree *active)
  6196. {
  6197. stb_dirtree_file f;
  6198. f.dir = dir;
  6199. f.size = size;
  6200. f.last_modified = last;
  6201. f.name = stb_strdup(name, active->string_pool);
  6202. ++active->dirs[dir].num_files;
  6203. stb_arr_push(active->files, f);
  6204. }
  6205. // version 02 supports > 4GB files
  6206. static char stb__signature[12] = { 's', 'T', 'b', 'D', 'i', 'R', 't', 'R', 'e', 'E', '0', '2' };
  6207. static void stb__dirtree_save_db(char *filename, stb_dirtree *data, char *root)
  6208. {
  6209. int i, num_dirs_final=0, num_files_final;
  6210. char *info = root ? root : (char*)"";
  6211. int *remap;
  6212. FILE *f = stb_p_fopen(filename, "wb");
  6213. if (!f) return;
  6214. fwrite(stb__signature, sizeof(stb__signature), 1, f);
  6215. fwrite(info, strlen(info)+1, 1, f);
  6216. // need to be slightly tricky and not write out NULLed directories, nor the root
  6217. // build remapping table of all dirs we'll be writing out
  6218. remap = (int *) malloc(sizeof(remap[0]) * stb_arr_len(data->dirs));
  6219. for (i=0; i < stb_arr_len(data->dirs); ++i) {
  6220. if (data->dirs[i].path == NULL || (root && 0==stb_stricmp(data->dirs[i].path, root))) {
  6221. remap[i] = -1;
  6222. } else {
  6223. remap[i] = num_dirs_final++;
  6224. }
  6225. }
  6226. fwrite(&num_dirs_final, 4, 1, f);
  6227. for (i=0; i < stb_arr_len(data->dirs); ++i) {
  6228. if (remap[i] >= 0) {
  6229. fwrite(&data->dirs[i].last_modified, 4, 1, f);
  6230. stb_fput_string(f, data->dirs[i].path);
  6231. }
  6232. }
  6233. num_files_final = 0;
  6234. for (i=0; i < stb_arr_len(data->files); ++i)
  6235. if (remap[data->files[i].dir] >= 0 && data->files[i].name)
  6236. ++num_files_final;
  6237. fwrite(&num_files_final, 4, 1, f);
  6238. for (i=0; i < stb_arr_len(data->files); ++i) {
  6239. if (remap[data->files[i].dir] >= 0 && data->files[i].name) {
  6240. stb_fput_ranged(f, remap[data->files[i].dir], 0, num_dirs_final);
  6241. stb_fput_varlen64(f, data->files[i].size);
  6242. fwrite(&data->files[i].last_modified, 4, 1, f);
  6243. stb_fput_string(f, data->files[i].name);
  6244. }
  6245. }
  6246. fclose(f);
  6247. }
  6248. // note: stomps any existing data, rather than appending
  6249. static void stb__dirtree_load_db(char *filename, stb_dirtree *data, char *dir)
  6250. {
  6251. char sig[2048];
  6252. int i,n;
  6253. FILE *f = stb_p_fopen(filename, "rb");
  6254. if (!f) return;
  6255. data->string_pool = stb_malloc(0,1);
  6256. fread(sig, sizeof(stb__signature), 1, f);
  6257. if (memcmp(stb__signature, sig, sizeof(stb__signature))) { fclose(f); return; }
  6258. if (!fread(sig, strlen(dir)+1, 1, f)) { fclose(f); return; }
  6259. if (stb_stricmp(sig,dir)) { fclose(f); return; }
  6260. // we can just read them straight in, because they're guaranteed to be valid
  6261. fread(&n, 4, 1, f);
  6262. stb_arr_setlen(data->dirs, n);
  6263. for(i=0; i < stb_arr_len(data->dirs); ++i) {
  6264. fread(&data->dirs[i].last_modified, 4, 1, f);
  6265. data->dirs[i].path = stb_fget_string(f, data->string_pool);
  6266. if (data->dirs[i].path == NULL) goto bail;
  6267. }
  6268. fread(&n, 4, 1, f);
  6269. stb_arr_setlen(data->files, n);
  6270. for (i=0; i < stb_arr_len(data->files); ++i) {
  6271. data->files[i].dir = stb_fget_ranged(f, 0, stb_arr_len(data->dirs));
  6272. data->files[i].size = stb_fget_varlen64(f);
  6273. fread(&data->files[i].last_modified, 4, 1, f);
  6274. data->files[i].name = stb_fget_string(f, data->string_pool);
  6275. if (data->files[i].name == NULL) goto bail;
  6276. }
  6277. if (0) {
  6278. bail:
  6279. stb_arr_free(data->dirs);
  6280. stb_arr_free(data->files);
  6281. }
  6282. fclose(f);
  6283. }
  6284. FILE *hlog;
  6285. static int stb__dircount, stb__dircount_mask, stb__showfile;
  6286. static void stb__dirtree_scandir(char *path, time_t last_time, stb_dirtree *active)
  6287. {
  6288. // this is dumb depth first; theoretically it might be faster
  6289. // to fully traverse each directory before visiting its children,
  6290. // but it's complicated and didn't seem like a gain in the test app
  6291. int n;
  6292. struct _wfinddatai64_t c_file;
  6293. long hFile;
  6294. stb__wchar full_path[1024];
  6295. int has_slash;
  6296. if (stb__showfile) printf("<");
  6297. has_slash = (path[0] && path[strlen(path)-1] == '/');
  6298. // @TODO: do this concatenation without using swprintf to avoid this mess:
  6299. #if (defined(_MSC_VER) && _MSC_VER < 1400) // || (defined(__clang__))
  6300. // confusingly, Windows Kits\10 needs to go down this path?!?
  6301. // except now it doesn't, I don't know what changed
  6302. if (has_slash)
  6303. swprintf(full_path, L"%s*", stb__from_utf8(path));
  6304. else
  6305. swprintf(full_path, L"%s/*", stb__from_utf8(path));
  6306. #else
  6307. if (has_slash)
  6308. swprintf((wchar_t *) full_path, (size_t) 1024, L"%s*", (wchar_t *) stb__from_utf8(path));
  6309. else
  6310. swprintf((wchar_t *) full_path, (size_t) 1024, L"%s/*", (wchar_t *) stb__from_utf8(path));
  6311. #endif
  6312. // it's possible this directory is already present: that means it was in the
  6313. // cache, but its parent wasn't... in that case, we're done with it
  6314. if (stb__showfile) printf("C[%d]", stb_arr_len(active->dirs));
  6315. for (n=0; n < stb_arr_len(active->dirs); ++n)
  6316. if (0 == stb_stricmp(active->dirs[n].path, path)) {
  6317. if (stb__showfile) printf("D");
  6318. return;
  6319. }
  6320. if (stb__showfile) printf("E");
  6321. // otherwise, we need to add it
  6322. stb__dirtree_add_dir(path, last_time, active);
  6323. n = stb_arr_lastn(active->dirs);
  6324. if (stb__showfile) printf("[");
  6325. if( (hFile = (long) _wfindfirsti64( (wchar_t *) full_path, &c_file )) != -1L ) {
  6326. do {
  6327. if (stb__showfile) printf(")");
  6328. if (c_file.attrib & _A_SUBDIR) {
  6329. // ignore subdirectories starting with '.', e.g. "." and ".."
  6330. if (c_file.name[0] != '.') {
  6331. char *new_path = (char *) full_path;
  6332. char *temp = stb__to_utf8((stb__wchar *) c_file.name);
  6333. if (has_slash)
  6334. stb_p_sprintf(new_path stb_p_size(sizeof(full_path)), "%s%s", path, temp);
  6335. else
  6336. stb_p_sprintf(new_path stb_p_size(sizeof(full_path)), "%s/%s", path, temp);
  6337. if (stb__dircount_mask) {
  6338. ++stb__dircount;
  6339. if (!(stb__dircount & stb__dircount_mask)) {
  6340. char dummy_path[128], *pad;
  6341. stb_strncpy(dummy_path, new_path, sizeof(dummy_path)-1);
  6342. if (strlen(dummy_path) > 96) {
  6343. stb_p_strcpy_s(dummy_path+96/2-1,128, "...");
  6344. stb_p_strcpy_s(dummy_path+96/2+2,128, new_path + strlen(new_path)-96/2+2);
  6345. }
  6346. pad = dummy_path + strlen(dummy_path);
  6347. while (pad < dummy_path+98)
  6348. *pad++ = ' ';
  6349. *pad = 0;
  6350. printf("%s\r", dummy_path);
  6351. #if 0
  6352. if (hlog == 0) {
  6353. hlog = stb_p_fopen("c:/x/temp.log", "w");
  6354. fprintf(hlog, "%s\n", dummy_path);
  6355. }
  6356. #endif
  6357. }
  6358. }
  6359. stb__dirtree_scandir(new_path, c_file.time_write, active);
  6360. }
  6361. } else {
  6362. char *temp = stb__to_utf8((stb__wchar *) c_file.name);
  6363. stb__dirtree_add_file(temp, n, c_file.size, c_file.time_write, active);
  6364. }
  6365. if (stb__showfile) printf("(");
  6366. } while( _wfindnexti64( hFile, &c_file ) == 0 );
  6367. if (stb__showfile) printf("]");
  6368. _findclose( hFile );
  6369. }
  6370. if (stb__showfile) printf(">\n");
  6371. }
  6372. // scan the database and see if it's all valid
  6373. static int stb__dirtree_update_db(stb_dirtree *db, stb_dirtree *active)
  6374. {
  6375. int changes_detected = STB_FALSE;
  6376. int i;
  6377. int *remap;
  6378. int *rescan=NULL;
  6379. remap = (int *) malloc(sizeof(remap[0]) * stb_arr_len(db->dirs));
  6380. memset(remap, 0, sizeof(remap[0]) * stb_arr_len(db->dirs));
  6381. rescan = NULL;
  6382. for (i=0; i < stb_arr_len(db->dirs); ++i) {
  6383. struct _stat info;
  6384. if (stb__dircount_mask) {
  6385. ++stb__dircount;
  6386. if (!(stb__dircount & stb__dircount_mask)) {
  6387. printf(".");
  6388. }
  6389. }
  6390. if (0 == _stat(db->dirs[i].path, &info)) {
  6391. if (info.st_mode & _S_IFDIR) {
  6392. // it's still a directory, as expected
  6393. int n = abs((int) (info.st_mtime - db->dirs[i].last_modified));
  6394. if (n > 1 && n != 3600) { // the 3600 is a hack because sometimes this jumps for no apparent reason, even when no time zone or DST issues are at play
  6395. // it's changed! force a rescan
  6396. // we don't want to scan it until we've stat()d its
  6397. // subdirs, though, so we queue it
  6398. if (stb__showfile) printf("Changed: %s - %08x:%08x\n", db->dirs[i].path, (unsigned int) db->dirs[i].last_modified, (unsigned int) info.st_mtime);
  6399. stb_arr_push(rescan, i);
  6400. // update the last_mod time
  6401. db->dirs[i].last_modified = info.st_mtime;
  6402. // ignore existing files in this dir
  6403. remap[i] = -1;
  6404. changes_detected = STB_TRUE;
  6405. } else {
  6406. // it hasn't changed, just copy it through unchanged
  6407. stb__dirtree_add_dir(db->dirs[i].path, db->dirs[i].last_modified, active);
  6408. remap[i] = stb_arr_lastn(active->dirs);
  6409. }
  6410. } else {
  6411. // this path used to refer to a directory, but now it's a file!
  6412. // assume that the parent directory is going to be forced to rescan anyway
  6413. goto delete_entry;
  6414. }
  6415. } else {
  6416. delete_entry:
  6417. // directory no longer exists, so don't copy it
  6418. // we don't free it because it's in the string pool now
  6419. db->dirs[i].path = NULL;
  6420. remap[i] = -1;
  6421. changes_detected = STB_TRUE;
  6422. }
  6423. }
  6424. // at this point, we have:
  6425. //
  6426. // <rescan> holds a list of directory indices that need to be scanned due to being out of date
  6427. // <remap> holds the directory index in <active> for each dir in <db>, if it exists; -1 if not
  6428. // directories in <rescan> are not in <active> yet
  6429. // so we can go ahead and remap all the known files right now
  6430. for (i=0; i < stb_arr_len(db->files); ++i) {
  6431. int dir = db->files[i].dir;
  6432. if (remap[dir] >= 0) {
  6433. stb__dirtree_add_file(db->files[i].name, remap[dir], db->files[i].size, db->files[i].last_modified, active);
  6434. }
  6435. }
  6436. // at this point we're done with db->files, and done with remap
  6437. free(remap);
  6438. // now scan those directories using the standard scan
  6439. for (i=0; i < stb_arr_len(rescan); ++i) {
  6440. int z = rescan[i];
  6441. stb__dirtree_scandir(db->dirs[z].path, db->dirs[z].last_modified, active);
  6442. }
  6443. stb_arr_free(rescan);
  6444. return changes_detected;
  6445. }
  6446. static void stb__dirtree_free_raw(stb_dirtree *d)
  6447. {
  6448. stb_free(d->string_pool);
  6449. stb_arr_free(d->dirs);
  6450. stb_arr_free(d->files);
  6451. }
  6452. stb_dirtree *stb_dirtree_get_with_file(char *dir, char *cache_file)
  6453. {
  6454. stb_dirtree *output = (stb_dirtree *) malloc(sizeof(*output));
  6455. stb_dirtree db,active;
  6456. int prev_dir_count, cache_mismatch;
  6457. char *stripped_dir; // store the directory name without a trailing '/' or '\\'
  6458. // load the database of last-known state on disk
  6459. db.string_pool = NULL;
  6460. db.files = NULL;
  6461. db.dirs = NULL;
  6462. stripped_dir = stb_strip_final_slash(stb_p_strdup(dir));
  6463. if (cache_file != NULL)
  6464. stb__dirtree_load_db(cache_file, &db, stripped_dir);
  6465. else if (stb__showfile)
  6466. printf("No cache file\n");
  6467. active.files = NULL;
  6468. active.dirs = NULL;
  6469. active.string_pool = stb_malloc(0,1); // @TODO: share string pools between both?
  6470. // check all the directories in the database; make note if
  6471. // anything we scanned had changed, and rescan those things
  6472. cache_mismatch = stb__dirtree_update_db(&db, &active);
  6473. // check the root tree
  6474. prev_dir_count = stb_arr_len(active.dirs); // record how many directories we've seen
  6475. stb__dirtree_scandir(stripped_dir, 0, &active); // no last_modified time available for root
  6476. if (stb__dircount_mask)
  6477. printf(" \r");
  6478. // done with the DB; write it back out if any changes, i.e. either
  6479. // 1. any inconsistency found between cached information and actual disk
  6480. // or 2. if scanning the root found any new directories--which we detect because
  6481. // more than one directory got added to the active db during that scan
  6482. if (cache_mismatch || stb_arr_len(active.dirs) > prev_dir_count+1)
  6483. stb__dirtree_save_db(cache_file, &active, stripped_dir);
  6484. free(stripped_dir);
  6485. stb__dirtree_free_raw(&db);
  6486. *output = active;
  6487. return output;
  6488. }
  6489. stb_dirtree *stb_dirtree_get_dir(char *dir, char *cache_dir)
  6490. {
  6491. int i;
  6492. stb_uint8 sha[20];
  6493. char dir_lower[1024];
  6494. char cache_file[1024],*s;
  6495. if (cache_dir == NULL)
  6496. return stb_dirtree_get_with_file(dir, NULL);
  6497. stb_p_strcpy_s(dir_lower, sizeof(dir_lower), dir);
  6498. stb_tolower(dir_lower);
  6499. stb_sha1(sha, (unsigned char *) dir_lower, (unsigned int) strlen(dir_lower));
  6500. stb_p_strcpy_s(cache_file, sizeof(cache_file), cache_dir);
  6501. s = cache_file + strlen(cache_file);
  6502. if (s[-1] != '/' && s[-1] != '\\') *s++ = '/';
  6503. stb_p_strcpy_s(s, sizeof(cache_file), "dirtree_");
  6504. s += strlen(s);
  6505. for (i=0; i < 8; ++i) {
  6506. char *hex = (char*)"0123456789abcdef";
  6507. stb_uint z = sha[i];
  6508. *s++ = hex[z >> 4];
  6509. *s++ = hex[z & 15];
  6510. }
  6511. stb_p_strcpy_s(s, sizeof(cache_file), ".bin");
  6512. return stb_dirtree_get_with_file(dir, cache_file);
  6513. }
  6514. stb_dirtree *stb_dirtree_get(char *dir)
  6515. {
  6516. char cache_dir[256];
  6517. stb_p_strcpy_s(cache_dir, sizeof(cache_dir), "c:/bindata");
  6518. #ifdef STB_HAS_REGISTRY
  6519. {
  6520. void *reg = stb_reg_open("rHKLM", "Software\\SilverSpaceship\\stb");
  6521. if (reg) {
  6522. stb_reg_read(reg, "dirtree", cache_dir, sizeof(cache_dir));
  6523. stb_reg_close(reg);
  6524. }
  6525. }
  6526. #endif
  6527. return stb_dirtree_get_dir(dir, cache_dir);
  6528. }
  6529. void stb_dirtree_free(stb_dirtree *d)
  6530. {
  6531. stb__dirtree_free_raw(d);
  6532. free(d);
  6533. }
  6534. void stb_dirtree_db_add_dir(stb_dirtree *active, char *path, time_t last)
  6535. {
  6536. stb__dirtree_add_dir(path, last, active);
  6537. }
  6538. void stb_dirtree_db_add_file(stb_dirtree *active, char *name, int dir, stb_int64 size, time_t last)
  6539. {
  6540. stb__dirtree_add_file(name, dir, size, last, active);
  6541. }
  6542. void stb_dirtree_db_read(stb_dirtree *target, char *filename, char *dir)
  6543. {
  6544. char *s = stb_strip_final_slash(stb_p_strdup(dir));
  6545. target->dirs = 0;
  6546. target->files = 0;
  6547. target->string_pool = 0;
  6548. stb__dirtree_load_db(filename, target, s);
  6549. free(s);
  6550. }
  6551. void stb_dirtree_db_write(stb_dirtree *target, char *filename, char *dir)
  6552. {
  6553. stb__dirtree_save_db(filename, target, 0); // don't strip out any directories
  6554. }
  6555. #endif // STB_DEFINE
  6556. #endif // _WIN32
  6557. #endif // STB_NO_STB_STRINGS
  6558. //////////////////////////////////////////////////////////////////////////////
  6559. //
  6560. // STB_MALLOC_WRAPPER
  6561. //
  6562. // you can use the wrapper functions with your own malloc wrapper,
  6563. // or define STB_MALLOC_WRAPPER project-wide to have
  6564. // malloc/free/realloc/strdup all get vectored to it
  6565. // this has too many very specific error messages you could google for and find in stb.h,
  6566. // so don't use it if they don't want any stb.h-identifiable strings
  6567. #if defined(STB_DEFINE) && !defined(STB_NO_STB_STRINGS)
  6568. typedef struct
  6569. {
  6570. void *p;
  6571. char *file;
  6572. int line;
  6573. size_t size;
  6574. } stb_malloc_record;
  6575. #ifndef STB_MALLOC_HISTORY_COUNT
  6576. #define STB_MALLOC_HISTORY_COUNT 50 // 800 bytes
  6577. #endif
  6578. stb_malloc_record *stb__allocations;
  6579. static int stb__alloc_size, stb__alloc_limit, stb__alloc_mask;
  6580. int stb__alloc_count;
  6581. stb_malloc_record stb__alloc_history[STB_MALLOC_HISTORY_COUNT];
  6582. int stb__history_pos;
  6583. static int stb__hashfind(void *p)
  6584. {
  6585. stb_uint32 h = stb_hashptr(p);
  6586. int s,n = h & stb__alloc_mask;
  6587. if (stb__allocations[n].p == p)
  6588. return n;
  6589. s = stb_rehash(h)|1;
  6590. for(;;) {
  6591. if (stb__allocations[n].p == NULL)
  6592. return -1;
  6593. n = (n+s) & stb__alloc_mask;
  6594. if (stb__allocations[n].p == p)
  6595. return n;
  6596. }
  6597. }
  6598. size_t stb_wrapper_allocsize(void *p)
  6599. {
  6600. int n = stb__hashfind(p);
  6601. if (n < 0) return 0;
  6602. return stb__allocations[n].size;
  6603. }
  6604. static int stb__historyfind(void *p)
  6605. {
  6606. int n = stb__history_pos;
  6607. int i;
  6608. for (i=0; i < STB_MALLOC_HISTORY_COUNT; ++i) {
  6609. if (--n < 0) n = STB_MALLOC_HISTORY_COUNT-1;
  6610. if (stb__alloc_history[n].p == p)
  6611. return n;
  6612. }
  6613. return -1;
  6614. }
  6615. static void stb__add_alloc(void *p, size_t sz, char *file, int line);
  6616. static void stb__grow_alloc(void)
  6617. {
  6618. int i,old_num = stb__alloc_size;
  6619. stb_malloc_record *old = stb__allocations;
  6620. if (stb__alloc_size == 0)
  6621. stb__alloc_size = 64;
  6622. else
  6623. stb__alloc_size *= 2;
  6624. stb__allocations = (stb_malloc_record *) stb__realloc_raw(NULL, stb__alloc_size * sizeof(stb__allocations[0]));
  6625. if (stb__allocations == NULL)
  6626. stb_fatal("Internal error: couldn't grow malloc wrapper table");
  6627. memset(stb__allocations, 0, stb__alloc_size * sizeof(stb__allocations[0]));
  6628. stb__alloc_limit = (stb__alloc_size*3)>>2;
  6629. stb__alloc_mask = stb__alloc_size-1;
  6630. stb__alloc_count = 0;
  6631. for (i=0; i < old_num; ++i)
  6632. if (old[i].p > STB_DEL) {
  6633. stb__add_alloc(old[i].p, old[i].size, old[i].file, old[i].line);
  6634. assert(stb__hashfind(old[i].p) >= 0);
  6635. }
  6636. for (i=0; i < old_num; ++i)
  6637. if (old[i].p > STB_DEL)
  6638. assert(stb__hashfind(old[i].p) >= 0);
  6639. stb__realloc_raw(old, 0);
  6640. }
  6641. static void stb__add_alloc(void *p, size_t sz, char *file, int line)
  6642. {
  6643. stb_uint32 h;
  6644. int n;
  6645. if (stb__alloc_count >= stb__alloc_limit)
  6646. stb__grow_alloc();
  6647. h = stb_hashptr(p);
  6648. n = h & stb__alloc_mask;
  6649. if (stb__allocations[n].p > STB_DEL) {
  6650. int s = stb_rehash(h)|1;
  6651. do {
  6652. n = (n+s) & stb__alloc_mask;
  6653. } while (stb__allocations[n].p > STB_DEL);
  6654. }
  6655. assert(stb__allocations[n].p == NULL || stb__allocations[n].p == STB_DEL);
  6656. stb__allocations[n].p = p;
  6657. stb__allocations[n].size = sz;
  6658. stb__allocations[n].line = line;
  6659. stb__allocations[n].file = file;
  6660. ++stb__alloc_count;
  6661. }
  6662. static void stb__remove_alloc(int n, char *file, int line)
  6663. {
  6664. stb__alloc_history[stb__history_pos] = stb__allocations[n];
  6665. stb__alloc_history[stb__history_pos].file = file;
  6666. stb__alloc_history[stb__history_pos].line = line;
  6667. if (++stb__history_pos == STB_MALLOC_HISTORY_COUNT)
  6668. stb__history_pos = 0;
  6669. stb__allocations[n].p = STB_DEL;
  6670. --stb__alloc_count;
  6671. }
  6672. void stb_wrapper_malloc(void *p, size_t sz, char *file, int line)
  6673. {
  6674. if (!p) return;
  6675. stb__add_alloc(p,sz,file,line);
  6676. }
  6677. void stb_wrapper_free(void *p, char *file, int line)
  6678. {
  6679. int n;
  6680. if (p == NULL) return;
  6681. n = stb__hashfind(p);
  6682. if (n >= 0)
  6683. stb__remove_alloc(n, file, line);
  6684. else {
  6685. // tried to free something we hadn't allocated!
  6686. n = stb__historyfind(p);
  6687. assert(0); /* NOTREACHED */
  6688. if (n >= 0)
  6689. stb_fatal("Attempted to free %d-byte block %p at %s:%d previously freed/realloced at %s:%d",
  6690. stb__alloc_history[n].size, p,
  6691. file, line,
  6692. stb__alloc_history[n].file, stb__alloc_history[n].line);
  6693. else
  6694. stb_fatal("Attempted to free unknown block %p at %s:%d", p, file,line);
  6695. }
  6696. }
  6697. void stb_wrapper_check(void *p)
  6698. {
  6699. int n;
  6700. if (p == NULL) return;
  6701. n = stb__hashfind(p);
  6702. if (n >= 0) return;
  6703. for (n=0; n < stb__alloc_size; ++n)
  6704. if (stb__allocations[n].p == p)
  6705. stb_fatal("Internal error: pointer %p was allocated, but hash search failed", p);
  6706. // tried to free something that wasn't allocated!
  6707. n = stb__historyfind(p);
  6708. if (n >= 0)
  6709. stb_fatal("Checked %d-byte block %p previously freed/realloced at %s:%d",
  6710. stb__alloc_history[n].size, p,
  6711. stb__alloc_history[n].file, stb__alloc_history[n].line);
  6712. stb_fatal("Checked unknown block %p");
  6713. }
  6714. void stb_wrapper_realloc(void *p, void *q, size_t sz, char *file, int line)
  6715. {
  6716. int n;
  6717. if (p == NULL) { stb_wrapper_malloc(q, sz, file, line); return; }
  6718. if (q == NULL) return; // nothing happened
  6719. n = stb__hashfind(p);
  6720. if (n == -1) {
  6721. // tried to free something we hadn't allocated!
  6722. // this is weird, though, because we got past the realloc!
  6723. n = stb__historyfind(p);
  6724. assert(0); /* NOTREACHED */
  6725. if (n >= 0)
  6726. stb_fatal("Attempted to realloc %d-byte block %p at %s:%d previously freed/realloced at %s:%d",
  6727. stb__alloc_history[n].size, p,
  6728. file, line,
  6729. stb__alloc_history[n].file, stb__alloc_history[n].line);
  6730. else
  6731. stb_fatal("Attempted to realloc unknown block %p at %s:%d", p, file,line);
  6732. } else {
  6733. if (q == p) {
  6734. stb__allocations[n].size = sz;
  6735. stb__allocations[n].file = file;
  6736. stb__allocations[n].line = line;
  6737. } else {
  6738. stb__remove_alloc(n, file, line);
  6739. stb__add_alloc(q,sz,file,line);
  6740. }
  6741. }
  6742. }
  6743. void stb_wrapper_listall(void (*func)(void *ptr, size_t sz, char *file, int line))
  6744. {
  6745. int i;
  6746. for (i=0; i < stb__alloc_size; ++i)
  6747. if (stb__allocations[i].p > STB_DEL)
  6748. func(stb__allocations[i].p , stb__allocations[i].size,
  6749. stb__allocations[i].file, stb__allocations[i].line);
  6750. }
  6751. void stb_wrapper_dump(char *filename)
  6752. {
  6753. int i;
  6754. FILE *f = stb_p_fopen(filename, "w");
  6755. if (!f) return;
  6756. for (i=0; i < stb__alloc_size; ++i)
  6757. if (stb__allocations[i].p > STB_DEL)
  6758. fprintf(f, "%p %7d - %4d %s\n",
  6759. stb__allocations[i].p , (int) stb__allocations[i].size,
  6760. stb__allocations[i].line, stb__allocations[i].file);
  6761. }
  6762. #endif // STB_DEFINE
  6763. //////////////////////////////////////////////////////////////////////////////
  6764. //
  6765. // stb_pointer_set
  6766. //
  6767. //
  6768. // For data structures that support querying by key, data structure
  6769. // classes always hand-wave away the issue of what to do if two entries
  6770. // have the same key: basically, store a linked list of all the nodes
  6771. // which have the same key (a LISP-style list).
  6772. //
  6773. // The thing is, it's not that trivial. If you have an O(log n)
  6774. // lookup data structure, but then n/4 items have the same value,
  6775. // you don't want to spend O(n) time scanning that list when
  6776. // deleting an item if you already have a pointer to the item.
  6777. // (You have to spend O(n) time enumerating all the items with
  6778. // a given key, sure, and you can't accelerate deleting a particular
  6779. // item if you only have the key, not a pointer to the item.)
  6780. //
  6781. // I'm going to call this data structure, whatever it turns out to
  6782. // be, a "pointer set", because we don't store any associated data for
  6783. // items in this data structure, we just answer the question of
  6784. // whether an item is in it or not (it's effectively one bit per pointer).
  6785. // Technically they don't have to be pointers; you could cast ints
  6786. // to (void *) if you want, but you can't store 0 or 1 because of the
  6787. // hash table.
  6788. //
  6789. // Since the fastest data structure we might want to add support for
  6790. // identical-keys to is a hash table with O(1)-ish lookup time,
  6791. // that means that the conceptual "linked list of all items with
  6792. // the same indexed value" that we build needs to have the same
  6793. // performance; that way when we index a table we think is arbitrary
  6794. // ints, but in fact half of them are 0, we don't get screwed.
  6795. //
  6796. // Therefore, it needs to be a hash table, at least when it gets
  6797. // large. On the other hand, when the data has totally arbitrary ints
  6798. // or floats, there won't be many collisions, and we'll have tons of
  6799. // 1-item bitmaps. That will be grossly inefficient as hash tables;
  6800. // trade-off; the hash table is reasonably efficient per-item when
  6801. // it's large, but not when it's small. So we need to do something
  6802. // Judy-like and use different strategies depending on the size.
  6803. //
  6804. // Like Judy, we'll use the bottom bit to encode the strategy:
  6805. //
  6806. // bottom bits:
  6807. // 00 - direct pointer
  6808. // 01 - 4-item bucket (16 bytes, no length, NULLs)
  6809. // 10 - N-item array
  6810. // 11 - hash table
  6811. typedef struct stb_ps stb_ps;
  6812. STB_EXTERN int stb_ps_find (stb_ps *ps, void *value);
  6813. STB_EXTERN stb_ps * stb_ps_add (stb_ps *ps, void *value);
  6814. STB_EXTERN stb_ps * stb_ps_remove(stb_ps *ps, void *value);
  6815. STB_EXTERN stb_ps * stb_ps_remove_any(stb_ps *ps, void **value);
  6816. STB_EXTERN void stb_ps_delete(stb_ps *ps);
  6817. STB_EXTERN int stb_ps_count (stb_ps *ps);
  6818. STB_EXTERN stb_ps * stb_ps_copy (stb_ps *ps);
  6819. STB_EXTERN int stb_ps_subset(stb_ps *bigger, stb_ps *smaller);
  6820. STB_EXTERN int stb_ps_eq (stb_ps *p0, stb_ps *p1);
  6821. STB_EXTERN void ** stb_ps_getlist (stb_ps *ps, int *count);
  6822. STB_EXTERN int stb_ps_writelist(stb_ps *ps, void **list, int size );
  6823. // enum and fastlist don't allocate storage, but you must consume the
  6824. // list before there's any chance the data structure gets screwed up;
  6825. STB_EXTERN int stb_ps_enum (stb_ps *ps, void *data,
  6826. int (*func)(void *value, void*data) );
  6827. STB_EXTERN void ** stb_ps_fastlist(stb_ps *ps, int *count);
  6828. // result:
  6829. // returns a list, *count is the length of that list,
  6830. // but some entries of the list may be invalid;
  6831. // test with 'stb_ps_fastlist_valid(x)'
  6832. #define stb_ps_fastlist_valid(x) ((stb_uinta) (x) > 1)
  6833. #ifdef STB_DEFINE
  6834. enum
  6835. {
  6836. STB_ps_direct = 0,
  6837. STB_ps_bucket = 1,
  6838. STB_ps_array = 2,
  6839. STB_ps_hash = 3,
  6840. };
  6841. #define STB_BUCKET_SIZE 4
  6842. typedef struct
  6843. {
  6844. void *p[STB_BUCKET_SIZE];
  6845. } stb_ps_bucket;
  6846. #define GetBucket(p) ((stb_ps_bucket *) ((char *) (p) - STB_ps_bucket))
  6847. #define EncodeBucket(p) ((stb_ps *) ((char *) (p) + STB_ps_bucket))
  6848. static void stb_bucket_free(stb_ps_bucket *b)
  6849. {
  6850. free(b);
  6851. }
  6852. static stb_ps_bucket *stb_bucket_create2(void *v0, void *v1)
  6853. {
  6854. stb_ps_bucket *b = (stb_ps_bucket*) malloc(sizeof(*b));
  6855. b->p[0] = v0;
  6856. b->p[1] = v1;
  6857. b->p[2] = NULL;
  6858. b->p[3] = NULL;
  6859. return b;
  6860. }
  6861. static stb_ps_bucket * stb_bucket_create3(void **v)
  6862. {
  6863. stb_ps_bucket *b = (stb_ps_bucket*) malloc(sizeof(*b));
  6864. b->p[0] = v[0];
  6865. b->p[1] = v[1];
  6866. b->p[2] = v[2];
  6867. b->p[3] = NULL;
  6868. return b;
  6869. }
  6870. // could use stb_arr, but this will save us memory
  6871. typedef struct
  6872. {
  6873. int count;
  6874. void *p[1];
  6875. } stb_ps_array;
  6876. #define GetArray(p) ((stb_ps_array *) ((char *) (p) - STB_ps_array))
  6877. #define EncodeArray(p) ((stb_ps *) ((char *) (p) + STB_ps_array))
  6878. static int stb_ps_array_max = 13;
  6879. typedef struct
  6880. {
  6881. int size, mask;
  6882. int count, count_deletes;
  6883. int grow_threshhold;
  6884. int shrink_threshhold;
  6885. int rehash_threshhold;
  6886. int any_offset;
  6887. void *table[1];
  6888. } stb_ps_hash;
  6889. #define GetHash(p) ((stb_ps_hash *) ((char *) (p) - STB_ps_hash))
  6890. #define EncodeHash(p) ((stb_ps *) ((char *) (p) + STB_ps_hash))
  6891. #define stb_ps_empty(v) (((stb_uint32) v) <= 1)
  6892. static stb_ps_hash *stb_ps_makehash(int size, int old_size, void **old_data)
  6893. {
  6894. int i;
  6895. stb_ps_hash *h = (stb_ps_hash *) malloc(sizeof(*h) + (size-1) * sizeof(h->table[0]));
  6896. assert(stb_is_pow2(size));
  6897. h->size = size;
  6898. h->mask = size-1;
  6899. h->shrink_threshhold = (int) (0.3f * size);
  6900. h-> grow_threshhold = (int) (0.8f * size);
  6901. h->rehash_threshhold = (int) (0.9f * size);
  6902. h->count = 0;
  6903. h->count_deletes = 0;
  6904. h->any_offset = 0;
  6905. memset(h->table, 0, size * sizeof(h->table[0]));
  6906. for (i=0; i < old_size; ++i)
  6907. if (!stb_ps_empty((size_t)old_data[i]))
  6908. stb_ps_add(EncodeHash(h), old_data[i]);
  6909. return h;
  6910. }
  6911. void stb_ps_delete(stb_ps *ps)
  6912. {
  6913. switch (3 & (int)(size_t) ps) {
  6914. case STB_ps_direct: break;
  6915. case STB_ps_bucket: stb_bucket_free(GetBucket(ps)); break;
  6916. case STB_ps_array : free(GetArray(ps)); break;
  6917. case STB_ps_hash : free(GetHash(ps)); break;
  6918. }
  6919. }
  6920. stb_ps *stb_ps_copy(stb_ps *ps)
  6921. {
  6922. int i;
  6923. // not a switch: order based on expected performance/power-law distribution
  6924. switch (3 & (int)(size_t) ps) {
  6925. case STB_ps_direct: return ps;
  6926. case STB_ps_bucket: {
  6927. stb_ps_bucket *n = (stb_ps_bucket *) malloc(sizeof(*n));
  6928. *n = *GetBucket(ps);
  6929. return EncodeBucket(n);
  6930. }
  6931. case STB_ps_array: {
  6932. stb_ps_array *a = GetArray(ps);
  6933. stb_ps_array *n = (stb_ps_array *) malloc(sizeof(*n) + stb_ps_array_max * sizeof(n->p[0]));
  6934. n->count = a->count;
  6935. for (i=0; i < a->count; ++i)
  6936. n->p[i] = a->p[i];
  6937. return EncodeArray(n);
  6938. }
  6939. case STB_ps_hash: {
  6940. stb_ps_hash *h = GetHash(ps);
  6941. stb_ps_hash *n = stb_ps_makehash(h->size, h->size, h->table);
  6942. return EncodeHash(n);
  6943. }
  6944. }
  6945. assert(0); /* NOTREACHED */
  6946. return NULL;
  6947. }
  6948. int stb_ps_find(stb_ps *ps, void *value)
  6949. {
  6950. int i, code = 3 & (int)(size_t) ps;
  6951. assert((3 & (int)(size_t) value) == STB_ps_direct);
  6952. assert(stb_ps_fastlist_valid(value));
  6953. // not a switch: order based on expected performance/power-law distribution
  6954. if (code == STB_ps_direct)
  6955. return value == ps;
  6956. if (code == STB_ps_bucket) {
  6957. stb_ps_bucket *b = GetBucket(ps);
  6958. assert(STB_BUCKET_SIZE == 4);
  6959. if (b->p[0] == value || b->p[1] == value ||
  6960. b->p[2] == value || b->p[3] == value)
  6961. return STB_TRUE;
  6962. return STB_FALSE;
  6963. }
  6964. if (code == STB_ps_array) {
  6965. stb_ps_array *a = GetArray(ps);
  6966. for (i=0; i < a->count; ++i)
  6967. if (a->p[i] == value)
  6968. return STB_TRUE;
  6969. return STB_FALSE;
  6970. } else {
  6971. stb_ps_hash *h = GetHash(ps);
  6972. stb_uint32 hash = stb_hashptr(value);
  6973. stb_uint32 s, n = hash & h->mask;
  6974. void **t = h->table;
  6975. if (t[n] == value) return STB_TRUE;
  6976. if (t[n] == NULL) return STB_FALSE;
  6977. s = stb_rehash(hash) | 1;
  6978. do {
  6979. n = (n + s) & h->mask;
  6980. if (t[n] == value) return STB_TRUE;
  6981. } while (t[n] != NULL);
  6982. return STB_FALSE;
  6983. }
  6984. }
  6985. stb_ps * stb_ps_add (stb_ps *ps, void *value)
  6986. {
  6987. #ifdef STB_DEBUG
  6988. assert(!stb_ps_find(ps,value));
  6989. #endif
  6990. if (value == NULL) return ps; // ignore NULL adds to avoid bad breakage
  6991. assert((3 & (int)(size_t) value) == STB_ps_direct);
  6992. assert(stb_ps_fastlist_valid(value));
  6993. assert(value != STB_DEL); // STB_DEL is less likely
  6994. switch (3 & (int)(size_t) ps) {
  6995. case STB_ps_direct:
  6996. if (ps == NULL) return (stb_ps *) value;
  6997. return EncodeBucket(stb_bucket_create2(ps,value));
  6998. case STB_ps_bucket: {
  6999. stb_ps_bucket *b = GetBucket(ps);
  7000. stb_ps_array *a;
  7001. assert(STB_BUCKET_SIZE == 4);
  7002. if (b->p[0] == NULL) { b->p[0] = value; return ps; }
  7003. if (b->p[1] == NULL) { b->p[1] = value; return ps; }
  7004. if (b->p[2] == NULL) { b->p[2] = value; return ps; }
  7005. if (b->p[3] == NULL) { b->p[3] = value; return ps; }
  7006. a = (stb_ps_array *) malloc(sizeof(*a) + 7 * sizeof(a->p[0])); // 8 slots, must be 2^k
  7007. memcpy(a->p, b, sizeof(*b));
  7008. a->p[4] = value;
  7009. a->count = 5;
  7010. stb_bucket_free(b);
  7011. return EncodeArray(a);
  7012. }
  7013. case STB_ps_array: {
  7014. stb_ps_array *a = GetArray(ps);
  7015. if (a->count == stb_ps_array_max) {
  7016. // promote from array to hash
  7017. stb_ps_hash *h = stb_ps_makehash(2 << stb_log2_ceil(a->count), a->count, a->p);
  7018. free(a);
  7019. return stb_ps_add(EncodeHash(h), value);
  7020. }
  7021. // do we need to resize the array? the array doubles in size when it
  7022. // crosses a power-of-two
  7023. if ((a->count & (a->count-1))==0) {
  7024. int newsize = a->count*2;
  7025. // clamp newsize to max if:
  7026. // 1. it's larger than max
  7027. // 2. newsize*1.5 is larger than max (to avoid extra resizing)
  7028. if (newsize + a->count > stb_ps_array_max)
  7029. newsize = stb_ps_array_max;
  7030. a = (stb_ps_array *) realloc(a, sizeof(*a) + (newsize-1) * sizeof(a->p[0]));
  7031. }
  7032. a->p[a->count++] = value;
  7033. return EncodeArray(a);
  7034. }
  7035. case STB_ps_hash: {
  7036. stb_ps_hash *h = GetHash(ps);
  7037. stb_uint32 hash = stb_hashptr(value);
  7038. stb_uint32 n = hash & h->mask;
  7039. void **t = h->table;
  7040. // find first NULL or STB_DEL entry
  7041. if (!stb_ps_empty((size_t)t[n])) {
  7042. stb_uint32 s = stb_rehash(hash) | 1;
  7043. do {
  7044. n = (n + s) & h->mask;
  7045. } while (!stb_ps_empty((size_t)t[n]));
  7046. }
  7047. if (t[n] == STB_DEL)
  7048. -- h->count_deletes;
  7049. t[n] = value;
  7050. ++ h->count;
  7051. if (h->count == h->grow_threshhold) {
  7052. stb_ps_hash *h2 = stb_ps_makehash(h->size*2, h->size, t);
  7053. free(h);
  7054. return EncodeHash(h2);
  7055. }
  7056. if (h->count + h->count_deletes == h->rehash_threshhold) {
  7057. stb_ps_hash *h2 = stb_ps_makehash(h->size, h->size, t);
  7058. free(h);
  7059. return EncodeHash(h2);
  7060. }
  7061. return ps;
  7062. }
  7063. }
  7064. return NULL; /* NOTREACHED */
  7065. }
  7066. stb_ps *stb_ps_remove(stb_ps *ps, void *value)
  7067. {
  7068. #ifdef STB_DEBUG
  7069. assert(stb_ps_find(ps, value));
  7070. #endif
  7071. assert((3 & (int)(size_t) value) == STB_ps_direct);
  7072. if (value == NULL) return ps; // ignore NULL removes to avoid bad breakage
  7073. switch (3 & (int)(size_t) ps) {
  7074. case STB_ps_direct:
  7075. return ps == value ? NULL : ps;
  7076. case STB_ps_bucket: {
  7077. stb_ps_bucket *b = GetBucket(ps);
  7078. int count=0;
  7079. assert(STB_BUCKET_SIZE == 4);
  7080. if (b->p[0] == value) b->p[0] = NULL; else count += (b->p[0] != NULL);
  7081. if (b->p[1] == value) b->p[1] = NULL; else count += (b->p[1] != NULL);
  7082. if (b->p[2] == value) b->p[2] = NULL; else count += (b->p[2] != NULL);
  7083. if (b->p[3] == value) b->p[3] = NULL; else count += (b->p[3] != NULL);
  7084. if (count == 1) { // shrink bucket at size 1
  7085. value = b->p[0];
  7086. if (value == NULL) value = b->p[1];
  7087. if (value == NULL) value = b->p[2];
  7088. if (value == NULL) value = b->p[3];
  7089. assert(value != NULL);
  7090. stb_bucket_free(b);
  7091. return (stb_ps *) value; // return STB_ps_direct of value
  7092. }
  7093. return ps;
  7094. }
  7095. case STB_ps_array: {
  7096. stb_ps_array *a = GetArray(ps);
  7097. int i;
  7098. for (i=0; i < a->count; ++i) {
  7099. if (a->p[i] == value) {
  7100. a->p[i] = a->p[--a->count];
  7101. if (a->count == 3) { // shrink to bucket!
  7102. stb_ps_bucket *b = stb_bucket_create3(a->p);
  7103. free(a);
  7104. return EncodeBucket(b);
  7105. }
  7106. return ps;
  7107. }
  7108. }
  7109. return ps;
  7110. }
  7111. case STB_ps_hash: {
  7112. stb_ps_hash *h = GetHash(ps);
  7113. stb_uint32 hash = stb_hashptr(value);
  7114. stb_uint32 s, n = hash & h->mask;
  7115. void **t = h->table;
  7116. if (t[n] != value) {
  7117. s = stb_rehash(hash) | 1;
  7118. do {
  7119. n = (n + s) & h->mask;
  7120. } while (t[n] != value);
  7121. }
  7122. t[n] = STB_DEL;
  7123. -- h->count;
  7124. ++ h->count_deletes;
  7125. // should we shrink down to an array?
  7126. if (h->count < stb_ps_array_max) {
  7127. int n = 1 << stb_log2_floor(stb_ps_array_max);
  7128. if (h->count < n) {
  7129. stb_ps_array *a = (stb_ps_array *) malloc(sizeof(*a) + (n-1) * sizeof(a->p[0]));
  7130. int i,j=0;
  7131. for (i=0; i < h->size; ++i)
  7132. if (!stb_ps_empty((size_t)t[i]))
  7133. a->p[j++] = t[i];
  7134. assert(j == h->count);
  7135. a->count = j;
  7136. free(h);
  7137. return EncodeArray(a);
  7138. }
  7139. }
  7140. if (h->count == h->shrink_threshhold) {
  7141. stb_ps_hash *h2 = stb_ps_makehash(h->size >> 1, h->size, t);
  7142. free(h);
  7143. return EncodeHash(h2);
  7144. }
  7145. return ps;
  7146. }
  7147. }
  7148. return ps; /* NOTREACHED */
  7149. }
  7150. stb_ps *stb_ps_remove_any(stb_ps *ps, void **value)
  7151. {
  7152. assert(ps != NULL);
  7153. switch (3 & (int)(size_t) ps) {
  7154. case STB_ps_direct:
  7155. *value = ps;
  7156. return NULL;
  7157. case STB_ps_bucket: {
  7158. stb_ps_bucket *b = GetBucket(ps);
  7159. int count=0, slast=0, last=0;
  7160. assert(STB_BUCKET_SIZE == 4);
  7161. if (b->p[0]) { ++count; last = 0; }
  7162. if (b->p[1]) { ++count; slast = last; last = 1; }
  7163. if (b->p[2]) { ++count; slast = last; last = 2; }
  7164. if (b->p[3]) { ++count; slast = last; last = 3; }
  7165. *value = b->p[last];
  7166. b->p[last] = 0;
  7167. if (count == 2) {
  7168. void *leftover = b->p[slast]; // second to last
  7169. stb_bucket_free(b);
  7170. return (stb_ps *) leftover;
  7171. }
  7172. return ps;
  7173. }
  7174. case STB_ps_array: {
  7175. stb_ps_array *a = GetArray(ps);
  7176. *value = a->p[a->count-1];
  7177. if (a->count == 4)
  7178. return stb_ps_remove(ps, *value);
  7179. --a->count;
  7180. return ps;
  7181. }
  7182. case STB_ps_hash: {
  7183. stb_ps_hash *h = GetHash(ps);
  7184. void **t = h->table;
  7185. stb_uint32 n = h->any_offset;
  7186. while (stb_ps_empty((size_t)t[n]))
  7187. n = (n + 1) & h->mask;
  7188. *value = t[n];
  7189. h->any_offset = (n+1) & h->mask;
  7190. // check if we need to skip down to the previous type
  7191. if (h->count-1 < stb_ps_array_max || h->count-1 == h->shrink_threshhold)
  7192. return stb_ps_remove(ps, *value);
  7193. t[n] = STB_DEL;
  7194. -- h->count;
  7195. ++ h->count_deletes;
  7196. return ps;
  7197. }
  7198. }
  7199. return ps; /* NOTREACHED */
  7200. }
  7201. void ** stb_ps_getlist(stb_ps *ps, int *count)
  7202. {
  7203. int i,n=0;
  7204. void **p = NULL;
  7205. switch (3 & (int)(size_t) ps) {
  7206. case STB_ps_direct:
  7207. if (ps == NULL) { *count = 0; return NULL; }
  7208. p = (void **) malloc(sizeof(*p) * 1);
  7209. p[0] = ps;
  7210. *count = 1;
  7211. return p;
  7212. case STB_ps_bucket: {
  7213. stb_ps_bucket *b = GetBucket(ps);
  7214. p = (void **) malloc(sizeof(*p) * STB_BUCKET_SIZE);
  7215. for (i=0; i < STB_BUCKET_SIZE; ++i)
  7216. if (b->p[i] != NULL)
  7217. p[n++] = b->p[i];
  7218. break;
  7219. }
  7220. case STB_ps_array: {
  7221. stb_ps_array *a = GetArray(ps);
  7222. p = (void **) malloc(sizeof(*p) * a->count);
  7223. memcpy(p, a->p, sizeof(*p) * a->count);
  7224. *count = a->count;
  7225. return p;
  7226. }
  7227. case STB_ps_hash: {
  7228. stb_ps_hash *h = GetHash(ps);
  7229. p = (void **) malloc(sizeof(*p) * h->count);
  7230. for (i=0; i < h->size; ++i)
  7231. if (!stb_ps_empty((size_t)h->table[i]))
  7232. p[n++] = h->table[i];
  7233. break;
  7234. }
  7235. }
  7236. *count = n;
  7237. return p;
  7238. }
  7239. int stb_ps_writelist(stb_ps *ps, void **list, int size )
  7240. {
  7241. int i,n=0;
  7242. switch (3 & (int)(size_t) ps) {
  7243. case STB_ps_direct:
  7244. if (ps == NULL || size <= 0) return 0;
  7245. list[0] = ps;
  7246. return 1;
  7247. case STB_ps_bucket: {
  7248. stb_ps_bucket *b = GetBucket(ps);
  7249. for (i=0; i < STB_BUCKET_SIZE; ++i)
  7250. if (b->p[i] != NULL && n < size)
  7251. list[n++] = b->p[i];
  7252. return n;
  7253. }
  7254. case STB_ps_array: {
  7255. stb_ps_array *a = GetArray(ps);
  7256. n = stb_min(size, a->count);
  7257. memcpy(list, a->p, sizeof(*list) * n);
  7258. return n;
  7259. }
  7260. case STB_ps_hash: {
  7261. stb_ps_hash *h = GetHash(ps);
  7262. if (size <= 0) return 0;
  7263. for (i=0; i < h->count; ++i) {
  7264. if (!stb_ps_empty((size_t)h->table[i])) {
  7265. list[n++] = h->table[i];
  7266. if (n == size) break;
  7267. }
  7268. }
  7269. return n;
  7270. }
  7271. }
  7272. return 0; /* NOTREACHED */
  7273. }
  7274. int stb_ps_enum(stb_ps *ps, void *data, int (*func)(void *value, void *data))
  7275. {
  7276. int i;
  7277. switch (3 & (int)(size_t) ps) {
  7278. case STB_ps_direct:
  7279. if (ps == NULL) return STB_TRUE;
  7280. return func(ps, data);
  7281. case STB_ps_bucket: {
  7282. stb_ps_bucket *b = GetBucket(ps);
  7283. for (i=0; i < STB_BUCKET_SIZE; ++i)
  7284. if (b->p[i] != NULL)
  7285. if (!func(b->p[i], data))
  7286. return STB_FALSE;
  7287. return STB_TRUE;
  7288. }
  7289. case STB_ps_array: {
  7290. stb_ps_array *a = GetArray(ps);
  7291. for (i=0; i < a->count; ++i)
  7292. if (!func(a->p[i], data))
  7293. return STB_FALSE;
  7294. return STB_TRUE;
  7295. }
  7296. case STB_ps_hash: {
  7297. stb_ps_hash *h = GetHash(ps);
  7298. for (i=0; i < h->count; ++i)
  7299. if (!stb_ps_empty((size_t)h->table[i]))
  7300. if (!func(h->table[i], data))
  7301. return STB_FALSE;
  7302. return STB_TRUE;
  7303. }
  7304. }
  7305. return STB_TRUE; /* NOTREACHED */
  7306. }
  7307. int stb_ps_count (stb_ps *ps)
  7308. {
  7309. switch (3 & (int)(size_t) ps) {
  7310. case STB_ps_direct:
  7311. return ps != NULL;
  7312. case STB_ps_bucket: {
  7313. stb_ps_bucket *b = GetBucket(ps);
  7314. return (b->p[0] != NULL) + (b->p[1] != NULL) +
  7315. (b->p[2] != NULL) + (b->p[3] != NULL);
  7316. }
  7317. case STB_ps_array: {
  7318. stb_ps_array *a = GetArray(ps);
  7319. return a->count;
  7320. }
  7321. case STB_ps_hash: {
  7322. stb_ps_hash *h = GetHash(ps);
  7323. return h->count;
  7324. }
  7325. }
  7326. return 0;
  7327. }
  7328. void ** stb_ps_fastlist(stb_ps *ps, int *count)
  7329. {
  7330. static void *storage;
  7331. switch (3 & (int)(size_t) ps) {
  7332. case STB_ps_direct:
  7333. if (ps == NULL) { *count = 0; return NULL; }
  7334. storage = ps;
  7335. *count = 1;
  7336. return &storage;
  7337. case STB_ps_bucket: {
  7338. stb_ps_bucket *b = GetBucket(ps);
  7339. *count = STB_BUCKET_SIZE;
  7340. return b->p;
  7341. }
  7342. case STB_ps_array: {
  7343. stb_ps_array *a = GetArray(ps);
  7344. *count = a->count;
  7345. return a->p;
  7346. }
  7347. case STB_ps_hash: {
  7348. stb_ps_hash *h = GetHash(ps);
  7349. *count = h->size;
  7350. return h->table;
  7351. }
  7352. }
  7353. return NULL; /* NOTREACHED */
  7354. }
  7355. int stb_ps_subset(stb_ps *bigger, stb_ps *smaller)
  7356. {
  7357. int i, listlen;
  7358. void **list = stb_ps_fastlist(smaller, &listlen);
  7359. for(i=0; i < listlen; ++i)
  7360. if (stb_ps_fastlist_valid(list[i]))
  7361. if (!stb_ps_find(bigger, list[i]))
  7362. return 0;
  7363. return 1;
  7364. }
  7365. int stb_ps_eq(stb_ps *p0, stb_ps *p1)
  7366. {
  7367. if (stb_ps_count(p0) != stb_ps_count(p1))
  7368. return 0;
  7369. return stb_ps_subset(p0, p1);
  7370. }
  7371. #undef GetBucket
  7372. #undef GetArray
  7373. #undef GetHash
  7374. #undef EncodeBucket
  7375. #undef EncodeArray
  7376. #undef EncodeHash
  7377. #endif
  7378. //////////////////////////////////////////////////////////////////////////////
  7379. //
  7380. // Random Numbers via Meresenne Twister or LCG
  7381. //
  7382. STB_EXTERN unsigned int stb_srandLCG(unsigned int seed);
  7383. STB_EXTERN unsigned int stb_randLCG(void);
  7384. STB_EXTERN double stb_frandLCG(void);
  7385. STB_EXTERN void stb_srand(unsigned int seed);
  7386. STB_EXTERN unsigned int stb_rand(void);
  7387. STB_EXTERN double stb_frand(void);
  7388. STB_EXTERN void stb_shuffle(void *p, size_t n, size_t sz,
  7389. unsigned int seed);
  7390. STB_EXTERN void stb_reverse(void *p, size_t n, size_t sz);
  7391. STB_EXTERN unsigned int stb_randLCG_explicit(unsigned int seed);
  7392. #define stb_rand_define(x,y) \
  7393. \
  7394. unsigned int x(void) \
  7395. { \
  7396. static unsigned int stb__rand = y; \
  7397. stb__rand = stb__rand * 2147001325 + 715136305; /* BCPL */ \
  7398. return 0x31415926 ^ ((stb__rand >> 16) + (stb__rand << 16)); \
  7399. }
  7400. #ifdef STB_DEFINE
  7401. unsigned int stb_randLCG_explicit(unsigned int seed)
  7402. {
  7403. return seed * 2147001325 + 715136305;
  7404. }
  7405. static unsigned int stb__rand_seed=0;
  7406. unsigned int stb_srandLCG(unsigned int seed)
  7407. {
  7408. unsigned int previous = stb__rand_seed;
  7409. stb__rand_seed = seed;
  7410. return previous;
  7411. }
  7412. unsigned int stb_randLCG(void)
  7413. {
  7414. stb__rand_seed = stb__rand_seed * 2147001325 + 715136305; // BCPL generator
  7415. // shuffle non-random bits to the middle, and xor to decorrelate with seed
  7416. return 0x31415926 ^ ((stb__rand_seed >> 16) + (stb__rand_seed << 16));
  7417. }
  7418. double stb_frandLCG(void)
  7419. {
  7420. return stb_randLCG() / ((double) (1 << 16) * (1 << 16));
  7421. }
  7422. void stb_shuffle(void *p, size_t n, size_t sz, unsigned int seed)
  7423. {
  7424. char *a;
  7425. unsigned int old_seed;
  7426. int i;
  7427. if (seed)
  7428. old_seed = stb_srandLCG(seed);
  7429. a = (char *) p + (n-1) * sz;
  7430. for (i=(int) n; i > 1; --i) {
  7431. int j = stb_randLCG() % i;
  7432. stb_swap(a, (char *) p + j * sz, sz);
  7433. a -= sz;
  7434. }
  7435. if (seed)
  7436. stb_srandLCG(old_seed);
  7437. }
  7438. void stb_reverse(void *p, size_t n, size_t sz)
  7439. {
  7440. size_t i,j = n-1;
  7441. for (i=0; i < j; ++i,--j) {
  7442. stb_swap((char *) p + i * sz, (char *) p + j * sz, sz);
  7443. }
  7444. }
  7445. // public domain Mersenne Twister by Michael Brundage
  7446. #define STB__MT_LEN 624
  7447. int stb__mt_index = STB__MT_LEN*sizeof(int)+1;
  7448. unsigned int stb__mt_buffer[STB__MT_LEN];
  7449. void stb_srand(unsigned int seed)
  7450. {
  7451. int i;
  7452. stb__mt_buffer[0]= seed & 0xffffffffUL;
  7453. for (i=1 ; i < STB__MT_LEN; ++i)
  7454. stb__mt_buffer[i] = (1812433253UL * (stb__mt_buffer[i-1] ^ (stb__mt_buffer[i-1] >> 30)) + i);
  7455. stb__mt_index = STB__MT_LEN*sizeof(unsigned int);
  7456. }
  7457. #define STB__MT_IA 397
  7458. #define STB__MT_IB (STB__MT_LEN - STB__MT_IA)
  7459. #define STB__UPPER_MASK 0x80000000
  7460. #define STB__LOWER_MASK 0x7FFFFFFF
  7461. #define STB__MATRIX_A 0x9908B0DF
  7462. #define STB__TWIST(b,i,j) ((b)[i] & STB__UPPER_MASK) | ((b)[j] & STB__LOWER_MASK)
  7463. #define STB__MAGIC(s) (((s)&1)*STB__MATRIX_A)
  7464. unsigned int stb_rand()
  7465. {
  7466. unsigned int * b = stb__mt_buffer;
  7467. int idx = stb__mt_index;
  7468. unsigned int s,r;
  7469. int i;
  7470. if (idx >= STB__MT_LEN*sizeof(unsigned int)) {
  7471. if (idx > STB__MT_LEN*sizeof(unsigned int))
  7472. stb_srand(0);
  7473. idx = 0;
  7474. i = 0;
  7475. for (; i < STB__MT_IB; i++) {
  7476. s = STB__TWIST(b, i, i+1);
  7477. b[i] = b[i + STB__MT_IA] ^ (s >> 1) ^ STB__MAGIC(s);
  7478. }
  7479. for (; i < STB__MT_LEN-1; i++) {
  7480. s = STB__TWIST(b, i, i+1);
  7481. b[i] = b[i - STB__MT_IB] ^ (s >> 1) ^ STB__MAGIC(s);
  7482. }
  7483. s = STB__TWIST(b, STB__MT_LEN-1, 0);
  7484. b[STB__MT_LEN-1] = b[STB__MT_IA-1] ^ (s >> 1) ^ STB__MAGIC(s);
  7485. }
  7486. stb__mt_index = idx + sizeof(unsigned int);
  7487. r = *(unsigned int *)((unsigned char *)b + idx);
  7488. r ^= (r >> 11);
  7489. r ^= (r << 7) & 0x9D2C5680;
  7490. r ^= (r << 15) & 0xEFC60000;
  7491. r ^= (r >> 18);
  7492. return r;
  7493. }
  7494. double stb_frand(void)
  7495. {
  7496. return stb_rand() / ((double) (1 << 16) * (1 << 16));
  7497. }
  7498. #endif
  7499. //////////////////////////////////////////////////////////////////////////////
  7500. //
  7501. // stb_dupe
  7502. //
  7503. // stb_dupe is a duplicate-finding system for very, very large data
  7504. // structures--large enough that sorting is too slow, but not so large
  7505. // that we can't keep all the data in memory. using it works as follows:
  7506. //
  7507. // 1. create an stb_dupe:
  7508. // provide a hash function
  7509. // provide an equality function
  7510. // provide an estimate for the size
  7511. // optionally provide a comparison function
  7512. //
  7513. // 2. traverse your data, 'adding' pointers to the stb_dupe
  7514. //
  7515. // 3. finish and ask for duplicates
  7516. //
  7517. // the stb_dupe will discard its intermediate data and build
  7518. // a collection of sorted lists of duplicates, with non-duplicate
  7519. // entries omitted entirely
  7520. //
  7521. //
  7522. // Implementation strategy:
  7523. //
  7524. // while collecting the N items, we keep a hash table of approximate
  7525. // size sqrt(N). (if you tell use the N up front, the hash table is
  7526. // just that size exactly)
  7527. //
  7528. // each entry in the hash table is just an stb__arr of pointers (no need
  7529. // to use stb_ps, because we don't need to delete from these)
  7530. //
  7531. // for step 3, for each entry in the hash table, we apply stb_dupe to it
  7532. // recursively. once the size gets small enough (or doesn't decrease
  7533. // significantly), we switch to either using qsort() on the comparison
  7534. // function, or else we just do the icky N^2 gather
  7535. typedef struct stb_dupe stb_dupe;
  7536. typedef int (*stb_compare_func)(void *a, void *b);
  7537. typedef int (*stb_hash_func)(void *a, unsigned int seed);
  7538. STB_EXTERN void stb_dupe_free(stb_dupe *sd);
  7539. STB_EXTERN stb_dupe *stb_dupe_create(stb_hash_func hash,
  7540. stb_compare_func eq, int size, stb_compare_func ineq);
  7541. STB_EXTERN void stb_dupe_add(stb_dupe *sd, void *item);
  7542. STB_EXTERN void stb_dupe_finish(stb_dupe *sd);
  7543. STB_EXTERN int stb_dupe_numsets(stb_dupe *sd);
  7544. STB_EXTERN void **stb_dupe_set(stb_dupe *sd, int num);
  7545. STB_EXTERN int stb_dupe_set_count(stb_dupe *sd, int num);
  7546. struct stb_dupe
  7547. {
  7548. void ***hash_table;
  7549. int hash_size;
  7550. int size_log2;
  7551. int population;
  7552. int hash_shift;
  7553. stb_hash_func hash;
  7554. stb_compare_func eq;
  7555. stb_compare_func ineq;
  7556. void ***dupes;
  7557. };
  7558. #ifdef STB_DEFINE
  7559. int stb_dupe_numsets(stb_dupe *sd)
  7560. {
  7561. assert(sd->hash_table == NULL);
  7562. return stb_arr_len(sd->dupes);
  7563. }
  7564. void **stb_dupe_set(stb_dupe *sd, int num)
  7565. {
  7566. assert(sd->hash_table == NULL);
  7567. return sd->dupes[num];
  7568. }
  7569. int stb_dupe_set_count(stb_dupe *sd, int num)
  7570. {
  7571. assert(sd->hash_table == NULL);
  7572. return stb_arr_len(sd->dupes[num]);
  7573. }
  7574. stb_dupe *stb_dupe_create(stb_hash_func hash, stb_compare_func eq, int size,
  7575. stb_compare_func ineq)
  7576. {
  7577. int i, hsize;
  7578. stb_dupe *sd = (stb_dupe *) malloc(sizeof(*sd));
  7579. sd->size_log2 = 4;
  7580. hsize = 1 << sd->size_log2;
  7581. while (hsize * hsize < size) {
  7582. ++sd->size_log2;
  7583. hsize *= 2;
  7584. }
  7585. sd->hash = hash;
  7586. sd->eq = eq;
  7587. sd->ineq = ineq;
  7588. sd->hash_shift = 0;
  7589. sd->population = 0;
  7590. sd->hash_size = hsize;
  7591. sd->hash_table = (void ***) malloc(sizeof(*sd->hash_table) * hsize);
  7592. for (i=0; i < hsize; ++i)
  7593. sd->hash_table[i] = NULL;
  7594. sd->dupes = NULL;
  7595. return sd;
  7596. }
  7597. void stb_dupe_add(stb_dupe *sd, void *item)
  7598. {
  7599. stb_uint32 hash = sd->hash(item, sd->hash_shift);
  7600. int z = hash & (sd->hash_size-1);
  7601. stb_arr_push(sd->hash_table[z], item);
  7602. ++sd->population;
  7603. }
  7604. void stb_dupe_free(stb_dupe *sd)
  7605. {
  7606. int i;
  7607. for (i=0; i < stb_arr_len(sd->dupes); ++i)
  7608. if (sd->dupes[i])
  7609. stb_arr_free(sd->dupes[i]);
  7610. stb_arr_free(sd->dupes);
  7611. free(sd);
  7612. }
  7613. static stb_compare_func stb__compare;
  7614. static int stb__dupe_compare(const void *a, const void *b)
  7615. {
  7616. void *p = *(void **) a;
  7617. void *q = *(void **) b;
  7618. return stb__compare(p,q);
  7619. }
  7620. void stb_dupe_finish(stb_dupe *sd)
  7621. {
  7622. int i,j,k;
  7623. assert(sd->dupes == NULL);
  7624. for (i=0; i < sd->hash_size; ++i) {
  7625. void ** list = sd->hash_table[i];
  7626. if (list != NULL) {
  7627. int n = stb_arr_len(list);
  7628. // @TODO: measure to find good numbers instead of just making them up!
  7629. int thresh = (sd->ineq ? 200 : 20);
  7630. // if n is large enough to be worth it, and n is smaller than
  7631. // before (so we can guarantee we'll use a smaller hash table);
  7632. // and there are enough hash bits left, assuming full 32-bit hash
  7633. if (n > thresh && n < (sd->population >> 3) && sd->hash_shift + sd->size_log2*2 < 32) {
  7634. // recursively process this row using stb_dupe, O(N log log N)
  7635. stb_dupe *d = stb_dupe_create(sd->hash, sd->eq, n, sd->ineq);
  7636. d->hash_shift = stb_randLCG_explicit(sd->hash_shift);
  7637. for (j=0; j < n; ++j)
  7638. stb_dupe_add(d, list[j]);
  7639. stb_arr_free(sd->hash_table[i]);
  7640. stb_dupe_finish(d);
  7641. for (j=0; j < stb_arr_len(d->dupes); ++j) {
  7642. stb_arr_push(sd->dupes, d->dupes[j]);
  7643. d->dupes[j] = NULL; // take over ownership
  7644. }
  7645. stb_dupe_free(d);
  7646. } else if (sd->ineq) {
  7647. // process this row using qsort(), O(N log N)
  7648. stb__compare = sd->ineq;
  7649. qsort(list, n, sizeof(list[0]), stb__dupe_compare);
  7650. // find equal subsequences of the list
  7651. for (j=0; j < n-1; ) {
  7652. // find a subsequence from j..k
  7653. for (k=j; k < n; ++k)
  7654. // only use ineq so eq can be left undefined
  7655. if (sd->ineq(list[j], list[k]))
  7656. break;
  7657. // k is the first one not in the subsequence
  7658. if (k-j > 1) {
  7659. void **mylist = NULL;
  7660. stb_arr_setlen(mylist, k-j);
  7661. memcpy(mylist, list+j, sizeof(list[j]) * (k-j));
  7662. stb_arr_push(sd->dupes, mylist);
  7663. }
  7664. j = k;
  7665. }
  7666. stb_arr_free(sd->hash_table[i]);
  7667. } else {
  7668. // process this row using eq(), O(N^2)
  7669. for (j=0; j < n; ++j) {
  7670. if (list[j] != NULL) {
  7671. void **output = NULL;
  7672. for (k=j+1; k < n; ++k) {
  7673. if (sd->eq(list[j], list[k])) {
  7674. if (output == NULL)
  7675. stb_arr_push(output, list[j]);
  7676. stb_arr_push(output, list[k]);
  7677. list[k] = NULL;
  7678. }
  7679. }
  7680. list[j] = NULL;
  7681. if (output)
  7682. stb_arr_push(sd->dupes, output);
  7683. }
  7684. }
  7685. stb_arr_free(sd->hash_table[i]);
  7686. }
  7687. }
  7688. }
  7689. free(sd->hash_table);
  7690. sd->hash_table = NULL;
  7691. }
  7692. #endif
  7693. //////////////////////////////////////////////////////////////////////////////
  7694. //
  7695. // templatized Sort routine
  7696. //
  7697. // This is an attempt to implement a templated sorting algorithm.
  7698. // To use it, you have to explicitly instantiate it as a _function_,
  7699. // then you call that function. This allows the comparison to be inlined,
  7700. // giving the sort similar performance to C++ sorts.
  7701. //
  7702. // It implements quicksort with three-way-median partitioning (generally
  7703. // well-behaved), with a final insertion sort pass.
  7704. //
  7705. // When you define the compare expression, you should assume you have
  7706. // elements of your array pointed to by 'a' and 'b', and perform the comparison
  7707. // on those. OR you can use one or more statements; first say '0;', then
  7708. // write whatever code you want, and compute the result into a variable 'c'.
  7709. #define stb_declare_sort(FUNCNAME, TYPE) \
  7710. void FUNCNAME(TYPE *p, int n)
  7711. #define stb_define_sort(FUNCNAME,TYPE,COMPARE) \
  7712. stb__define_sort( void, FUNCNAME,TYPE,COMPARE)
  7713. #define stb_define_sort_static(FUNCNAME,TYPE,COMPARE) \
  7714. stb__define_sort(static void, FUNCNAME,TYPE,COMPARE)
  7715. #define stb__define_sort(MODE, FUNCNAME, TYPE, COMPARE) \
  7716. \
  7717. static void STB_(FUNCNAME,_ins_sort)(TYPE *p, int n) \
  7718. { \
  7719. int i,j; \
  7720. for (i=1; i < n; ++i) { \
  7721. TYPE t = p[i], *a = &t; \
  7722. j = i; \
  7723. while (j > 0) { \
  7724. TYPE *b = &p[j-1]; \
  7725. int c = COMPARE; \
  7726. if (!c) break; \
  7727. p[j] = p[j-1]; \
  7728. --j; \
  7729. } \
  7730. if (i != j) \
  7731. p[j] = t; \
  7732. } \
  7733. } \
  7734. \
  7735. static void STB_(FUNCNAME,_quicksort)(TYPE *p, int n) \
  7736. { \
  7737. /* threshold for transitioning to insertion sort */ \
  7738. while (n > 12) { \
  7739. TYPE *a,*b,t; \
  7740. int c01,c12,c,m,i,j; \
  7741. \
  7742. /* compute median of three */ \
  7743. m = n >> 1; \
  7744. a = &p[0]; \
  7745. b = &p[m]; \
  7746. c = COMPARE; \
  7747. c01 = c; \
  7748. a = &p[m]; \
  7749. b = &p[n-1]; \
  7750. c = COMPARE; \
  7751. c12 = c; \
  7752. /* if 0 >= mid >= end, or 0 < mid < end, then use mid */ \
  7753. if (c01 != c12) { \
  7754. /* otherwise, we'll need to swap something else to middle */ \
  7755. int z; \
  7756. a = &p[0]; \
  7757. b = &p[n-1]; \
  7758. c = COMPARE; \
  7759. /* 0>mid && mid<n: 0>n => n; 0<n => 0 */ \
  7760. /* 0<mid && mid>n: 0>n => 0; 0<n => n */ \
  7761. z = (c == c12) ? 0 : n-1; \
  7762. t = p[z]; \
  7763. p[z] = p[m]; \
  7764. p[m] = t; \
  7765. } \
  7766. /* now p[m] is the median-of-three */ \
  7767. /* swap it to the beginning so it won't move around */ \
  7768. t = p[0]; \
  7769. p[0] = p[m]; \
  7770. p[m] = t; \
  7771. \
  7772. /* partition loop */ \
  7773. i=1; \
  7774. j=n-1; \
  7775. for(;;) { \
  7776. /* handling of equality is crucial here */ \
  7777. /* for sentinels & efficiency with duplicates */ \
  7778. b = &p[0]; \
  7779. for (;;++i) { \
  7780. a=&p[i]; \
  7781. c = COMPARE; \
  7782. if (!c) break; \
  7783. } \
  7784. a = &p[0]; \
  7785. for (;;--j) { \
  7786. b=&p[j]; \
  7787. c = COMPARE; \
  7788. if (!c) break; \
  7789. } \
  7790. /* make sure we haven't crossed */ \
  7791. if (i >= j) break; \
  7792. t = p[i]; \
  7793. p[i] = p[j]; \
  7794. p[j] = t; \
  7795. \
  7796. ++i; \
  7797. --j; \
  7798. } \
  7799. /* recurse on smaller side, iterate on larger */ \
  7800. if (j < (n-i)) { \
  7801. STB_(FUNCNAME,_quicksort)(p,j); \
  7802. p = p+i; \
  7803. n = n-i; \
  7804. } else { \
  7805. STB_(FUNCNAME,_quicksort)(p+i, n-i); \
  7806. n = j; \
  7807. } \
  7808. } \
  7809. } \
  7810. \
  7811. MODE FUNCNAME(TYPE *p, int n) \
  7812. { \
  7813. STB_(FUNCNAME, _quicksort)(p, n); \
  7814. STB_(FUNCNAME, _ins_sort)(p, n); \
  7815. } \
  7816. //////////////////////////////////////////////////////////////////////////////
  7817. //
  7818. // stb_bitset an array of booleans indexed by integers
  7819. //
  7820. typedef stb_uint32 stb_bitset;
  7821. STB_EXTERN stb_bitset *stb_bitset_new(int value, int len);
  7822. #define stb_bitset_clearall(arr,len) (memset(arr, 0, 4 * (len)))
  7823. #define stb_bitset_setall(arr,len) (memset(arr, 255, 4 * (len)))
  7824. #define stb_bitset_setbit(arr,n) ((arr)[(n) >> 5] |= (1 << (n & 31)))
  7825. #define stb_bitset_clearbit(arr,n) ((arr)[(n) >> 5] &= ~(1 << (n & 31)))
  7826. #define stb_bitset_testbit(arr,n) ((arr)[(n) >> 5] & (1 << (n & 31)))
  7827. STB_EXTERN stb_bitset *stb_bitset_union(stb_bitset *p0, stb_bitset *p1, int len);
  7828. STB_EXTERN int *stb_bitset_getlist(stb_bitset *out, int start, int end);
  7829. STB_EXTERN int stb_bitset_eq(stb_bitset *p0, stb_bitset *p1, int len);
  7830. STB_EXTERN int stb_bitset_disjoint(stb_bitset *p0, stb_bitset *p1, int len);
  7831. STB_EXTERN int stb_bitset_disjoint_0(stb_bitset *p0, stb_bitset *p1, int len);
  7832. STB_EXTERN int stb_bitset_subset(stb_bitset *bigger, stb_bitset *smaller, int len);
  7833. STB_EXTERN int stb_bitset_unioneq_changed(stb_bitset *p0, stb_bitset *p1, int len);
  7834. #ifdef STB_DEFINE
  7835. int stb_bitset_eq(stb_bitset *p0, stb_bitset *p1, int len)
  7836. {
  7837. int i;
  7838. for (i=0; i < len; ++i)
  7839. if (p0[i] != p1[i]) return 0;
  7840. return 1;
  7841. }
  7842. int stb_bitset_disjoint(stb_bitset *p0, stb_bitset *p1, int len)
  7843. {
  7844. int i;
  7845. for (i=0; i < len; ++i)
  7846. if (p0[i] & p1[i]) return 0;
  7847. return 1;
  7848. }
  7849. int stb_bitset_disjoint_0(stb_bitset *p0, stb_bitset *p1, int len)
  7850. {
  7851. int i;
  7852. for (i=0; i < len; ++i)
  7853. if ((p0[i] | p1[i]) != 0xffffffff) return 0;
  7854. return 1;
  7855. }
  7856. int stb_bitset_subset(stb_bitset *bigger, stb_bitset *smaller, int len)
  7857. {
  7858. int i;
  7859. for (i=0; i < len; ++i)
  7860. if ((bigger[i] & smaller[i]) != smaller[i]) return 0;
  7861. return 1;
  7862. }
  7863. stb_bitset *stb_bitset_union(stb_bitset *p0, stb_bitset *p1, int len)
  7864. {
  7865. int i;
  7866. stb_bitset *d = (stb_bitset *) malloc(sizeof(*d) * len);
  7867. for (i=0; i < len; ++i) d[i] = p0[i] | p1[i];
  7868. return d;
  7869. }
  7870. int stb_bitset_unioneq_changed(stb_bitset *p0, stb_bitset *p1, int len)
  7871. {
  7872. int i, changed=0;
  7873. for (i=0; i < len; ++i) {
  7874. stb_bitset d = p0[i] | p1[i];
  7875. if (d != p0[i]) {
  7876. p0[i] = d;
  7877. changed = 1;
  7878. }
  7879. }
  7880. return changed;
  7881. }
  7882. stb_bitset *stb_bitset_new(int value, int len)
  7883. {
  7884. int i;
  7885. stb_bitset *d = (stb_bitset *) malloc(sizeof(*d) * len);
  7886. if (value) value = 0xffffffff;
  7887. for (i=0; i < len; ++i) d[i] = value;
  7888. return d;
  7889. }
  7890. int *stb_bitset_getlist(stb_bitset *out, int start, int end)
  7891. {
  7892. int *list = NULL;
  7893. int i;
  7894. for (i=start; i < end; ++i)
  7895. if (stb_bitset_testbit(out, i))
  7896. stb_arr_push(list, i);
  7897. return list;
  7898. }
  7899. #endif
  7900. //////////////////////////////////////////////////////////////////////////////
  7901. //
  7902. // stb_wordwrap quality word-wrapping for fixed-width fonts
  7903. //
  7904. STB_EXTERN int stb_wordwrap(int *pairs, int pair_max, int count, char *str);
  7905. STB_EXTERN int *stb_wordwrapalloc(int count, char *str);
  7906. #ifdef STB_DEFINE
  7907. int stb_wordwrap(int *pairs, int pair_max, int count, char *str)
  7908. {
  7909. int n=0,i=0, start=0,nonwhite=0;
  7910. if (pairs == NULL) pair_max = 0x7ffffff0;
  7911. else pair_max *= 2;
  7912. // parse
  7913. for(;;) {
  7914. int s=i; // first whitespace char; last nonwhite+1
  7915. int w; // word start
  7916. // accept whitespace
  7917. while (isspace(str[i])) {
  7918. if (str[i] == '\n' || str[i] == '\r') {
  7919. if (str[i] + str[i+1] == '\n' + '\r') ++i;
  7920. if (n >= pair_max) return -1;
  7921. if (pairs) pairs[n] = start, pairs[n+1] = s-start;
  7922. n += 2;
  7923. nonwhite=0;
  7924. start = i+1;
  7925. s = start;
  7926. }
  7927. ++i;
  7928. }
  7929. if (i >= start+count) {
  7930. // we've gone off the end using whitespace
  7931. if (nonwhite) {
  7932. if (n >= pair_max) return -1;
  7933. if (pairs) pairs[n] = start, pairs[n+1] = s-start;
  7934. n += 2;
  7935. start = s = i;
  7936. nonwhite=0;
  7937. } else {
  7938. // output all the whitespace
  7939. while (i >= start+count) {
  7940. if (n >= pair_max) return -1;
  7941. if (pairs) pairs[n] = start, pairs[n+1] = count;
  7942. n += 2;
  7943. start += count;
  7944. }
  7945. s = start;
  7946. }
  7947. }
  7948. if (str[i] == 0) break;
  7949. // now scan out a word and see if it fits
  7950. w = i;
  7951. while (str[i] && !isspace(str[i])) {
  7952. ++i;
  7953. }
  7954. // wrapped?
  7955. if (i > start + count) {
  7956. // huge?
  7957. if (i-s <= count) {
  7958. if (n >= pair_max) return -1;
  7959. if (pairs) pairs[n] = start, pairs[n+1] = s-start;
  7960. n += 2;
  7961. start = w;
  7962. } else {
  7963. // This word is longer than one line. If we wrap it onto N lines
  7964. // there are leftover chars. do those chars fit on the cur line?
  7965. // But if we have leading whitespace, we force it to start here.
  7966. if ((w-start) + ((i-w) % count) <= count || !nonwhite) {
  7967. // output a full line
  7968. if (n >= pair_max) return -1;
  7969. if (pairs) pairs[n] = start, pairs[n+1] = count;
  7970. n += 2;
  7971. start += count;
  7972. w = start;
  7973. } else {
  7974. // output a partial line, trimming trailing whitespace
  7975. if (s != start) {
  7976. if (n >= pair_max) return -1;
  7977. if (pairs) pairs[n] = start, pairs[n+1] = s-start;
  7978. n += 2;
  7979. start = w;
  7980. }
  7981. }
  7982. // now output full lines as needed
  7983. while (start + count <= i) {
  7984. if (n >= pair_max) return -1;
  7985. if (pairs) pairs[n] = start, pairs[n+1] = count;
  7986. n += 2;
  7987. start += count;
  7988. }
  7989. }
  7990. }
  7991. nonwhite=1;
  7992. }
  7993. if (start < i) {
  7994. if (n >= pair_max) return -1;
  7995. if (pairs) pairs[n] = start, pairs[n+1] = i-start;
  7996. n += 2;
  7997. }
  7998. return n>>1;
  7999. }
  8000. int *stb_wordwrapalloc(int count, char *str)
  8001. {
  8002. int n = stb_wordwrap(NULL,0,count,str);
  8003. int *z = NULL;
  8004. stb_arr_setlen(z, n*2);
  8005. stb_wordwrap(z, n, count, str);
  8006. return z;
  8007. }
  8008. #endif
  8009. //////////////////////////////////////////////////////////////////////////////
  8010. //
  8011. // stb_match: wildcards and regexping
  8012. //
  8013. STB_EXTERN int stb_wildmatch (char *expr, char *candidate);
  8014. STB_EXTERN int stb_wildmatchi(char *expr, char *candidate);
  8015. STB_EXTERN int stb_wildfind (char *expr, char *candidate);
  8016. STB_EXTERN int stb_wildfindi (char *expr, char *candidate);
  8017. STB_EXTERN int stb_regex(char *regex, char *candidate);
  8018. typedef struct stb_matcher stb_matcher;
  8019. STB_EXTERN stb_matcher *stb_regex_matcher(char *regex);
  8020. STB_EXTERN int stb_matcher_match(stb_matcher *m, char *str);
  8021. STB_EXTERN int stb_matcher_find(stb_matcher *m, char *str);
  8022. STB_EXTERN void stb_matcher_free(stb_matcher *f);
  8023. STB_EXTERN stb_matcher *stb_lex_matcher(void);
  8024. STB_EXTERN int stb_lex_item(stb_matcher *m, const char *str, int result);
  8025. STB_EXTERN int stb_lex_item_wild(stb_matcher *matcher, const char *regex, int result);
  8026. STB_EXTERN int stb_lex(stb_matcher *m, char *str, int *len);
  8027. #ifdef STB_DEFINE
  8028. static int stb__match_qstring(char *candidate, char *qstring, int qlen, int insensitive)
  8029. {
  8030. int i;
  8031. if (insensitive) {
  8032. for (i=0; i < qlen; ++i)
  8033. if (qstring[i] == '?') {
  8034. if (!candidate[i]) return 0;
  8035. } else
  8036. if (tolower(qstring[i]) != tolower(candidate[i]))
  8037. return 0;
  8038. } else {
  8039. for (i=0; i < qlen; ++i)
  8040. if (qstring[i] == '?') {
  8041. if (!candidate[i]) return 0;
  8042. } else
  8043. if (qstring[i] != candidate[i])
  8044. return 0;
  8045. }
  8046. return 1;
  8047. }
  8048. static int stb__find_qstring(char *candidate, char *qstring, int qlen, int insensitive)
  8049. {
  8050. char c;
  8051. int offset=0;
  8052. while (*qstring == '?') {
  8053. ++qstring;
  8054. --qlen;
  8055. ++candidate;
  8056. if (qlen == 0) return 0;
  8057. if (*candidate == 0) return -1;
  8058. }
  8059. c = *qstring++;
  8060. --qlen;
  8061. if (insensitive) c = tolower(c);
  8062. while (candidate[offset]) {
  8063. if (c == (insensitive ? tolower(candidate[offset]) : candidate[offset]))
  8064. if (stb__match_qstring(candidate+offset+1, qstring, qlen, insensitive))
  8065. return offset;
  8066. ++offset;
  8067. }
  8068. return -1;
  8069. }
  8070. int stb__wildmatch_raw2(char *expr, char *candidate, int search, int insensitive)
  8071. {
  8072. int where=0;
  8073. int start = -1;
  8074. if (!search) {
  8075. // parse to first '*'
  8076. if (*expr != '*')
  8077. start = 0;
  8078. while (*expr != '*') {
  8079. if (!*expr)
  8080. return *candidate == 0 ? 0 : -1;
  8081. if (*expr == '?') {
  8082. if (!*candidate) return -1;
  8083. } else {
  8084. if (insensitive) {
  8085. if (tolower(*candidate) != tolower(*expr))
  8086. return -1;
  8087. } else
  8088. if (*candidate != *expr)
  8089. return -1;
  8090. }
  8091. ++candidate, ++expr, ++where;
  8092. }
  8093. } else {
  8094. // 0-length search string
  8095. if (!*expr)
  8096. return 0;
  8097. }
  8098. assert(search || *expr == '*');
  8099. if (!search)
  8100. ++expr;
  8101. // implicit '*' at this point
  8102. while (*expr) {
  8103. int o=0;
  8104. // combine redundant * characters
  8105. while (expr[0] == '*') ++expr;
  8106. // ok, at this point, expr[-1] == '*',
  8107. // and expr[0] != '*'
  8108. if (!expr[0]) return start >= 0 ? start : 0;
  8109. // now find next '*'
  8110. o = 0;
  8111. while (expr[o] != '*') {
  8112. if (expr[o] == 0)
  8113. break;
  8114. ++o;
  8115. }
  8116. // if no '*', scan to end, then match at end
  8117. if (expr[o] == 0 && !search) {
  8118. int z;
  8119. for (z=0; z < o; ++z)
  8120. if (candidate[z] == 0)
  8121. return -1;
  8122. while (candidate[z])
  8123. ++z;
  8124. // ok, now check if they match
  8125. if (stb__match_qstring(candidate+z-o, expr, o, insensitive))
  8126. return start >= 0 ? start : 0;
  8127. return -1;
  8128. } else {
  8129. // if yes '*', then do stb__find_qmatch on the intervening chars
  8130. int n = stb__find_qstring(candidate, expr, o, insensitive);
  8131. if (n < 0)
  8132. return -1;
  8133. if (start < 0)
  8134. start = where + n;
  8135. expr += o;
  8136. candidate += n+o;
  8137. }
  8138. if (*expr == 0) {
  8139. assert(search);
  8140. return start;
  8141. }
  8142. assert(*expr == '*');
  8143. ++expr;
  8144. }
  8145. return start >= 0 ? start : 0;
  8146. }
  8147. int stb__wildmatch_raw(char *expr, char *candidate, int search, int insensitive)
  8148. {
  8149. char buffer[256];
  8150. // handle multiple search strings
  8151. char *s = strchr(expr, ';');
  8152. char *last = expr;
  8153. while (s) {
  8154. int z;
  8155. // need to allow for non-writeable strings... assume they're small
  8156. if (s - last < 256) {
  8157. stb_strncpy(buffer, last, (int) (s-last+1));
  8158. z = stb__wildmatch_raw2(buffer, candidate, search, insensitive);
  8159. } else {
  8160. *s = 0;
  8161. z = stb__wildmatch_raw2(last, candidate, search, insensitive);
  8162. *s = ';';
  8163. }
  8164. if (z >= 0) return z;
  8165. last = s+1;
  8166. s = strchr(last, ';');
  8167. }
  8168. return stb__wildmatch_raw2(last, candidate, search, insensitive);
  8169. }
  8170. int stb_wildmatch(char *expr, char *candidate)
  8171. {
  8172. return stb__wildmatch_raw(expr, candidate, 0,0) >= 0;
  8173. }
  8174. int stb_wildmatchi(char *expr, char *candidate)
  8175. {
  8176. return stb__wildmatch_raw(expr, candidate, 0,1) >= 0;
  8177. }
  8178. int stb_wildfind(char *expr, char *candidate)
  8179. {
  8180. return stb__wildmatch_raw(expr, candidate, 1,0);
  8181. }
  8182. int stb_wildfindi(char *expr, char *candidate)
  8183. {
  8184. return stb__wildmatch_raw(expr, candidate, 1,1);
  8185. }
  8186. typedef struct
  8187. {
  8188. stb_int16 transition[256];
  8189. } stb_dfa;
  8190. // an NFA node represents a state you're in; it then has
  8191. // an arbitrary number of edges dangling off of it
  8192. // note this isn't utf8-y
  8193. typedef struct
  8194. {
  8195. stb_int16 match; // character/set to match
  8196. stb_uint16 node; // output node to go to
  8197. } stb_nfa_edge;
  8198. typedef struct
  8199. {
  8200. stb_int16 goal; // does reaching this win the prize?
  8201. stb_uint8 active; // is this in the active list
  8202. stb_nfa_edge *out;
  8203. stb_uint16 *eps; // list of epsilon closures
  8204. } stb_nfa_node;
  8205. #define STB__DFA_UNDEF -1
  8206. #define STB__DFA_GOAL -2
  8207. #define STB__DFA_END -3
  8208. #define STB__DFA_MGOAL -4
  8209. #define STB__DFA_VALID 0
  8210. #define STB__NFA_STOP_GOAL -1
  8211. // compiled regexp
  8212. struct stb_matcher
  8213. {
  8214. stb_uint16 start_node;
  8215. stb_int16 dfa_start;
  8216. stb_uint32 *charset;
  8217. int num_charset;
  8218. int match_start;
  8219. stb_nfa_node *nodes;
  8220. int does_lex;
  8221. // dfa matcher
  8222. stb_dfa * dfa;
  8223. stb_uint32 * dfa_mapping;
  8224. stb_int16 * dfa_result;
  8225. int num_words_per_dfa;
  8226. };
  8227. static int stb__add_node(stb_matcher *matcher)
  8228. {
  8229. stb_nfa_node z;
  8230. z.active = 0;
  8231. z.eps = 0;
  8232. z.goal = 0;
  8233. z.out = 0;
  8234. stb_arr_push(matcher->nodes, z);
  8235. return stb_arr_len(matcher->nodes)-1;
  8236. }
  8237. static void stb__add_epsilon(stb_matcher *matcher, int from, int to)
  8238. {
  8239. assert(from != to);
  8240. if (matcher->nodes[from].eps == NULL)
  8241. stb_arr_malloc((void **) &matcher->nodes[from].eps, matcher);
  8242. stb_arr_push(matcher->nodes[from].eps, to);
  8243. }
  8244. static void stb__add_edge(stb_matcher *matcher, int from, int to, int type)
  8245. {
  8246. stb_nfa_edge z = { (stb_int16)type, (stb_uint16)to };
  8247. if (matcher->nodes[from].out == NULL)
  8248. stb_arr_malloc((void **) &matcher->nodes[from].out, matcher);
  8249. stb_arr_push(matcher->nodes[from].out, z);
  8250. }
  8251. static char *stb__reg_parse_alt(stb_matcher *m, int s, char *r, stb_uint16 *e);
  8252. static char *stb__reg_parse(stb_matcher *matcher, int start, char *regex, stb_uint16 *end)
  8253. {
  8254. int n;
  8255. int last_start = -1;
  8256. stb_uint16 last_end = start;
  8257. while (*regex) {
  8258. switch (*regex) {
  8259. case '(':
  8260. last_start = last_end;
  8261. regex = stb__reg_parse_alt(matcher, last_end, regex+1, &last_end);
  8262. if (regex == NULL || *regex != ')')
  8263. return NULL;
  8264. ++regex;
  8265. break;
  8266. case '|':
  8267. case ')':
  8268. *end = last_end;
  8269. return regex;
  8270. case '?':
  8271. if (last_start < 0) return NULL;
  8272. stb__add_epsilon(matcher, last_start, last_end);
  8273. ++regex;
  8274. break;
  8275. case '*':
  8276. if (last_start < 0) return NULL;
  8277. stb__add_epsilon(matcher, last_start, last_end);
  8278. // fall through
  8279. case '+':
  8280. if (last_start < 0) return NULL;
  8281. stb__add_epsilon(matcher, last_end, last_start);
  8282. // prevent links back to last_end from chaining to last_start
  8283. n = stb__add_node(matcher);
  8284. stb__add_epsilon(matcher, last_end, n);
  8285. last_end = n;
  8286. ++regex;
  8287. break;
  8288. case '{': // not supported!
  8289. // @TODO: given {n,m}, clone last_start to last_end m times,
  8290. // and include epsilons from start to first m-n blocks
  8291. return NULL;
  8292. case '\\':
  8293. ++regex;
  8294. if (!*regex) return NULL;
  8295. // fallthrough
  8296. default: // match exactly this character
  8297. n = stb__add_node(matcher);
  8298. stb__add_edge(matcher, last_end, n, *regex);
  8299. last_start = last_end;
  8300. last_end = n;
  8301. ++regex;
  8302. break;
  8303. case '$':
  8304. n = stb__add_node(matcher);
  8305. stb__add_edge(matcher, last_end, n, '\n');
  8306. last_start = last_end;
  8307. last_end = n;
  8308. ++regex;
  8309. break;
  8310. case '.':
  8311. n = stb__add_node(matcher);
  8312. stb__add_edge(matcher, last_end, n, -1);
  8313. last_start = last_end;
  8314. last_end = n;
  8315. ++regex;
  8316. break;
  8317. case '[': {
  8318. stb_uint8 flags[256];
  8319. int invert = 0,z;
  8320. ++regex;
  8321. if (matcher->num_charset == 0) {
  8322. matcher->charset = (stb_uint *) stb_malloc(matcher, sizeof(*matcher->charset) * 256);
  8323. memset(matcher->charset, 0, sizeof(*matcher->charset) * 256);
  8324. }
  8325. memset(flags,0,sizeof(flags));
  8326. // leading ^ is special
  8327. if (*regex == '^')
  8328. ++regex, invert = 1;
  8329. // leading ] is special
  8330. if (*regex == ']') {
  8331. flags[(int) ']'] = 1;
  8332. ++regex;
  8333. }
  8334. while (*regex != ']') {
  8335. stb_uint a;
  8336. if (!*regex) return NULL;
  8337. a = *regex++;
  8338. if (regex[0] == '-' && regex[1] != ']') {
  8339. stb_uint i,b = regex[1];
  8340. regex += 2;
  8341. if (b == 0) return NULL;
  8342. if (a > b) return NULL;
  8343. for (i=a; i <= b; ++i)
  8344. flags[i] = 1;
  8345. } else
  8346. flags[a] = 1;
  8347. }
  8348. ++regex;
  8349. if (invert) {
  8350. int i;
  8351. for (i=0; i < 256; ++i)
  8352. flags[i] = 1-flags[i];
  8353. }
  8354. // now check if any existing charset matches
  8355. for (z=0; z < matcher->num_charset; ++z) {
  8356. int i, k[2] = { 0, 1 << z};
  8357. for (i=0; i < 256; ++i) {
  8358. unsigned int f = k[flags[i]];
  8359. if ((matcher->charset[i] & k[1]) != f)
  8360. break;
  8361. }
  8362. if (i == 256) break;
  8363. }
  8364. if (z == matcher->num_charset) {
  8365. int i;
  8366. ++matcher->num_charset;
  8367. if (matcher->num_charset > 32) {
  8368. assert(0); /* NOTREACHED */
  8369. return NULL; // too many charsets, oops
  8370. }
  8371. for (i=0; i < 256; ++i)
  8372. if (flags[i])
  8373. matcher->charset[i] |= (1 << z);
  8374. }
  8375. n = stb__add_node(matcher);
  8376. stb__add_edge(matcher, last_end, n, -2 - z);
  8377. last_start = last_end;
  8378. last_end = n;
  8379. break;
  8380. }
  8381. }
  8382. }
  8383. *end = last_end;
  8384. return regex;
  8385. }
  8386. static char *stb__reg_parse_alt(stb_matcher *matcher, int start, char *regex, stb_uint16 *end)
  8387. {
  8388. stb_uint16 last_end = start;
  8389. stb_uint16 main_end;
  8390. int head, tail;
  8391. head = stb__add_node(matcher);
  8392. stb__add_epsilon(matcher, start, head);
  8393. regex = stb__reg_parse(matcher, head, regex, &last_end);
  8394. if (regex == NULL) return NULL;
  8395. if (*regex == 0 || *regex == ')') {
  8396. *end = last_end;
  8397. return regex;
  8398. }
  8399. main_end = last_end;
  8400. tail = stb__add_node(matcher);
  8401. stb__add_epsilon(matcher, last_end, tail);
  8402. // start alternatives from the same starting node; use epsilon
  8403. // transitions to combine their endings
  8404. while(*regex && *regex != ')') {
  8405. assert(*regex == '|');
  8406. head = stb__add_node(matcher);
  8407. stb__add_epsilon(matcher, start, head);
  8408. regex = stb__reg_parse(matcher, head, regex+1, &last_end);
  8409. if (regex == NULL)
  8410. return NULL;
  8411. stb__add_epsilon(matcher, last_end, tail);
  8412. }
  8413. *end = tail;
  8414. return regex;
  8415. }
  8416. static char *stb__wild_parse(stb_matcher *matcher, int start, char *str, stb_uint16 *end)
  8417. {
  8418. int n;
  8419. stb_uint16 last_end;
  8420. last_end = stb__add_node(matcher);
  8421. stb__add_epsilon(matcher, start, last_end);
  8422. while (*str) {
  8423. switch (*str) {
  8424. // fallthrough
  8425. default: // match exactly this character
  8426. n = stb__add_node(matcher);
  8427. if (toupper(*str) == tolower(*str)) {
  8428. stb__add_edge(matcher, last_end, n, *str);
  8429. } else {
  8430. stb__add_edge(matcher, last_end, n, tolower(*str));
  8431. stb__add_edge(matcher, last_end, n, toupper(*str));
  8432. }
  8433. last_end = n;
  8434. ++str;
  8435. break;
  8436. case '?':
  8437. n = stb__add_node(matcher);
  8438. stb__add_edge(matcher, last_end, n, -1);
  8439. last_end = n;
  8440. ++str;
  8441. break;
  8442. case '*':
  8443. n = stb__add_node(matcher);
  8444. stb__add_edge(matcher, last_end, n, -1);
  8445. stb__add_epsilon(matcher, last_end, n);
  8446. stb__add_epsilon(matcher, n, last_end);
  8447. last_end = n;
  8448. ++str;
  8449. break;
  8450. }
  8451. }
  8452. // now require end of string to match
  8453. n = stb__add_node(matcher);
  8454. stb__add_edge(matcher, last_end, n, 0);
  8455. last_end = n;
  8456. *end = last_end;
  8457. return str;
  8458. }
  8459. static int stb__opt(stb_matcher *m, int n)
  8460. {
  8461. for(;;) {
  8462. stb_nfa_node *p = &m->nodes[n];
  8463. if (p->goal) return n;
  8464. if (stb_arr_len(p->out)) return n;
  8465. if (stb_arr_len(p->eps) != 1) return n;
  8466. n = p->eps[0];
  8467. }
  8468. }
  8469. static void stb__optimize(stb_matcher *m)
  8470. {
  8471. // if the target of any edge is a node with exactly
  8472. // one out-epsilon, shorten it
  8473. int i,j;
  8474. for (i=0; i < stb_arr_len(m->nodes); ++i) {
  8475. stb_nfa_node *p = &m->nodes[i];
  8476. for (j=0; j < stb_arr_len(p->out); ++j)
  8477. p->out[j].node = stb__opt(m,p->out[j].node);
  8478. for (j=0; j < stb_arr_len(p->eps); ++j)
  8479. p->eps[j] = stb__opt(m,p->eps[j] );
  8480. }
  8481. m->start_node = stb__opt(m,m->start_node);
  8482. }
  8483. void stb_matcher_free(stb_matcher *f)
  8484. {
  8485. stb_free(f);
  8486. }
  8487. static stb_matcher *stb__alloc_matcher(void)
  8488. {
  8489. stb_matcher *matcher = (stb_matcher *) stb_malloc(0,sizeof(*matcher));
  8490. matcher->start_node = 0;
  8491. stb_arr_malloc((void **) &matcher->nodes, matcher);
  8492. matcher->num_charset = 0;
  8493. matcher->match_start = 0;
  8494. matcher->does_lex = 0;
  8495. matcher->dfa_start = STB__DFA_UNDEF;
  8496. stb_arr_malloc((void **) &matcher->dfa, matcher);
  8497. stb_arr_malloc((void **) &matcher->dfa_mapping, matcher);
  8498. stb_arr_malloc((void **) &matcher->dfa_result, matcher);
  8499. stb__add_node(matcher);
  8500. return matcher;
  8501. }
  8502. static void stb__lex_reset(stb_matcher *matcher)
  8503. {
  8504. // flush cached dfa data
  8505. stb_arr_setlen(matcher->dfa, 0);
  8506. stb_arr_setlen(matcher->dfa_mapping, 0);
  8507. stb_arr_setlen(matcher->dfa_result, 0);
  8508. matcher->dfa_start = STB__DFA_UNDEF;
  8509. }
  8510. stb_matcher *stb_regex_matcher(char *regex)
  8511. {
  8512. char *z;
  8513. stb_uint16 end;
  8514. stb_matcher *matcher = stb__alloc_matcher();
  8515. if (*regex == '^') {
  8516. matcher->match_start = 1;
  8517. ++regex;
  8518. }
  8519. z = stb__reg_parse_alt(matcher, matcher->start_node, regex, &end);
  8520. if (!z || *z) {
  8521. stb_free(matcher);
  8522. return NULL;
  8523. }
  8524. ((matcher->nodes)[(int) end]).goal = STB__NFA_STOP_GOAL;
  8525. return matcher;
  8526. }
  8527. stb_matcher *stb_lex_matcher(void)
  8528. {
  8529. stb_matcher *matcher = stb__alloc_matcher();
  8530. matcher->match_start = 1;
  8531. matcher->does_lex = 1;
  8532. return matcher;
  8533. }
  8534. int stb_lex_item(stb_matcher *matcher, const char *regex, int result)
  8535. {
  8536. char *z;
  8537. stb_uint16 end;
  8538. z = stb__reg_parse_alt(matcher, matcher->start_node, (char*) regex, &end);
  8539. if (z == NULL)
  8540. return 0;
  8541. stb__lex_reset(matcher);
  8542. matcher->nodes[(int) end].goal = result;
  8543. return 1;
  8544. }
  8545. int stb_lex_item_wild(stb_matcher *matcher, const char *regex, int result)
  8546. {
  8547. char *z;
  8548. stb_uint16 end;
  8549. z = stb__wild_parse(matcher, matcher->start_node, (char*) regex, &end);
  8550. if (z == NULL)
  8551. return 0;
  8552. stb__lex_reset(matcher);
  8553. matcher->nodes[(int) end].goal = result;
  8554. return 1;
  8555. }
  8556. static void stb__clear(stb_matcher *m, stb_uint16 *list)
  8557. {
  8558. int i;
  8559. for (i=0; i < stb_arr_len(list); ++i)
  8560. m->nodes[(int) list[i]].active = 0;
  8561. }
  8562. static int stb__clear_goalcheck(stb_matcher *m, stb_uint16 *list)
  8563. {
  8564. int i, t=0;
  8565. for (i=0; i < stb_arr_len(list); ++i) {
  8566. t += m->nodes[(int) list[i]].goal;
  8567. m->nodes[(int) list[i]].active = 0;
  8568. }
  8569. return t;
  8570. }
  8571. static stb_uint16 * stb__add_if_inactive(stb_matcher *m, stb_uint16 *list, int n)
  8572. {
  8573. if (!m->nodes[n].active) {
  8574. stb_arr_push(list, n);
  8575. m->nodes[n].active = 1;
  8576. }
  8577. return list;
  8578. }
  8579. static stb_uint16 * stb__eps_closure(stb_matcher *m, stb_uint16 *list)
  8580. {
  8581. int i,n = stb_arr_len(list);
  8582. for(i=0; i < n; ++i) {
  8583. stb_uint16 *e = m->nodes[(int) list[i]].eps;
  8584. if (e) {
  8585. int j,k = stb_arr_len(e);
  8586. for (j=0; j < k; ++j)
  8587. list = stb__add_if_inactive(m, list, e[j]);
  8588. n = stb_arr_len(list);
  8589. }
  8590. }
  8591. return list;
  8592. }
  8593. int stb_matcher_match(stb_matcher *m, char *str)
  8594. {
  8595. int result = 0;
  8596. int i,j,y,z;
  8597. stb_uint16 *previous = NULL;
  8598. stb_uint16 *current = NULL;
  8599. stb_uint16 *temp;
  8600. stb_arr_setsize(previous, 4);
  8601. stb_arr_setsize(current, 4);
  8602. previous = stb__add_if_inactive(m, previous, m->start_node);
  8603. previous = stb__eps_closure(m,previous);
  8604. stb__clear(m, previous);
  8605. while (*str && stb_arr_len(previous)) {
  8606. y = stb_arr_len(previous);
  8607. for (i=0; i < y; ++i) {
  8608. stb_nfa_node *n = &m->nodes[(int) previous[i]];
  8609. z = stb_arr_len(n->out);
  8610. for (j=0; j < z; ++j) {
  8611. if (n->out[j].match >= 0) {
  8612. if (n->out[j].match == *str)
  8613. current = stb__add_if_inactive(m, current, n->out[j].node);
  8614. } else if (n->out[j].match == -1) {
  8615. if (*str != '\n')
  8616. current = stb__add_if_inactive(m, current, n->out[j].node);
  8617. } else if (n->out[j].match < -1) {
  8618. int z = -n->out[j].match - 2;
  8619. if (m->charset[(stb_uint8) *str] & (1 << z))
  8620. current = stb__add_if_inactive(m, current, n->out[j].node);
  8621. }
  8622. }
  8623. }
  8624. stb_arr_setlen(previous, 0);
  8625. temp = previous;
  8626. previous = current;
  8627. current = temp;
  8628. previous = stb__eps_closure(m,previous);
  8629. stb__clear(m, previous);
  8630. ++str;
  8631. }
  8632. // transition to pick up a '$' at the end
  8633. y = stb_arr_len(previous);
  8634. for (i=0; i < y; ++i)
  8635. m->nodes[(int) previous[i]].active = 1;
  8636. for (i=0; i < y; ++i) {
  8637. stb_nfa_node *n = &m->nodes[(int) previous[i]];
  8638. z = stb_arr_len(n->out);
  8639. for (j=0; j < z; ++j) {
  8640. if (n->out[j].match == '\n')
  8641. current = stb__add_if_inactive(m, current, n->out[j].node);
  8642. }
  8643. }
  8644. previous = stb__eps_closure(m,previous);
  8645. stb__clear(m, previous);
  8646. y = stb_arr_len(previous);
  8647. for (i=0; i < y; ++i)
  8648. if (m->nodes[(int) previous[i]].goal)
  8649. result = 1;
  8650. stb_arr_free(previous);
  8651. stb_arr_free(current);
  8652. return result && *str == 0;
  8653. }
  8654. stb_int16 stb__get_dfa_node(stb_matcher *m, stb_uint16 *list)
  8655. {
  8656. stb_uint16 node;
  8657. stb_uint32 data[8], *state, *newstate;
  8658. int i,j,n;
  8659. state = (stb_uint32 *) stb_temp(data, m->num_words_per_dfa * 4);
  8660. memset(state, 0, m->num_words_per_dfa*4);
  8661. n = stb_arr_len(list);
  8662. for (i=0; i < n; ++i) {
  8663. int x = list[i];
  8664. state[x >> 5] |= 1 << (x & 31);
  8665. }
  8666. // @TODO use a hash table
  8667. n = stb_arr_len(m->dfa_mapping);
  8668. i=j=0;
  8669. for(; j < n; ++i, j += m->num_words_per_dfa) {
  8670. // @TODO special case for <= 32
  8671. if (!memcmp(state, m->dfa_mapping + j, m->num_words_per_dfa*4)) {
  8672. node = i;
  8673. goto done;
  8674. }
  8675. }
  8676. assert(stb_arr_len(m->dfa) == i);
  8677. node = i;
  8678. newstate = stb_arr_addn(m->dfa_mapping, m->num_words_per_dfa);
  8679. memcpy(newstate, state, m->num_words_per_dfa*4);
  8680. // set all transitions to 'unknown'
  8681. stb_arr_add(m->dfa);
  8682. memset(m->dfa[i].transition, -1, sizeof(m->dfa[i].transition));
  8683. if (m->does_lex) {
  8684. int result = -1;
  8685. n = stb_arr_len(list);
  8686. for (i=0; i < n; ++i) {
  8687. if (m->nodes[(int) list[i]].goal > result)
  8688. result = m->nodes[(int) list[i]].goal;
  8689. }
  8690. stb_arr_push(m->dfa_result, result);
  8691. }
  8692. done:
  8693. stb_tempfree(data, state);
  8694. return node;
  8695. }
  8696. static int stb__matcher_dfa(stb_matcher *m, char *str_c, int *len)
  8697. {
  8698. stb_uint8 *str = (stb_uint8 *) str_c;
  8699. stb_int16 node,prevnode;
  8700. stb_dfa *trans;
  8701. int match_length = 0;
  8702. stb_int16 match_result=0;
  8703. if (m->dfa_start == STB__DFA_UNDEF) {
  8704. stb_uint16 *list;
  8705. m->num_words_per_dfa = (stb_arr_len(m->nodes)+31) >> 5;
  8706. stb__optimize(m);
  8707. list = stb__add_if_inactive(m, NULL, m->start_node);
  8708. list = stb__eps_closure(m,list);
  8709. if (m->does_lex) {
  8710. m->dfa_start = stb__get_dfa_node(m,list);
  8711. stb__clear(m, list);
  8712. // DON'T allow start state to be a goal state!
  8713. // this allows people to specify regexes that can match 0
  8714. // characters without them actually matching (also we don't
  8715. // check _before_ advancing anyway
  8716. if (m->dfa_start <= STB__DFA_MGOAL)
  8717. m->dfa_start = -(m->dfa_start - STB__DFA_MGOAL);
  8718. } else {
  8719. if (stb__clear_goalcheck(m, list))
  8720. m->dfa_start = STB__DFA_GOAL;
  8721. else
  8722. m->dfa_start = stb__get_dfa_node(m,list);
  8723. }
  8724. stb_arr_free(list);
  8725. }
  8726. prevnode = STB__DFA_UNDEF;
  8727. node = m->dfa_start;
  8728. trans = m->dfa;
  8729. if (m->dfa_start == STB__DFA_GOAL)
  8730. return 1;
  8731. for(;;) {
  8732. assert(node >= STB__DFA_VALID);
  8733. // fast inner DFA loop; especially if STB__DFA_VALID is 0
  8734. do {
  8735. prevnode = node;
  8736. node = trans[node].transition[*str++];
  8737. } while (node >= STB__DFA_VALID);
  8738. assert(node >= STB__DFA_MGOAL - stb_arr_len(m->dfa));
  8739. assert(node < stb_arr_len(m->dfa));
  8740. // special case for lex: need _longest_ match, so notice goal
  8741. // state without stopping
  8742. if (node <= STB__DFA_MGOAL) {
  8743. match_length = (int) (str - (stb_uint8 *) str_c);
  8744. node = -(node - STB__DFA_MGOAL);
  8745. match_result = node;
  8746. continue;
  8747. }
  8748. // slow NFA->DFA conversion
  8749. // or we hit the goal or the end of the string, but those
  8750. // can only happen once per search...
  8751. if (node == STB__DFA_UNDEF) {
  8752. // build a list -- @TODO special case <= 32 states
  8753. // heck, use a more compact data structure for <= 16 and <= 8 ?!
  8754. // @TODO keep states/newstates around instead of reallocating them
  8755. stb_uint16 *states = NULL;
  8756. stb_uint16 *newstates = NULL;
  8757. int i,j,y,z;
  8758. stb_uint32 *flags = &m->dfa_mapping[prevnode * m->num_words_per_dfa];
  8759. assert(prevnode != STB__DFA_UNDEF);
  8760. stb_arr_setsize(states, 4);
  8761. stb_arr_setsize(newstates,4);
  8762. for (j=0; j < m->num_words_per_dfa; ++j) {
  8763. for (i=0; i < 32; ++i) {
  8764. if (*flags & (1 << i))
  8765. stb_arr_push(states, j*32+i);
  8766. }
  8767. ++flags;
  8768. }
  8769. // states is now the states we were in in the previous node;
  8770. // so now we can compute what node it transitions to on str[-1]
  8771. y = stb_arr_len(states);
  8772. for (i=0; i < y; ++i) {
  8773. stb_nfa_node *n = &m->nodes[(int) states[i]];
  8774. z = stb_arr_len(n->out);
  8775. for (j=0; j < z; ++j) {
  8776. if (n->out[j].match >= 0) {
  8777. if (n->out[j].match == str[-1] || (str[-1] == 0 && n->out[j].match == '\n'))
  8778. newstates = stb__add_if_inactive(m, newstates, n->out[j].node);
  8779. } else if (n->out[j].match == -1) {
  8780. if (str[-1] != '\n' && str[-1])
  8781. newstates = stb__add_if_inactive(m, newstates, n->out[j].node);
  8782. } else if (n->out[j].match < -1) {
  8783. int z = -n->out[j].match - 2;
  8784. if (m->charset[str[-1]] & (1 << z))
  8785. newstates = stb__add_if_inactive(m, newstates, n->out[j].node);
  8786. }
  8787. }
  8788. }
  8789. // AND add in the start state!
  8790. if (!m->match_start || (str[-1] == '\n' && !m->does_lex))
  8791. newstates = stb__add_if_inactive(m, newstates, m->start_node);
  8792. // AND epsilon close it
  8793. newstates = stb__eps_closure(m, newstates);
  8794. // if it's a goal state, then that's all there is to it
  8795. if (stb__clear_goalcheck(m, newstates)) {
  8796. if (m->does_lex) {
  8797. match_length = (int) (str - (stb_uint8 *) str_c);
  8798. node = stb__get_dfa_node(m,newstates);
  8799. match_result = node;
  8800. node = -node + STB__DFA_MGOAL;
  8801. trans = m->dfa; // could have gotten realloc()ed
  8802. } else
  8803. node = STB__DFA_GOAL;
  8804. } else if (str[-1] == 0 || stb_arr_len(newstates) == 0) {
  8805. node = STB__DFA_END;
  8806. } else {
  8807. node = stb__get_dfa_node(m,newstates);
  8808. trans = m->dfa; // could have gotten realloc()ed
  8809. }
  8810. trans[prevnode].transition[str[-1]] = node;
  8811. if (node <= STB__DFA_MGOAL)
  8812. node = -(node - STB__DFA_MGOAL);
  8813. stb_arr_free(newstates);
  8814. stb_arr_free(states);
  8815. }
  8816. if (node == STB__DFA_GOAL) {
  8817. return 1;
  8818. }
  8819. if (node == STB__DFA_END) {
  8820. if (m->does_lex) {
  8821. if (match_result) {
  8822. if (len) *len = match_length;
  8823. return m->dfa_result[(int) match_result];
  8824. }
  8825. }
  8826. return 0;
  8827. }
  8828. assert(node != STB__DFA_UNDEF);
  8829. }
  8830. }
  8831. int stb_matcher_find(stb_matcher *m, char *str)
  8832. {
  8833. assert(m->does_lex == 0);
  8834. return stb__matcher_dfa(m, str, NULL);
  8835. }
  8836. int stb_lex(stb_matcher *m, char *str, int *len)
  8837. {
  8838. assert(m->does_lex);
  8839. return stb__matcher_dfa(m, str, len);
  8840. }
  8841. #ifdef STB_PERFECT_HASH
  8842. int stb_regex(char *regex, char *str)
  8843. {
  8844. static stb_perfect p;
  8845. static stb_matcher ** matchers;
  8846. static char ** regexps;
  8847. static char ** regexp_cache;
  8848. static unsigned short *mapping;
  8849. int z = stb_perfect_hash(&p, (int)(size_t) regex);
  8850. if (z >= 0) {
  8851. if (strcmp(regex, regexp_cache[(int) mapping[z]])) {
  8852. int i = mapping[z];
  8853. stb_matcher_free(matchers[i]);
  8854. free(regexp_cache[i]);
  8855. regexps[i] = regex;
  8856. regexp_cache[i] = stb_p_strdup(regex);
  8857. matchers[i] = stb_regex_matcher(regex);
  8858. }
  8859. } else {
  8860. int i,n;
  8861. if (regex == NULL) {
  8862. for (i=0; i < stb_arr_len(matchers); ++i) {
  8863. stb_matcher_free(matchers[i]);
  8864. free(regexp_cache[i]);
  8865. }
  8866. stb_arr_free(matchers);
  8867. stb_arr_free(regexps);
  8868. stb_arr_free(regexp_cache);
  8869. stb_perfect_destroy(&p);
  8870. free(mapping); mapping = NULL;
  8871. return -1;
  8872. }
  8873. stb_arr_push(regexps, regex);
  8874. stb_arr_push(regexp_cache, stb_p_strdup(regex));
  8875. stb_arr_push(matchers, stb_regex_matcher(regex));
  8876. stb_perfect_destroy(&p);
  8877. n = stb_perfect_create(&p, (unsigned int *) (char **) regexps, stb_arr_len(regexps));
  8878. mapping = (unsigned short *) realloc(mapping, n * sizeof(*mapping));
  8879. for (i=0; i < stb_arr_len(regexps); ++i)
  8880. mapping[stb_perfect_hash(&p, (int)(size_t) regexps[i])] = i;
  8881. z = stb_perfect_hash(&p, (int)(size_t) regex);
  8882. }
  8883. return stb_matcher_find(matchers[(int) mapping[z]], str);
  8884. }
  8885. #endif
  8886. #endif // STB_DEFINE
  8887. #if 0
  8888. //////////////////////////////////////////////////////////////////////////////
  8889. //
  8890. // C source-code introspection
  8891. //
  8892. // runtime structure
  8893. typedef struct
  8894. {
  8895. char *name;
  8896. char *type; // base type
  8897. char *comment; // content of comment field
  8898. int size; // size of base type
  8899. int offset; // field offset
  8900. int arrcount[8]; // array sizes; -1 = pointer indirection; 0 = end of list
  8901. } stb_info_field;
  8902. typedef struct
  8903. {
  8904. char *structname;
  8905. int size;
  8906. int num_fields;
  8907. stb_info_field *fields;
  8908. } stb_info_struct;
  8909. extern stb_info_struct stb_introspect_output[];
  8910. //
  8911. STB_EXTERN void stb_introspect_precompiled(stb_info_struct *compiled);
  8912. STB_EXTERN void stb__introspect(char *path, char *file);
  8913. #define stb_introspect_ship() stb__introspect(NULL, NULL, stb__introspect_output)
  8914. #ifdef STB_SHIP
  8915. #define stb_introspect() stb_introspect_ship()
  8916. #define stb_introspect_path(p) stb_introspect_ship()
  8917. #else
  8918. // bootstrapping: define stb_introspect() (or 'path') the first time
  8919. #define stb_introspect() stb__introspect(NULL, __FILE__, NULL)
  8920. #define stb_introspect_auto() stb__introspect(NULL, __FILE__, stb__introspect_output)
  8921. #define stb_introspect_path(p) stb__introspect(p, __FILE__, NULL)
  8922. #define stb_introspect_path(p) stb__introspect(p, __FILE__, NULL)
  8923. #endif
  8924. #ifdef STB_DEFINE
  8925. #ifndef STB_INTROSPECT_CPP
  8926. #ifdef __cplusplus
  8927. #define STB_INTROSPECT_CPP 1
  8928. #else
  8929. #define STB_INTROSPECT_CPP 0
  8930. #endif
  8931. #endif
  8932. void stb_introspect_precompiled(stb_info_struct *compiled)
  8933. {
  8934. }
  8935. static void stb__introspect_filename(char *buffer, char *path)
  8936. {
  8937. #if STB_INTROSPECT_CPP
  8938. stb_p_sprintf(buffer stb_p_size(9999), "%s/stb_introspect.cpp", path);
  8939. #else
  8940. stb_p_sprintf(buffer stb_p_size(9999), "%s/stb_introspect.c", path);
  8941. #endif
  8942. }
  8943. static void stb__introspect_compute(char *path, char *file)
  8944. {
  8945. int i;
  8946. char ** include_list = NULL;
  8947. char ** introspect_list = NULL;
  8948. FILE *f;
  8949. f = stb_p_fopen(file, "w");
  8950. if (!f) return;
  8951. fputs("// if you get compiler errors, change the following 0 to a 1:\n", f);
  8952. fputs("#define STB_INTROSPECT_INVALID 0\n\n", f);
  8953. fputs("// this will force the code to compile, and force the introspector\n", f);
  8954. fputs("// to run and then exit, allowing you to recompile\n\n\n", f);
  8955. fputs("#include \"stb.h\"\n\n",f );
  8956. fputs("#if STB_INTROSPECT_INVALID\n", f);
  8957. fputs(" stb_info_struct stb__introspect_output[] = { (void *) 1 }\n", f);
  8958. fputs("#else\n\n", f);
  8959. for (i=0; i < stb_arr_len(include_list); ++i)
  8960. fprintf(f, " #include \"%s\"\n", include_list[i]);
  8961. fputs(" stb_info_struct stb__introspect_output[] =\n{\n", f);
  8962. for (i=0; i < stb_arr_len(introspect_list); ++i)
  8963. fprintf(f, " stb_introspect_%s,\n", introspect_list[i]);
  8964. fputs(" };\n", f);
  8965. fputs("#endif\n", f);
  8966. fclose(f);
  8967. }
  8968. static stb_info_struct *stb__introspect_info;
  8969. #ifndef STB_SHIP
  8970. #endif
  8971. void stb__introspect(char *path, char *file, stb_info_struct *compiled)
  8972. {
  8973. static int first=1;
  8974. if (!first) return;
  8975. first=0;
  8976. stb__introspect_info = compiled;
  8977. #ifndef STB_SHIP
  8978. if (path || file) {
  8979. int bail_flag = compiled && compiled[0].structname == (void *) 1;
  8980. int needs_building = bail_flag;
  8981. struct stb__stat st;
  8982. char buffer[1024], buffer2[1024];
  8983. if (!path) {
  8984. stb_splitpath(buffer, file, STB_PATH);
  8985. path = buffer;
  8986. }
  8987. // bail if the source path doesn't exist
  8988. if (!stb_fexists(path)) return;
  8989. stb__introspect_filename(buffer2, path);
  8990. // get source/include files timestamps, compare to output-file timestamp;
  8991. // if mismatched, regenerate
  8992. if (stb__stat(buffer2, &st))
  8993. needs_building = STB_TRUE;
  8994. {
  8995. // find any file that contains an introspection command and is newer
  8996. // if needs_building is already true, we don't need to do this test,
  8997. // but we still need these arrays, so go ahead and get them
  8998. char **all[3];
  8999. all[0] = stb_readdir_files_mask(path, "*.h");
  9000. all[1] = stb_readdir_files_mask(path, "*.c");
  9001. all[2] = stb_readdir_files_mask(path, "*.cpp");
  9002. int i,j;
  9003. if (needs_building) {
  9004. for (j=0; j < 3; ++j) {
  9005. for (i=0; i < stb_arr_len(all[j]); ++i) {
  9006. struct stb__stat st2;
  9007. if (!stb__stat(all[j][i], &st2)) {
  9008. if (st.st_mtime < st2.st_mtime) {
  9009. char *z = stb_filec(all[j][i], NULL);
  9010. int found=STB_FALSE;
  9011. while (y) {
  9012. y = strstr(y, "//si");
  9013. if (y && isspace(y[4])) {
  9014. found = STB_TRUE;
  9015. break;
  9016. }
  9017. }
  9018. needs_building = STB_TRUE;
  9019. goto done;
  9020. }
  9021. }
  9022. }
  9023. }
  9024. done:;
  9025. }
  9026. char *z = stb_filec(all[i], NULL), *y = z;
  9027. int found=STB_FALSE;
  9028. while (y) {
  9029. y = strstr(y, "//si");
  9030. if (y && isspace(y[4])) {
  9031. found = STB_TRUE;
  9032. break;
  9033. }
  9034. }
  9035. if (found)
  9036. stb_arr_push(introspect_h, stb_p_strdup(all[i]));
  9037. free(z);
  9038. }
  9039. }
  9040. stb_readdir_free(all);
  9041. if (!needs_building) {
  9042. for (i=0; i < stb_arr_len(introspect_h); ++i) {
  9043. struct stb__stat st2;
  9044. if (!stb__stat(introspect_h[i], &st2))
  9045. if (st.st_mtime < st2.st_mtime)
  9046. needs_building = STB_TRUE;
  9047. }
  9048. }
  9049. if (needs_building) {
  9050. stb__introspect_compute(path, buffer2);
  9051. }
  9052. }
  9053. }
  9054. #endif
  9055. }
  9056. #endif
  9057. #endif
  9058. #ifdef STB_INTROSPECT
  9059. // compile-time code-generator
  9060. #define INTROSPECT(x) int main(int argc, char **argv) { stb__introspect(__FILE__); return 0; }
  9061. #define FILE(x)
  9062. void stb__introspect(char *filename)
  9063. {
  9064. char *file = stb_file(filename, NULL);
  9065. char *s = file, *t, **p;
  9066. char *out_name = "stb_introspect.c";
  9067. char *out_path;
  9068. STB_ARR(char) filelist = NULL;
  9069. int i,n;
  9070. if (!file) stb_fatal("Couldn't open %s", filename);
  9071. out_path = stb_splitpathdup(filename, STB_PATH);
  9072. // search for the macros
  9073. while (*s) {
  9074. char buffer[256];
  9075. while (*s && !isupper(*s)) ++s;
  9076. s = stb_strtok_invert(buffer, s, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
  9077. s = stb_skipwhite(s);
  9078. if (*s == '(') {
  9079. ++s;
  9080. t = strchr(s, ')');
  9081. if (t == NULL) stb_fatal("Error parsing %s", filename);
  9082. }
  9083. }
  9084. }
  9085. #endif
  9086. //////////////////////////////////////////////////////////////////////////////
  9087. //
  9088. // STB-C sliding-window dictionary compression
  9089. //
  9090. // This uses a DEFLATE-style sliding window, but no bitwise entropy.
  9091. // Everything is on byte boundaries, so you could then apply a byte-wise
  9092. // entropy code, though that's nowhere near as effective.
  9093. //
  9094. // An STB-C stream begins with a 16-byte header:
  9095. // 4 bytes: 0x57 0xBC 0x00 0x00
  9096. // 8 bytes: big-endian size of decompressed data, 64-bits
  9097. // 4 bytes: big-endian size of window (how far back decompressor may need)
  9098. //
  9099. // The following symbols appear in the stream (these were determined ad hoc,
  9100. // not by analysis):
  9101. //
  9102. // [dict] 00000100 yyyyyyyy yyyyyyyy yyyyyyyy xxxxxxxx xxxxxxxx
  9103. // [END] 00000101 11111010 cccccccc cccccccc cccccccc cccccccc
  9104. // [dict] 00000110 yyyyyyyy yyyyyyyy yyyyyyyy xxxxxxxx
  9105. // [literals] 00000111 zzzzzzzz zzzzzzzz
  9106. // [literals] 00001zzz zzzzzzzz
  9107. // [dict] 00010yyy yyyyyyyy yyyyyyyy xxxxxxxx xxxxxxxx
  9108. // [dict] 00011yyy yyyyyyyy yyyyyyyy xxxxxxxx
  9109. // [literals] 001zzzzz
  9110. // [dict] 01yyyyyy yyyyyyyy xxxxxxxx
  9111. // [dict] 1xxxxxxx yyyyyyyy
  9112. //
  9113. // xxxxxxxx: match length - 1
  9114. // yyyyyyyy: backwards distance - 1
  9115. // zzzzzzzz: num literals - 1
  9116. // cccccccc: adler32 checksum of decompressed data
  9117. // (all big-endian)
  9118. STB_EXTERN stb_uint stb_decompress_length(stb_uchar *input);
  9119. STB_EXTERN stb_uint stb_decompress(stb_uchar *out,stb_uchar *in,stb_uint len);
  9120. STB_EXTERN stb_uint stb_compress (stb_uchar *out,stb_uchar *in,stb_uint len);
  9121. STB_EXTERN void stb_compress_window(int z);
  9122. STB_EXTERN void stb_compress_hashsize(unsigned int z);
  9123. STB_EXTERN int stb_compress_tofile(char *filename, char *in, stb_uint len);
  9124. STB_EXTERN int stb_compress_intofile(FILE *f, char *input, stb_uint len);
  9125. STB_EXTERN char *stb_decompress_fromfile(char *filename, stb_uint *len);
  9126. STB_EXTERN int stb_compress_stream_start(FILE *f);
  9127. STB_EXTERN void stb_compress_stream_end(int close);
  9128. STB_EXTERN void stb_write(char *data, int data_len);
  9129. #ifdef STB_DEFINE
  9130. stb_uint stb_decompress_length(stb_uchar *input)
  9131. {
  9132. return (input[8] << 24) + (input[9] << 16) + (input[10] << 8) + input[11];
  9133. }
  9134. //////////////////// decompressor ///////////////////////
  9135. // simple implementation that just writes whole thing into big block
  9136. static unsigned char *stb__barrier;
  9137. static unsigned char *stb__barrier2;
  9138. static unsigned char *stb__barrier3;
  9139. static unsigned char *stb__barrier4;
  9140. static stb_uchar *stb__dout;
  9141. static void stb__match(stb_uchar *data, stb_uint length)
  9142. {
  9143. // INVERSE of memmove... write each byte before copying the next...
  9144. assert (stb__dout + length <= stb__barrier);
  9145. if (stb__dout + length > stb__barrier) { stb__dout += length; return; }
  9146. if (data < stb__barrier4) { stb__dout = stb__barrier+1; return; }
  9147. while (length--) *stb__dout++ = *data++;
  9148. }
  9149. static void stb__lit(stb_uchar *data, stb_uint length)
  9150. {
  9151. assert (stb__dout + length <= stb__barrier);
  9152. if (stb__dout + length > stb__barrier) { stb__dout += length; return; }
  9153. if (data < stb__barrier2) { stb__dout = stb__barrier+1; return; }
  9154. memcpy(stb__dout, data, length);
  9155. stb__dout += length;
  9156. }
  9157. #define stb__in2(x) ((i[x] << 8) + i[(x)+1])
  9158. #define stb__in3(x) ((i[x] << 16) + stb__in2((x)+1))
  9159. #define stb__in4(x) ((i[x] << 24) + stb__in3((x)+1))
  9160. static stb_uchar *stb_decompress_token(stb_uchar *i)
  9161. {
  9162. if (*i >= 0x20) { // use fewer if's for cases that expand small
  9163. if (*i >= 0x80) stb__match(stb__dout-i[1]-1, i[0] - 0x80 + 1), i += 2;
  9164. else if (*i >= 0x40) stb__match(stb__dout-(stb__in2(0) - 0x4000 + 1), i[2]+1), i += 3;
  9165. else /* *i >= 0x20 */ stb__lit(i+1, i[0] - 0x20 + 1), i += 1 + (i[0] - 0x20 + 1);
  9166. } else { // more ifs for cases that expand large, since overhead is amortized
  9167. if (*i >= 0x18) stb__match(stb__dout-(stb__in3(0) - 0x180000 + 1), i[3]+1), i += 4;
  9168. else if (*i >= 0x10) stb__match(stb__dout-(stb__in3(0) - 0x100000 + 1), stb__in2(3)+1), i += 5;
  9169. else if (*i >= 0x08) stb__lit(i+2, stb__in2(0) - 0x0800 + 1), i += 2 + (stb__in2(0) - 0x0800 + 1);
  9170. else if (*i == 0x07) stb__lit(i+3, stb__in2(1) + 1), i += 3 + (stb__in2(1) + 1);
  9171. else if (*i == 0x06) stb__match(stb__dout-(stb__in3(1)+1), i[4]+1), i += 5;
  9172. else if (*i == 0x04) stb__match(stb__dout-(stb__in3(1)+1), stb__in2(4)+1), i += 6;
  9173. }
  9174. return i;
  9175. }
  9176. stb_uint stb_decompress(stb_uchar *output, stb_uchar *i, stb_uint length)
  9177. {
  9178. stb_uint olen;
  9179. if (stb__in4(0) != 0x57bC0000) return 0;
  9180. if (stb__in4(4) != 0) return 0; // error! stream is > 4GB
  9181. olen = stb_decompress_length(i);
  9182. stb__barrier2 = i;
  9183. stb__barrier3 = i+length;
  9184. stb__barrier = output + olen;
  9185. stb__barrier4 = output;
  9186. i += 16;
  9187. stb__dout = output;
  9188. while (1) {
  9189. stb_uchar *old_i = i;
  9190. i = stb_decompress_token(i);
  9191. if (i == old_i) {
  9192. if (*i == 0x05 && i[1] == 0xfa) {
  9193. assert(stb__dout == output + olen);
  9194. if (stb__dout != output + olen) return 0;
  9195. if (stb_adler32(1, output, olen) != (stb_uint) stb__in4(2))
  9196. return 0;
  9197. return olen;
  9198. } else {
  9199. assert(0); /* NOTREACHED */
  9200. return 0;
  9201. }
  9202. }
  9203. assert(stb__dout <= output + olen);
  9204. if (stb__dout > output + olen)
  9205. return 0;
  9206. }
  9207. }
  9208. char *stb_decompress_fromfile(char *filename, unsigned int *len)
  9209. {
  9210. unsigned int n;
  9211. char *q;
  9212. unsigned char *p;
  9213. FILE *f = stb_p_fopen(filename, "rb"); if (f == NULL) return NULL;
  9214. fseek(f, 0, SEEK_END);
  9215. n = ftell(f);
  9216. fseek(f, 0, SEEK_SET);
  9217. p = (unsigned char * ) malloc(n); if (p == NULL) return NULL;
  9218. size_t _s = fread(p, 1, n, f);
  9219. fclose(f);
  9220. if (p == NULL) return NULL;
  9221. if (p[0] != 0x57 || p[1] != 0xBc || p[2] || p[3]) { free(p); return NULL; }
  9222. q = (char *) malloc(stb_decompress_length(p)+1);
  9223. if (!q) { free(p); return NULL; }
  9224. *len = stb_decompress((unsigned char *) q, p, n);
  9225. if (*len) q[*len] = 0;
  9226. free(p);
  9227. return q;
  9228. }
  9229. #if 0
  9230. // streaming decompressor
  9231. static struct
  9232. {
  9233. stb__uchar *in_buffer;
  9234. stb__uchar *match;
  9235. stb__uint pending_literals;
  9236. stb__uint pending_match;
  9237. } xx;
  9238. static void stb__match(stb_uchar *data, stb_uint length)
  9239. {
  9240. // INVERSE of memmove... write each byte before copying the next...
  9241. assert (stb__dout + length <= stb__barrier);
  9242. if (stb__dout + length > stb__barrier) { stb__dout += length; return; }
  9243. if (data < stb__barrier2) { stb__dout = stb__barrier+1; return; }
  9244. while (length--) *stb__dout++ = *data++;
  9245. }
  9246. static void stb__lit(stb_uchar *data, stb_uint length)
  9247. {
  9248. assert (stb__dout + length <= stb__barrier);
  9249. if (stb__dout + length > stb__barrier) { stb__dout += length; return; }
  9250. if (data < stb__barrier2) { stb__dout = stb__barrier+1; return; }
  9251. memcpy(stb__dout, data, length);
  9252. stb__dout += length;
  9253. }
  9254. static void sx_match(stb_uchar *data, stb_uint length)
  9255. {
  9256. xx.match = data;
  9257. xx.pending_match = length;
  9258. }
  9259. static void sx_lit(stb_uchar *data, stb_uint length)
  9260. {
  9261. xx.pending_lit = length;
  9262. }
  9263. static int stb_decompress_token_state(void)
  9264. {
  9265. stb__uchar *i = xx.in_buffer;
  9266. if (*i >= 0x20) { // use fewer if's for cases that expand small
  9267. if (*i >= 0x80) sx_match(stb__dout-i[1]-1, i[0] - 0x80 + 1), i += 2;
  9268. else if (*i >= 0x40) sx_match(stb__dout-(stb__in2(0) - 0x4000 + 1), i[2]+1), i += 3;
  9269. else /* *i >= 0x20 */ sx_lit(i+1, i[0] - 0x20 + 1), i += 1;
  9270. } else { // more ifs for cases that expand large, since overhead is amortized
  9271. if (*i >= 0x18) sx_match(stb__dout-(stb__in3(0) - 0x180000 + 1), i[3]+1), i += 4;
  9272. else if (*i >= 0x10) sx_match(stb__dout-(stb__in3(0) - 0x100000 + 1), stb__in2(3)+1), i += 5;
  9273. else if (*i >= 0x08) sx_lit(i+2, stb__in2(0) - 0x0800 + 1), i += 2;
  9274. else if (*i == 0x07) sx_lit(i+3, stb__in2(1) + 1), i += 3;
  9275. else if (*i == 0x06) sx_match(stb__dout-(stb__in3(1)+1), i[4]+1), i += 5;
  9276. else if (*i == 0x04) sx_match(stb__dout-(stb__in3(1)+1), stb__in2(4)+1), i += 6;
  9277. else return 0;
  9278. }
  9279. xx.in_buffer = i;
  9280. return 1;
  9281. }
  9282. #endif
  9283. //////////////////// compressor ///////////////////////
  9284. static unsigned int stb_matchlen(stb_uchar *m1, stb_uchar *m2, stb_uint maxlen)
  9285. {
  9286. stb_uint i;
  9287. for (i=0; i < maxlen; ++i)
  9288. if (m1[i] != m2[i]) return i;
  9289. return i;
  9290. }
  9291. // simple implementation that just takes the source data in a big block
  9292. static stb_uchar *stb__out;
  9293. static FILE *stb__outfile;
  9294. static stb_uint stb__outbytes;
  9295. static void stb__write(unsigned char v)
  9296. {
  9297. fputc(v, stb__outfile);
  9298. ++stb__outbytes;
  9299. }
  9300. #define stb_out(v) (stb__out ? (void)(*stb__out++ = (stb_uchar) (v)) : stb__write((stb_uchar) (v)))
  9301. static void stb_out2(stb_uint v)
  9302. {
  9303. stb_out(v >> 8);
  9304. stb_out(v);
  9305. }
  9306. static void stb_out3(stb_uint v) { stb_out(v >> 16); stb_out(v >> 8); stb_out(v); }
  9307. static void stb_out4(stb_uint v) { stb_out(v >> 24); stb_out(v >> 16);
  9308. stb_out(v >> 8 ); stb_out(v); }
  9309. static void outliterals(stb_uchar *in, ptrdiff_t numlit)
  9310. {
  9311. while (numlit > 65536) {
  9312. outliterals(in,65536);
  9313. in += 65536;
  9314. numlit -= 65536;
  9315. }
  9316. if (numlit == 0) ;
  9317. else if (numlit <= 32) stb_out (0x000020 + (stb_uint) numlit-1);
  9318. else if (numlit <= 2048) stb_out2(0x000800 + (stb_uint) numlit-1);
  9319. else /* numlit <= 65536) */ stb_out3(0x070000 + (stb_uint) numlit-1);
  9320. if (stb__out) {
  9321. memcpy(stb__out,in,numlit);
  9322. stb__out += numlit;
  9323. } else
  9324. fwrite(in, 1, numlit, stb__outfile);
  9325. }
  9326. static int stb__window = 0x40000; // 256K
  9327. void stb_compress_window(int z)
  9328. {
  9329. if (z >= 0x1000000) z = 0x1000000; // limit of implementation
  9330. if (z < 0x100) z = 0x100; // insanely small
  9331. stb__window = z;
  9332. }
  9333. static int stb_not_crap(int best, int dist)
  9334. {
  9335. return ((best > 2 && dist <= 0x00100)
  9336. || (best > 5 && dist <= 0x04000)
  9337. || (best > 7 && dist <= 0x80000));
  9338. }
  9339. static stb_uint stb__hashsize = 32768;
  9340. void stb_compress_hashsize(unsigned int y)
  9341. {
  9342. unsigned int z = 1024;
  9343. while (z < y) z <<= 1;
  9344. stb__hashsize = z >> 2; // pass in bytes, store #pointers
  9345. }
  9346. // note that you can play with the hashing functions all you
  9347. // want without needing to change the decompressor
  9348. #define stb__hc(q,h,c) (((h) << 7) + ((h) >> 25) + q[c])
  9349. #define stb__hc2(q,h,c,d) (((h) << 14) + ((h) >> 18) + (q[c] << 7) + q[d])
  9350. #define stb__hc3(q,c,d,e) ((q[c] << 14) + (q[d] << 7) + q[e])
  9351. static stb_uint32 stb__running_adler;
  9352. static int stb_compress_chunk(stb_uchar *history,
  9353. stb_uchar *start,
  9354. stb_uchar *end,
  9355. int length,
  9356. int *pending_literals,
  9357. stb_uchar **chash,
  9358. stb_uint mask)
  9359. {
  9360. int window = stb__window;
  9361. stb_uint match_max;
  9362. stb_uchar *lit_start = start - *pending_literals;
  9363. stb_uchar *q = start;
  9364. #define STB__SCRAMBLE(h) (((h) + ((h) >> 16)) & mask)
  9365. // stop short of the end so we don't scan off the end doing
  9366. // the hashing; this means we won't compress the last few bytes
  9367. // unless they were part of something longer
  9368. while (q < start+length && q+12 < end) {
  9369. int m;
  9370. stb_uint h1,h2,h3,h4, h;
  9371. stb_uchar *t;
  9372. int best = 2, dist=0;
  9373. if (q+65536 > end)
  9374. match_max = (stb_uint) (end-q);
  9375. else
  9376. match_max = 65536u;
  9377. #define stb__nc(b,d) ((d) <= window && ((b) > 9 || stb_not_crap(b,d)))
  9378. #define STB__TRY(t,p) /* avoid retrying a match we already tried */ \
  9379. if (p ? dist != (int) (q-t) : 1) \
  9380. if ((m = (int) stb_matchlen(t, q, match_max)) > best)\
  9381. if (stb__nc(m,(int) (q-(t)))) \
  9382. best = m, dist = (int) (q - (t))
  9383. // rather than search for all matches, only try 4 candidate locations,
  9384. // chosen based on 4 different hash functions of different lengths.
  9385. // this strategy is inspired by LZO; hashing is unrolled here using the
  9386. // 'hc' macro
  9387. h = stb__hc3(q,0, 1, 2); h1 = STB__SCRAMBLE(h);
  9388. t = chash[h1]; if (t) STB__TRY(t,0);
  9389. h = stb__hc2(q,h, 3, 4); h2 = STB__SCRAMBLE(h);
  9390. h = stb__hc2(q,h, 5, 6); t = chash[h2]; if (t) STB__TRY(t,1);
  9391. h = stb__hc2(q,h, 7, 8); h3 = STB__SCRAMBLE(h);
  9392. h = stb__hc2(q,h, 9,10); t = chash[h3]; if (t) STB__TRY(t,1);
  9393. h = stb__hc2(q,h,11,12); h4 = STB__SCRAMBLE(h);
  9394. t = chash[h4]; if (t) STB__TRY(t,1);
  9395. // because we use a shared hash table, can only update it
  9396. // _after_ we've probed all of them
  9397. chash[h1] = chash[h2] = chash[h3] = chash[h4] = q;
  9398. if (best > 2)
  9399. assert(dist > 0);
  9400. // see if our best match qualifies
  9401. if (best < 3) { // fast path literals
  9402. ++q;
  9403. } else if (best > 2 && best <= 0x80 && dist <= 0x100) {
  9404. outliterals(lit_start, q-lit_start); lit_start = (q += best);
  9405. stb_out(0x80 + best-1);
  9406. stb_out(dist-1);
  9407. } else if (best > 5 && best <= 0x100 && dist <= 0x4000) {
  9408. outliterals(lit_start, q-lit_start); lit_start = (q += best);
  9409. stb_out2(0x4000 + dist-1);
  9410. stb_out(best-1);
  9411. } else if (best > 7 && best <= 0x100 && dist <= 0x80000) {
  9412. outliterals(lit_start, q-lit_start); lit_start = (q += best);
  9413. stb_out3(0x180000 + dist-1);
  9414. stb_out(best-1);
  9415. } else if (best > 8 && best <= 0x10000 && dist <= 0x80000) {
  9416. outliterals(lit_start, q-lit_start); lit_start = (q += best);
  9417. stb_out3(0x100000 + dist-1);
  9418. stb_out2(best-1);
  9419. } else if (best > 9 && dist <= 0x1000000) {
  9420. if (best > 65536) best = 65536;
  9421. outliterals(lit_start, q-lit_start); lit_start = (q += best);
  9422. if (best <= 0x100) {
  9423. stb_out(0x06);
  9424. stb_out3(dist-1);
  9425. stb_out(best-1);
  9426. } else {
  9427. stb_out(0x04);
  9428. stb_out3(dist-1);
  9429. stb_out2(best-1);
  9430. }
  9431. } else { // fallback literals if no match was a balanced tradeoff
  9432. ++q;
  9433. }
  9434. }
  9435. // if we didn't get all the way, add the rest to literals
  9436. if (q-start < length)
  9437. q = start+length;
  9438. // the literals are everything from lit_start to q
  9439. *pending_literals = (int) (q - lit_start);
  9440. stb__running_adler = stb_adler32(stb__running_adler, start, (int) (q - start));
  9441. return (int) (q - start);
  9442. }
  9443. static int stb_compress_inner(stb_uchar *input, stb_uint length)
  9444. {
  9445. int literals = 0;
  9446. stb_uint len,i;
  9447. stb_uchar **chash;
  9448. chash = (stb_uchar**) malloc(stb__hashsize * sizeof(stb_uchar*));
  9449. if (chash == NULL) return 0; // failure
  9450. for (i=0; i < stb__hashsize; ++i)
  9451. chash[i] = NULL;
  9452. // stream signature
  9453. stb_out(0x57); stb_out(0xbc);
  9454. stb_out2(0);
  9455. stb_out4(0); // 64-bit length requires 32-bit leading 0
  9456. stb_out4(length);
  9457. stb_out4(stb__window);
  9458. stb__running_adler = 1;
  9459. len = stb_compress_chunk(input, input, input+length, length, &literals, chash, stb__hashsize-1);
  9460. assert(len == length);
  9461. outliterals(input+length - literals, literals);
  9462. free(chash);
  9463. stb_out2(0x05fa); // end opcode
  9464. stb_out4(stb__running_adler);
  9465. return 1; // success
  9466. }
  9467. stb_uint stb_compress(stb_uchar *out, stb_uchar *input, stb_uint length)
  9468. {
  9469. stb__out = out;
  9470. stb__outfile = NULL;
  9471. stb_compress_inner(input, length);
  9472. return (stb_uint) (stb__out - out);
  9473. }
  9474. int stb_compress_tofile(char *filename, char *input, unsigned int length)
  9475. {
  9476. //int maxlen = length + 512 + (length >> 2); // total guess
  9477. //char *buffer = (char *) malloc(maxlen);
  9478. //int blen = stb_compress((stb_uchar*)buffer, (stb_uchar*)input, length);
  9479. stb__out = NULL;
  9480. stb__outfile = stb_p_fopen(filename, "wb");
  9481. if (!stb__outfile) return 0;
  9482. stb__outbytes = 0;
  9483. if (!stb_compress_inner((stb_uchar*)input, length))
  9484. return 0;
  9485. fclose(stb__outfile);
  9486. return stb__outbytes;
  9487. }
  9488. int stb_compress_intofile(FILE *f, char *input, unsigned int length)
  9489. {
  9490. //int maxlen = length + 512 + (length >> 2); // total guess
  9491. //char *buffer = (char*)malloc(maxlen);
  9492. //int blen = stb_compress((stb_uchar*)buffer, (stb_uchar*)input, length);
  9493. stb__out = NULL;
  9494. stb__outfile = f;
  9495. if (!stb__outfile) return 0;
  9496. stb__outbytes = 0;
  9497. if (!stb_compress_inner((stb_uchar*)input, length))
  9498. return 0;
  9499. return stb__outbytes;
  9500. }
  9501. ////////////////////// streaming I/O version /////////////////////
  9502. static size_t stb_out_backpatch_id(void)
  9503. {
  9504. if (stb__out)
  9505. return (size_t) stb__out;
  9506. else
  9507. return ftell(stb__outfile);
  9508. }
  9509. static void stb_out_backpatch(size_t id, stb_uint value)
  9510. {
  9511. stb_uchar data[4] = { (stb_uchar)(value >> 24), (stb_uchar)(value >> 16), (stb_uchar)(value >> 8), (stb_uchar)(value) };
  9512. if (stb__out) {
  9513. memcpy((void *) id, data, 4);
  9514. } else {
  9515. stb_uint where = ftell(stb__outfile);
  9516. fseek(stb__outfile, (long) id, SEEK_SET);
  9517. fwrite(data, 4, 1, stb__outfile);
  9518. fseek(stb__outfile, where, SEEK_SET);
  9519. }
  9520. }
  9521. // ok, the wraparound buffer was a total failure. let's instead
  9522. // use a copying-in-place buffer, which lets us share the code.
  9523. // This is way less efficient but it'll do for now.
  9524. static struct
  9525. {
  9526. stb_uchar *buffer;
  9527. int size; // physical size of buffer in bytes
  9528. int valid; // amount of valid data in bytes
  9529. int start; // bytes of data already output
  9530. int window;
  9531. int fsize;
  9532. int pending_literals; // bytes not-quite output but counted in start
  9533. int length_id;
  9534. stb_uint total_bytes;
  9535. stb_uchar **chash;
  9536. stb_uint hashmask;
  9537. } xtb;
  9538. static int stb_compress_streaming_start(void)
  9539. {
  9540. stb_uint i;
  9541. xtb.size = stb__window * 3;
  9542. xtb.buffer = (stb_uchar*)malloc(xtb.size);
  9543. if (!xtb.buffer) return 0;
  9544. xtb.chash = (stb_uchar**)malloc(sizeof(*xtb.chash) * stb__hashsize);
  9545. if (!xtb.chash) {
  9546. free(xtb.buffer);
  9547. return 0;
  9548. }
  9549. for (i=0; i < stb__hashsize; ++i)
  9550. xtb.chash[i] = NULL;
  9551. xtb.hashmask = stb__hashsize-1;
  9552. xtb.valid = 0;
  9553. xtb.start = 0;
  9554. xtb.window = stb__window;
  9555. xtb.fsize = stb__window;
  9556. xtb.pending_literals = 0;
  9557. xtb.total_bytes = 0;
  9558. // stream signature
  9559. stb_out(0x57); stb_out(0xbc); stb_out2(0);
  9560. stb_out4(0); // 64-bit length requires 32-bit leading 0
  9561. xtb.length_id = (int) stb_out_backpatch_id();
  9562. stb_out4(0); // we don't know the output length yet
  9563. stb_out4(stb__window);
  9564. stb__running_adler = 1;
  9565. return 1;
  9566. }
  9567. static int stb_compress_streaming_end(void)
  9568. {
  9569. // flush out any remaining data
  9570. stb_compress_chunk(xtb.buffer, xtb.buffer+xtb.start, xtb.buffer+xtb.valid,
  9571. xtb.valid-xtb.start, &xtb.pending_literals, xtb.chash, xtb.hashmask);
  9572. // write out pending literals
  9573. outliterals(xtb.buffer + xtb.valid - xtb.pending_literals, xtb.pending_literals);
  9574. stb_out2(0x05fa); // end opcode
  9575. stb_out4(stb__running_adler);
  9576. stb_out_backpatch(xtb.length_id, xtb.total_bytes);
  9577. free(xtb.buffer);
  9578. free(xtb.chash);
  9579. return 1;
  9580. }
  9581. void stb_write(char *data, int data_len)
  9582. {
  9583. stb_uint i;
  9584. // @TODO: fast path for filling the buffer and doing nothing else
  9585. // if (xtb.valid + data_len < xtb.size)
  9586. xtb.total_bytes += data_len;
  9587. while (data_len) {
  9588. // fill buffer
  9589. if (xtb.valid < xtb.size) {
  9590. int amt = xtb.size - xtb.valid;
  9591. if (data_len < amt) amt = data_len;
  9592. memcpy(xtb.buffer + xtb.valid, data, amt);
  9593. data_len -= amt;
  9594. data += amt;
  9595. xtb.valid += amt;
  9596. }
  9597. if (xtb.valid < xtb.size)
  9598. return;
  9599. // at this point, the buffer is full
  9600. // if we can process some data, go for it; make sure
  9601. // we leave an 'fsize's worth of data, though
  9602. if (xtb.start + xtb.fsize < xtb.valid) {
  9603. int amount = (xtb.valid - xtb.fsize) - xtb.start;
  9604. int n;
  9605. assert(amount > 0);
  9606. n = stb_compress_chunk(xtb.buffer, xtb.buffer + xtb.start, xtb.buffer + xtb.valid,
  9607. amount, &xtb.pending_literals, xtb.chash, xtb.hashmask);
  9608. xtb.start += n;
  9609. }
  9610. assert(xtb.start + xtb.fsize >= xtb.valid);
  9611. // at this point, our future size is too small, so we
  9612. // need to flush some history. we, in fact, flush exactly
  9613. // one window's worth of history
  9614. {
  9615. int flush = xtb.window;
  9616. assert(xtb.start >= flush);
  9617. assert(xtb.valid >= flush);
  9618. // if 'pending literals' extends back into the shift region,
  9619. // write them out
  9620. if (xtb.start - xtb.pending_literals < flush) {
  9621. outliterals(xtb.buffer + xtb.start - xtb.pending_literals, xtb.pending_literals);
  9622. xtb.pending_literals = 0;
  9623. }
  9624. // now shift the window
  9625. memmove(xtb.buffer, xtb.buffer + flush, xtb.valid - flush);
  9626. xtb.start -= flush;
  9627. xtb.valid -= flush;
  9628. for (i=0; i <= xtb.hashmask; ++i)
  9629. if (xtb.chash[i] < xtb.buffer + flush)
  9630. xtb.chash[i] = NULL;
  9631. else
  9632. xtb.chash[i] -= flush;
  9633. }
  9634. // and now that we've made room for more data, go back to the top
  9635. }
  9636. }
  9637. int stb_compress_stream_start(FILE *f)
  9638. {
  9639. stb__out = NULL;
  9640. stb__outfile = f;
  9641. if (f == NULL)
  9642. return 0;
  9643. if (!stb_compress_streaming_start())
  9644. return 0;
  9645. return 1;
  9646. }
  9647. void stb_compress_stream_end(int close)
  9648. {
  9649. stb_compress_streaming_end();
  9650. if (close && stb__outfile) {
  9651. fclose(stb__outfile);
  9652. }
  9653. }
  9654. #endif // STB_DEFINE
  9655. //////////////////////////////////////////////////////////////////////////////
  9656. //
  9657. // File abstraction... tired of not having this... we can write
  9658. // compressors to be layers over these that auto-close their children.
  9659. typedef struct stbfile
  9660. {
  9661. int (*getbyte)(struct stbfile *); // -1 on EOF
  9662. unsigned int (*getdata)(struct stbfile *, void *block, unsigned int len);
  9663. int (*putbyte)(struct stbfile *, int byte);
  9664. unsigned int (*putdata)(struct stbfile *, void *block, unsigned int len);
  9665. unsigned int (*size)(struct stbfile *);
  9666. unsigned int (*tell)(struct stbfile *);
  9667. void (*backpatch)(struct stbfile *, unsigned int tell, void *block, unsigned int len);
  9668. void (*close)(struct stbfile *);
  9669. FILE *f; // file to fread/fwrite
  9670. unsigned char *buffer; // input/output buffer
  9671. unsigned char *indata, *inend; // input buffer
  9672. union {
  9673. int various;
  9674. void *ptr;
  9675. };
  9676. } stbfile;
  9677. STB_EXTERN unsigned int stb_getc(stbfile *f); // read
  9678. STB_EXTERN int stb_putc(stbfile *f, int ch); // write
  9679. STB_EXTERN unsigned int stb_getdata(stbfile *f, void *buffer, unsigned int len); // read
  9680. STB_EXTERN unsigned int stb_putdata(stbfile *f, void *buffer, unsigned int len); // write
  9681. STB_EXTERN unsigned int stb_tell(stbfile *f); // read
  9682. STB_EXTERN unsigned int stb_size(stbfile *f); // read/write
  9683. STB_EXTERN void stb_backpatch(stbfile *f, unsigned int tell, void *buffer, unsigned int len); // write
  9684. #ifdef STB_DEFINE
  9685. unsigned int stb_getc(stbfile *f) { return f->getbyte(f); }
  9686. int stb_putc(stbfile *f, int ch) { return f->putbyte(f, ch); }
  9687. unsigned int stb_getdata(stbfile *f, void *buffer, unsigned int len)
  9688. {
  9689. return f->getdata(f, buffer, len);
  9690. }
  9691. unsigned int stb_putdata(stbfile *f, void *buffer, unsigned int len)
  9692. {
  9693. return f->putdata(f, buffer, len);
  9694. }
  9695. void stb_close(stbfile *f)
  9696. {
  9697. f->close(f);
  9698. free(f);
  9699. }
  9700. unsigned int stb_tell(stbfile *f) { return f->tell(f); }
  9701. unsigned int stb_size(stbfile *f) { return f->size(f); }
  9702. void stb_backpatch(stbfile *f, unsigned int tell, void *buffer, unsigned int len)
  9703. {
  9704. f->backpatch(f,tell,buffer,len);
  9705. }
  9706. // FILE * implementation
  9707. static int stb__fgetbyte(stbfile *f) { return fgetc(f->f); }
  9708. static int stb__fputbyte(stbfile *f, int ch) { return fputc(ch, f->f)==0; }
  9709. static unsigned int stb__fgetdata(stbfile *f, void *buffer, unsigned int len) { return (unsigned int) fread(buffer,1,len,f->f); }
  9710. static unsigned int stb__fputdata(stbfile *f, void *buffer, unsigned int len) { return (unsigned int) fwrite(buffer,1,len,f->f); }
  9711. static unsigned int stb__fsize(stbfile *f) { return (unsigned int) stb_filelen(f->f); }
  9712. static unsigned int stb__ftell(stbfile *f) { return (unsigned int) ftell(f->f); }
  9713. static void stb__fbackpatch(stbfile *f, unsigned int where, void *buffer, unsigned int len)
  9714. {
  9715. fseek(f->f, where, SEEK_SET);
  9716. fwrite(buffer, 1, len, f->f);
  9717. fseek(f->f, 0, SEEK_END);
  9718. }
  9719. static void stb__fclose(stbfile *f) { fclose(f->f); }
  9720. stbfile *stb_openf(FILE *f)
  9721. {
  9722. stbfile m = { stb__fgetbyte, stb__fgetdata,
  9723. stb__fputbyte, stb__fputdata,
  9724. stb__fsize, stb__ftell, stb__fbackpatch, stb__fclose,
  9725. 0,0,0, };
  9726. stbfile *z = (stbfile *) malloc(sizeof(*z));
  9727. if (z) {
  9728. *z = m;
  9729. z->f = f;
  9730. }
  9731. return z;
  9732. }
  9733. static int stb__nogetbyte(stbfile *f) { assert(0); return -1; }
  9734. static unsigned int stb__nogetdata(stbfile *f, void *buffer, unsigned int len) { assert(0); return 0; }
  9735. static int stb__noputbyte(stbfile *f, int ch) { assert(0); return 0; }
  9736. static unsigned int stb__noputdata(stbfile *f, void *buffer, unsigned int len) { assert(0); return 0; }
  9737. static void stb__nobackpatch(stbfile *f, unsigned int where, void *buffer, unsigned int len) { assert(0); }
  9738. static int stb__bgetbyte(stbfile *s)
  9739. {
  9740. if (s->indata < s->inend)
  9741. return *s->indata++;
  9742. else
  9743. return -1;
  9744. }
  9745. static unsigned int stb__bgetdata(stbfile *s, void *buffer, unsigned int len)
  9746. {
  9747. if (s->indata + len > s->inend)
  9748. len = (unsigned int) (s->inend - s->indata);
  9749. memcpy(buffer, s->indata, len);
  9750. s->indata += len;
  9751. return len;
  9752. }
  9753. static unsigned int stb__bsize(stbfile *s) { return (unsigned int) (s->inend - s->buffer); }
  9754. static unsigned int stb__btell(stbfile *s) { return (unsigned int) (s->indata - s->buffer); }
  9755. static void stb__bclose(stbfile *s)
  9756. {
  9757. if (s->various)
  9758. free(s->buffer);
  9759. }
  9760. stbfile *stb_open_inbuffer(void *buffer, unsigned int len)
  9761. {
  9762. stbfile m = { stb__bgetbyte, stb__bgetdata,
  9763. stb__noputbyte, stb__noputdata,
  9764. stb__bsize, stb__btell, stb__nobackpatch, stb__bclose };
  9765. stbfile *z = (stbfile *) malloc(sizeof(*z));
  9766. if (z) {
  9767. *z = m;
  9768. z->buffer = (unsigned char *) buffer;
  9769. z->indata = z->buffer;
  9770. z->inend = z->indata + len;
  9771. }
  9772. return z;
  9773. }
  9774. stbfile *stb_open_inbuffer_free(void *buffer, unsigned int len)
  9775. {
  9776. stbfile *z = stb_open_inbuffer(buffer, len);
  9777. if (z)
  9778. z->various = 1; // free
  9779. return z;
  9780. }
  9781. #ifndef STB_VERSION
  9782. // if we've been cut-and-pasted elsewhere, you get a limited
  9783. // version of stb_open, without the 'k' flag and utf8 support
  9784. static void stb__fclose2(stbfile *f)
  9785. {
  9786. fclose(f->f);
  9787. }
  9788. stbfile *stb_open(char *filename, char *mode)
  9789. {
  9790. FILE *f = stb_p_fopen(filename, mode);
  9791. stbfile *s;
  9792. if (f == NULL) return NULL;
  9793. s = stb_openf(f);
  9794. if (s)
  9795. s->close = stb__fclose2;
  9796. return s;
  9797. }
  9798. #else
  9799. // the full version depends on some code in stb.h; this
  9800. // also includes the memory buffer output format implemented with stb_arr
  9801. static void stb__fclose2(stbfile *f)
  9802. {
  9803. stb_fclose(f->f, f->various);
  9804. }
  9805. stbfile *stb_open(char *filename, char *mode)
  9806. {
  9807. FILE *f = stb_fopen(filename, mode[0] == 'k' ? mode+1 : mode);
  9808. stbfile *s;
  9809. if (f == NULL) return NULL;
  9810. s = stb_openf(f);
  9811. if (s) {
  9812. s->close = stb__fclose2;
  9813. s->various = mode[0] == 'k' ? stb_keep_if_different : stb_keep_yes;
  9814. }
  9815. return s;
  9816. }
  9817. static int stb__aputbyte(stbfile *f, int ch)
  9818. {
  9819. stb_arr_push(f->buffer, ch);
  9820. return 1;
  9821. }
  9822. static unsigned int stb__aputdata(stbfile *f, void *data, unsigned int len)
  9823. {
  9824. memcpy(stb_arr_addn(f->buffer, (int) len), data, len);
  9825. return len;
  9826. }
  9827. static unsigned int stb__asize(stbfile *f) { return stb_arr_len(f->buffer); }
  9828. static void stb__abackpatch(stbfile *f, unsigned int where, void *data, unsigned int len)
  9829. {
  9830. memcpy(f->buffer+where, data, len);
  9831. }
  9832. static void stb__aclose(stbfile *f)
  9833. {
  9834. *(unsigned char **) f->ptr = f->buffer;
  9835. }
  9836. stbfile *stb_open_outbuffer(unsigned char **update_on_close)
  9837. {
  9838. stbfile m = { stb__nogetbyte, stb__nogetdata,
  9839. stb__aputbyte, stb__aputdata,
  9840. stb__asize, stb__asize, stb__abackpatch, stb__aclose };
  9841. stbfile *z = (stbfile *) malloc(sizeof(*z));
  9842. if (z) {
  9843. z->ptr = update_on_close;
  9844. *z = m;
  9845. }
  9846. return z;
  9847. }
  9848. #endif
  9849. #endif
  9850. //////////////////////////////////////////////////////////////////////////////
  9851. //
  9852. // Arithmetic coder... based on cbloom's notes on the subject, should be
  9853. // less code than a huffman code.
  9854. typedef struct
  9855. {
  9856. unsigned int range_low;
  9857. unsigned int range_high;
  9858. unsigned int code, range; // decode
  9859. int buffered_u8;
  9860. int pending_ffs;
  9861. stbfile *output;
  9862. } stb_arith;
  9863. STB_EXTERN void stb_arith_init_encode(stb_arith *a, stbfile *out);
  9864. STB_EXTERN void stb_arith_init_decode(stb_arith *a, stbfile *in);
  9865. STB_EXTERN stbfile *stb_arith_encode_close(stb_arith *a);
  9866. STB_EXTERN stbfile *stb_arith_decode_close(stb_arith *a);
  9867. STB_EXTERN void stb_arith_encode(stb_arith *a, unsigned int totalfreq, unsigned int freq, unsigned int cumfreq);
  9868. STB_EXTERN void stb_arith_encode_log2(stb_arith *a, unsigned int totalfreq2, unsigned int freq, unsigned int cumfreq);
  9869. STB_EXTERN unsigned int stb_arith_decode_value(stb_arith *a, unsigned int totalfreq);
  9870. STB_EXTERN void stb_arith_decode_advance(stb_arith *a, unsigned int totalfreq, unsigned int freq, unsigned int cumfreq);
  9871. STB_EXTERN unsigned int stb_arith_decode_value_log2(stb_arith *a, unsigned int totalfreq2);
  9872. STB_EXTERN void stb_arith_decode_advance_log2(stb_arith *a, unsigned int totalfreq2, unsigned int freq, unsigned int cumfreq);
  9873. STB_EXTERN void stb_arith_encode_byte(stb_arith *a, int byte);
  9874. STB_EXTERN int stb_arith_decode_byte(stb_arith *a);
  9875. // this is a memory-inefficient way of doing things, but it's
  9876. // fast(?) and simple
  9877. typedef struct
  9878. {
  9879. unsigned short cumfreq;
  9880. unsigned short samples;
  9881. } stb_arith_symstate_item;
  9882. typedef struct
  9883. {
  9884. int num_sym;
  9885. unsigned int pow2;
  9886. int countdown;
  9887. stb_arith_symstate_item data[1];
  9888. } stb_arith_symstate;
  9889. #ifdef STB_DEFINE
  9890. void stb_arith_init_encode(stb_arith *a, stbfile *out)
  9891. {
  9892. a->range_low = 0;
  9893. a->range_high = 0xffffffff;
  9894. a->pending_ffs = -1; // means no buffered character currently, to speed up normal case
  9895. a->output = out;
  9896. }
  9897. static void stb__arith_carry(stb_arith *a)
  9898. {
  9899. int i;
  9900. assert(a->pending_ffs != -1); // can't carry with no data
  9901. stb_putc(a->output, a->buffered_u8);
  9902. for (i=0; i < a->pending_ffs; ++i)
  9903. stb_putc(a->output, 0);
  9904. }
  9905. static void stb__arith_putbyte(stb_arith *a, int byte)
  9906. {
  9907. if (a->pending_ffs) {
  9908. if (a->pending_ffs == -1) { // means no buffered data; encoded for fast path efficiency
  9909. if (byte == 0xff)
  9910. stb_putc(a->output, byte); // just write it immediately
  9911. else {
  9912. a->buffered_u8 = byte;
  9913. a->pending_ffs = 0;
  9914. }
  9915. } else if (byte == 0xff) {
  9916. ++a->pending_ffs;
  9917. } else {
  9918. int i;
  9919. stb_putc(a->output, a->buffered_u8);
  9920. for (i=0; i < a->pending_ffs; ++i)
  9921. stb_putc(a->output, 0xff);
  9922. }
  9923. } else if (byte == 0xff) {
  9924. ++a->pending_ffs;
  9925. } else {
  9926. // fast path
  9927. stb_putc(a->output, a->buffered_u8);
  9928. a->buffered_u8 = byte;
  9929. }
  9930. }
  9931. static void stb__arith_flush(stb_arith *a)
  9932. {
  9933. if (a->pending_ffs >= 0) {
  9934. int i;
  9935. stb_putc(a->output, a->buffered_u8);
  9936. for (i=0; i < a->pending_ffs; ++i)
  9937. stb_putc(a->output, 0xff);
  9938. }
  9939. }
  9940. static void stb__renorm_encoder(stb_arith *a)
  9941. {
  9942. stb__arith_putbyte(a, a->range_low >> 24);
  9943. a->range_low <<= 8;
  9944. a->range_high = (a->range_high << 8) | 0xff;
  9945. }
  9946. static void stb__renorm_decoder(stb_arith *a)
  9947. {
  9948. int c = stb_getc(a->output);
  9949. a->code = (a->code << 8) + (c >= 0 ? c : 0); // if EOF, insert 0
  9950. }
  9951. void stb_arith_encode(stb_arith *a, unsigned int totalfreq, unsigned int freq, unsigned int cumfreq)
  9952. {
  9953. unsigned int range = a->range_high - a->range_low;
  9954. unsigned int old = a->range_low;
  9955. range /= totalfreq;
  9956. a->range_low += range * cumfreq;
  9957. a->range_high = a->range_low + range*freq;
  9958. if (a->range_low < old)
  9959. stb__arith_carry(a);
  9960. while (a->range_high - a->range_low < 0x1000000)
  9961. stb__renorm_encoder(a);
  9962. }
  9963. void stb_arith_encode_log2(stb_arith *a, unsigned int totalfreq2, unsigned int freq, unsigned int cumfreq)
  9964. {
  9965. unsigned int range = a->range_high - a->range_low;
  9966. unsigned int old = a->range_low;
  9967. range >>= totalfreq2;
  9968. a->range_low += range * cumfreq;
  9969. a->range_high = a->range_low + range*freq;
  9970. if (a->range_low < old)
  9971. stb__arith_carry(a);
  9972. while (a->range_high - a->range_low < 0x1000000)
  9973. stb__renorm_encoder(a);
  9974. }
  9975. unsigned int stb_arith_decode_value(stb_arith *a, unsigned int totalfreq)
  9976. {
  9977. unsigned int freqsize = a->range / totalfreq;
  9978. unsigned int z = a->code / freqsize;
  9979. return z >= totalfreq ? totalfreq-1 : z;
  9980. }
  9981. void stb_arith_decode_advance(stb_arith *a, unsigned int totalfreq, unsigned int freq, unsigned int cumfreq)
  9982. {
  9983. unsigned int freqsize = a->range / totalfreq; // @OPTIMIZE, share with above divide somehow?
  9984. a->code -= freqsize * cumfreq;
  9985. a->range = freqsize * freq;
  9986. while (a->range < 0x1000000)
  9987. stb__renorm_decoder(a);
  9988. }
  9989. unsigned int stb_arith_decode_value_log2(stb_arith *a, unsigned int totalfreq2)
  9990. {
  9991. unsigned int freqsize = a->range >> totalfreq2;
  9992. unsigned int z = a->code / freqsize;
  9993. return z >= (1U<<totalfreq2) ? (1U<<totalfreq2)-1 : z;
  9994. }
  9995. void stb_arith_decode_advance_log2(stb_arith *a, unsigned int totalfreq2, unsigned int freq, unsigned int cumfreq)
  9996. {
  9997. unsigned int freqsize = a->range >> totalfreq2;
  9998. a->code -= freqsize * cumfreq;
  9999. a->range = freqsize * freq;
  10000. while (a->range < 0x1000000)
  10001. stb__renorm_decoder(a);
  10002. }
  10003. stbfile *stb_arith_encode_close(stb_arith *a)
  10004. {
  10005. // put exactly as many bytes as we'll read, so we can turn on/off arithmetic coding in a stream
  10006. stb__arith_putbyte(a, a->range_low >> 24);
  10007. stb__arith_putbyte(a, a->range_low >> 16);
  10008. stb__arith_putbyte(a, a->range_low >> 8);
  10009. stb__arith_putbyte(a, a->range_low >> 0);
  10010. stb__arith_flush(a);
  10011. return a->output;
  10012. }
  10013. stbfile *stb_arith_decode_close(stb_arith *a)
  10014. {
  10015. return a->output;
  10016. }
  10017. #endif
  10018. //////////////////////////////////////////////////////////////////////////////
  10019. //
  10020. // Threads
  10021. //
  10022. #ifndef _WIN32
  10023. #ifdef STB_THREADS
  10024. #error "threads not implemented except for Windows"
  10025. #endif
  10026. #endif
  10027. // call this function to free any global variables for memory testing
  10028. STB_EXTERN void stb_thread_cleanup(void);
  10029. typedef void * (*stb_thread_func)(void *);
  10030. // do not rely on these types, this is an implementation detail.
  10031. // compare against STB_THREAD_NULL and ST_SEMAPHORE_NULL
  10032. typedef void *stb_thread;
  10033. typedef void *stb_semaphore;
  10034. typedef void *stb_mutex;
  10035. typedef struct stb__sync *stb_sync;
  10036. #define STB_SEMAPHORE_NULL NULL
  10037. #define STB_THREAD_NULL NULL
  10038. #define STB_MUTEX_NULL NULL
  10039. #define STB_SYNC_NULL NULL
  10040. // get the number of processors (limited to those in the affinity mask for this process).
  10041. STB_EXTERN int stb_processor_count(void);
  10042. // force to run on a single core -- needed for RDTSC to work, e.g. for iprof
  10043. STB_EXTERN void stb_force_uniprocessor(void);
  10044. // stb_work functions: queue up work to be done by some worker threads
  10045. // set number of threads to serve the queue; you can change this on the fly,
  10046. // but if you decrease it, it won't decrease until things currently on the
  10047. // queue are finished
  10048. STB_EXTERN void stb_work_numthreads(int n);
  10049. // set maximum number of units in the queue; you can only set this BEFORE running any work functions
  10050. STB_EXTERN int stb_work_maxunits(int n);
  10051. // enqueue some work to be done (can do this from any thread, or even from a piece of work);
  10052. // return value of f is stored in *return_code if non-NULL
  10053. STB_EXTERN int stb_work(stb_thread_func f, void *d, volatile void **return_code);
  10054. // as above, but stb_sync_reach is called on 'rel' after work is complete
  10055. STB_EXTERN int stb_work_reach(stb_thread_func f, void *d, volatile void **return_code, stb_sync rel);
  10056. // necessary to call this when using volatile to order writes/reads
  10057. STB_EXTERN void stb_barrier(void);
  10058. // support for independent queues with their own threads
  10059. typedef struct stb__workqueue stb_workqueue;
  10060. STB_EXTERN stb_workqueue*stb_workq_new(int numthreads, int max_units);
  10061. STB_EXTERN stb_workqueue*stb_workq_new_flags(int numthreads, int max_units, int no_add_mutex, int no_remove_mutex);
  10062. STB_EXTERN void stb_workq_delete(stb_workqueue *q);
  10063. STB_EXTERN void stb_workq_numthreads(stb_workqueue *q, int n);
  10064. STB_EXTERN int stb_workq(stb_workqueue *q, stb_thread_func f, void *d, volatile void **return_code);
  10065. STB_EXTERN int stb_workq_reach(stb_workqueue *q, stb_thread_func f, void *d, volatile void **return_code, stb_sync rel);
  10066. STB_EXTERN int stb_workq_length(stb_workqueue *q);
  10067. STB_EXTERN stb_thread stb_create_thread (stb_thread_func f, void *d);
  10068. STB_EXTERN stb_thread stb_create_thread2(stb_thread_func f, void *d, volatile void **return_code, stb_semaphore rel);
  10069. STB_EXTERN void stb_destroy_thread(stb_thread t);
  10070. STB_EXTERN stb_semaphore stb_sem_new(int max_val);
  10071. STB_EXTERN stb_semaphore stb_sem_new_extra(int max_val, int start_val);
  10072. STB_EXTERN void stb_sem_delete (stb_semaphore s);
  10073. STB_EXTERN void stb_sem_waitfor(stb_semaphore s);
  10074. STB_EXTERN void stb_sem_release(stb_semaphore s);
  10075. STB_EXTERN stb_mutex stb_mutex_new(void);
  10076. STB_EXTERN void stb_mutex_delete(stb_mutex m);
  10077. STB_EXTERN void stb_mutex_begin(stb_mutex m);
  10078. STB_EXTERN void stb_mutex_end(stb_mutex m);
  10079. STB_EXTERN stb_sync stb_sync_new(void);
  10080. STB_EXTERN void stb_sync_delete(stb_sync s);
  10081. STB_EXTERN int stb_sync_set_target(stb_sync s, int count);
  10082. STB_EXTERN void stb_sync_reach_and_wait(stb_sync s); // wait for 'target' reachers
  10083. STB_EXTERN int stb_sync_reach(stb_sync s);
  10084. typedef struct stb__threadqueue stb_threadqueue;
  10085. #define STB_THREADQ_DYNAMIC 0
  10086. STB_EXTERN stb_threadqueue *stb_threadq_new(int item_size, int num_items, int many_add, int many_remove);
  10087. STB_EXTERN void stb_threadq_delete(stb_threadqueue *tq);
  10088. STB_EXTERN int stb_threadq_get(stb_threadqueue *tq, void *output);
  10089. STB_EXTERN void stb_threadq_get_block(stb_threadqueue *tq, void *output);
  10090. STB_EXTERN int stb_threadq_add(stb_threadqueue *tq, void *input);
  10091. // can return FALSE if STB_THREADQ_DYNAMIC and attempt to grow fails
  10092. STB_EXTERN int stb_threadq_add_block(stb_threadqueue *tq, void *input);
  10093. #ifdef STB_THREADS
  10094. #ifdef STB_DEFINE
  10095. typedef struct
  10096. {
  10097. stb_thread_func f;
  10098. void *d;
  10099. volatile void **return_val;
  10100. stb_semaphore sem;
  10101. } stb__thread;
  10102. // this is initialized along all possible paths to create threads, therefore
  10103. // it's always initialized before any other threads are create, therefore
  10104. // it's free of races AS LONG AS you only create threads through stb_*
  10105. static stb_mutex stb__threadmutex, stb__workmutex;
  10106. static void stb__threadmutex_init(void)
  10107. {
  10108. if (stb__threadmutex == STB_SEMAPHORE_NULL) {
  10109. stb__threadmutex = stb_mutex_new();
  10110. stb__workmutex = stb_mutex_new();
  10111. }
  10112. }
  10113. #ifdef STB_THREAD_TEST
  10114. volatile float stb__t1=1, stb__t2;
  10115. static void stb__wait(int n)
  10116. {
  10117. float z = 0;
  10118. int i;
  10119. for (i=0; i < n; ++i)
  10120. z += 1 / (stb__t1+i);
  10121. stb__t2 = z;
  10122. }
  10123. #else
  10124. #define stb__wait(x)
  10125. #endif
  10126. #ifdef _WIN32
  10127. // avoid including windows.h -- note that our definitions aren't
  10128. // exactly the same (we don't define the security descriptor struct)
  10129. // so if you want to include windows.h, make sure you do it first.
  10130. #include <process.h>
  10131. #ifndef _WINDOWS_ // check windows.h guard
  10132. #define STB__IMPORT STB_EXTERN __declspec(dllimport)
  10133. #define STB__DW unsigned long
  10134. STB__IMPORT int __stdcall TerminateThread(void *, STB__DW);
  10135. STB__IMPORT void * __stdcall CreateSemaphoreA(void *sec, long,long,char*);
  10136. STB__IMPORT int __stdcall CloseHandle(void *);
  10137. STB__IMPORT STB__DW __stdcall WaitForSingleObject(void *, STB__DW);
  10138. STB__IMPORT int __stdcall ReleaseSemaphore(void *, long, long *);
  10139. STB__IMPORT void __stdcall Sleep(STB__DW);
  10140. #endif
  10141. // necessary to call this when using volatile to order writes/reads
  10142. void stb_barrier(void)
  10143. {
  10144. #ifdef MemoryBarrier
  10145. MemoryBarrier();
  10146. #else
  10147. long temp;
  10148. __asm xchg temp,eax;
  10149. #endif
  10150. }
  10151. static void stb__thread_run(void *t)
  10152. {
  10153. void *res;
  10154. stb__thread info = * (stb__thread *) t;
  10155. free(t);
  10156. res = info.f(info.d);
  10157. if (info.return_val)
  10158. *info.return_val = res;
  10159. if (info.sem != STB_SEMAPHORE_NULL)
  10160. stb_sem_release(info.sem);
  10161. }
  10162. static stb_thread stb_create_thread_raw(stb_thread_func f, void *d, volatile void **return_code, stb_semaphore rel)
  10163. {
  10164. #ifdef _MT
  10165. #if defined(STB_FASTMALLOC) && !defined(STB_FASTMALLOC_ITS_OKAY_I_ONLY_MALLOC_IN_ONE_THREAD)
  10166. stb_fatal("Error! Cannot use STB_FASTMALLOC with threads.\n");
  10167. return STB_THREAD_NULL;
  10168. #else
  10169. unsigned long id;
  10170. stb__thread *data = (stb__thread *) malloc(sizeof(*data));
  10171. if (!data) return NULL;
  10172. stb__threadmutex_init();
  10173. data->f = f;
  10174. data->d = d;
  10175. data->return_val = return_code;
  10176. data->sem = rel;
  10177. id = _beginthread(stb__thread_run, 0, data);
  10178. if (id == -1) return NULL;
  10179. return (void *) id;
  10180. #endif
  10181. #else
  10182. #ifdef STB_NO_STB_STRINGS
  10183. stb_fatal("Invalid compilation");
  10184. #else
  10185. stb_fatal("Must compile mult-threaded to use stb_thread/stb_work.");
  10186. #endif
  10187. return NULL;
  10188. #endif
  10189. }
  10190. // trivial win32 wrappers
  10191. void stb_destroy_thread(stb_thread t) { TerminateThread(t,0); }
  10192. stb_semaphore stb_sem_new(int maxv) {return CreateSemaphoreA(NULL,0,maxv,NULL); }
  10193. stb_semaphore stb_sem_new_extra(int maxv,int start){return CreateSemaphoreA(NULL,start,maxv,NULL); }
  10194. void stb_sem_delete(stb_semaphore s) { if (s != NULL) CloseHandle(s); }
  10195. void stb_sem_waitfor(stb_semaphore s) { WaitForSingleObject(s, 0xffffffff); } // INFINITE
  10196. void stb_sem_release(stb_semaphore s) { ReleaseSemaphore(s,1,NULL); }
  10197. static void stb__thread_sleep(int ms) { Sleep(ms); }
  10198. #ifndef _WINDOWS_
  10199. STB__IMPORT int __stdcall GetProcessAffinityMask(void *, STB__DW *, STB__DW *);
  10200. STB__IMPORT void * __stdcall GetCurrentProcess(void);
  10201. STB__IMPORT int __stdcall SetProcessAffinityMask(void *, STB__DW);
  10202. #endif
  10203. int stb_processor_count(void)
  10204. {
  10205. unsigned long proc,sys;
  10206. GetProcessAffinityMask(GetCurrentProcess(), &proc, &sys);
  10207. return stb_bitcount(proc);
  10208. }
  10209. void stb_force_uniprocessor(void)
  10210. {
  10211. unsigned long proc,sys;
  10212. GetProcessAffinityMask(GetCurrentProcess(), &proc, &sys);
  10213. if (stb_bitcount(proc) > 1) {
  10214. int z;
  10215. for (z=0; z < 32; ++z)
  10216. if (proc & (1 << z))
  10217. break;
  10218. if (z < 32) {
  10219. proc = 1 << z;
  10220. SetProcessAffinityMask(GetCurrentProcess(), proc);
  10221. }
  10222. }
  10223. }
  10224. #ifdef _WINDOWS_
  10225. #define STB_MUTEX_NATIVE
  10226. void *stb_mutex_new(void)
  10227. {
  10228. CRITICAL_SECTION *p = (CRITICAL_SECTION *) malloc(sizeof(*p));
  10229. if (p)
  10230. #if _WIN32_WINNT >= 0x0500
  10231. InitializeCriticalSectionAndSpinCount(p, 500);
  10232. #else
  10233. InitializeCriticalSection(p);
  10234. #endif
  10235. return p;
  10236. }
  10237. void stb_mutex_delete(void *p)
  10238. {
  10239. if (p) {
  10240. DeleteCriticalSection((CRITICAL_SECTION *) p);
  10241. free(p);
  10242. }
  10243. }
  10244. void stb_mutex_begin(void *p)
  10245. {
  10246. stb__wait(500);
  10247. if (p)
  10248. EnterCriticalSection((CRITICAL_SECTION *) p);
  10249. }
  10250. void stb_mutex_end(void *p)
  10251. {
  10252. if (p)
  10253. LeaveCriticalSection((CRITICAL_SECTION *) p);
  10254. stb__wait(500);
  10255. }
  10256. #endif // _WINDOWS_
  10257. #if 0
  10258. // for future reference,
  10259. // InterlockedCompareExchange for x86:
  10260. int cas64_mp(void * dest, void * xcmp, void * xxchg) {
  10261. __asm
  10262. {
  10263. mov esi, [xxchg] ; exchange
  10264. mov ebx, [esi + 0]
  10265. mov ecx, [esi + 4]
  10266. mov esi, [xcmp] ; comparand
  10267. mov eax, [esi + 0]
  10268. mov edx, [esi + 4]
  10269. mov edi, [dest] ; destination
  10270. lock cmpxchg8b [edi]
  10271. jz yyyy;
  10272. mov [esi + 0], eax;
  10273. mov [esi + 4], edx;
  10274. yyyy:
  10275. xor eax, eax;
  10276. setz al;
  10277. };
  10278. inline unsigned __int64 _InterlockedCompareExchange64(volatile unsigned __int64 *dest
  10279. ,unsigned __int64 exchange
  10280. ,unsigned __int64 comperand)
  10281. {
  10282. //value returned in eax::edx
  10283. __asm {
  10284. lea esi,comperand;
  10285. lea edi,exchange;
  10286. mov eax,[esi];
  10287. mov edx,4[esi];
  10288. mov ebx,[edi];
  10289. mov ecx,4[edi];
  10290. mov esi,dest;
  10291. lock CMPXCHG8B [esi];
  10292. }
  10293. #endif // #if 0
  10294. #endif // _WIN32
  10295. stb_thread stb_create_thread2(stb_thread_func f, void *d, volatile void **return_code, stb_semaphore rel)
  10296. {
  10297. return stb_create_thread_raw(f,d,return_code,rel);
  10298. }
  10299. stb_thread stb_create_thread(stb_thread_func f, void *d)
  10300. {
  10301. return stb_create_thread2(f,d,NULL,STB_SEMAPHORE_NULL);
  10302. }
  10303. // mutex implemented by wrapping semaphore
  10304. #ifndef STB_MUTEX_NATIVE
  10305. stb_mutex stb_mutex_new(void) { return stb_sem_new_extra(1,1); }
  10306. void stb_mutex_delete(stb_mutex m) { stb_sem_delete (m); }
  10307. void stb_mutex_begin(stb_mutex m) { stb__wait(500); if (m) stb_sem_waitfor(m); }
  10308. void stb_mutex_end(stb_mutex m) { if (m) stb_sem_release(m); stb__wait(500); }
  10309. #endif
  10310. // thread merge operation
  10311. struct stb__sync
  10312. {
  10313. int target; // target number of threads to hit it
  10314. int sofar; // total threads that hit it
  10315. int waiting; // total threads waiting
  10316. stb_mutex start; // mutex to prevent starting again before finishing previous
  10317. stb_mutex mutex; // mutex while tweaking state
  10318. stb_semaphore release; // semaphore wake up waiting threads
  10319. // we have to wake them up one at a time, rather than using a single release
  10320. // call, because win32 semaphores don't let you dynamically change the max count!
  10321. };
  10322. stb_sync stb_sync_new(void)
  10323. {
  10324. stb_sync s = (stb_sync) malloc(sizeof(*s));
  10325. if (!s) return s;
  10326. s->target = s->sofar = s->waiting = 0;
  10327. s->mutex = stb_mutex_new();
  10328. s->start = stb_mutex_new();
  10329. s->release = stb_sem_new(1);
  10330. if (s->mutex == STB_MUTEX_NULL || s->release == STB_SEMAPHORE_NULL || s->start == STB_MUTEX_NULL) {
  10331. stb_mutex_delete(s->mutex);
  10332. stb_mutex_delete(s->mutex);
  10333. stb_sem_delete(s->release);
  10334. free(s);
  10335. return NULL;
  10336. }
  10337. return s;
  10338. }
  10339. void stb_sync_delete(stb_sync s)
  10340. {
  10341. if (s->waiting) {
  10342. // it's bad to delete while there are threads waiting!
  10343. // shall we wait for them to reach, or just bail? just bail
  10344. assert(0);
  10345. }
  10346. stb_mutex_delete(s->mutex);
  10347. stb_mutex_delete(s->release);
  10348. free(s);
  10349. }
  10350. int stb_sync_set_target(stb_sync s, int count)
  10351. {
  10352. // don't allow setting a target until the last one is fully released;
  10353. // note that this can lead to inefficient pipelining, and maybe we'd
  10354. // be better off ping-ponging between two internal syncs?
  10355. // I tried seeing how often this happened using TryEnterCriticalSection
  10356. // and could _never_ get it to happen in imv(stb), even with more threads
  10357. // than processors. So who knows!
  10358. stb_mutex_begin(s->start);
  10359. // this mutex is pointless, since it's not valid for threads
  10360. // to call reach() before anyone calls set_target() anyway
  10361. stb_mutex_begin(s->mutex);
  10362. assert(s->target == 0); // enforced by start mutex
  10363. s->target = count;
  10364. s->sofar = 0;
  10365. s->waiting = 0;
  10366. stb_mutex_end(s->mutex);
  10367. return STB_TRUE;
  10368. }
  10369. void stb__sync_release(stb_sync s)
  10370. {
  10371. if (s->waiting)
  10372. stb_sem_release(s->release);
  10373. else {
  10374. s->target = 0;
  10375. stb_mutex_end(s->start);
  10376. }
  10377. }
  10378. int stb_sync_reach(stb_sync s)
  10379. {
  10380. int n;
  10381. stb_mutex_begin(s->mutex);
  10382. assert(s->sofar < s->target);
  10383. n = ++s->sofar; // record this value to avoid possible race if we did 'return s->sofar';
  10384. if (s->sofar == s->target)
  10385. stb__sync_release(s);
  10386. stb_mutex_end(s->mutex);
  10387. return n;
  10388. }
  10389. void stb_sync_reach_and_wait(stb_sync s)
  10390. {
  10391. stb_mutex_begin(s->mutex);
  10392. assert(s->sofar < s->target);
  10393. ++s->sofar;
  10394. if (s->sofar == s->target) {
  10395. stb__sync_release(s);
  10396. stb_mutex_end(s->mutex);
  10397. } else {
  10398. ++s->waiting; // we're waiting, so one more waiter
  10399. stb_mutex_end(s->mutex); // release the mutex to other threads
  10400. stb_sem_waitfor(s->release); // wait for merge completion
  10401. stb_mutex_begin(s->mutex); // on merge completion, grab the mutex
  10402. --s->waiting; // we're done waiting
  10403. stb__sync_release(s); // restart the next waiter
  10404. stb_mutex_end(s->mutex); // and now we're done
  10405. // this ends the same as the first case, but it's a lot
  10406. // clearer to understand without sharing the code
  10407. }
  10408. }
  10409. struct stb__threadqueue
  10410. {
  10411. stb_mutex add, remove;
  10412. stb_semaphore nonempty, nonfull;
  10413. int head_blockers; // number of threads blocking--used to know whether to release(avail)
  10414. int tail_blockers;
  10415. int head, tail, array_size, growable;
  10416. int item_size;
  10417. char *data;
  10418. };
  10419. static int stb__tq_wrap(volatile stb_threadqueue *z, int p)
  10420. {
  10421. if (p == z->array_size)
  10422. return p - z->array_size;
  10423. else
  10424. return p;
  10425. }
  10426. int stb__threadq_get_raw(stb_threadqueue *tq2, void *output, int block)
  10427. {
  10428. volatile stb_threadqueue *tq = (volatile stb_threadqueue *) tq2;
  10429. if (tq->head == tq->tail && !block) return 0;
  10430. stb_mutex_begin(tq->remove);
  10431. while (tq->head == tq->tail) {
  10432. if (!block) {
  10433. stb_mutex_end(tq->remove);
  10434. return 0;
  10435. }
  10436. ++tq->head_blockers;
  10437. stb_mutex_end(tq->remove);
  10438. stb_sem_waitfor(tq->nonempty);
  10439. stb_mutex_begin(tq->remove);
  10440. --tq->head_blockers;
  10441. }
  10442. memcpy(output, tq->data + tq->head*tq->item_size, tq->item_size);
  10443. stb_barrier();
  10444. tq->head = stb__tq_wrap(tq, tq->head+1);
  10445. stb_sem_release(tq->nonfull);
  10446. if (tq->head_blockers) // can't check if actually non-empty due to race?
  10447. stb_sem_release(tq->nonempty); // if there are other blockers, wake one
  10448. stb_mutex_end(tq->remove);
  10449. return STB_TRUE;
  10450. }
  10451. int stb__threadq_grow(volatile stb_threadqueue *tq)
  10452. {
  10453. int n;
  10454. char *p;
  10455. assert(tq->remove != STB_MUTEX_NULL); // must have this to allow growth!
  10456. stb_mutex_begin(tq->remove);
  10457. n = tq->array_size * 2;
  10458. p = (char *) realloc(tq->data, n * tq->item_size);
  10459. if (p == NULL) {
  10460. stb_mutex_end(tq->remove);
  10461. stb_mutex_end(tq->add);
  10462. return STB_FALSE;
  10463. }
  10464. if (tq->tail < tq->head) {
  10465. memcpy(p + tq->array_size * tq->item_size, p, tq->tail * tq->item_size);
  10466. tq->tail += tq->array_size;
  10467. }
  10468. tq->data = p;
  10469. tq->array_size = n;
  10470. stb_mutex_end(tq->remove);
  10471. return STB_TRUE;
  10472. }
  10473. int stb__threadq_add_raw(stb_threadqueue *tq2, void *input, int block)
  10474. {
  10475. int tail,pos;
  10476. volatile stb_threadqueue *tq = (volatile stb_threadqueue *) tq2;
  10477. stb_mutex_begin(tq->add);
  10478. for(;;) {
  10479. pos = tq->tail;
  10480. tail = stb__tq_wrap(tq, pos+1);
  10481. if (tail != tq->head) break;
  10482. // full
  10483. if (tq->growable) {
  10484. if (!stb__threadq_grow(tq)) {
  10485. stb_mutex_end(tq->add);
  10486. return STB_FALSE; // out of memory
  10487. }
  10488. } else if (!block) {
  10489. stb_mutex_end(tq->add);
  10490. return STB_FALSE;
  10491. } else {
  10492. ++tq->tail_blockers;
  10493. stb_mutex_end(tq->add);
  10494. stb_sem_waitfor(tq->nonfull);
  10495. stb_mutex_begin(tq->add);
  10496. --tq->tail_blockers;
  10497. }
  10498. }
  10499. memcpy(tq->data + tq->item_size * pos, input, tq->item_size);
  10500. stb_barrier();
  10501. tq->tail = tail;
  10502. stb_sem_release(tq->nonempty);
  10503. if (tq->tail_blockers) // can't check if actually non-full due to race?
  10504. stb_sem_release(tq->nonfull);
  10505. stb_mutex_end(tq->add);
  10506. return STB_TRUE;
  10507. }
  10508. int stb_threadq_length(stb_threadqueue *tq2)
  10509. {
  10510. int a,b,n;
  10511. volatile stb_threadqueue *tq = (volatile stb_threadqueue *) tq2;
  10512. stb_mutex_begin(tq->add);
  10513. a = tq->head;
  10514. b = tq->tail;
  10515. n = tq->array_size;
  10516. stb_mutex_end(tq->add);
  10517. if (a > b) b += n;
  10518. return b-a;
  10519. }
  10520. int stb_threadq_get(stb_threadqueue *tq, void *output)
  10521. {
  10522. return stb__threadq_get_raw(tq, output, STB_FALSE);
  10523. }
  10524. void stb_threadq_get_block(stb_threadqueue *tq, void *output)
  10525. {
  10526. stb__threadq_get_raw(tq, output, STB_TRUE);
  10527. }
  10528. int stb_threadq_add(stb_threadqueue *tq, void *input)
  10529. {
  10530. return stb__threadq_add_raw(tq, input, STB_FALSE);
  10531. }
  10532. int stb_threadq_add_block(stb_threadqueue *tq, void *input)
  10533. {
  10534. return stb__threadq_add_raw(tq, input, STB_TRUE);
  10535. }
  10536. void stb_threadq_delete(stb_threadqueue *tq)
  10537. {
  10538. if (tq) {
  10539. free(tq->data);
  10540. stb_mutex_delete(tq->add);
  10541. stb_mutex_delete(tq->remove);
  10542. stb_sem_delete(tq->nonempty);
  10543. stb_sem_delete(tq->nonfull);
  10544. free(tq);
  10545. }
  10546. }
  10547. #define STB_THREADQUEUE_DYNAMIC 0
  10548. stb_threadqueue *stb_threadq_new(int item_size, int num_items, int many_add, int many_remove)
  10549. {
  10550. int error=0;
  10551. stb_threadqueue *tq = (stb_threadqueue *) malloc(sizeof(*tq));
  10552. if (tq == NULL) return NULL;
  10553. if (num_items == STB_THREADQUEUE_DYNAMIC) {
  10554. tq->growable = STB_TRUE;
  10555. num_items = 32;
  10556. } else
  10557. tq->growable = STB_FALSE;
  10558. tq->item_size = item_size;
  10559. tq->array_size = num_items+1;
  10560. tq->add = tq->remove = STB_MUTEX_NULL;
  10561. tq->nonempty = tq->nonfull = STB_SEMAPHORE_NULL;
  10562. tq->data = NULL;
  10563. if (many_add)
  10564. { tq->add = stb_mutex_new(); if (tq->add == STB_MUTEX_NULL) goto error; }
  10565. if (many_remove || tq->growable)
  10566. { tq->remove = stb_mutex_new(); if (tq->remove == STB_MUTEX_NULL) goto error; }
  10567. tq->nonempty = stb_sem_new(1); if (tq->nonempty == STB_SEMAPHORE_NULL) goto error;
  10568. tq->nonfull = stb_sem_new(1); if (tq->nonfull == STB_SEMAPHORE_NULL) goto error;
  10569. tq->data = (char *) malloc(tq->item_size * tq->array_size);
  10570. if (tq->data == NULL) goto error;
  10571. tq->head = tq->tail = 0;
  10572. tq->head_blockers = tq->tail_blockers = 0;
  10573. return tq;
  10574. error:
  10575. stb_threadq_delete(tq);
  10576. return NULL;
  10577. }
  10578. typedef struct
  10579. {
  10580. stb_thread_func f;
  10581. void *d;
  10582. volatile void **retval;
  10583. stb_sync sync;
  10584. } stb__workinfo;
  10585. //static volatile stb__workinfo *stb__work;
  10586. struct stb__workqueue
  10587. {
  10588. int numthreads;
  10589. stb_threadqueue *tq;
  10590. };
  10591. static stb_workqueue *stb__work_global;
  10592. static void *stb__thread_workloop(void *p)
  10593. {
  10594. volatile stb_workqueue *q = (volatile stb_workqueue *) p;
  10595. for(;;) {
  10596. void *z;
  10597. stb__workinfo w;
  10598. stb_threadq_get_block(q->tq, &w);
  10599. if (w.f == NULL) // null work is a signal to end the thread
  10600. return NULL;
  10601. z = w.f(w.d);
  10602. if (w.retval) { stb_barrier(); *w.retval = z; }
  10603. if (w.sync != STB_SYNC_NULL) stb_sync_reach(w.sync);
  10604. }
  10605. }
  10606. stb_workqueue *stb_workq_new(int num_threads, int max_units)
  10607. {
  10608. return stb_workq_new_flags(num_threads, max_units, 0,0);
  10609. }
  10610. stb_workqueue *stb_workq_new_flags(int numthreads, int max_units, int no_add_mutex, int no_remove_mutex)
  10611. {
  10612. stb_workqueue *q = (stb_workqueue *) malloc(sizeof(*q));
  10613. if (q == NULL) return NULL;
  10614. q->tq = stb_threadq_new(sizeof(stb__workinfo), max_units, !no_add_mutex, !no_remove_mutex);
  10615. if (q->tq == NULL) { free(q); return NULL; }
  10616. q->numthreads = 0;
  10617. stb_workq_numthreads(q, numthreads);
  10618. return q;
  10619. }
  10620. void stb_workq_delete(stb_workqueue *q)
  10621. {
  10622. while (stb_workq_length(q) != 0)
  10623. stb__thread_sleep(1);
  10624. stb_threadq_delete(q->tq);
  10625. free(q);
  10626. }
  10627. static int stb__work_maxitems = STB_THREADQUEUE_DYNAMIC;
  10628. static void stb_work_init(int num_threads)
  10629. {
  10630. if (stb__work_global == NULL) {
  10631. stb__threadmutex_init();
  10632. stb_mutex_begin(stb__workmutex);
  10633. stb_barrier();
  10634. if (*(stb_workqueue * volatile *) &stb__work_global == NULL)
  10635. stb__work_global = stb_workq_new(num_threads, stb__work_maxitems);
  10636. stb_mutex_end(stb__workmutex);
  10637. }
  10638. }
  10639. static int stb__work_raw(stb_workqueue *q, stb_thread_func f, void *d, volatile void **return_code, stb_sync rel)
  10640. {
  10641. stb__workinfo w;
  10642. if (q == NULL) {
  10643. stb_work_init(1);
  10644. q = stb__work_global;
  10645. }
  10646. w.f = f;
  10647. w.d = d;
  10648. w.retval = return_code;
  10649. w.sync = rel;
  10650. return stb_threadq_add(q->tq, &w);
  10651. }
  10652. int stb_workq_length(stb_workqueue *q)
  10653. {
  10654. return stb_threadq_length(q->tq);
  10655. }
  10656. int stb_workq(stb_workqueue *q, stb_thread_func f, void *d, volatile void **return_code)
  10657. {
  10658. if (f == NULL) return 0;
  10659. return stb_workq_reach(q, f, d, return_code, NULL);
  10660. }
  10661. int stb_workq_reach(stb_workqueue *q, stb_thread_func f, void *d, volatile void **return_code, stb_sync rel)
  10662. {
  10663. if (f == NULL) return 0;
  10664. return stb__work_raw(q, f, d, return_code, rel);
  10665. }
  10666. static void stb__workq_numthreads(stb_workqueue *q, int n)
  10667. {
  10668. while (q->numthreads < n) {
  10669. stb_create_thread(stb__thread_workloop, q);
  10670. ++q->numthreads;
  10671. }
  10672. while (q->numthreads > n) {
  10673. stb__work_raw(q, NULL, NULL, NULL, NULL);
  10674. --q->numthreads;
  10675. }
  10676. }
  10677. void stb_workq_numthreads(stb_workqueue *q, int n)
  10678. {
  10679. stb_mutex_begin(stb__threadmutex);
  10680. stb__workq_numthreads(q,n);
  10681. stb_mutex_end(stb__threadmutex);
  10682. }
  10683. int stb_work_maxunits(int n)
  10684. {
  10685. if (stb__work_global == NULL) {
  10686. stb__work_maxitems = n;
  10687. stb_work_init(1);
  10688. }
  10689. return stb__work_maxitems;
  10690. }
  10691. int stb_work(stb_thread_func f, void *d, volatile void **return_code)
  10692. {
  10693. return stb_workq(stb__work_global, f,d,return_code);
  10694. }
  10695. int stb_work_reach(stb_thread_func f, void *d, volatile void **return_code, stb_sync rel)
  10696. {
  10697. return stb_workq_reach(stb__work_global, f,d,return_code,rel);
  10698. }
  10699. void stb_work_numthreads(int n)
  10700. {
  10701. if (stb__work_global == NULL)
  10702. stb_work_init(n);
  10703. else
  10704. stb_workq_numthreads(stb__work_global, n);
  10705. }
  10706. #endif // STB_DEFINE
  10707. //////////////////////////////////////////////////////////////////////////////
  10708. //
  10709. // Background disk I/O
  10710. //
  10711. //
  10712. #define STB_BGIO_READ_ALL (-1)
  10713. STB_EXTERN int stb_bgio_read (char *filename, int offset, int len, stb_uchar **result, int *olen);
  10714. STB_EXTERN int stb_bgio_readf (FILE *f , int offset, int len, stb_uchar **result, int *olen);
  10715. STB_EXTERN int stb_bgio_read_to (char *filename, int offset, int len, stb_uchar *buffer, int *olen);
  10716. STB_EXTERN int stb_bgio_readf_to(FILE *f , int offset, int len, stb_uchar *buffer, int *olen);
  10717. typedef struct
  10718. {
  10719. int have_data;
  10720. int is_valid;
  10721. int is_dir;
  10722. time_t filetime;
  10723. stb_int64 filesize;
  10724. } stb_bgstat;
  10725. STB_EXTERN int stb_bgio_stat (char *filename, stb_bgstat *result);
  10726. #ifdef STB_DEFINE
  10727. static stb_workqueue *stb__diskio;
  10728. static stb_mutex stb__diskio_mutex;
  10729. void stb_thread_cleanup(void)
  10730. {
  10731. if (stb__work_global) stb_workq_delete(stb__work_global); stb__work_global = NULL;
  10732. if (stb__threadmutex) stb_mutex_delete(stb__threadmutex); stb__threadmutex = NULL;
  10733. if (stb__workmutex) stb_mutex_delete(stb__workmutex); stb__workmutex = NULL;
  10734. if (stb__diskio) stb_workq_delete(stb__diskio); stb__diskio = NULL;
  10735. if (stb__diskio_mutex)stb_mutex_delete(stb__diskio_mutex);stb__diskio_mutex= NULL;
  10736. }
  10737. typedef struct
  10738. {
  10739. char *filename;
  10740. FILE *f;
  10741. int offset;
  10742. int len;
  10743. stb_bgstat *stat_out;
  10744. stb_uchar *output;
  10745. stb_uchar **result;
  10746. int *len_output;
  10747. int *flag;
  10748. } stb__disk_command;
  10749. #define STB__MAX_DISK_COMMAND 100
  10750. static stb__disk_command stb__dc_queue[STB__MAX_DISK_COMMAND];
  10751. static int stb__dc_offset;
  10752. void stb__io_init(void)
  10753. {
  10754. if (!stb__diskio) {
  10755. stb__threadmutex_init();
  10756. stb_mutex_begin(stb__threadmutex);
  10757. stb_barrier();
  10758. if (*(stb_thread * volatile *) &stb__diskio == NULL) {
  10759. stb__diskio_mutex = stb_mutex_new();
  10760. // use many threads so OS can try to schedule seeks
  10761. stb__diskio = stb_workq_new_flags(16,STB__MAX_DISK_COMMAND,STB_FALSE,STB_FALSE);
  10762. }
  10763. stb_mutex_end(stb__threadmutex);
  10764. }
  10765. }
  10766. static void * stb__io_error(stb__disk_command *dc)
  10767. {
  10768. if (dc->len_output) *dc->len_output = 0;
  10769. if (dc->result) *dc->result = NULL;
  10770. if (dc->flag) *dc->flag = -1;
  10771. return NULL;
  10772. }
  10773. static void * stb__io_task(void *p)
  10774. {
  10775. stb__disk_command *dc = (stb__disk_command *) p;
  10776. int len;
  10777. FILE *f;
  10778. stb_uchar *buf;
  10779. if (dc->stat_out) {
  10780. struct _stati64 s;
  10781. if (!_stati64(dc->filename, &s)) {
  10782. dc->stat_out->filesize = s.st_size;
  10783. dc->stat_out->filetime = s.st_mtime;
  10784. dc->stat_out->is_dir = s.st_mode & _S_IFDIR;
  10785. dc->stat_out->is_valid = (s.st_mode & _S_IFREG) || dc->stat_out->is_dir;
  10786. } else
  10787. dc->stat_out->is_valid = 0;
  10788. stb_barrier();
  10789. dc->stat_out->have_data = 1;
  10790. free(dc->filename);
  10791. return 0;
  10792. }
  10793. if (dc->f) {
  10794. #ifdef WIN32
  10795. f = _fdopen(_dup(_fileno(dc->f)), "rb");
  10796. #else
  10797. f = fdopen(dup(fileno(dc->f)), "rb");
  10798. #endif
  10799. if (!f)
  10800. return stb__io_error(dc);
  10801. } else {
  10802. f = fopen(dc->filename, "rb");
  10803. free(dc->filename);
  10804. if (!f)
  10805. return stb__io_error(dc);
  10806. }
  10807. len = dc->len;
  10808. if (len < 0) {
  10809. fseek(f, 0, SEEK_END);
  10810. len = ftell(f) - dc->offset;
  10811. }
  10812. if (fseek(f, dc->offset, SEEK_SET)) {
  10813. fclose(f);
  10814. return stb__io_error(dc);
  10815. }
  10816. if (dc->output)
  10817. buf = dc->output;
  10818. else {
  10819. buf = (stb_uchar *) malloc(len);
  10820. if (buf == NULL) {
  10821. fclose(f);
  10822. return stb__io_error(dc);
  10823. }
  10824. }
  10825. len = fread(buf, 1, len, f);
  10826. fclose(f);
  10827. if (dc->len_output) *dc->len_output = len;
  10828. if (dc->result) *dc->result = buf;
  10829. if (dc->flag) *dc->flag = 1;
  10830. return NULL;
  10831. }
  10832. int stb__io_add(char *fname, FILE *f, int off, int len, stb_uchar *out, stb_uchar **result, int *olen, int *flag, stb_bgstat *stat)
  10833. {
  10834. int res;
  10835. stb__io_init();
  10836. // do memory allocation outside of mutex
  10837. if (fname) fname = stb_p_strdup(fname);
  10838. stb_mutex_begin(stb__diskio_mutex);
  10839. {
  10840. stb__disk_command *dc = &stb__dc_queue[stb__dc_offset];
  10841. dc->filename = fname;
  10842. dc->f = f;
  10843. dc->offset = off;
  10844. dc->len = len;
  10845. dc->output = out;
  10846. dc->result = result;
  10847. dc->len_output = olen;
  10848. dc->flag = flag;
  10849. dc->stat_out = stat;
  10850. res = stb_workq(stb__diskio, stb__io_task, dc, NULL);
  10851. if (res)
  10852. stb__dc_offset = (stb__dc_offset + 1 == STB__MAX_DISK_COMMAND ? 0 : stb__dc_offset+1);
  10853. }
  10854. stb_mutex_end(stb__diskio_mutex);
  10855. return res;
  10856. }
  10857. int stb_bgio_read(char *filename, int offset, int len, stb_uchar **result, int *olen)
  10858. {
  10859. return stb__io_add(filename,NULL,offset,len,NULL,result,olen,NULL,NULL);
  10860. }
  10861. int stb_bgio_readf(FILE *f, int offset, int len, stb_uchar **result, int *olen)
  10862. {
  10863. return stb__io_add(NULL,f,offset,len,NULL,result,olen,NULL,NULL);
  10864. }
  10865. int stb_bgio_read_to(char *filename, int offset, int len, stb_uchar *buffer, int *olen)
  10866. {
  10867. return stb__io_add(filename,NULL,offset,len,buffer,NULL,olen,NULL,NULL);
  10868. }
  10869. int stb_bgio_readf_to(FILE *f, int offset, int len, stb_uchar *buffer, int *olen)
  10870. {
  10871. return stb__io_add(NULL,f,offset,len,buffer,NULL,olen,NULL,NULL);
  10872. }
  10873. STB_EXTERN int stb_bgio_stat (char *filename, stb_bgstat *result)
  10874. {
  10875. result->have_data = 0;
  10876. return stb__io_add(filename,NULL,0,0,0,NULL,0,NULL, result);
  10877. }
  10878. #endif
  10879. #endif
  10880. //////////////////////////////////////////////////////////////////////////////
  10881. //
  10882. // Fast malloc implementation
  10883. //
  10884. // This is a clone of TCMalloc, but without the thread support.
  10885. // 1. large objects are allocated directly, page-aligned
  10886. // 2. small objects are allocated in homogeonous heaps, 0 overhead
  10887. //
  10888. // We keep an allocation table for pages a la TCMalloc. This would
  10889. // require 4MB for the entire address space, but we only allocate
  10890. // the parts that are in use. The overhead from using homogenous heaps
  10891. // everywhere is 3MB. (That is, if you allocate 1 object of each size,
  10892. // you'll use 3MB.)
  10893. #if defined(STB_DEFINE) && ((defined(_WIN32) && !defined(_M_AMD64)) || defined(STB_FASTMALLOC))
  10894. #ifdef _WIN32
  10895. #ifndef _WINDOWS_
  10896. #ifndef STB__IMPORT
  10897. #define STB__IMPORT STB_EXTERN __declspec(dllimport)
  10898. #define STB__DW unsigned long
  10899. #endif
  10900. STB__IMPORT void * __stdcall VirtualAlloc(void *p, unsigned long size, unsigned long type, unsigned long protect);
  10901. STB__IMPORT int __stdcall VirtualFree(void *p, unsigned long size, unsigned long freetype);
  10902. #endif
  10903. #define stb__alloc_pages_raw(x) (stb_uint32) VirtualAlloc(NULL, (x), 0x3000, 0x04)
  10904. #define stb__dealloc_pages_raw(p) VirtualFree((void *) p, 0, 0x8000)
  10905. #else
  10906. #error "Platform not currently supported"
  10907. #endif
  10908. typedef struct stb__span
  10909. {
  10910. int start, len;
  10911. struct stb__span *next, *prev;
  10912. void *first_free;
  10913. unsigned short list; // 1..256 free; 257..511 sizeclass; 0=large block
  10914. short allocations; // # outstanding allocations for sizeclass
  10915. } stb__span; // 24
  10916. static stb__span **stb__span_for_page;
  10917. static int stb__firstpage, stb__lastpage;
  10918. static void stb__update_page_range(int first, int last)
  10919. {
  10920. stb__span **sfp;
  10921. int i, f,l;
  10922. if (first >= stb__firstpage && last <= stb__lastpage) return;
  10923. if (stb__span_for_page == NULL) {
  10924. f = first;
  10925. l = f+stb_max(last-f, 16384);
  10926. l = stb_min(l, 1<<20);
  10927. } else if (last > stb__lastpage) {
  10928. f = stb__firstpage;
  10929. l = f + (stb__lastpage - f) * 2;
  10930. l = stb_clamp(last, l,1<<20);
  10931. } else {
  10932. l = stb__lastpage;
  10933. f = l - (l - stb__firstpage) * 2;
  10934. f = stb_clamp(f, 0,first);
  10935. }
  10936. sfp = (stb__span **) stb__alloc_pages_raw(sizeof(void *) * (l-f));
  10937. for (i=f; i < stb__firstpage; ++i) sfp[i - f] = NULL;
  10938. for ( ; i < stb__lastpage ; ++i) sfp[i - f] = stb__span_for_page[i - stb__firstpage];
  10939. for ( ; i < l ; ++i) sfp[i - f] = NULL;
  10940. if (stb__span_for_page) stb__dealloc_pages_raw(stb__span_for_page);
  10941. stb__firstpage = f;
  10942. stb__lastpage = l;
  10943. stb__span_for_page = sfp;
  10944. }
  10945. static stb__span *stb__span_free=NULL;
  10946. static stb__span *stb__span_first, *stb__span_end;
  10947. static stb__span *stb__span_alloc(void)
  10948. {
  10949. stb__span *s = stb__span_free;
  10950. if (s)
  10951. stb__span_free = s->next;
  10952. else {
  10953. if (!stb__span_first) {
  10954. stb__span_first = (stb__span *) stb__alloc_pages_raw(65536);
  10955. if (stb__span_first == NULL) return NULL;
  10956. stb__span_end = stb__span_first + (65536 / sizeof(stb__span));
  10957. }
  10958. s = stb__span_first++;
  10959. if (stb__span_first == stb__span_end) stb__span_first = NULL;
  10960. }
  10961. return s;
  10962. }
  10963. static stb__span *stb__spanlist[512];
  10964. static void stb__spanlist_unlink(stb__span *s)
  10965. {
  10966. if (s->prev)
  10967. s->prev->next = s->next;
  10968. else {
  10969. int n = s->list;
  10970. assert(stb__spanlist[n] == s);
  10971. stb__spanlist[n] = s->next;
  10972. }
  10973. if (s->next)
  10974. s->next->prev = s->prev;
  10975. s->next = s->prev = NULL;
  10976. s->list = 0;
  10977. }
  10978. static void stb__spanlist_add(int n, stb__span *s)
  10979. {
  10980. s->list = n;
  10981. s->next = stb__spanlist[n];
  10982. s->prev = NULL;
  10983. stb__spanlist[n] = s;
  10984. if (s->next) s->next->prev = s;
  10985. }
  10986. #define stb__page_shift 12
  10987. #define stb__page_size (1 << stb__page_shift)
  10988. #define stb__page_number(x) ((x) >> stb__page_shift)
  10989. #define stb__page_address(x) ((x) << stb__page_shift)
  10990. static void stb__set_span_for_page(stb__span *s)
  10991. {
  10992. int i;
  10993. for (i=0; i < s->len; ++i)
  10994. stb__span_for_page[s->start + i - stb__firstpage] = s;
  10995. }
  10996. static stb__span *stb__coalesce(stb__span *a, stb__span *b)
  10997. {
  10998. assert(a->start + a->len == b->start);
  10999. if (a->list) stb__spanlist_unlink(a);
  11000. if (b->list) stb__spanlist_unlink(b);
  11001. a->len += b->len;
  11002. b->len = 0;
  11003. b->next = stb__span_free;
  11004. stb__span_free = b;
  11005. stb__set_span_for_page(a);
  11006. return a;
  11007. }
  11008. static void stb__free_span(stb__span *s)
  11009. {
  11010. stb__span *n = NULL;
  11011. if (s->start > stb__firstpage) {
  11012. n = stb__span_for_page[s->start-1 - stb__firstpage];
  11013. if (n && n->allocations == -2 && n->start + n->len == s->start) s = stb__coalesce(n,s);
  11014. }
  11015. if (s->start + s->len < stb__lastpage) {
  11016. n = stb__span_for_page[s->start + s->len - stb__firstpage];
  11017. if (n && n->allocations == -2 && s->start + s->len == n->start) s = stb__coalesce(s,n);
  11018. }
  11019. s->allocations = -2;
  11020. stb__spanlist_add(s->len > 256 ? 256 : s->len, s);
  11021. }
  11022. static stb__span *stb__alloc_pages(int num)
  11023. {
  11024. stb__span *s = stb__span_alloc();
  11025. int p;
  11026. if (!s) return NULL;
  11027. p = stb__alloc_pages_raw(num << stb__page_shift);
  11028. if (p == 0) { s->next = stb__span_free; stb__span_free = s; return 0; }
  11029. assert(stb__page_address(stb__page_number(p)) == p);
  11030. p = stb__page_number(p);
  11031. stb__update_page_range(p, p+num);
  11032. s->start = p;
  11033. s->len = num;
  11034. s->next = NULL;
  11035. s->prev = NULL;
  11036. stb__set_span_for_page(s);
  11037. return s;
  11038. }
  11039. static stb__span *stb__alloc_span(int pagecount)
  11040. {
  11041. int i;
  11042. stb__span *p = NULL;
  11043. for(i=pagecount; i < 256; ++i)
  11044. if (stb__spanlist[i]) {
  11045. p = stb__spanlist[i];
  11046. break;
  11047. }
  11048. if (!p) {
  11049. p = stb__spanlist[256];
  11050. while (p && p->len < pagecount)
  11051. p = p->next;
  11052. }
  11053. if (!p) {
  11054. p = stb__alloc_pages(pagecount < 16 ? 16 : pagecount);
  11055. if (p == NULL) return 0;
  11056. } else
  11057. stb__spanlist_unlink(p);
  11058. if (p->len > pagecount) {
  11059. stb__span *q = stb__span_alloc();
  11060. if (q) {
  11061. q->start = p->start + pagecount;
  11062. q->len = p->len - pagecount;
  11063. p->len = pagecount;
  11064. for (i=0; i < q->len; ++i)
  11065. stb__span_for_page[q->start+i - stb__firstpage] = q;
  11066. stb__spanlist_add(q->len > 256 ? 256 : q->len, q);
  11067. }
  11068. }
  11069. return p;
  11070. }
  11071. #define STB__MAX_SMALL_SIZE 32768
  11072. #define STB__MAX_SIZE_CLASSES 256
  11073. static unsigned char stb__class_base[32];
  11074. static unsigned char stb__class_shift[32];
  11075. static unsigned char stb__pages_for_class[STB__MAX_SIZE_CLASSES];
  11076. static int stb__size_for_class[STB__MAX_SIZE_CLASSES];
  11077. stb__span *stb__get_nonempty_sizeclass(int c)
  11078. {
  11079. int s = c + 256, i, size, tsize; // remap to span-list index
  11080. char *z;
  11081. void *q;
  11082. stb__span *p = stb__spanlist[s];
  11083. if (p) {
  11084. if (p->first_free) return p; // fast path: it's in the first one in list
  11085. for (p=p->next; p; p=p->next)
  11086. if (p->first_free) {
  11087. // move to front for future queries
  11088. stb__spanlist_unlink(p);
  11089. stb__spanlist_add(s, p);
  11090. return p;
  11091. }
  11092. }
  11093. // no non-empty ones, so allocate a new one
  11094. p = stb__alloc_span(stb__pages_for_class[c]);
  11095. if (!p) return NULL;
  11096. // create the free list up front
  11097. size = stb__size_for_class[c];
  11098. tsize = stb__pages_for_class[c] << stb__page_shift;
  11099. i = 0;
  11100. z = (char *) stb__page_address(p->start);
  11101. q = NULL;
  11102. while (i + size <= tsize) {
  11103. * (void **) z = q; q = z;
  11104. z += size;
  11105. i += size;
  11106. }
  11107. p->first_free = q;
  11108. p->allocations = 0;
  11109. stb__spanlist_add(s,p);
  11110. return p;
  11111. }
  11112. static int stb__sizeclass(size_t sz)
  11113. {
  11114. int z = stb_log2_floor(sz); // -1 below to group e.g. 13,14,15,16 correctly
  11115. return stb__class_base[z] + ((sz-1) >> stb__class_shift[z]);
  11116. }
  11117. static void stb__init_sizeclass(void)
  11118. {
  11119. int i, size, overhead;
  11120. int align_shift = 2; // allow 4-byte and 12-byte blocks as well, vs. TCMalloc
  11121. int next_class = 1;
  11122. int last_log = 0;
  11123. for (i = 0; i < align_shift; i++) {
  11124. stb__class_base [i] = next_class;
  11125. stb__class_shift[i] = align_shift;
  11126. }
  11127. for (size = 1 << align_shift; size <= STB__MAX_SMALL_SIZE; size += 1 << align_shift) {
  11128. i = stb_log2_floor(size);
  11129. if (i > last_log) {
  11130. if (size == 16) ++align_shift; // switch from 4-byte to 8-byte alignment
  11131. else if (size >= 128 && align_shift < 8) ++align_shift;
  11132. stb__class_base[i] = next_class - ((size-1) >> align_shift);
  11133. stb__class_shift[i] = align_shift;
  11134. last_log = i;
  11135. }
  11136. stb__size_for_class[next_class++] = size;
  11137. }
  11138. for (i=1; i <= STB__MAX_SMALL_SIZE; ++i)
  11139. assert(i <= stb__size_for_class[stb__sizeclass(i)]);
  11140. overhead = 0;
  11141. for (i = 1; i < next_class; i++) {
  11142. int s = stb__size_for_class[i];
  11143. size = stb__page_size;
  11144. while (size % s > size >> 3)
  11145. size += stb__page_size;
  11146. stb__pages_for_class[i] = (unsigned char) (size >> stb__page_shift);
  11147. overhead += size;
  11148. }
  11149. assert(overhead < (4 << 20)); // make sure it's under 4MB of overhead
  11150. }
  11151. #ifdef STB_DEBUG
  11152. #define stb__smemset(a,b,c) memset((void *) a, b, c)
  11153. #elif defined(STB_FASTMALLOC_INIT)
  11154. #define stb__smemset(a,b,c) memset((void *) a, b, c)
  11155. #else
  11156. #define stb__smemset(a,b,c)
  11157. #endif
  11158. void *stb_smalloc(size_t sz)
  11159. {
  11160. stb__span *s;
  11161. if (sz == 0) return NULL;
  11162. if (stb__size_for_class[1] == 0) stb__init_sizeclass();
  11163. if (sz > STB__MAX_SMALL_SIZE) {
  11164. s = stb__alloc_span((sz + stb__page_size - 1) >> stb__page_shift);
  11165. if (s == NULL) return NULL;
  11166. s->list = 0;
  11167. s->next = s->prev = NULL;
  11168. s->allocations = -32767;
  11169. stb__smemset(stb__page_address(s->start), 0xcd, (sz+3)&~3);
  11170. return (void *) stb__page_address(s->start);
  11171. } else {
  11172. void *p;
  11173. int c = stb__sizeclass(sz);
  11174. s = stb__spanlist[256+c];
  11175. if (!s || !s->first_free)
  11176. s = stb__get_nonempty_sizeclass(c);
  11177. if (s == NULL) return NULL;
  11178. p = s->first_free;
  11179. s->first_free = * (void **) p;
  11180. ++s->allocations;
  11181. stb__smemset(p,0xcd, sz);
  11182. return p;
  11183. }
  11184. }
  11185. int stb_ssize(void *p)
  11186. {
  11187. stb__span *s;
  11188. if (p == NULL) return 0;
  11189. s = stb__span_for_page[stb__page_number((stb_uint) p) - stb__firstpage];
  11190. if (s->list >= 256) {
  11191. return stb__size_for_class[s->list - 256];
  11192. } else {
  11193. assert(s->list == 0);
  11194. return s->len << stb__page_shift;
  11195. }
  11196. }
  11197. void stb_sfree(void *p)
  11198. {
  11199. stb__span *s;
  11200. if (p == NULL) return;
  11201. s = stb__span_for_page[stb__page_number((stb_uint) p) - stb__firstpage];
  11202. if (s->list >= 256) {
  11203. stb__smemset(p, 0xfe, stb__size_for_class[s->list-256]);
  11204. * (void **) p = s->first_free;
  11205. s->first_free = p;
  11206. if (--s->allocations == 0) {
  11207. stb__spanlist_unlink(s);
  11208. stb__free_span(s);
  11209. }
  11210. } else {
  11211. assert(s->list == 0);
  11212. stb__smemset(p, 0xfe, stb_ssize(p));
  11213. stb__free_span(s);
  11214. }
  11215. }
  11216. void *stb_srealloc(void *p, size_t sz)
  11217. {
  11218. size_t cur_size;
  11219. if (p == NULL) return stb_smalloc(sz);
  11220. if (sz == 0) { stb_sfree(p); return NULL; }
  11221. cur_size = stb_ssize(p);
  11222. if (sz > cur_size || sz <= (cur_size >> 1)) {
  11223. void *q;
  11224. if (sz > cur_size && sz < (cur_size << 1)) sz = cur_size << 1;
  11225. q = stb_smalloc(sz); if (q == NULL) return NULL;
  11226. memcpy(q, p, sz < cur_size ? sz : cur_size);
  11227. stb_sfree(p);
  11228. return q;
  11229. }
  11230. return p;
  11231. }
  11232. void *stb_scalloc(size_t n, size_t sz)
  11233. {
  11234. void *p;
  11235. if (n == 0 || sz == 0) return NULL;
  11236. if (stb_log2_ceil(n) + stb_log2_ceil(n) >= 32) return NULL;
  11237. p = stb_smalloc(n*sz);
  11238. if (p) memset(p, 0, n*sz);
  11239. return p;
  11240. }
  11241. char *stb_sstrdup(char *s)
  11242. {
  11243. int n = strlen(s);
  11244. char *p = (char *) stb_smalloc(n+1);
  11245. if (p) stb_p_strcpy_s(p,n+1,s);
  11246. return p;
  11247. }
  11248. #endif // STB_DEFINE
  11249. //////////////////////////////////////////////////////////////////////////////
  11250. //
  11251. // Source code constants
  11252. //
  11253. // This is a trivial system to let you specify constants in source code,
  11254. // then while running you can change the constants.
  11255. //
  11256. // Note that you can't wrap the #defines, because we need to know their
  11257. // names. So we provide a pre-wrapped version without 'STB_' for convenience;
  11258. // to request it, #define STB_CONVENIENT_H, yielding:
  11259. // KI -- integer
  11260. // KU -- unsigned integer
  11261. // KF -- float
  11262. // KD -- double
  11263. // KS -- string constant
  11264. //
  11265. // Defaults to functioning in debug build, not in release builds.
  11266. // To force on, define STB_ALWAYS_H
  11267. #ifdef STB_CONVENIENT_H
  11268. #define KI(x) STB_I(x)
  11269. #define KU(x) STB_UI(x)
  11270. #define KF(x) STB_F(x)
  11271. #define KD(x) STB_D(x)
  11272. #define KS(x) STB_S(x)
  11273. #endif
  11274. STB_EXTERN void stb_source_path(char *str);
  11275. #ifdef STB_DEFINE
  11276. char *stb__source_path;
  11277. void stb_source_path(char *path)
  11278. {
  11279. stb__source_path = path;
  11280. }
  11281. char *stb__get_sourcefile_path(char *file)
  11282. {
  11283. static char filebuf[512];
  11284. if (stb__source_path) {
  11285. stb_p_sprintf(filebuf stb_p_size(sizeof(filebuf)), "%s/%s", stb__source_path, file);
  11286. if (stb_fexists(filebuf)) return filebuf;
  11287. }
  11288. if (stb_fexists(file)) return file;
  11289. stb_p_sprintf(filebuf stb_p_size(sizeof(filebuf)), "../%s", file);
  11290. if (!stb_fexists(filebuf)) return filebuf;
  11291. return file;
  11292. }
  11293. #endif
  11294. #define STB_F(x) ((float) STB_H(x))
  11295. #define STB_UI(x) ((unsigned int) STB_I(x))
  11296. #if !defined(STB_DEBUG) && !defined(STB_ALWAYS_H)
  11297. #define STB_D(x) ((double) (x))
  11298. #define STB_I(x) ((int) (x))
  11299. #define STB_S(x) ((char *) (x))
  11300. #else
  11301. #define STB_D(x) stb__double_constant(__FILE__, __LINE__-1, (x))
  11302. #define STB_I(x) stb__int_constant(__FILE__, __LINE__-1, (x))
  11303. #define STB_S(x) stb__string_constant(__FILE__, __LINE__-1, (x))
  11304. STB_EXTERN double stb__double_constant(char *file, int line, double x);
  11305. STB_EXTERN int stb__int_constant(char *file, int line, int x);
  11306. STB_EXTERN char * stb__string_constant(char *file, int line, char *str);
  11307. #ifdef STB_DEFINE
  11308. enum
  11309. {
  11310. STB__CTYPE_int,
  11311. STB__CTYPE_uint,
  11312. STB__CTYPE_float,
  11313. STB__CTYPE_double,
  11314. STB__CTYPE_string,
  11315. };
  11316. typedef struct
  11317. {
  11318. int line;
  11319. int type;
  11320. union {
  11321. int ival;
  11322. double dval;
  11323. char *sval;
  11324. };
  11325. } stb__Entry;
  11326. typedef struct
  11327. {
  11328. stb__Entry *entries;
  11329. char *filename;
  11330. time_t timestamp;
  11331. char **file_data;
  11332. int file_len;
  11333. unsigned short *line_index;
  11334. } stb__FileEntry;
  11335. static void stb__constant_parse(stb__FileEntry *f, int i)
  11336. {
  11337. char *s;
  11338. int n;
  11339. if (!stb_arr_valid(f->entries, i)) return;
  11340. n = f->entries[i].line;
  11341. if (n >= f->file_len) return;
  11342. s = f->file_data[n];
  11343. switch (f->entries[i].type) {
  11344. case STB__CTYPE_float:
  11345. while (*s) {
  11346. if (!strncmp(s, "STB_D(", 6)) { s+=6; goto matched_float; }
  11347. if (!strncmp(s, "STB_F(", 6)) { s+=6; goto matched_float; }
  11348. if (!strncmp(s, "KD(", 3)) { s+=3; goto matched_float; }
  11349. if (!strncmp(s, "KF(", 3)) { s+=3; goto matched_float; }
  11350. ++s;
  11351. }
  11352. break;
  11353. matched_float:
  11354. f->entries[i].dval = strtod(s, NULL);
  11355. break;
  11356. case STB__CTYPE_int:
  11357. while (*s) {
  11358. if (!strncmp(s, "STB_I(", 6)) { s+=6; goto matched_int; }
  11359. if (!strncmp(s, "STB_UI(", 7)) { s+=7; goto matched_int; }
  11360. if (!strncmp(s, "KI(", 3)) { s+=3; goto matched_int; }
  11361. if (!strncmp(s, "KU(", 3)) { s+=3; goto matched_int; }
  11362. ++s;
  11363. }
  11364. break;
  11365. matched_int: {
  11366. int neg=0;
  11367. s = stb_skipwhite(s);
  11368. while (*s == '-') { neg = !neg; s = stb_skipwhite(s+1); } // handle '- - 5', pointlessly
  11369. if (s[0] == '0' && tolower(s[1]) == 'x')
  11370. f->entries[i].ival = strtol(s, NULL, 16);
  11371. else if (s[0] == '0')
  11372. f->entries[i].ival = strtol(s, NULL, 8);
  11373. else
  11374. f->entries[i].ival = strtol(s, NULL, 10);
  11375. if (neg) f->entries[i].ival = -f->entries[i].ival;
  11376. break;
  11377. }
  11378. case STB__CTYPE_string:
  11379. // @TODO
  11380. break;
  11381. }
  11382. }
  11383. static stb_sdict *stb__constant_file_hash;
  11384. stb__Entry *stb__constant_get_entry(char *filename, int line, int type)
  11385. {
  11386. int i;
  11387. stb__FileEntry *f;
  11388. if (stb__constant_file_hash == NULL)
  11389. stb__constant_file_hash = stb_sdict_new(STB_TRUE);
  11390. f = (stb__FileEntry*) stb_sdict_get(stb__constant_file_hash, filename);
  11391. if (f == NULL) {
  11392. char *s = stb__get_sourcefile_path(filename);
  11393. if (s == NULL || !stb_fexists(s)) return 0;
  11394. f = (stb__FileEntry *) malloc(sizeof(*f));
  11395. f->timestamp = stb_ftimestamp(s);
  11396. f->file_data = stb_stringfile(s, &f->file_len);
  11397. f->filename = stb_p_strdup(s); // cache the full path
  11398. f->entries = NULL;
  11399. f->line_index = 0;
  11400. stb_arr_setlen(f->line_index, f->file_len);
  11401. memset(f->line_index, 0xff, stb_arr_storage(f->line_index));
  11402. } else {
  11403. time_t t = stb_ftimestamp(f->filename);
  11404. if (f->timestamp != t) {
  11405. f->timestamp = t;
  11406. free(f->file_data);
  11407. f->file_data = stb_stringfile(f->filename, &f->file_len);
  11408. stb_arr_setlen(f->line_index, f->file_len);
  11409. for (i=0; i < stb_arr_len(f->entries); ++i)
  11410. stb__constant_parse(f, i);
  11411. }
  11412. }
  11413. if (line >= f->file_len) return 0;
  11414. if (f->line_index[line] >= stb_arr_len(f->entries)) {
  11415. // need a new entry
  11416. int n = stb_arr_len(f->entries);
  11417. stb__Entry e;
  11418. e.line = line;
  11419. if (line < f->file_len)
  11420. f->line_index[line] = n;
  11421. e.type = type;
  11422. stb_arr_push(f->entries, e);
  11423. stb__constant_parse(f, n);
  11424. }
  11425. return f->entries + f->line_index[line];
  11426. }
  11427. double stb__double_constant(char *file, int line, double x)
  11428. {
  11429. stb__Entry *e = stb__constant_get_entry(file, line, STB__CTYPE_float);
  11430. if (!e) return x;
  11431. return e->dval;
  11432. }
  11433. int stb__int_constant(char *file, int line, int x)
  11434. {
  11435. stb__Entry *e = stb__constant_get_entry(file, line, STB__CTYPE_int);
  11436. if (!e) return x;
  11437. return e->ival;
  11438. }
  11439. char * stb__string_constant(char *file, int line, char *x)
  11440. {
  11441. stb__Entry *e = stb__constant_get_entry(file, line, STB__CTYPE_string);
  11442. if (!e) return x;
  11443. return e->sval;
  11444. }
  11445. #endif // STB_DEFINE
  11446. #endif // !STB_DEBUG && !STB_ALWAYS_H
  11447. #ifdef STB_STUA
  11448. #error "STUA is no longer supported"
  11449. //////////////////////////////////////////////////////////////////////////
  11450. //
  11451. // stua: little scripting language
  11452. //
  11453. // define STB_STUA to compile it
  11454. //
  11455. // see http://nothings.org/stb/stb_stua.html for documentation
  11456. //
  11457. // basic parsing model:
  11458. //
  11459. // lexical analysis
  11460. // use stb_lex() to parse tokens; keywords get their own tokens
  11461. //
  11462. // parsing:
  11463. // recursive descent parser. too much of a hassle to make an unambiguous
  11464. // LR(1) grammar, and one-pass generation is clumsier (recursive descent
  11465. // makes it easier to e.g. compile nested functions). on the other hand,
  11466. // dictionary syntax required hackery to get extra lookahead.
  11467. //
  11468. // codegen:
  11469. // output into an evaluation tree, using array indices as 'pointers'
  11470. //
  11471. // run:
  11472. // traverse the tree; support for 'break/continue/return' is tricky
  11473. //
  11474. // garbage collection:
  11475. // stu__mark and sweep; explicit stack with non-stu__compile_global_scope roots
  11476. typedef stb_int32 stua_obj;
  11477. typedef stb_idict stua_dict;
  11478. STB_EXTERN void stua_run_script(char *s);
  11479. STB_EXTERN void stua_uninit(void);
  11480. extern stua_obj stua_globals;
  11481. STB_EXTERN double stua_number(stua_obj z);
  11482. STB_EXTERN stua_obj stua_getnil(void);
  11483. STB_EXTERN stua_obj stua_getfalse(void);
  11484. STB_EXTERN stua_obj stua_gettrue(void);
  11485. STB_EXTERN stua_obj stua_string(char *z);
  11486. STB_EXTERN stua_obj stua_make_number(double d);
  11487. STB_EXTERN stua_obj stua_box(int type, void *data, int size);
  11488. enum
  11489. {
  11490. STUA_op_negate=129,
  11491. STUA_op_shl, STUA_op_ge,
  11492. STUA_op_shr, STUA_op_le,
  11493. STUA_op_shru,
  11494. STUA_op_last
  11495. };
  11496. #define STUA_NO_VALUE 2 // equivalent to a tagged NULL
  11497. STB_EXTERN stua_obj (*stua_overload)(int op, stua_obj a, stua_obj b, stua_obj c);
  11498. STB_EXTERN stua_obj stua_error(char *err, ...);
  11499. STB_EXTERN stua_obj stua_pushroot(stua_obj o);
  11500. STB_EXTERN void stua_poproot ( void );
  11501. #ifdef STB_DEFINE
  11502. // INTERPRETER
  11503. // 31-bit floating point implementation
  11504. // force the (1 << 30) bit (2nd highest bit) to be zero by re-biasing the exponent;
  11505. // then shift and set the bottom bit
  11506. static stua_obj stu__floatp(float *f)
  11507. {
  11508. unsigned int n = *(unsigned int *) f;
  11509. unsigned int e = n & (0xff << 23);
  11510. assert(sizeof(int) == 4 && sizeof(float) == 4);
  11511. if (!e) // zero?
  11512. n = n; // no change
  11513. else if (e < (64 << 23)) // underflow of the packed encoding?
  11514. n = (n & 0x80000000); // signed 0
  11515. else if (e > (190 << 23)) // overflow of the encoding? (or INF or NAN)
  11516. n = (n & 0x80000000) + (127 << 23); // new INF encoding
  11517. else
  11518. n -= 0x20000000;
  11519. // now we need to shuffle the bits so that the spare bit is at the bottom
  11520. assert((n & 0x40000000) == 0);
  11521. return (n & 0x80000000) + (n << 1) + 1;
  11522. }
  11523. static unsigned char stu__getfloat_addend[256];
  11524. static float stu__getfloat(stua_obj v)
  11525. {
  11526. unsigned int n;
  11527. unsigned int e = ((unsigned int) v) >> 24;
  11528. n = (int) v >> 1; // preserve high bit
  11529. n += stu__getfloat_addend[e] << 24;
  11530. return *(float *) &n;
  11531. }
  11532. stua_obj stua_float(float f)
  11533. {
  11534. return stu__floatp(&f);
  11535. }
  11536. static void stu__float_init(void)
  11537. {
  11538. int i;
  11539. stu__getfloat_addend[0] = 0; // do nothing to biased exponent of 0
  11540. for (i=1; i < 127; ++i)
  11541. stu__getfloat_addend[i] = 32; // undo the -0x20000000
  11542. stu__getfloat_addend[127] = 64; // convert packed INF to INF (0x3f -> 0x7f)
  11543. for (i=0; i < 128; ++i) // for signed floats, remove the bit we just shifted down
  11544. stu__getfloat_addend[128+i] = stu__getfloat_addend[i] - 64;
  11545. }
  11546. // Tagged data type implementation
  11547. // TAGS:
  11548. #define stu__int_tag 0 // of 2 bits // 00 int
  11549. #define stu__float_tag 1 // of 1 bit // 01 float
  11550. #define stu__ptr_tag 2 // of 2 bits // 10 boxed
  11551. // 11 float
  11552. #define stu__tag(x) ((x) & 3)
  11553. #define stu__number(x) (stu__tag(x) != stu__ptr_tag)
  11554. #define stu__isint(x) (stu__tag(x) == stu__int_tag)
  11555. #define stu__int(x) ((x) >> 2)
  11556. #define stu__float(x) (stu__getfloat(x))
  11557. #define stu__makeint(v) ((v)*4+stu__int_tag)
  11558. // boxed data, and tag support for boxed data
  11559. enum
  11560. {
  11561. STU___float = 1, STU___int = 2,
  11562. STU___number = 3, STU___string = 4,
  11563. STU___function = 5, STU___dict = 6,
  11564. STU___boolean = 7, STU___error = 8,
  11565. };
  11566. // boxed data
  11567. #define STU__BOX short type, stua_gc
  11568. typedef struct stu__box { STU__BOX; } stu__box;
  11569. stu__box stu__nil = { 0, 1 };
  11570. stu__box stu__true = { STU___boolean, 1, };
  11571. stu__box stu__false = { STU___boolean, 1, };
  11572. #define stu__makeptr(v) ((stua_obj) (v) + stu__ptr_tag)
  11573. #define stua_nil stu__makeptr(&stu__nil)
  11574. #define stua_true stu__makeptr(&stu__true)
  11575. #define stua_false stu__makeptr(&stu__false)
  11576. stua_obj stua_getnil(void) { return stua_nil; }
  11577. stua_obj stua_getfalse(void) { return stua_false; }
  11578. stua_obj stua_gettrue(void) { return stua_true; }
  11579. #define stu__ptr(x) ((stu__box *) ((x) - stu__ptr_tag))
  11580. #define stu__checkt(t,x) ((t) == STU___float ? ((x) & 1) == stu__float_tag : \
  11581. (t) == STU___int ? stu__isint(x) : \
  11582. (t) == STU___number ? stu__number(x) : \
  11583. stu__tag(x) == stu__ptr_tag && stu__ptr(x)->type == (t))
  11584. typedef struct
  11585. {
  11586. STU__BOX;
  11587. void *ptr;
  11588. } stu__wrapper;
  11589. // implementation of a 'function' or function + closure
  11590. typedef struct stu__func
  11591. {
  11592. STU__BOX;
  11593. stua_obj closure_source; // 0 - regular function; 4 - C function
  11594. // if closure, pointer to source function
  11595. union {
  11596. stua_obj closure_data; // partial-application data
  11597. void *store; // pointer to free that holds 'code'
  11598. stua_obj (*func)(stua_dict *context);
  11599. } f;
  11600. // closure ends here
  11601. short *code;
  11602. int num_param;
  11603. stua_obj *param; // list of parameter strings
  11604. } stu__func;
  11605. // apply this to 'short *code' to get at data
  11606. #define stu__const(f) ((stua_obj *) (f))
  11607. static void stu__free_func(stu__func *f)
  11608. {
  11609. if (f->closure_source == 0) free(f->f.store);
  11610. if ((stb_uint) f->closure_source <= 4) free(f->param);
  11611. free(f);
  11612. }
  11613. #define stu__pd(x) ((stua_dict *) stu__ptr(x))
  11614. #define stu__pw(x) ((stu__wrapper *) stu__ptr(x))
  11615. #define stu__pf(x) ((stu__func *) stu__ptr(x))
  11616. // garbage-collection
  11617. static stu__box ** stu__gc_ptrlist;
  11618. static stua_obj * stu__gc_root_stack;
  11619. stua_obj stua_pushroot(stua_obj o) { stb_arr_push(stu__gc_root_stack, o); return o; }
  11620. void stua_poproot ( void ) { stb_arr_pop(stu__gc_root_stack); }
  11621. static stb_sdict *stu__strings;
  11622. static void stu__mark(stua_obj z)
  11623. {
  11624. int i;
  11625. stu__box *p = stu__ptr(z);
  11626. if (p->stua_gc == 1) return; // already marked
  11627. assert(p->stua_gc == 0);
  11628. p->stua_gc = 1;
  11629. switch(p->type) {
  11630. case STU___function: {
  11631. stu__func *f = (stu__func *) p;
  11632. if ((stb_uint) f->closure_source <= 4) {
  11633. if (f->closure_source == 0) {
  11634. for (i=1; i <= f->code[0]; ++i)
  11635. if (!stu__number(((stua_obj *) f->code)[-i]))
  11636. stu__mark(((stua_obj *) f->code)[-i]);
  11637. }
  11638. for (i=0; i < f->num_param; ++i)
  11639. stu__mark(f->param[i]);
  11640. } else {
  11641. stu__mark(f->closure_source);
  11642. stu__mark(f->f.closure_data);
  11643. }
  11644. break;
  11645. }
  11646. case STU___dict: {
  11647. stua_dict *e = (stua_dict *) p;
  11648. for (i=0; i < e->limit; ++i)
  11649. if (e->table[i].k != STB_IEMPTY && e->table[i].k != STB_IDEL) {
  11650. if (!stu__number(e->table[i].k)) stu__mark((int) e->table[i].k);
  11651. if (!stu__number(e->table[i].v)) stu__mark((int) e->table[i].v);
  11652. }
  11653. break;
  11654. }
  11655. }
  11656. }
  11657. static int stu__num_allocs, stu__size_allocs;
  11658. static stua_obj stu__flow_val = stua_nil; // used for break & return
  11659. static void stua_gc(int force)
  11660. {
  11661. int i;
  11662. if (!force && stu__num_allocs == 0 && stu__size_allocs == 0) return;
  11663. stu__num_allocs = stu__size_allocs = 0;
  11664. //printf("[gc]\n");
  11665. // clear marks
  11666. for (i=0; i < stb_arr_len(stu__gc_ptrlist); ++i)
  11667. stu__gc_ptrlist[i]->stua_gc = 0;
  11668. // stu__mark everything reachable
  11669. stu__nil.stua_gc = stu__true.stua_gc = stu__false.stua_gc = 1;
  11670. stu__mark(stua_globals);
  11671. if (!stu__number(stu__flow_val))
  11672. stu__mark(stu__flow_val);
  11673. for (i=0; i < stb_arr_len(stu__gc_root_stack); ++i)
  11674. if (!stu__number(stu__gc_root_stack[i]))
  11675. stu__mark(stu__gc_root_stack[i]);
  11676. // sweep unreachables
  11677. for (i=0; i < stb_arr_len(stu__gc_ptrlist);) {
  11678. stu__box *z = stu__gc_ptrlist[i];
  11679. if (!z->stua_gc) {
  11680. switch (z->type) {
  11681. case STU___dict: stb_idict_destroy((stua_dict *) z); break;
  11682. case STU___error: free(((stu__wrapper *) z)->ptr); break;
  11683. case STU___string: stb_sdict_remove(stu__strings, (char*) ((stu__wrapper *) z)->ptr, NULL); free(z); break;
  11684. case STU___function: stu__free_func((stu__func *) z); break;
  11685. }
  11686. // swap in the last item over this, and repeat
  11687. z = stb_arr_pop(stu__gc_ptrlist);
  11688. stu__gc_ptrlist[i] = z;
  11689. } else
  11690. ++i;
  11691. }
  11692. }
  11693. static void stu__consider_gc(stua_obj x)
  11694. {
  11695. if (stu__size_allocs < 100000) return;
  11696. if (stu__num_allocs < 10 && stu__size_allocs < 1000000) return;
  11697. stb_arr_push(stu__gc_root_stack, x);
  11698. stua_gc(0);
  11699. stb_arr_pop(stu__gc_root_stack);
  11700. }
  11701. static stua_obj stu__makeobj(int type, void *data, int size, int safe_to_gc)
  11702. {
  11703. stua_obj x = stu__makeptr(data);
  11704. ((stu__box *) data)->type = type;
  11705. stb_arr_push(stu__gc_ptrlist, (stu__box *) data);
  11706. stu__num_allocs += 1;
  11707. stu__size_allocs += size;
  11708. if (safe_to_gc) stu__consider_gc(x);
  11709. return x;
  11710. }
  11711. stua_obj stua_box(int type, void *data, int size)
  11712. {
  11713. stu__wrapper *p = (stu__wrapper *) malloc(sizeof(*p));
  11714. p->ptr = data;
  11715. return stu__makeobj(type, p, size, 0);
  11716. }
  11717. // a stu string can be directly compared for equality, because
  11718. // they go into a hash table
  11719. stua_obj stua_string(char *z)
  11720. {
  11721. stu__wrapper *b = (stu__wrapper *) stb_sdict_get(stu__strings, z);
  11722. if (b == NULL) {
  11723. int o = stua_box(STU___string, NULL, strlen(z) + sizeof(*b));
  11724. b = stu__pw(o);
  11725. stb_sdict_add(stu__strings, z, b);
  11726. stb_sdict_getkey(stu__strings, z, (char **) &b->ptr);
  11727. }
  11728. return stu__makeptr(b);
  11729. }
  11730. // stb_obj dictionary is just an stb_idict
  11731. static void stu__set(stua_dict *d, stua_obj k, stua_obj v)
  11732. { if (stb_idict_set(d, k, v)) stu__size_allocs += 8; }
  11733. static stua_obj stu__get(stua_dict *d, stua_obj k, stua_obj res)
  11734. {
  11735. stb_idict_get_flag(d, k, &res);
  11736. return res;
  11737. }
  11738. static stua_obj make_string(char *z, int len)
  11739. {
  11740. stua_obj s;
  11741. char temp[256], *q = (char *) stb_temp(temp, len+1), *p = q;
  11742. while (len > 0) {
  11743. if (*z == '\\') {
  11744. if (z[1] == 'n') *p = '\n';
  11745. else if (z[1] == 'r') *p = '\r';
  11746. else if (z[1] == 't') *p = '\t';
  11747. else *p = z[1];
  11748. p += 1; z += 2; len -= 2;
  11749. } else {
  11750. *p++ = *z++; len -= 1;
  11751. }
  11752. }
  11753. *p = 0;
  11754. s = stua_string(q);
  11755. stb_tempfree(temp, q);
  11756. return s;
  11757. }
  11758. enum token_names
  11759. {
  11760. T__none=128,
  11761. ST_shl = STUA_op_shl, ST_ge = STUA_op_ge,
  11762. ST_shr = STUA_op_shr, ST_le = STUA_op_le,
  11763. ST_shru = STUA_op_shru, STU__negate = STUA_op_negate,
  11764. ST__reset_numbering = STUA_op_last,
  11765. ST_white,
  11766. ST_id, ST_float, ST_decimal, ST_hex, ST_char,ST_string, ST_number,
  11767. // make sure the keywords come _AFTER_ ST_id, so stb_lex prefer them
  11768. ST_if, ST_while, ST_for, ST_eq, ST_nil,
  11769. ST_then, ST_do, ST_in, ST_ne, ST_true,
  11770. ST_else, ST_break, ST_let, ST_and, ST_false,
  11771. ST_elseif, ST_continue, ST_into, ST_or, ST_repeat,
  11772. ST_end, ST_as, ST_return, ST_var, ST_func,
  11773. ST_catch, ST__frame,
  11774. ST__max_terminals,
  11775. STU__defaultparm, STU__seq,
  11776. };
  11777. static stua_dict * stu__globaldict;
  11778. stua_obj stua_globals;
  11779. static enum
  11780. {
  11781. FLOW_normal, FLOW_continue, FLOW_break, FLOW_return, FLOW_error,
  11782. } stu__flow;
  11783. stua_obj stua_error(char *z, ...)
  11784. {
  11785. stua_obj a;
  11786. char temp[4096], *x;
  11787. va_list v; va_start(v,z); vsprintf(temp, z, v); va_end(v);
  11788. x = stb_p_strdup(temp);
  11789. a = stua_box(STU___error, x, strlen(x));
  11790. stu__flow = FLOW_error;
  11791. stu__flow_val = a;
  11792. return stua_nil;
  11793. }
  11794. double stua_number(stua_obj z)
  11795. {
  11796. return stu__tag(z) == stu__int_tag ? stu__int(z) : stu__float(z);
  11797. }
  11798. stua_obj stua_make_number(double d)
  11799. {
  11800. double e = floor(d);
  11801. if (e == d && e < (1 << 29) && e >= -(1 << 29))
  11802. return stu__makeint((int) e);
  11803. else
  11804. return stua_float((float) d);
  11805. }
  11806. stua_obj (*stua_overload)(int op, stua_obj a, stua_obj b, stua_obj c) = NULL;
  11807. static stua_obj stu__op(int op, stua_obj a, stua_obj b, stua_obj c)
  11808. {
  11809. stua_obj r = STUA_NO_VALUE;
  11810. if (op == '+') {
  11811. if (stu__checkt(STU___string, a) && stu__checkt(STU___string, b)) {
  11812. ;// @TODO: string concatenation
  11813. } else if (stu__checkt(STU___function, a) && stu__checkt(STU___dict, b)) {
  11814. stu__func *f = (stu__func *) malloc(12);
  11815. assert(offsetof(stu__func, code)==12);
  11816. f->closure_source = a;
  11817. f->f.closure_data = b;
  11818. return stu__makeobj(STU___function, f, 16, 1);
  11819. }
  11820. }
  11821. if (stua_overload) r = stua_overload(op,a,b,c);
  11822. if (stu__flow != FLOW_error && r == STUA_NO_VALUE)
  11823. stua_error("Typecheck for operator %d", op), r=stua_nil;
  11824. return r;
  11825. }
  11826. #define STU__EVAL2(a,b) \
  11827. a = stu__eval(stu__f[n+1]); if (stu__flow) break; stua_pushroot(a); \
  11828. b = stu__eval(stu__f[n+2]); stua_poproot(); if (stu__flow) break;
  11829. #define STU__FB(op) \
  11830. STU__EVAL2(a,b) \
  11831. if (stu__tag(a) == stu__int_tag && stu__tag(b) == stu__int_tag) \
  11832. return ((a) op (b)); \
  11833. if (stu__number(a) && stu__number(b)) \
  11834. return stua_make_number(stua_number(a) op stua_number(b)); \
  11835. return stu__op(stu__f[n], a,b, stua_nil)
  11836. #define STU__F(op) \
  11837. STU__EVAL2(a,b) \
  11838. if (stu__number(a) && stu__number(b)) \
  11839. return stua_make_number(stua_number(a) op stua_number(b)); \
  11840. return stu__op(stu__f[n], a,b, stua_nil)
  11841. #define STU__I(op) \
  11842. STU__EVAL2(a,b) \
  11843. if (stu__tag(a) == stu__int_tag && stu__tag(b) == stu__int_tag) \
  11844. return stu__makeint(stu__int(a) op stu__int(b)); \
  11845. return stu__op(stu__f[n], a,b, stua_nil)
  11846. #define STU__C(op) \
  11847. STU__EVAL2(a,b) \
  11848. if (stu__number(a) && stu__number(b)) \
  11849. return (stua_number(a) op stua_number(b)) ? stua_true : stua_false; \
  11850. return stu__op(stu__f[n], a,b, stua_nil)
  11851. #define STU__CE(op) \
  11852. STU__EVAL2(a,b) \
  11853. return (a op b) ? stua_true : stua_false
  11854. static short *stu__f;
  11855. static stua_obj stu__f_obj;
  11856. static stua_dict *stu__c;
  11857. static stua_obj stu__funceval(stua_obj fo, stua_obj co);
  11858. static int stu__cond(stua_obj x)
  11859. {
  11860. if (stu__flow) return 0;
  11861. if (!stu__checkt(STU___boolean, x))
  11862. x = stu__op('!', x, stua_nil, stua_nil);
  11863. if (x == stua_true ) return 1;
  11864. if (x == stua_false) return 0;
  11865. stu__flow = FLOW_error;
  11866. return 0;
  11867. }
  11868. // had to manually eliminate tailcall recursion for debugging complex stuff
  11869. #define TAILCALL(x) n = (x); goto top;
  11870. static stua_obj stu__eval(int n)
  11871. {
  11872. top:
  11873. if (stu__flow >= FLOW_return) return stua_nil; // is this needed?
  11874. if (n < 0) return stu__const(stu__f)[n];
  11875. assert(n != 0 && n != 1);
  11876. switch (stu__f[n]) {
  11877. stua_obj a,b,c;
  11878. case ST_catch: a = stu__eval(stu__f[n+1]);
  11879. if (stu__flow == FLOW_error) { a=stu__flow_val; stu__flow = FLOW_normal; }
  11880. return a;
  11881. case ST_var: b = stu__eval(stu__f[n+2]); if (stu__flow) break;
  11882. stu__set(stu__c, stu__const(stu__f)[stu__f[n+1]], b);
  11883. return b;
  11884. case STU__seq: stu__eval(stu__f[n+1]); if (stu__flow) break;
  11885. TAILCALL(stu__f[n+2]);
  11886. case ST_if: if (!stu__cond(stu__eval(stu__f[n+1]))) return stua_nil;
  11887. TAILCALL(stu__f[n+2]);
  11888. case ST_else: a = stu__cond(stu__eval(stu__f[n+1]));
  11889. TAILCALL(stu__f[n + 2 + !a]);
  11890. #define STU__HANDLE_BREAK \
  11891. if (stu__flow >= FLOW_break) { \
  11892. if (stu__flow == FLOW_break) { \
  11893. a = stu__flow_val; \
  11894. stu__flow = FLOW_normal; \
  11895. stu__flow_val = stua_nil; \
  11896. return a; \
  11897. } \
  11898. return stua_nil; \
  11899. }
  11900. case ST_as: stu__eval(stu__f[n+3]);
  11901. STU__HANDLE_BREAK
  11902. // fallthrough!
  11903. case ST_while: a = stua_nil; stua_pushroot(a);
  11904. while (stu__cond(stu__eval(stu__f[n+1]))) {
  11905. stua_poproot();
  11906. a = stu__eval(stu__f[n+2]);
  11907. STU__HANDLE_BREAK
  11908. stu__flow = FLOW_normal; // clear 'continue' flag
  11909. stua_pushroot(a);
  11910. if (stu__f[n+3]) stu__eval(stu__f[n+3]);
  11911. STU__HANDLE_BREAK
  11912. stu__flow = FLOW_normal; // clear 'continue' flag
  11913. }
  11914. stua_poproot();
  11915. return a;
  11916. case ST_break: stu__flow = FLOW_break; stu__flow_val = stu__eval(stu__f[n+1]); break;
  11917. case ST_continue:stu__flow = FLOW_continue; break;
  11918. case ST_return: stu__flow = FLOW_return; stu__flow_val = stu__eval(stu__f[n+1]); break;
  11919. case ST__frame: return stu__f_obj;
  11920. case '[': STU__EVAL2(a,b);
  11921. if (stu__checkt(STU___dict, a))
  11922. return stu__get(stu__pd(a), b, stua_nil);
  11923. return stu__op(stu__f[n], a, b, stua_nil);
  11924. case '=': a = stu__eval(stu__f[n+2]); if (stu__flow) break;
  11925. n = stu__f[n+1];
  11926. if (stu__f[n] == ST_id) {
  11927. if (!stb_idict_update(stu__c, stu__const(stu__f)[stu__f[n+1]], a))
  11928. if (!stb_idict_update(stu__globaldict, stu__const(stu__f)[stu__f[n+1]], a))
  11929. return stua_error("Assignment to undefined variable");
  11930. } else if (stu__f[n] == '[') {
  11931. stua_pushroot(a);
  11932. b = stu__eval(stu__f[n+1]); if (stu__flow) { stua_poproot(); break; }
  11933. stua_pushroot(b);
  11934. c = stu__eval(stu__f[n+2]); stua_poproot(); stua_poproot();
  11935. if (stu__flow) break;
  11936. if (!stu__checkt(STU___dict, b)) return stua_nil;
  11937. stu__set(stu__pd(b), c, a);
  11938. } else {
  11939. return stu__op(stu__f[n], stu__eval(n), a, stua_nil);
  11940. }
  11941. return a;
  11942. case STU__defaultparm:
  11943. a = stu__eval(stu__f[n+2]);
  11944. stu__flow = FLOW_normal;
  11945. if (stb_idict_add(stu__c, stu__const(stu__f)[stu__f[n+1]], a))
  11946. stu__size_allocs += 8;
  11947. return stua_nil;
  11948. case ST_id: a = stu__get(stu__c, stu__const(stu__f)[stu__f[n+1]], STUA_NO_VALUE); // try local variable
  11949. return a != STUA_NO_VALUE // else try stu__compile_global_scope variable
  11950. ? a : stu__get(stu__globaldict, stu__const(stu__f)[stu__f[n+1]], stua_nil);
  11951. case STU__negate:a = stu__eval(stu__f[n+1]); if (stu__flow) break;
  11952. return stu__isint(a) ? -a : stu__op(stu__f[n], a, stua_nil, stua_nil);
  11953. case '~': a = stu__eval(stu__f[n+1]); if (stu__flow) break;
  11954. return stu__isint(a) ? (~a)&~3 : stu__op(stu__f[n], a, stua_nil, stua_nil);
  11955. case '!': a = stu__eval(stu__f[n+1]); if (stu__flow) break;
  11956. a = stu__cond(a); if (stu__flow) break;
  11957. return a ? stua_true : stua_false;
  11958. case ST_eq: STU__CE(==); case ST_le: STU__C(<=); case '<': STU__C(<);
  11959. case ST_ne: STU__CE(!=); case ST_ge: STU__C(>=); case '>': STU__C(>);
  11960. case '+' : STU__FB(+); case '*': STU__F(*); case '&': STU__I(&); case ST_shl: STU__I(<<);
  11961. case '-' : STU__FB(-); case '/': STU__F(/); case '|': STU__I(|); case ST_shr: STU__I(>>);
  11962. case '%': STU__I(%); case '^': STU__I(^);
  11963. case ST_shru: STU__EVAL2(a,b);
  11964. if (stu__tag(a) == stu__int_tag && stu__tag(b) == stu__int_tag)
  11965. return stu__makeint((unsigned) stu__int(a) >> stu__int(b));
  11966. return stu__op(stu__f[n], a,b, stua_nil);
  11967. case ST_and: a = stu__eval(stu__f[n+1]); b = stu__cond(a); if (stu__flow) break;
  11968. return a ? stu__eval(stu__f[n+2]) : a;
  11969. case ST_or : a = stu__eval(stu__f[n+1]); b = stu__cond(a); if (stu__flow) break;
  11970. return a ? b : stu__eval(stu__f[n+2]);
  11971. case'(':case':': STU__EVAL2(a,b);
  11972. if (!stu__checkt(STU___function, a))
  11973. return stu__op(stu__f[n], a,b, stua_nil);
  11974. if (!stu__checkt(STU___dict, b))
  11975. return stua_nil;
  11976. if (stu__f[n] == ':')
  11977. b = stu__makeobj(STU___dict, stb_idict_copy(stu__pd(b)), stb_idict_memory_usage(stu__pd(b)), 0);
  11978. a = stu__funceval(a,b);
  11979. return a;
  11980. case '{' : {
  11981. stua_dict *d;
  11982. d = stb_idict_new_size(stu__f[n+1] > 40 ? 64 : 16);
  11983. if (d == NULL)
  11984. return stua_nil; // breakpoint fodder
  11985. c = stu__makeobj(STU___dict, d, 32, 1);
  11986. stua_pushroot(c);
  11987. a = stu__f[n+1];
  11988. for (b=0; b < a; ++b) {
  11989. stua_obj x = stua_pushroot(stu__eval(stu__f[n+2 + b*2 + 0]));
  11990. stua_obj y = stu__eval(stu__f[n+2 + b*2 + 1]);
  11991. stua_poproot();
  11992. if (stu__flow) { stua_poproot(); return stua_nil; }
  11993. stu__set(d, x, y);
  11994. }
  11995. stua_poproot();
  11996. return c;
  11997. }
  11998. default: if (stu__f[n] < 0) return stu__const(stu__f)[stu__f[n]];
  11999. assert(0); /* NOTREACHED */ // internal error!
  12000. }
  12001. return stua_nil;
  12002. }
  12003. int stb__stua_nesting;
  12004. static stua_obj stu__funceval(stua_obj fo, stua_obj co)
  12005. {
  12006. stu__func *f = stu__pf(fo);
  12007. stua_dict *context = stu__pd(co);
  12008. int i,j;
  12009. stua_obj p;
  12010. short *tf = stu__f; // save previous function
  12011. stua_dict *tc = stu__c;
  12012. if (stu__flow == FLOW_error) return stua_nil;
  12013. assert(stu__flow == FLOW_normal);
  12014. stua_pushroot(fo);
  12015. stua_pushroot(co);
  12016. stu__consider_gc(stua_nil);
  12017. while ((stb_uint) f->closure_source > 4) {
  12018. // add data from closure to context
  12019. stua_dict *e = (stua_dict *) stu__pd(f->f.closure_data);
  12020. for (i=0; i < e->limit; ++i)
  12021. if (e->table[i].k != STB_IEMPTY && e->table[i].k != STB_IDEL)
  12022. if (stb_idict_add(context, e->table[i].k, e->table[i].v))
  12023. stu__size_allocs += 8;
  12024. // use add so if it's already defined, we don't override it; that way
  12025. // explicit parameters win over applied ones, and most recent applications
  12026. // win over previous ones
  12027. f = stu__pf(f->closure_source);
  12028. }
  12029. for (j=0, i=0; i < f->num_param; ++i)
  12030. // if it doesn't already exist, add it from the numbered parameters
  12031. if (stb_idict_add(context, f->param[i], stu__get(context, stu__int(j), stua_nil)))
  12032. ++j;
  12033. // @TODO: if (stu__get(context, stu__int(f->num_param+1)) != STUA_NO_VALUE) // error: too many parameters
  12034. // @TODO: ditto too few parameters
  12035. if (f->closure_source == 4)
  12036. p = f->f.func(context);
  12037. else {
  12038. stu__f = f->code, stu__c = context;
  12039. stu__f_obj = co;
  12040. ++stb__stua_nesting;
  12041. if (stu__f[1])
  12042. p = stu__eval(stu__f[1]);
  12043. else
  12044. p = stua_nil;
  12045. --stb__stua_nesting;
  12046. stu__f = tf, stu__c = tc; // restore previous function
  12047. if (stu__flow == FLOW_return) {
  12048. stu__flow = FLOW_normal;
  12049. p = stu__flow_val;
  12050. stu__flow_val = stua_nil;
  12051. }
  12052. }
  12053. stua_poproot();
  12054. stua_poproot();
  12055. return p;
  12056. }
  12057. // Parser
  12058. static int stu__tok;
  12059. static stua_obj stu__tokval;
  12060. static char *stu__curbuf, *stu__bufstart;
  12061. static stb_matcher *stu__lex_matcher;
  12062. static unsigned char stu__prec[ST__max_terminals], stu__end[ST__max_terminals];
  12063. static void stu__nexttoken(void)
  12064. {
  12065. int len;
  12066. retry:
  12067. stu__tok = stb_lex(stu__lex_matcher, stu__curbuf, &len);
  12068. if (stu__tok == 0)
  12069. return;
  12070. switch(stu__tok) {
  12071. case ST_white : stu__curbuf += len; goto retry;
  12072. case T__none : stu__tok = *stu__curbuf; break;
  12073. case ST_string: stu__tokval = make_string(stu__curbuf+1, len-2); break;
  12074. case ST_id : stu__tokval = make_string(stu__curbuf, len); break;
  12075. case ST_hex : stu__tokval = stu__makeint(strtol(stu__curbuf+2,NULL,16)); stu__tok = ST_number; break;
  12076. case ST_decimal: stu__tokval = stu__makeint(strtol(stu__curbuf ,NULL,10)); stu__tok = ST_number; break;
  12077. case ST_float : stu__tokval = stua_float((float) atof(stu__curbuf)) ; stu__tok = ST_number; break;
  12078. case ST_char : stu__tokval = stu__curbuf[2] == '\\' ? stu__curbuf[3] : stu__curbuf[2];
  12079. if (stu__curbuf[3] == 't') stu__tokval = '\t';
  12080. if (stu__curbuf[3] == 'n') stu__tokval = '\n';
  12081. if (stu__curbuf[3] == 'r') stu__tokval = '\r';
  12082. stu__tokval = stu__makeint(stu__tokval);
  12083. stu__tok = ST_number;
  12084. break;
  12085. }
  12086. stu__curbuf += len;
  12087. }
  12088. static struct { int stu__tok; char *regex; } stu__lexemes[] =
  12089. {
  12090. ST_white , "([ \t\n\r]|/\\*(.|\n)*\\*/|//[^\r\n]*([\r\n]|$))+",
  12091. ST_id , "[_a-zA-Z][_a-zA-Z0-9]*",
  12092. ST_hex , "0x[0-9a-fA-F]+",
  12093. ST_decimal, "[0-9]+[0-9]*",
  12094. ST_float , "[0-9]+\\.?[0-9]*([eE][-+]?[0-9]+)?",
  12095. ST_float , "\\.[0-9]+([eE][-+]?[0-9]+)?",
  12096. ST_char , "c'(\\\\.|[^\\'])'",
  12097. ST_string , "\"(\\\\.|[^\\\"\n\r])*\"",
  12098. ST_string , "\'(\\\\.|[^\\\'\n\r])*\'",
  12099. #define stua_key4(a,b,c,d) ST_##a, #a, ST_##b, #b, ST_##c, #c, ST_##d, #d,
  12100. stua_key4(if,then,else,elseif) stua_key4(while,do,for,in)
  12101. stua_key4(func,var,let,break) stua_key4(nil,true,false,end)
  12102. stua_key4(return,continue,as,repeat) stua_key4(_frame,catch,catch,catch)
  12103. ST_shl, "<<", ST_and, "&&", ST_eq, "==", ST_ge, ">=",
  12104. ST_shr, ">>", ST_or , "||", ST_ne, "!=", ST_le, "<=",
  12105. ST_shru,">>>", ST_into, "=>",
  12106. T__none, ".",
  12107. };
  12108. typedef struct
  12109. {
  12110. stua_obj *data; // constants being compiled
  12111. short *code; // code being compiled
  12112. stua_dict *locals;
  12113. short *non_local_refs;
  12114. } stu__comp_func;
  12115. static stu__comp_func stu__pfunc;
  12116. static stu__comp_func *func_stack = NULL;
  12117. static void stu__push_func_comp(void)
  12118. {
  12119. stb_arr_push(func_stack, stu__pfunc);
  12120. stu__pfunc.data = NULL;
  12121. stu__pfunc.code = NULL;
  12122. stu__pfunc.locals = stb_idict_new_size(16);
  12123. stu__pfunc.non_local_refs = NULL;
  12124. stb_arr_push(stu__pfunc.code, 0); // number of data items
  12125. stb_arr_push(stu__pfunc.code, 1); // starting execution address
  12126. }
  12127. static void stu__pop_func_comp(void)
  12128. {
  12129. stb_arr_free(stu__pfunc.code);
  12130. stb_arr_free(stu__pfunc.data);
  12131. stb_idict_destroy(stu__pfunc.locals);
  12132. stb_arr_free(stu__pfunc.non_local_refs);
  12133. stu__pfunc = stb_arr_pop(func_stack);
  12134. }
  12135. // if an id is a reference to an outer lexical scope, this
  12136. // function returns the "name" of it, and updates the stack
  12137. // structures to make sure the names are propagated in.
  12138. static int stu__nonlocal_id(stua_obj var_obj)
  12139. {
  12140. stua_obj dummy, var = var_obj;
  12141. int i, n = stb_arr_len(func_stack), j,k;
  12142. if (stb_idict_get_flag(stu__pfunc.locals, var, &dummy)) return 0;
  12143. for (i=n-1; i > 1; --i) {
  12144. if (stb_idict_get_flag(func_stack[i].locals, var, &dummy))
  12145. break;
  12146. }
  12147. if (i <= 1) return 0; // stu__compile_global_scope
  12148. j = i; // need to access variable from j'th frame
  12149. for (i=0; i < stb_arr_len(stu__pfunc.non_local_refs); ++i)
  12150. if (stu__pfunc.non_local_refs[i] == j) return j-n;
  12151. stb_arr_push(stu__pfunc.non_local_refs, j-n);
  12152. // now make sure all the parents propagate it down
  12153. for (k=n-1; k > 1; --k) {
  12154. if (j-k >= 0) return j-n; // comes direct from this parent
  12155. for(i=0; i < stb_arr_len(func_stack[k].non_local_refs); ++i)
  12156. if (func_stack[k].non_local_refs[i] == j-k)
  12157. return j-n;
  12158. stb_arr_push(func_stack[k].non_local_refs, j-k);
  12159. }
  12160. assert (k != 1);
  12161. return j-n;
  12162. }
  12163. static int stu__off(void) { return stb_arr_len(stu__pfunc.code); }
  12164. static void stu__cc(int a)
  12165. {
  12166. assert(a >= -2000 && a < 5000);
  12167. stb_arr_push(stu__pfunc.code, a);
  12168. }
  12169. static int stu__cc1(int a) { stu__cc(a); return stu__off()-1; }
  12170. static int stu__cc2(int a, int b) { stu__cc(a); stu__cc(b); return stu__off()-2; }
  12171. static int stu__cc3(int a, int b, int c) {
  12172. if (a == '=') assert(c != 0);
  12173. stu__cc(a); stu__cc(b); stu__cc(c); return stu__off()-3; }
  12174. static int stu__cc4(int a, int b, int c, int d) { stu__cc(a); stu__cc(b); stu__cc(c); stu__cc(d); return stu__off()-4; }
  12175. static int stu__cdv(stua_obj p)
  12176. {
  12177. int i;
  12178. assert(p != STUA_NO_VALUE);
  12179. for (i=0; i < stb_arr_len(stu__pfunc.data); ++i)
  12180. if (stu__pfunc.data[i] == p)
  12181. break;
  12182. if (i == stb_arr_len(stu__pfunc.data))
  12183. stb_arr_push(stu__pfunc.data, p);
  12184. return ~i;
  12185. }
  12186. static int stu__cdt(void)
  12187. {
  12188. int z = stu__cdv(stu__tokval);
  12189. stu__nexttoken();
  12190. return z;
  12191. }
  12192. static int stu__seq(int a, int b)
  12193. {
  12194. return !a ? b : !b ? a : stu__cc3(STU__seq, a,b);
  12195. }
  12196. static char stu__comp_err_str[1024];
  12197. static int stu__comp_err_line;
  12198. static int stu__err(char *str, ...)
  12199. {
  12200. va_list v;
  12201. char *s = stu__bufstart;
  12202. stu__comp_err_line = 1;
  12203. while (s < stu__curbuf) {
  12204. if (s[0] == '\n' || s[0] == '\r') {
  12205. if (s[0]+s[1] == '\n' + '\r') ++s;
  12206. ++stu__comp_err_line;
  12207. }
  12208. ++s;
  12209. }
  12210. va_start(v, str);
  12211. vsprintf(stu__comp_err_str, str, v);
  12212. va_end(v);
  12213. return 0;
  12214. }
  12215. static int stu__accept(int p)
  12216. {
  12217. if (stu__tok != p) return 0;
  12218. stu__nexttoken();
  12219. return 1;
  12220. }
  12221. static int stu__demand(int p)
  12222. {
  12223. if (stu__accept(p)) return 1;
  12224. return stu__err("Didn't find expected stu__tok");
  12225. }
  12226. static int stu__demandv(int p, stua_obj *val)
  12227. {
  12228. if (stu__tok == p || p==0) {
  12229. *val = stu__tokval;
  12230. stu__nexttoken();
  12231. return 1;
  12232. } else
  12233. return 0;
  12234. }
  12235. static int stu__expr(int p);
  12236. int stu__nexpr(int p) { stu__nexttoken(); return stu__expr(p); }
  12237. static int stu__statements(int once, int as);
  12238. static int stu__parse_if(void) // parse both ST_if and ST_elseif
  12239. {
  12240. int b,c,a;
  12241. a = stu__nexpr(1); if (!a) return 0;
  12242. if (!stu__demand(ST_then)) return stu__err("expecting THEN");
  12243. b = stu__statements(0,0); if (!b) return 0;
  12244. if (b == 1) b = -1;
  12245. if (stu__tok == ST_elseif) {
  12246. return stu__parse_if();
  12247. } else if (stu__accept(ST_else)) {
  12248. c = stu__statements(0,0); if (!c) return 0;
  12249. if (!stu__demand(ST_end)) return stu__err("expecting END after else clause");
  12250. return stu__cc4(ST_else, a, b, c);
  12251. } else {
  12252. if (!stu__demand(ST_end)) return stu__err("expecting END in if statement");
  12253. return stu__cc3(ST_if, a, b);
  12254. }
  12255. }
  12256. int stu__varinit(int z, int in_globals)
  12257. {
  12258. int a,b;
  12259. stu__nexttoken();
  12260. while (stu__demandv(ST_id, &b)) {
  12261. if (!stb_idict_add(stu__pfunc.locals, b, 1))
  12262. if (!in_globals) return stu__err("Redefined variable %s.", stu__pw(b)->ptr);
  12263. if (stu__accept('=')) {
  12264. a = stu__expr(1); if (!a) return 0;
  12265. } else
  12266. a = stu__cdv(stua_nil);
  12267. z = stu__seq(z, stu__cc3(ST_var, stu__cdv(b), a));
  12268. if (!stu__accept(',')) break;
  12269. }
  12270. return z;
  12271. }
  12272. static int stu__compile_unary(int z, int outparm, int require_inparm)
  12273. {
  12274. int op = stu__tok, a, b;
  12275. stu__nexttoken();
  12276. if (outparm) {
  12277. if (require_inparm || (stu__tok && stu__tok != ST_end && stu__tok != ST_else && stu__tok != ST_elseif && stu__tok !=';')) {
  12278. a = stu__expr(1); if (!a) return 0;
  12279. } else
  12280. a = stu__cdv(stua_nil);
  12281. b = stu__cc2(op, a);
  12282. } else
  12283. b = stu__cc1(op);
  12284. return stu__seq(z,b);
  12285. }
  12286. static int stu__assign(void)
  12287. {
  12288. int z;
  12289. stu__accept(ST_let);
  12290. z = stu__expr(1); if (!z) return 0;
  12291. if (stu__accept('=')) {
  12292. int y,p = (z >= 0 ? stu__pfunc.code[z] : 0);
  12293. if (z < 0 || (p != ST_id && p != '[')) return stu__err("Invalid lvalue in assignment");
  12294. y = stu__assign(); if (!y) return 0;
  12295. z = stu__cc3('=', z, y);
  12296. }
  12297. return z;
  12298. }
  12299. static int stu__statements(int once, int stop_while)
  12300. {
  12301. int a,b, c, z=0;
  12302. for(;;) {
  12303. switch (stu__tok) {
  12304. case ST_if : a = stu__parse_if(); if (!a) return 0;
  12305. z = stu__seq(z, a);
  12306. break;
  12307. case ST_while : if (stop_while) return (z ? z:1);
  12308. a = stu__nexpr(1); if (!a) return 0;
  12309. if (stu__accept(ST_as)) c = stu__statements(0,0); else c = 0;
  12310. if (!stu__demand(ST_do)) return stu__err("expecting DO");
  12311. b = stu__statements(0,0); if (!b) return 0;
  12312. if (!stu__demand(ST_end)) return stu__err("expecting END");
  12313. if (b == 1) b = -1;
  12314. z = stu__seq(z, stu__cc4(ST_while, a, b, c));
  12315. break;
  12316. case ST_repeat : stu__nexttoken();
  12317. c = stu__statements(0,1); if (!c) return 0;
  12318. if (!stu__demand(ST_while)) return stu__err("expecting WHILE");
  12319. a = stu__expr(1); if (!a) return 0;
  12320. if (!stu__demand(ST_do)) return stu__err("expecting DO");
  12321. b = stu__statements(0,0); if (!b) return 0;
  12322. if (!stu__demand(ST_end)) return stu__err("expecting END");
  12323. if (b == 1) b = -1;
  12324. z = stu__seq(z, stu__cc4(ST_as, a, b, c));
  12325. break;
  12326. case ST_catch : a = stu__nexpr(1); if (!a) return 0;
  12327. z = stu__seq(z, stu__cc2(ST_catch, a));
  12328. break;
  12329. case ST_var : z = stu__varinit(z,0); break;
  12330. case ST_return : z = stu__compile_unary(z,1,1); break;
  12331. case ST_continue:z = stu__compile_unary(z,0,0); break;
  12332. case ST_break : z = stu__compile_unary(z,1,0); break;
  12333. case ST_into : if (z == 0 && !once) return stu__err("=> cannot be first statement in block");
  12334. a = stu__nexpr(99);
  12335. b = (a >= 0? stu__pfunc.code[a] : 0);
  12336. if (a < 0 || (b != ST_id && b != '[')) return stu__err("Invalid lvalue on right side of =>");
  12337. z = stu__cc3('=', a, z);
  12338. break;
  12339. default : if (stu__end[stu__tok]) return once ? 0 : (z ? z:1);
  12340. a = stu__assign(); if (!a) return 0;
  12341. stu__accept(';');
  12342. if (stu__tok && !stu__end[stu__tok]) {
  12343. if (a < 0)
  12344. return stu__err("Constant has no effect");
  12345. if (stu__pfunc.code[a] != '(' && stu__pfunc.code[a] != '=')
  12346. return stu__err("Expression has no effect");
  12347. }
  12348. z = stu__seq(z, a);
  12349. break;
  12350. }
  12351. if (!z) return 0;
  12352. stu__accept(';');
  12353. if (once && stu__tok != ST_into) return z;
  12354. }
  12355. }
  12356. static int stu__postexpr(int z, int p);
  12357. static int stu__dictdef(int end, int *count)
  12358. {
  12359. int z,n=0,i,flags=0;
  12360. short *dict=NULL;
  12361. stu__nexttoken();
  12362. while (stu__tok != end) {
  12363. if (stu__tok == ST_id) {
  12364. stua_obj id = stu__tokval;
  12365. stu__nexttoken();
  12366. if (stu__tok == '=') {
  12367. flags |= 1;
  12368. stb_arr_push(dict, stu__cdv(id));
  12369. z = stu__nexpr(1); if (!z) return 0;
  12370. } else {
  12371. z = stu__cc2(ST_id, stu__cdv(id));
  12372. z = stu__postexpr(z,1); if (!z) return 0;
  12373. flags |= 2;
  12374. stb_arr_push(dict, stu__cdv(stu__makeint(n++)));
  12375. }
  12376. } else {
  12377. z = stu__expr(1); if (!z) return 0;
  12378. flags |= 2;
  12379. stb_arr_push(dict, stu__cdv(stu__makeint(n++)));
  12380. }
  12381. if (end != ')' && flags == 3) { z=stu__err("can't mix initialized and uninitialized defs"); goto done;}
  12382. stb_arr_push(dict, z);
  12383. if (!stu__accept(',')) break;
  12384. }
  12385. if (!stu__demand(end))
  12386. return stu__err(end == ')' ? "Expecting ) at end of function call"
  12387. : "Expecting } at end of dictionary definition");
  12388. z = stu__cc2('{', stb_arr_len(dict)/2);
  12389. for (i=0; i < stb_arr_len(dict); ++i)
  12390. stu__cc(dict[i]);
  12391. if (count) *count = n;
  12392. done:
  12393. stb_arr_free(dict);
  12394. return z;
  12395. }
  12396. static int stu__comp_id(void)
  12397. {
  12398. int z,d;
  12399. d = stu__nonlocal_id(stu__tokval);
  12400. if (d == 0)
  12401. return z = stu__cc2(ST_id, stu__cdt());
  12402. // access a non-local frame by naming it with the appropriate int
  12403. assert(d < 0);
  12404. z = stu__cdv(d); // relative frame # is the 'variable' in our local frame
  12405. z = stu__cc2(ST_id, z); // now access that dictionary
  12406. return stu__cc3('[', z, stu__cdt()); // now access the variable from that dir
  12407. }
  12408. static stua_obj stu__funcdef(stua_obj *id, stua_obj *func);
  12409. static int stu__expr(int p)
  12410. {
  12411. int z;
  12412. // unary
  12413. switch (stu__tok) {
  12414. case ST_number: z = stu__cdt(); break;
  12415. case ST_string: z = stu__cdt(); break; // @TODO - string concatenation like C
  12416. case ST_id : z = stu__comp_id(); break;
  12417. case ST__frame: z = stu__cc1(ST__frame); stu__nexttoken(); break;
  12418. case ST_func : z = stu__funcdef(NULL,NULL); break;
  12419. case ST_if : z = stu__parse_if(); break;
  12420. case ST_nil : z = stu__cdv(stua_nil); stu__nexttoken(); break;
  12421. case ST_true : z = stu__cdv(stua_true); stu__nexttoken(); break;
  12422. case ST_false : z = stu__cdv(stua_false); stu__nexttoken(); break;
  12423. case '-' : z = stu__nexpr(99); if (z) z=stu__cc2(STU__negate,z); else return z; break;
  12424. case '!' : z = stu__nexpr(99); if (z) z=stu__cc2('!',z); else return z; break;
  12425. case '~' : z = stu__nexpr(99); if (z) z=stu__cc2('~',z); else return z; break;
  12426. case '{' : z = stu__dictdef('}', NULL); break;
  12427. default : return stu__err("Unexpected token");
  12428. case '(' : stu__nexttoken(); z = stu__statements(0,0); if (!stu__demand(')')) return stu__err("Expecting )");
  12429. }
  12430. return stu__postexpr(z,p);
  12431. }
  12432. static int stu__postexpr(int z, int p)
  12433. {
  12434. int q;
  12435. // postfix
  12436. while (stu__tok == '(' || stu__tok == '[' || stu__tok == '.') {
  12437. if (stu__accept('.')) {
  12438. // MUST be followed by a plain identifier! use [] for other stuff
  12439. if (stu__tok != ST_id) return stu__err("Must follow . with plain name; try [] instead");
  12440. z = stu__cc3('[', z, stu__cdv(stu__tokval));
  12441. stu__nexttoken();
  12442. } else if (stu__accept('[')) {
  12443. while (stu__tok != ']') {
  12444. int r = stu__expr(1); if (!r) return 0;
  12445. z = stu__cc3('[', z, r);
  12446. if (!stu__accept(',')) break;
  12447. }
  12448. if (!stu__demand(']')) return stu__err("Expecting ]");
  12449. } else {
  12450. int n, p = stu__dictdef(')', &n); if (!p) return 0;
  12451. #if 0 // this is incorrect!
  12452. if (z > 0 && stu__pfunc.code[z] == ST_id) {
  12453. stua_obj q = stu__get(stu__globaldict, stu__pfunc.data[-stu__pfunc.code[z+1]-1], stua_nil);
  12454. if (stu__checkt(STU___function, q))
  12455. if ((stu__pf(q))->num_param != n)
  12456. return stu__err("Incorrect number of parameters");
  12457. }
  12458. #endif
  12459. z = stu__cc3('(', z, p);
  12460. }
  12461. }
  12462. // binop - this implementation taken from lcc
  12463. for (q=stu__prec[stu__tok]; q >= p; --q) {
  12464. while (stu__prec[stu__tok] == q) {
  12465. int o = stu__tok, y = stu__nexpr(p+1); if (!y) return 0;
  12466. z = stu__cc3(o,z,y);
  12467. }
  12468. }
  12469. return z;
  12470. }
  12471. static stua_obj stu__finish_func(stua_obj *param, int start)
  12472. {
  12473. int n, size;
  12474. stu__func *f = (stu__func *) malloc(sizeof(*f));
  12475. f->closure_source = 0;
  12476. f->num_param = stb_arr_len(param);
  12477. f->param = (int *) stb_copy(param, f->num_param * sizeof(*f->param));
  12478. size = stb_arr_storage(stu__pfunc.code) + stb_arr_storage(stu__pfunc.data) + sizeof(*f) + 8;
  12479. f->f.store = malloc(stb_arr_storage(stu__pfunc.code) + stb_arr_storage(stu__pfunc.data));
  12480. f->code = (short *) ((char *) f->f.store + stb_arr_storage(stu__pfunc.data));
  12481. memcpy(f->code, stu__pfunc.code, stb_arr_storage(stu__pfunc.code));
  12482. f->code[1] = start;
  12483. f->code[0] = stb_arr_len(stu__pfunc.data);
  12484. for (n=0; n < f->code[0]; ++n)
  12485. ((stua_obj *) f->code)[-1-n] = stu__pfunc.data[n];
  12486. return stu__makeobj(STU___function, f, size, 0);
  12487. }
  12488. static int stu__funcdef(stua_obj *id, stua_obj *result)
  12489. {
  12490. int n,z=0,i,q;
  12491. stua_obj *param = NULL;
  12492. short *nonlocal;
  12493. stua_obj v,f=stua_nil;
  12494. assert(stu__tok == ST_func);
  12495. stu__nexttoken();
  12496. if (id) {
  12497. if (!stu__demandv(ST_id, id)) return stu__err("Expecting function name");
  12498. } else
  12499. stu__accept(ST_id);
  12500. if (!stu__demand('(')) return stu__err("Expecting ( for function parameter");
  12501. stu__push_func_comp();
  12502. while (stu__tok != ')') {
  12503. if (!stu__demandv(ST_id, &v)) { z=stu__err("Expecting parameter name"); goto done; }
  12504. stb_idict_add(stu__pfunc.locals, v, 1);
  12505. if (stu__tok == '=') {
  12506. n = stu__nexpr(1); if (!n) { z=0; goto done; }
  12507. z = stu__seq(z, stu__cc3(STU__defaultparm, stu__cdv(v), n));
  12508. } else
  12509. stb_arr_push(param, v);
  12510. if (!stu__accept(',')) break;
  12511. }
  12512. if (!stu__demand(')')) { z=stu__err("Expecting ) at end of parameter list"); goto done; }
  12513. n = stu__statements(0,0); if (!n) { z=0; goto done; }
  12514. if (!stu__demand(ST_end)) { z=stu__err("Expecting END at end of function"); goto done; }
  12515. if (n == 1) n = 0;
  12516. n = stu__seq(z,n);
  12517. f = stu__finish_func(param, n);
  12518. if (result) { *result = f; z=1; stu__pop_func_comp(); }
  12519. else {
  12520. nonlocal = stu__pfunc.non_local_refs;
  12521. stu__pfunc.non_local_refs = NULL;
  12522. stu__pop_func_comp();
  12523. z = stu__cdv(f);
  12524. if (nonlocal) { // build a closure with references to the needed frames
  12525. short *initcode = NULL;
  12526. for (i=0; i < stb_arr_len(nonlocal); ++i) {
  12527. int k = nonlocal[i], p;
  12528. stb_arr_push(initcode, stu__cdv(k));
  12529. if (k == -1) p = stu__cc1(ST__frame);
  12530. else { p = stu__cdv(stu__makeint(k+1)); p = stu__cc2(ST_id, p); }
  12531. stb_arr_push(initcode, p);
  12532. }
  12533. q = stu__cc2('{', stb_arr_len(nonlocal));
  12534. for (i=0; i < stb_arr_len(initcode); ++i)
  12535. stu__cc(initcode[i]);
  12536. z = stu__cc3('+', z, q);
  12537. stb_arr_free(initcode);
  12538. }
  12539. stb_arr_free(nonlocal);
  12540. }
  12541. done:
  12542. stb_arr_free(param);
  12543. if (!z) stu__pop_func_comp();
  12544. return z;
  12545. }
  12546. static int stu__compile_global_scope(void)
  12547. {
  12548. stua_obj o;
  12549. int z=0;
  12550. stu__push_func_comp();
  12551. while (stu__tok != 0) {
  12552. if (stu__tok == ST_func) {
  12553. stua_obj id, f;
  12554. if (!stu__funcdef(&id,&f))
  12555. goto error;
  12556. stu__set(stu__globaldict, id, f);
  12557. } else if (stu__tok == ST_var) {
  12558. z = stu__varinit(z,1); if (!z) goto error;
  12559. } else {
  12560. int y = stu__statements(1,0); if (!y) goto error;
  12561. z = stu__seq(z,y);
  12562. }
  12563. stu__accept(';');
  12564. }
  12565. o = stu__finish_func(NULL, z);
  12566. stu__pop_func_comp();
  12567. o = stu__funceval(o, stua_globals); // initialize stu__globaldict
  12568. if (stu__flow == FLOW_error)
  12569. printf("Error: %s\n", ((stu__wrapper *) stu__ptr(stu__flow_val))->ptr);
  12570. return 1;
  12571. error:
  12572. stu__pop_func_comp();
  12573. return 0;
  12574. }
  12575. stua_obj stu__myprint(stua_dict *context)
  12576. {
  12577. stua_obj x = stu__get(context, stua_string("x"), stua_nil);
  12578. if ((x & 1) == stu__float_tag) printf("%f", stu__getfloat(x));
  12579. else if (stu__tag(x) == stu__int_tag) printf("%d", stu__int(x));
  12580. else {
  12581. stu__wrapper *s = stu__pw(x);
  12582. if (s->type == STU___string || s->type == STU___error)
  12583. printf("%s", s->ptr);
  12584. else if (s->type == STU___dict) printf("{{dictionary}}");
  12585. else if (s->type == STU___function) printf("[[function]]");
  12586. else
  12587. printf("[[ERROR:%s]]", s->ptr);
  12588. }
  12589. return x;
  12590. }
  12591. void stua_init(void)
  12592. {
  12593. if (!stu__globaldict) {
  12594. int i;
  12595. stua_obj s;
  12596. stu__func *f;
  12597. stu__prec[ST_and] = stu__prec[ST_or] = 1;
  12598. stu__prec[ST_eq ] = stu__prec[ST_ne] = stu__prec[ST_le] =
  12599. stu__prec[ST_ge] = stu__prec['>' ] = stu__prec['<'] = 2;
  12600. stu__prec[':'] = 3;
  12601. stu__prec['&'] = stu__prec['|'] = stu__prec['^'] = 4;
  12602. stu__prec['+'] = stu__prec['-'] = 5;
  12603. stu__prec['*'] = stu__prec['/'] = stu__prec['%'] =
  12604. stu__prec[ST_shl]= stu__prec[ST_shr]= stu__prec[ST_shru]= 6;
  12605. stu__end[')'] = stu__end[ST_end] = stu__end[ST_else] = 1;
  12606. stu__end[ST_do] = stu__end[ST_elseif] = 1;
  12607. stu__float_init();
  12608. stu__lex_matcher = stb_lex_matcher();
  12609. for (i=0; i < sizeof(stu__lexemes)/sizeof(stu__lexemes[0]); ++i)
  12610. stb_lex_item(stu__lex_matcher, stu__lexemes[i].regex, stu__lexemes[i].stu__tok);
  12611. stu__globaldict = stb_idict_new_size(64);
  12612. stua_globals = stu__makeobj(STU___dict, stu__globaldict, 0,0);
  12613. stu__strings = stb_sdict_new(0);
  12614. stu__curbuf = stu__bufstart = "func _print(x) end\n"
  12615. "func print()\n var x=0 while _frame[x] != nil as x=x+1 do _print(_frame[x]) end end\n";
  12616. stu__nexttoken();
  12617. if (!stu__compile_global_scope())
  12618. printf("Compile error in line %d: %s\n", stu__comp_err_line, stu__comp_err_str);
  12619. s = stu__get(stu__globaldict, stua_string("_print"), stua_nil);
  12620. if (stu__tag(s) == stu__ptr_tag && stu__ptr(s)->type == STU___function) {
  12621. f = stu__pf(s);
  12622. free(f->f.store);
  12623. f->closure_source = 4;
  12624. f->f.func = stu__myprint;
  12625. f->code = NULL;
  12626. }
  12627. }
  12628. }
  12629. void stua_uninit(void)
  12630. {
  12631. if (stu__globaldict) {
  12632. stb_idict_remove_all(stu__globaldict);
  12633. stb_arr_setlen(stu__gc_root_stack, 0);
  12634. stua_gc(1);
  12635. stb_idict_destroy(stu__globaldict);
  12636. stb_sdict_delete(stu__strings);
  12637. stb_matcher_free(stu__lex_matcher);
  12638. stb_arr_free(stu__gc_ptrlist);
  12639. stb_arr_free(func_stack);
  12640. stb_arr_free(stu__gc_root_stack);
  12641. stu__globaldict = NULL;
  12642. }
  12643. }
  12644. void stua_run_script(char *s)
  12645. {
  12646. stua_init();
  12647. stu__curbuf = stu__bufstart = s;
  12648. stu__nexttoken();
  12649. stu__flow = FLOW_normal;
  12650. if (!stu__compile_global_scope())
  12651. printf("Compile error in line %d: %s\n", stu__comp_err_line, stu__comp_err_str);
  12652. stua_gc(1);
  12653. }
  12654. #endif // STB_DEFINE
  12655. #endif // STB_STUA
  12656. #undef STB_EXTERN
  12657. #endif // STB_INCLUDE_STB_H
  12658. /*
  12659. ------------------------------------------------------------------------------
  12660. This software is available under 2 licenses -- choose whichever you prefer.
  12661. ------------------------------------------------------------------------------
  12662. ALTERNATIVE A - MIT License
  12663. Copyright (c) 2017 Sean Barrett
  12664. Permission is hereby granted, free of charge, to any person obtaining a copy of
  12665. this software and associated documentation files (the "Software"), to deal in
  12666. the Software without restriction, including without limitation the rights to
  12667. use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  12668. of the Software, and to permit persons to whom the Software is furnished to do
  12669. so, subject to the following conditions:
  12670. The above copyright notice and this permission notice shall be included in all
  12671. copies or substantial portions of the Software.
  12672. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12673. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  12674. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  12675. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  12676. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  12677. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  12678. SOFTWARE.
  12679. ------------------------------------------------------------------------------
  12680. ALTERNATIVE B - Public Domain (www.unlicense.org)
  12681. This is free and unencumbered software released into the public domain.
  12682. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
  12683. software, either in source code form or as a compiled binary, for any purpose,
  12684. commercial or non-commercial, and by any means.
  12685. In jurisdictions that recognize copyright laws, the author or authors of this
  12686. software dedicate any and all copyright interest in the software to the public
  12687. domain. We make this dedication for the benefit of the public at large and to
  12688. the detriment of our heirs and successors. We intend this dedication to be an
  12689. overt act of relinquishment in perpetuity of all present and future rights to
  12690. this software under copyright law.
  12691. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12692. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  12693. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  12694. AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  12695. ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  12696. WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  12697. ------------------------------------------------------------------------------
  12698. */