synctex_parser.m 331 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924
  1. /*
  2. Copyright (c) 2008-2017 jerome DOT laurens AT u-bourgogne DOT fr
  3. This file is part of the __SyncTeX__ package.
  4. [//]: # (Latest Revision: Sun Oct 15 15:09:55 UTC 2017)
  5. [//]: # (Version: 1.21)
  6. See `synctex_parser_readme.md` for more details
  7. ## License
  8. Permission is hereby granted, free of charge, to any person
  9. obtaining a copy of this software and associated documentation
  10. files (the "Software"), to deal in the Software without
  11. restriction, including without limitation the rights to use,
  12. copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. copies of the Software, and to permit persons to whom the
  14. Software is furnished to do so, subject to the following
  15. conditions:
  16. The above copyright notice and this permission notice shall be
  17. included in all copies or substantial portions of the Software.
  18. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  19. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  20. OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  21. NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  22. HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  23. WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  24. FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  25. OTHER DEALINGS IN THE SOFTWARE
  26. Except as contained in this notice, the name of the copyright holder
  27. shall not be used in advertising or otherwise to promote the sale,
  28. use or other dealings in this Software without prior written
  29. authorization from the copyright holder.
  30. Acknowledgments:
  31. ----------------
  32. The author received useful remarks from the pdfTeX developers, especially Hahn The Thanh,
  33. and significant help from XeTeX developer Jonathan Kew
  34. Nota Bene:
  35. ----------
  36. If you include or use a significant part of the synctex package into a software,
  37. I would appreciate to be listed as contributor and see "SyncTeX" highlighted.
  38. */
  39. /* We assume that high level application like pdf viewers will want
  40. * to embed this code as is. We assume that they also have locale.h and setlocale.
  41. * For other tools such as TeXLive tools, you must define SYNCTEX_USE_LOCAL_HEADER,
  42. * when building. You also have to create and customize synctex_parser_local.h to fit your system.
  43. * In particular, the HAVE_LOCALE_H and HAVE_SETLOCALE macros should be properly defined.
  44. * With this design, you should not need to edit this file. */
  45. /**
  46. * \file synctex_parser.c
  47. * \brief SyncTeX file parser and controller.
  48. * - author: Jérôme LAURENS
  49. * \version 1.21
  50. * \date Sun Oct 15 15:09:55 UTC 2017
  51. *
  52. * Reads and parse *.synctex[.gz] files,
  53. * performs edit and display queries.
  54. *
  55. * See
  56. * - synctex_scanner_new_with_output_file
  57. * - synctex_scanner_parse
  58. * - synctex_scanner_free
  59. * - synctex_display_query
  60. * - synctex_edit_query
  61. * - synctex_scanner_next_result
  62. * - synctex_scanner_reset_result
  63. *
  64. * The data is organized in a graph with multiple entries.
  65. * The root object is a scanner, it is created with the contents on a synctex file.
  66. * Each node of the tree is a synctex_node_t object.
  67. * There are 3 subtrees, two of them sharing the same leaves.
  68. * The first tree is the list of input records, where input file names are associated with tags.
  69. * The second tree is the box tree as given by TeX when shipping pages out.
  70. * First level objects are sheets and forms, containing boxes, glues, kerns...
  71. * The third tree allows to browse leaves according to tag and line.
  72. */
  73. # if defined(SYNCTEX_USE_LOCAL_HEADER)
  74. # include "synctex_parser_local.h"
  75. # else
  76. # define HAVE_LOCALE_H 1
  77. # define HAVE_SETLOCALE 1
  78. # if defined(_MSC_VER)
  79. # define SYNCTEX_INLINE __inline
  80. # else
  81. # define SYNCTEX_INLINE inline
  82. # endif
  83. # endif
  84. #include <stdlib.h>
  85. #include <stdarg.h>
  86. #include <stdio.h>
  87. #include <string.h>
  88. #include <errno.h>
  89. #include <limits.h>
  90. #if defined(HAVE_LOCALE_H)
  91. #include <locale.h>
  92. #endif
  93. /* Mark unused paramters, so that there will be no compile warnings. */
  94. #ifdef __DARWIN_UNIX03
  95. # define SYNCTEX_UNUSED(x) SYNCTEX_PRAGMA(unused(x))
  96. # define SYNCTEX_PRAGMA(x) _Pragma ( #x )
  97. #else
  98. # define SYNCTEX_UNUSED(x) (void)(x);
  99. #endif
  100. #include "synctex_parser_advanced.h"
  101. SYNCTEX_INLINE static int _synctex_abs(int x) {
  102. return x>0? x: -x;
  103. }
  104. /* These are the possible extensions of the synctex file */
  105. const char * synctex_suffix = ".synctex";
  106. const char * synctex_suffix_gz = ".gz";
  107. typedef synctex_node_p(*synctex_node_new_f)(synctex_scanner_p);
  108. typedef void(*synctex_node_fld_f)(synctex_node_p);
  109. typedef char *(*synctex_node_str_f)(synctex_node_p);
  110. /**
  111. * Pseudo class.
  112. * - author: J. Laurens
  113. *
  114. * Each nodes has a class, it is therefore called an object.
  115. * Each class has a unique scanner.
  116. * Each class has a type which is a unique identifier.
  117. * The class points to various methods,
  118. * each of them vary amongst objects.
  119. * Each class has a data model which stores node's attributes.
  120. * Each class has an tree model which stores children and parent.
  121. * Inspectors give access to data and tree elements.
  122. */
  123. /* 8 fields + size: spcflnat */
  124. typedef struct synctex_tree_model_t {
  125. int sibling;
  126. int parent;
  127. int child;
  128. int friend;
  129. int last;
  130. int next_hbox;
  131. int arg_sibling;
  132. int target;
  133. int size;
  134. } synctex_tree_model_s;
  135. typedef const synctex_tree_model_s * synctex_tree_model_p;
  136. typedef struct synctex_data_model_t {
  137. int tag;
  138. int line;
  139. int column;
  140. int h;
  141. int v;
  142. int width;
  143. int height;
  144. int depth;
  145. int mean_line;
  146. int weight;
  147. int h_V;
  148. int v_V;
  149. int width_V;
  150. int height_V;
  151. int depth_V;
  152. int name;
  153. int page;
  154. int size;
  155. } synctex_data_model_s;
  156. typedef const synctex_data_model_s * synctex_data_model_p;
  157. typedef int (*synctex_int_getter_f)(synctex_node_p);
  158. typedef struct synctex_tlcpector_t {
  159. synctex_int_getter_f tag;
  160. synctex_int_getter_f line;
  161. synctex_int_getter_f column;
  162. } synctex_tlcpector_s;
  163. typedef const synctex_tlcpector_s * synctex_tlcpector_p;
  164. static int _synctex_int_none(synctex_node_p node) {
  165. SYNCTEX_UNUSED(node)
  166. return 0;
  167. }
  168. static const synctex_tlcpector_s synctex_tlcpector_none = {
  169. &_synctex_int_none, /* tag */
  170. &_synctex_int_none, /* line */
  171. &_synctex_int_none, /* column */
  172. };
  173. typedef struct synctex_inspector_t {
  174. synctex_int_getter_f h;
  175. synctex_int_getter_f v;
  176. synctex_int_getter_f width;
  177. synctex_int_getter_f height;
  178. synctex_int_getter_f depth;
  179. } synctex_inspector_s;
  180. typedef const synctex_inspector_s * synctex_inspector_p;
  181. static const synctex_inspector_s synctex_inspector_none = {
  182. &_synctex_int_none, /* h */
  183. &_synctex_int_none, /* v */
  184. &_synctex_int_none, /* width */
  185. &_synctex_int_none, /* height */
  186. &_synctex_int_none, /* depth */
  187. };
  188. typedef float (*synctex_float_getter_f)(synctex_node_p);
  189. typedef struct synctex_vispector_t {
  190. synctex_float_getter_f h;
  191. synctex_float_getter_f v;
  192. synctex_float_getter_f width;
  193. synctex_float_getter_f height;
  194. synctex_float_getter_f depth;
  195. } synctex_vispector_s;
  196. static float _synctex_float_none(synctex_node_p node) {
  197. SYNCTEX_UNUSED(node)
  198. return 0;
  199. }
  200. static const synctex_vispector_s synctex_vispector_none = {
  201. &_synctex_float_none, /* h */
  202. &_synctex_float_none, /* v */
  203. &_synctex_float_none, /* width */
  204. &_synctex_float_none, /* height */
  205. &_synctex_float_none, /* depth */
  206. };
  207. typedef const synctex_vispector_s * synctex_vispector_p;
  208. struct synctex_class_t {
  209. synctex_scanner_p scanner;
  210. synctex_node_type_t type;
  211. synctex_node_new_f new;
  212. synctex_node_fld_f free;
  213. synctex_node_fld_f log;
  214. synctex_node_fld_f display;
  215. synctex_node_str_f abstract;
  216. synctex_tree_model_p navigator;
  217. synctex_data_model_p modelator;
  218. synctex_tlcpector_p tlcpector;
  219. synctex_inspector_p inspector;
  220. synctex_vispector_p vispector;
  221. };
  222. /**
  223. * Nota bene: naming convention.
  224. * For static API, when the name contains "proxy", it applies to proxies.
  225. * When the name contains "noxy", it applies to non proxies only.
  226. * When the name contains "node", well it depends...
  227. */
  228. typedef synctex_node_p synctex_proxy_p;
  229. typedef synctex_node_p synctex_noxy_p;
  230. # ifdef SYNCTEX_NOTHING
  231. # pragma mark -
  232. # pragma mark Abstract OBJECTS and METHODS
  233. # endif
  234. /**
  235. * \def SYNCTEX_MSG_SEND
  236. * \brief Takes care of sending the given message if possible.
  237. * - parameter NODE: of type synctex_node_p
  238. * - parameter SELECTOR: one of the class_ pointer properties
  239. */
  240. # define SYNCTEX_MSG_SEND(NODE,SELECTOR) do {\
  241. synctex_node_p N__ = NODE;\
  242. if (N__ && N__->class_->SELECTOR) {\
  243. (*(N__->class_->SELECTOR))(N__);\
  244. }\
  245. } while (synctex_NO)
  246. /**
  247. * Free the given node by sending the free message.
  248. * - parameter NODE: of type synctex_node_p
  249. */
  250. static void synctex_node_free(synctex_node_p node) {
  251. SYNCTEX_MSG_SEND(node,free);
  252. }
  253. # if defined(SYNCTEX_TESTING)
  254. # if !defined(SYNCTEX_USE_HANDLE)
  255. # define SYNCTEX_USE_HANDLE 1
  256. # endif
  257. # if !defined(SYNCTEX_USE_CHARINDEX)
  258. # define SYNCTEX_USE_CHARINDEX 1
  259. # endif
  260. # endif
  261. SYNCTEX_INLINE static synctex_node_p _synctex_new_handle_with_target(synctex_node_p target);
  262. # if defined(SYNCTEX_USE_HANDLE)
  263. # define SYNCTEX_SCANNER_FREE_HANDLE(SCANR) \
  264. __synctex_scanner_free_handle(SCANR)
  265. # define SYNCTEX_SCANNER_REMOVE_HANDLE_TO(WHAT) \
  266. __synctex_scanner_remove_handle_to(WHAT)
  267. # define SYNCTEX_REGISTER_HANDLE_TO(NODE) \
  268. __synctex_scanner_register_handle_to(NODE)
  269. # else
  270. # define SYNCTEX_SCANNER_FREE_HANDLE(SCANR)
  271. # define SYNCTEX_SCANNER_REMOVE_HANDLE_TO(WHAT)
  272. # define SYNCTEX_REGISTER_HANDLE_TO(NODE)
  273. # endif
  274. # if defined(SYNCTEX_USE_CHARINDEX)
  275. # define SYNCTEX_CHARINDEX(NODE) (NODE->char_index)
  276. # define SYNCTEX_LINEINDEX(NODE) (NODE->line_index)
  277. # define SYNCTEX_PRINT_CHARINDEX_FMT "#%i"
  278. # define SYNCTEX_PRINT_CHARINDEX_WHAT ,SYNCTEX_CHARINDEX(node)
  279. # define SYNCTEX_PRINT_CHARINDEX \
  280. printf(SYNCTEX_PRINT_CHARINDEX_FMT SYNCTEX_PRINT_CHARINDEX_WHAT)
  281. # define SYNCTEX_PRINT_LINEINDEX_FMT "L#%i"
  282. # define SYNCTEX_PRINT_LINEINDEX_WHAT ,SYNCTEX_LINEINDEX(node)
  283. # define SYNCTEX_PRINT_LINEINDEX \
  284. printf(SYNCTEX_PRINT_LINEINDEX_FMT SYNCTEX_PRINT_LINEINDEX_WHAT)
  285. # define SYNCTEX_PRINT_CHARINDEX_NL \
  286. printf(SYNCTEX_PRINT_CHARINDEX_FMT "\n" SYNCTEX_PRINT_CHARINDEX_WHAT)
  287. # define SYNCTEX_PRINT_LINEINDEX_NL \
  288. printf(SYNCTEX_PRINT_CHARINDEX_FMT "\n"SYNCTEX_PRINT_LINEINDEX_WHAT)
  289. # define SYNCTEX_IMPLEMENT_CHARINDEX(NODE,CORRECTION)\
  290. NODE->char_index = (synctex_charindex_t)(scanner->reader->charindex_offset+SYNCTEX_CUR-SYNCTEX_START+(CORRECTION)); \
  291. NODE->line_index = scanner->reader->line_number;
  292. # else
  293. # define SYNCTEX_CHARINDEX(NODE) 0
  294. # define SYNCTEX_LINEINDEX(NODE) 0
  295. # define SYNCTEX_PRINT_CHARINDEX_FMT
  296. # define SYNCTEX_PRINT_CHARINDEX_WHAT
  297. # define SYNCTEX_PRINT_CHARINDEX
  298. # define SYNCTEX_PRINT_CHARINDEX
  299. # define SYNCTEX_PRINT_LINEINDEX_FMT
  300. # define SYNCTEX_PRINT_LINEINDEX_WHAT
  301. # define SYNCTEX_PRINT_LINEINDEX
  302. # define SYNCTEX_PRINT_CHARINDEX_NL printf("\n")
  303. # define SYNCTEX_PRINT_LINEINDEX_NL printf("\n")
  304. # define SYNCTEX_IMPLEMENT_CHARINDEX(NODE,CORRECTION)
  305. # endif
  306. /**
  307. * The next macros are used to access the node tree info
  308. * SYNCTEX_DATA(node) points to the first synctex integer or pointer data of node
  309. * SYNCTEX_DATA(node)[index] is the information at index
  310. * for example, the page of a sheet is stored in SYNCTEX_DATA(sheet)[_synctex_data_page_idx]
  311. * - parameter NODE: of type synctex_node_p
  312. * If the name starts with "__", the argument is nonullable
  313. */
  314. # ifdef SYNCTEX_NOTHING
  315. # pragma mark -
  316. # pragma mark Tree SETGET
  317. # endif
  318. #if SYNCTEX_DEBUG > 1000
  319. #define SYNCTEX_PARAMETER_ASSERT(WHAT) \
  320. do { \
  321. if (!(WHAT)) { \
  322. printf("! Parameter failure: %s\n",#WHAT); \
  323. } \
  324. } while (synctex_NO)
  325. #define DEFINE_SYNCTEX_TREE_HAS(WHAT)\
  326. static synctex_bool_t _synctex_tree_has_##WHAT(synctex_node_p node) {\
  327. if (node) {\
  328. if (node->class_->navigator->WHAT>=0) {\
  329. return synctex_YES; \
  330. } else {\
  331. printf("WARNING: NO tree %s for %s\n", #WHAT, synctex_node_isa(node));\
  332. }\
  333. }\
  334. return synctex_NO;\
  335. }
  336. #else
  337. #define SYNCTEX_PARAMETER_ASSERT(WHAT)
  338. #define DEFINE_SYNCTEX_TREE_HAS(WHAT) \
  339. static synctex_bool_t _synctex_tree_has_##WHAT(synctex_node_p node) {\
  340. return (node && (node->class_->navigator->WHAT>=0));\
  341. }
  342. #endif
  343. # define DEFINE_SYNCTEX_TREE__GET(WHAT) \
  344. SYNCTEX_INLINE static synctex_node_p __synctex_tree_##WHAT(synctex_non_null_node_p node) {\
  345. return node->data[node->class_->navigator->WHAT].as_node;\
  346. }
  347. # define DEFINE_SYNCTEX_TREE_GET(WHAT) \
  348. DEFINE_SYNCTEX_TREE__GET(WHAT) \
  349. static synctex_node_p _synctex_tree_##WHAT(synctex_node_p node) {\
  350. if (_synctex_tree_has_##WHAT(node)) {\
  351. return __synctex_tree_##WHAT(node);\
  352. }\
  353. return 0;\
  354. }
  355. # define DEFINE_SYNCTEX_TREE__RESET(WHAT) \
  356. SYNCTEX_INLINE static synctex_node_p __synctex_tree_reset_##WHAT(synctex_non_null_node_p node) {\
  357. synctex_node_p old = node->data[node->class_->navigator->WHAT].as_node;\
  358. node->data[node->class_->navigator->WHAT].as_node=NULL;\
  359. return old;\
  360. }
  361. # define DEFINE_SYNCTEX_TREE_RESET(WHAT) \
  362. DEFINE_SYNCTEX_TREE__RESET(WHAT) \
  363. SYNCTEX_INLINE static synctex_node_p _synctex_tree_reset_##WHAT(synctex_node_p node) {\
  364. return _synctex_tree_has_##WHAT(node)? \
  365. __synctex_tree_reset_##WHAT(node): NULL; \
  366. }
  367. # define DEFINE_SYNCTEX_TREE__SET(WHAT) \
  368. SYNCTEX_INLINE static synctex_node_p __synctex_tree_set_##WHAT(synctex_non_null_node_p node, synctex_node_p new_value) {\
  369. synctex_node_p old = __synctex_tree_##WHAT(node);\
  370. node->data[node->class_->navigator->WHAT].as_node=new_value;\
  371. return old;\
  372. }
  373. # define DEFINE_SYNCTEX_TREE_SET(WHAT) \
  374. DEFINE_SYNCTEX_TREE__SET(WHAT) \
  375. SYNCTEX_INLINE static synctex_node_p _synctex_tree_set_##WHAT(synctex_node_p node, synctex_node_p new_value) {\
  376. return _synctex_tree_has_##WHAT(node)?\
  377. __synctex_tree_set_##WHAT(node,new_value):NULL;\
  378. }
  379. # define DEFINE_SYNCTEX_TREE__GETSETRESET(WHAT) \
  380. DEFINE_SYNCTEX_TREE__GET(WHAT) \
  381. DEFINE_SYNCTEX_TREE__SET(WHAT) \
  382. DEFINE_SYNCTEX_TREE__RESET(WHAT)
  383. # define DEFINE_SYNCTEX_TREE_GETSET(WHAT) \
  384. DEFINE_SYNCTEX_TREE_HAS(WHAT) \
  385. DEFINE_SYNCTEX_TREE_GET(WHAT) \
  386. DEFINE_SYNCTEX_TREE_SET(WHAT)
  387. # define DEFINE_SYNCTEX_TREE_GETRESET(WHAT) \
  388. DEFINE_SYNCTEX_TREE_HAS(WHAT) \
  389. DEFINE_SYNCTEX_TREE_GET(WHAT) \
  390. DEFINE_SYNCTEX_TREE_RESET(WHAT)
  391. # define DEFINE_SYNCTEX_TREE_GETSETRESET(WHAT) \
  392. DEFINE_SYNCTEX_TREE_HAS(WHAT) \
  393. DEFINE_SYNCTEX_TREE_GET(WHAT) \
  394. DEFINE_SYNCTEX_TREE_SET(WHAT) \
  395. DEFINE_SYNCTEX_TREE_RESET(WHAT)
  396. /*
  397. * _synctex_tree_set_... methods return the old value.
  398. * The return value of _synctex_tree_set_child and
  399. * _synctex_tree_set_sibling must be released somehown.
  400. */
  401. DEFINE_SYNCTEX_TREE__GETSETRESET(sibling)
  402. DEFINE_SYNCTEX_TREE_GETSETRESET(parent)
  403. DEFINE_SYNCTEX_TREE_GETSETRESET(child)
  404. DEFINE_SYNCTEX_TREE_GETSETRESET(friend)
  405. DEFINE_SYNCTEX_TREE_GETSET(last)
  406. DEFINE_SYNCTEX_TREE_GETSET(next_hbox)
  407. DEFINE_SYNCTEX_TREE_GETSET(arg_sibling)
  408. DEFINE_SYNCTEX_TREE_GETSETRESET(target)
  409. #if SYNCTEX_DEBUG>1000
  410. # undef SYNCTEX_USE_NODE_COUNT
  411. # define SYNCTEX_USE_NODE_COUNT 1
  412. #endif
  413. #if SYNCTEX_USE_NODE_COUNT>0
  414. # define SYNCTEX_DECLARE_NODE_COUNT int node_count;
  415. # define SYNCTEX_INIT_NODE_COUNT \
  416. do { node_count = 0; } while(synctex_NO)
  417. #else
  418. # define SYNCTEX_DECLARE_NODE_COUNT
  419. # define SYNCTEX_INIT_NODE_COUNT
  420. #endif
  421. #if SYNCTEX_USE_NODE_COUNT>10
  422. # define SYNCTEX_DID_NEW(N) _synctex_did_new(N)
  423. # define SYNCTEX_WILL_FREE(N) _synctex_will_free(N)
  424. #else
  425. # define SYNCTEX_DID_NEW(N)
  426. # define SYNCTEX_WILL_FREE(N)
  427. #endif
  428. #define SYNCTEX_HAS_CHILDREN(NODE) (NODE && _synctex_tree_child(NODE))
  429. # ifdef _X_SYNCTEX_WORK__
  430. # include "/usr/include/zlib.h"
  431. # else
  432. # include <zlib.h>
  433. # endif
  434. # ifdef SYNCTEX_NOTHING
  435. # pragma mark -
  436. # pragma mark STATUS
  437. # endif
  438. /* When the end of the synctex file has been reached: */
  439. # define SYNCTEX_STATUS_EOF 0
  440. /* When the function could not return the value it was asked for: */
  441. # define SYNCTEX_STATUS_NOT_OK (SYNCTEX_STATUS_EOF+1)
  442. /* When the function returns the value it was asked for:
  443. It must be the biggest one */
  444. # define SYNCTEX_STATUS_OK (SYNCTEX_STATUS_NOT_OK+1)
  445. /* Generic error: */
  446. # define SYNCTEX_STATUS_ERROR (SYNCTEX_STATUS_EOF-1)
  447. /* Parameter error: */
  448. # define SYNCTEX_STATUS_BAD_ARGUMENT (SYNCTEX_STATUS_ERROR-1)
  449. # ifdef SYNCTEX_NOTHING
  450. # pragma mark -
  451. # pragma mark File reader
  452. # endif
  453. /* We ensure that SYNCTEX_BUFFER_SIZE < UINT_MAX, I don't know if it makes sense... */
  454. /* Actually, the minimum buffer size is driven by integer and float parsing, including the unit.
  455. * ±0.123456789e123??
  456. */
  457. # define SYNCTEX_BUFFER_MIN_SIZE 32
  458. # define SYNCTEX_BUFFER_SIZE 32768
  459. #if SYNCTEX_BUFFER_SIZE >= UINT_MAX
  460. # error BAD BUFFER SIZE(1)
  461. #endif
  462. #if SYNCTEX_BUFFER_SIZE < SYNCTEX_BUFFER_MIN_SIZE
  463. # error BAD BUFFER SIZE(2)
  464. #endif
  465. typedef struct synctex_reader_t {
  466. gzFile file; /* The (possibly compressed) file */
  467. char * output;
  468. char * synctex;
  469. char * current; /* current location in the buffer */
  470. char * start; /* start of the buffer */
  471. char * end; /* end of the buffer */
  472. size_t min_size;
  473. size_t size;
  474. int lastv;
  475. int line_number;
  476. SYNCTEX_DECLARE_CHAR_OFFSET
  477. } synctex_reader_s;
  478. typedef synctex_reader_s * synctex_reader_p;
  479. typedef struct {
  480. synctex_status_t status;
  481. char * synctex;
  482. gzFile file;
  483. synctex_io_mode_t io_mode;
  484. } synctex_open_s;
  485. /* This functions opens the file at the "output" given location.
  486. * It manages the problem of quoted filenames that appear with pdftex and filenames containing the space character.
  487. * In TeXLive 2008, the synctex file created with pdftex did contain unexpected quotes.
  488. * This function will remove them if possible.
  489. * All the reference arguments will take a value on return. They must be non NULL.
  490. * - returns: an open structure which status is
  491. * SYNCTEX_STATUS_OK on success,
  492. * SYNCTEX_STATUS_ERROR on failure.
  493. * - note: on success, the caller is the owner
  494. * of the fields of the returned open structure.
  495. */
  496. static synctex_open_s __synctex_open_v2(const char * output, synctex_io_mode_t io_mode, synctex_bool_t add_quotes) {
  497. synctex_open_s open = {SYNCTEX_STATUS_ERROR, NULL, NULL, io_mode};
  498. char * quoteless_synctex_name = NULL;
  499. const char * mode = _synctex_get_io_mode_name(open.io_mode);
  500. size_t size = strlen(output)+strlen(synctex_suffix)+strlen(synctex_suffix_gz)+1;
  501. if (NULL == (open.synctex = (char *)malloc(size))) {
  502. _synctex_error("! __synctex_open_v2: Memory problem (1)\n");
  503. return open;
  504. }
  505. /* we have reserved for synctex enough memory to copy output (including its 2 eventual quotes), both suffices,
  506. * including the terminating character. size is free now. */
  507. if (open.synctex != strcpy(open.synctex,output)) {
  508. _synctex_error("! __synctex_open_v2: Copy problem\n");
  509. return_on_error:
  510. free(open.synctex);
  511. open.synctex = NULL;
  512. free(quoteless_synctex_name);/* We MUST have quoteless_synctex_name<>synctex_name */
  513. return open;
  514. }
  515. /* remove the last path extension if any */
  516. _synctex_strip_last_path_extension(open.synctex);
  517. if (!strlen(open.synctex)) {
  518. goto return_on_error;
  519. }
  520. /* now insert quotes. */
  521. if (add_quotes) {
  522. char * quoted = NULL;
  523. if (_synctex_copy_with_quoting_last_path_component(open.synctex,&quoted,size) || quoted == NULL) {
  524. /* There was an error or quoting does not make sense: */
  525. goto return_on_error;
  526. }
  527. quoteless_synctex_name = open.synctex;
  528. open.synctex = quoted;
  529. }
  530. /* Now add to open.synctex the first path extension. */
  531. if (open.synctex != strcat(open.synctex,synctex_suffix)){
  532. _synctex_error("! __synctex_open_v2: Concatenation problem (can't add suffix '%s')\n",synctex_suffix);
  533. goto return_on_error;
  534. }
  535. /* Add to quoteless_synctex_name as well, if relevant. */
  536. if (quoteless_synctex_name && (quoteless_synctex_name != strcat(quoteless_synctex_name,synctex_suffix))){
  537. free(quoteless_synctex_name);
  538. quoteless_synctex_name = NULL;
  539. }
  540. if (NULL == (open.file = gzopen(open.synctex,mode))) {
  541. /* Could not open this file */
  542. if (errno != ENOENT) {
  543. /* The file does exist, this is a lower level error, I can't do anything. */
  544. _synctex_error("could not open %s, error %i\n",open.synctex,errno);
  545. goto return_on_error;
  546. }
  547. /* Apparently, there is no uncompressed synctex file. Try the compressed version */
  548. if (open.synctex != strcat(open.synctex,synctex_suffix_gz)){
  549. _synctex_error("! __synctex_open_v2: Concatenation problem (can't add suffix '%s')\n",synctex_suffix_gz);
  550. goto return_on_error;
  551. }
  552. open.io_mode |= synctex_io_gz_mask;
  553. mode = _synctex_get_io_mode_name(open.io_mode); /* the file is a compressed and is a binary file, this caused errors on Windows */
  554. /* Add the suffix to the quoteless_synctex_name as well. */
  555. if (quoteless_synctex_name && (quoteless_synctex_name != strcat(quoteless_synctex_name,synctex_suffix_gz))){
  556. free(quoteless_synctex_name);
  557. quoteless_synctex_name = NULL;
  558. }
  559. if (NULL == (open.file = gzopen(open.synctex,mode))) {
  560. /* Could not open this file */
  561. if (errno != ENOENT) {
  562. /* The file does exist, this is a lower level error, I can't do anything. */
  563. _synctex_error("Could not open %s, error %i\n",open.synctex,errno);
  564. }
  565. goto return_on_error;
  566. }
  567. }
  568. /* At this point, the file is properly open.
  569. * If we are in the add_quotes mode, we change the file name by removing the quotes. */
  570. if (quoteless_synctex_name) {
  571. gzclose(open.file);
  572. if (rename(open.synctex,quoteless_synctex_name)) {
  573. _synctex_error("Could not rename %s to %s, error %i\n",open.synctex,quoteless_synctex_name,errno);
  574. /* We could not rename, reopen the file with the quoted name. */
  575. if (NULL == (open.file = gzopen(open.synctex,mode))) {
  576. /* No luck, could not re open this file, something has happened meanwhile */
  577. if (errno != ENOENT) {
  578. /* The file does not exist any more, it has certainly be removed somehow
  579. * this is a lower level error, I can't do anything. */
  580. _synctex_error("Could not open again %s, error %i\n",open.synctex,errno);
  581. }
  582. goto return_on_error;
  583. }
  584. } else {
  585. /* The file has been successfully renamed */
  586. if (NULL == (open.file = gzopen(quoteless_synctex_name,mode))) {
  587. /* Could not open this file */
  588. if (errno != ENOENT) {
  589. /* The file does exist, this is a lower level error, I can't do anything. */
  590. _synctex_error("Could not open renamed %s, error %i\n",quoteless_synctex_name,errno);
  591. }
  592. goto return_on_error;
  593. }
  594. /* The quote free file name should replace the old one:*/
  595. free(open.synctex);
  596. open.synctex = quoteless_synctex_name;
  597. quoteless_synctex_name = NULL;
  598. }
  599. }
  600. /* The operation is successfull, return the arguments by value. */
  601. open.status = SYNCTEX_STATUS_OK;
  602. return open;
  603. }
  604. /* Opens the ouput file, taking into account the eventual build_directory.
  605. * - returns: an open structure which status is
  606. * SYNCTEX_STATUS_OK on success,
  607. * SYNCTEX_STATUS_ERROR on failure.
  608. * - note: on success, the caller is the owner
  609. * of the fields of the returned open structure.
  610. */
  611. static synctex_open_s _synctex_open_v2(const char * output, const char * build_directory, synctex_io_mode_t io_mode, synctex_bool_t add_quotes) {
  612. synctex_open_s open = __synctex_open_v2(output,io_mode,add_quotes);
  613. if (open.status == SYNCTEX_STATUS_OK) {
  614. return open;
  615. }
  616. if (build_directory && strlen(build_directory)) {
  617. char * build_output;
  618. const char *lpc;
  619. size_t size;
  620. synctex_bool_t is_absolute;
  621. build_output = NULL;
  622. lpc = _synctex_last_path_component(output);
  623. size = strlen(build_directory)+strlen(lpc)+2; /* One for the '/' and one for the '\0'. */
  624. is_absolute = _synctex_path_is_absolute(build_directory);
  625. if (!is_absolute) {
  626. size += strlen(output);
  627. }
  628. if ((build_output = (char *)_synctex_malloc(size))) {
  629. if (is_absolute) {
  630. build_output[0] = '\0';
  631. } else {
  632. if (build_output != strcpy(build_output,output)) {
  633. _synctex_free(build_output);
  634. return open;
  635. }
  636. build_output[lpc-output]='\0';
  637. }
  638. if (build_output == strcat(build_output,build_directory)) {
  639. /* Append a path separator if necessary. */
  640. if (!SYNCTEX_IS_PATH_SEPARATOR(build_output[strlen(build_directory)-1])) {
  641. if (build_output != strcat(build_output,"/")) {
  642. _synctex_free(build_output);
  643. return open;
  644. }
  645. }
  646. /* Append the last path component of the output. */
  647. if (build_output != strcat(build_output,lpc)) {
  648. _synctex_free(build_output);
  649. return open;
  650. }
  651. open = __synctex_open_v2(build_output,io_mode,add_quotes);
  652. }
  653. _synctex_free(build_output);
  654. } /* if ((build_output... */
  655. } /* if (build_directory...) */
  656. return open;
  657. }
  658. static void synctex_reader_free(synctex_reader_p reader) {
  659. if (reader) {
  660. _synctex_free(reader->output);
  661. _synctex_free(reader->synctex);
  662. _synctex_free(reader->start);
  663. gzclose(reader->file);
  664. _synctex_free(reader);
  665. }
  666. }
  667. /*
  668. * Return reader on success.
  669. * Deallocate reader and return NULL on failure.
  670. */
  671. static synctex_reader_p synctex_reader_init_with_output_file(synctex_reader_p reader, const char * output, const char * build_directory) {
  672. if (reader) {
  673. /* now open the synctex file */
  674. synctex_open_s open = _synctex_open_v2(output,build_directory,0,synctex_ADD_QUOTES);
  675. if (open.status<SYNCTEX_STATUS_OK) {
  676. open = _synctex_open_v2(output,build_directory,0,synctex_DONT_ADD_QUOTES);
  677. if (open.status<SYNCTEX_STATUS_OK) {
  678. return NULL;
  679. }
  680. }
  681. reader->synctex = open.synctex;
  682. reader->file = open.file;
  683. /* make a private copy of output */
  684. if (NULL == (reader->output = (char *)_synctex_malloc(strlen(output)+1))){
  685. _synctex_error("! synctex_scanner_new_with_output_file: Memory problem (2), reader's output is not reliable.");
  686. } else if (reader->output != strcpy(reader->output,output)) {
  687. _synctex_free(reader->output);
  688. reader->output = NULL;
  689. _synctex_error("! synctex_scanner_new_with_output_file: Copy problem, reader's output is not reliable.");
  690. }
  691. reader->start = reader->end = reader->current = NULL;
  692. reader->min_size = SYNCTEX_BUFFER_MIN_SIZE;
  693. reader->size = SYNCTEX_BUFFER_SIZE;
  694. reader->start = reader->current =
  695. (char *)_synctex_malloc(reader->size+1); /* one more character for null termination */
  696. if (NULL == reader->start) {
  697. _synctex_error("! malloc error in synctex_reader_init_with_output_file.");
  698. //bailey:
  699. #ifdef SYNCTEX_DEBUG
  700. return reader;
  701. #else
  702. synctex_reader_free(reader);
  703. return NULL;
  704. #endif
  705. }
  706. reader->end = reader->start+reader->size;
  707. /* reader->end always points to a null terminating character.
  708. * Maybe there is another null terminating character between reader->current and reader->end-1.
  709. * At least, we are sure that reader->current points to a string covering a valid part of the memory. */
  710. # if defined(SYNCTEX_USE_CHARINDEX)
  711. reader->charindex_offset = -reader->size;
  712. # endif
  713. }
  714. return reader;
  715. }
  716. # if defined(SYNCTEX_USE_HANDLE)
  717. # define SYNCTEX_DECLARE_HANDLE synctex_node_p handle;
  718. # else
  719. # define SYNCTEX_DECLARE_HANDLE
  720. # endif
  721. # ifdef SYNCTEX_NOTHING
  722. # pragma mark -
  723. # pragma mark SCANNER
  724. # endif
  725. /**
  726. * The synctex scanner is the root object.
  727. * Is is initialized with the contents of a text file or a gzipped file.
  728. * The buffer_.* are first used to parse the text.
  729. */
  730. struct synctex_scanner_t {
  731. synctex_reader_p reader;
  732. SYNCTEX_DECLARE_NODE_COUNT
  733. SYNCTEX_DECLARE_HANDLE
  734. char * output_fmt; /* dvi or pdf, not yet used */
  735. synctex_iterator_p iterator;/* result iterator */
  736. int version; /* 1, not yet used */
  737. struct {
  738. unsigned has_parsed:1; /* Whether the scanner has parsed its underlying synctex file. */
  739. unsigned postamble:1; /* Whether the scanner has parsed its underlying synctex file. */
  740. unsigned reserved:sizeof(unsigned)-2; /* alignment */
  741. } flags;
  742. int pre_magnification; /* magnification from the synctex preamble */
  743. int pre_unit; /* unit from the synctex preamble */
  744. int pre_x_offset; /* X offset from the synctex preamble */
  745. int pre_y_offset; /* Y offset from the synctex preamble */
  746. int count; /* Number of records, from the synctex postamble */
  747. float unit; /* real unit, from synctex preamble or post scriptum */
  748. float x_offset; /* X offset, from synctex preamble or post scriptum */
  749. float y_offset; /* Y Offset, from synctex preamble or post scriptum */
  750. synctex_node_p input; /* The first input node, its siblings are the other input nodes */
  751. synctex_node_p sheet; /* The first sheet node, its siblings are the other sheet nodes */
  752. synctex_node_p form; /* The first form, its siblings are the other forms */
  753. synctex_node_p ref_in_sheet; /* The first form ref node in sheet, its friends are the other form ref nodes */
  754. synctex_node_p ref_in_form; /* The first form ref node, its friends are the other form ref nodes in sheet */
  755. int number_of_lists; /* The number of friend lists */
  756. synctex_node_r lists_of_friends;/* The friend lists */
  757. synctex_class_s class_[synctex_node_number_of_types]; /* The classes of the nodes of the scanner */
  758. int display_switcher;
  759. char * display_prompt;
  760. };
  761. /**
  762. * Create a new node of the given type.
  763. * - parameter scanner: of type synctex_node_p
  764. * - parameter type: a type, the client is responsible
  765. * to ask for an acceptable type.
  766. */
  767. synctex_node_p synctex_node_new(synctex_scanner_p scanner, synctex_node_type_t type) {
  768. return scanner? scanner->class_[type].new(scanner):NULL;
  769. }
  770. # if defined(SYNCTEX_USE_HANDLE)
  771. SYNCTEX_INLINE static void __synctex_scanner_free_handle(synctex_scanner_p scanner) {
  772. synctex_node_free(scanner->handle);
  773. }
  774. SYNCTEX_INLINE static void __synctex_scanner_remove_handle_to(synctex_node_p node) {
  775. synctex_node_p arg_sibling = NULL;
  776. synctex_node_p handle = node->class_->scanner->handle;
  777. while (handle) {
  778. synctex_node_p sibling;
  779. if (node == _synctex_tree_target(handle)) {
  780. sibling = __synctex_tree_reset_sibling(handle);
  781. if (arg_sibling) {
  782. __synctex_tree_set_sibling(arg_sibling, sibling);
  783. } else {
  784. node->class_->scanner->handle = sibling;
  785. }
  786. synctex_node_free(handle);
  787. break;
  788. } else {
  789. sibling = __synctex_tree_sibling(handle);
  790. }
  791. arg_sibling = handle;
  792. handle = sibling;
  793. }
  794. }
  795. SYNCTEX_INLINE static void __synctex_scanner_register_handle_to(synctex_node_p node) {
  796. synctex_node_p NNN = _synctex_new_handle_with_target(node);
  797. __synctex_tree_set_sibling(NNN,node->class_->scanner->handle);
  798. node->class_->scanner->handle = NNN;
  799. }
  800. #endif
  801. #if SYNCTEX_USE_NODE_COUNT>10
  802. SYNCTEX_INLINE static void _synctex_did_new(synctex_node_p node) {
  803. printf("NODE CREATED # %i, %s, %p\n",
  804. (node->class_->scanner->node_count)++,
  805. synctex_node_isa(node),
  806. node);
  807. }
  808. SYNCTEX_INLINE static void _synctex_will_free(synctex_node_p node) {
  809. printf("NODE DELETED # %i, %s, %p\n",
  810. --(node->class_->scanner->node_count),
  811. synctex_node_isa(node),
  812. node);
  813. }
  814. #endif
  815. /**
  816. * Free the given node.
  817. * - parameter node: of type synctex_node_p
  818. * - note: a node is meant to own its child and sibling.
  819. * It is not owned by its parent, unless it is its first child.
  820. * This destructor is for all nodes with children.
  821. */
  822. static void _synctex_free_node(synctex_node_p node) {
  823. if (node) {
  824. SYNCTEX_SCANNER_REMOVE_HANDLE_TO(node);
  825. SYNCTEX_WILL_FREE(node);
  826. synctex_node_free(__synctex_tree_sibling(node));
  827. synctex_node_free(_synctex_tree_child(node));
  828. _synctex_free(node);
  829. }
  830. return;
  831. }
  832. /**
  833. * Free the given handle.
  834. * - parameter node: of type synctex_node_p
  835. * - note: a node is meant to own its child and sibling.
  836. * It is not owned by its parent, unless it is its first child.
  837. * This destructor is for all handles.
  838. */
  839. static void _synctex_free_handle(synctex_node_p handle) {
  840. if (handle) {
  841. _synctex_free_handle(__synctex_tree_sibling(handle));
  842. _synctex_free_handle(_synctex_tree_child(handle));
  843. _synctex_free(handle);
  844. }
  845. return;
  846. }
  847. /**
  848. * Free the given leaf node.
  849. * - parameter node: of type synctex_node_p, with no child nor sibling.
  850. * - note: a node is meant to own its child and sibling.
  851. * It is not owned by its parent, unless it is its first child.
  852. * This destructor is for all nodes with no children.
  853. */
  854. static void _synctex_free_leaf(synctex_node_p node) {
  855. if (node) {
  856. SYNCTEX_SCANNER_REMOVE_HANDLE_TO(node);
  857. SYNCTEX_WILL_FREE(node);
  858. synctex_node_free(__synctex_tree_sibling(node));
  859. _synctex_free(node);
  860. }
  861. return;
  862. }
  863. /**
  864. SYNCTEX_CUR, SYNCTEX_START and SYNCTEX_END are convenient shortcuts
  865. */
  866. # define SYNCTEX_CUR (scanner->reader->current)
  867. # define SYNCTEX_START (scanner->reader->start)
  868. # define SYNCTEX_END (scanner->reader->end)
  869. /* Here are gathered all the possible status that the next scanning functions will return.
  870. * All these functions return a status, and pass their result through pointers.
  871. * Negative values correspond to errors.
  872. * The management of the buffer is causing some significant overhead.
  873. * Every function that may access the buffer returns a status related to the buffer and file state.
  874. * status >= SYNCTEX_STATUS_OK means the function worked as expected
  875. * status < SYNCTEX_STATUS_OK means the function did not work as expected
  876. * status == SYNCTEX_STATUS_NOT_OK means the function did not work as expected but there is still some material to parse.
  877. * status == SYNCTEX_STATUS_EOF means the function did not work as expected and there is no more material.
  878. * status<SYNCTEX_STATUS_EOF means an error
  879. */
  880. #if defined(SYNCTEX_USE_CHARINDEX)
  881. synctex_node_p synctex_scanner_handle(synctex_scanner_p scanner) {
  882. return scanner? scanner->handle:NULL;
  883. }
  884. #endif
  885. # ifdef SYNCTEX_NOTHING
  886. # pragma mark -
  887. # pragma mark Decoding prototypes
  888. # endif
  889. typedef struct {
  890. int integer;
  891. synctex_status_t status;
  892. } synctex_is_s;
  893. static synctex_is_s _synctex_decode_int(synctex_scanner_p scanner);
  894. static synctex_is_s _synctex_decode_int_opt(synctex_scanner_p scanner, int default_value);
  895. static synctex_is_s _synctex_decode_int_v(synctex_scanner_p scanner);
  896. typedef struct {
  897. char * string;
  898. synctex_status_t status;
  899. } synctex_ss_s;
  900. static synctex_ss_s _synctex_decode_string(synctex_scanner_p scanner);
  901. # ifdef SYNCTEX_NOTHING
  902. # pragma mark -
  903. # pragma mark Data SETGET
  904. # endif
  905. /**
  906. * The next macros are used to access the node data info
  907. * through the class modelator integer fields.
  908. * - parameter NODE: of type synctex_node_p
  909. */
  910. # define SYNCTEX_DATA(NODE) ((*((((NODE)->class_))->info))(NODE))
  911. #if defined SYNCTEX_DEBUG > 1000
  912. # define DEFINE_SYNCTEX_DATA_HAS(WHAT) \
  913. SYNCTEX_INLINE static synctex_bool_t __synctex_data_has_##WHAT(synctex_node_p node) {\
  914. return (node && (node->class_->modelator->WHAT>=0));\
  915. }\
  916. SYNCTEX_INLINE static synctex_bool_t _synctex_data_has_##WHAT(synctex_node_p node) {\
  917. if (node && (node->class_->modelator->WHAT<0)) {\
  918. printf("WARNING: NO %s for %s\n", #WHAT, synctex_node_isa(node));\
  919. }\
  920. return __synctex_data_has_##WHAT(node);\
  921. }
  922. #else
  923. # define DEFINE_SYNCTEX_DATA_HAS(WHAT) \
  924. SYNCTEX_INLINE static synctex_bool_t __synctex_data_has_##WHAT(synctex_node_p node) {\
  925. return (node && (node->class_->modelator->WHAT>=0));\
  926. }\
  927. SYNCTEX_INLINE static synctex_bool_t _synctex_data_has_##WHAT(synctex_node_p node) {\
  928. return __synctex_data_has_##WHAT(node);\
  929. }
  930. #endif
  931. SYNCTEX_INLINE static synctex_data_p __synctex_data(synctex_node_p node) {
  932. return node->data+node->class_->navigator->size;
  933. }
  934. # define DEFINE_SYNCTEX_DATA_INT_GETSET(WHAT) \
  935. DEFINE_SYNCTEX_DATA_HAS(WHAT)\
  936. static int _synctex_data_##WHAT(synctex_node_p node) {\
  937. if (_synctex_data_has_##WHAT(node)) {\
  938. return __synctex_data(node)[node->class_->modelator->WHAT].as_integer;\
  939. }\
  940. return 0;\
  941. }\
  942. static int _synctex_data_set_##WHAT(synctex_node_p node, int new_value) {\
  943. int old = 0;\
  944. if (_synctex_data_has_##WHAT(node)) {\
  945. old = __synctex_data(node)[node->class_->modelator->WHAT].as_integer;\
  946. __synctex_data(node)[node->class_->modelator->WHAT].as_integer=new_value;\
  947. }\
  948. return old;\
  949. }
  950. #define DEFINE_SYNCTEX_DATA_INT_DECODE(WHAT) \
  951. static synctex_status_t _synctex_data_decode_##WHAT(synctex_node_p node) {\
  952. if (_synctex_data_has_##WHAT(node)) {\
  953. synctex_is_s is = _synctex_decode_int(node->class_->scanner);\
  954. if (is.status == SYNCTEX_STATUS_OK) {\
  955. _synctex_data_set_##WHAT(node,is.integer);\
  956. } \
  957. return is.status;\
  958. }\
  959. return SYNCTEX_STATUS_BAD_ARGUMENT;\
  960. }
  961. # define DEFINE_SYNCTEX_DATA_INT_DECODE_v(WHAT) \
  962. static synctex_status_t _synctex_data_decode_##WHAT##_v(synctex_node_p node) {\
  963. if (_synctex_data_has_##WHAT(node)) {\
  964. synctex_is_s is = _synctex_decode_int_v(node->class_->scanner);\
  965. if (is.status == SYNCTEX_STATUS_OK) {\
  966. _synctex_data_set_##WHAT(node,is.integer);\
  967. } \
  968. return is.status;\
  969. }\
  970. return SYNCTEX_STATUS_BAD_ARGUMENT;\
  971. }
  972. #define DEFINE_SYNCTEX_DATA_STR_GETSET(WHAT) \
  973. DEFINE_SYNCTEX_DATA_HAS(WHAT)\
  974. static char * _synctex_data_##WHAT(synctex_node_p node) {\
  975. if (_synctex_data_has_##WHAT(node)) {\
  976. return node->data[node->class_->navigator->size+node->class_->modelator->WHAT].as_string;\
  977. }\
  978. return NULL;\
  979. }\
  980. static char * _synctex_data_set_##WHAT(synctex_node_p node, char * new_value) {\
  981. char * old = "";\
  982. if (_synctex_data_has_##WHAT(node)) {\
  983. old = node->data[node->class_->navigator->size+node->class_->modelator->WHAT].as_string;\
  984. node->data[node->class_->navigator->size+node->class_->modelator->WHAT].as_string =new_value;\
  985. }\
  986. return old;\
  987. }
  988. #define DEFINE_SYNCTEX_DATA_STR_DECODE(WHAT) \
  989. static synctex_status_t _synctex_data_decode_##WHAT(synctex_node_p node) {\
  990. if (_synctex_data_has_##WHAT(node)) {\
  991. synctex_ss_s ss = _synctex_decode_string(node->class_->scanner);\
  992. if (ss.status == SYNCTEX_STATUS_OK) {\
  993. _synctex_data_set_##WHAT(node,ss.string);\
  994. } \
  995. return ss.status;\
  996. }\
  997. return SYNCTEX_STATUS_BAD_ARGUMENT;\
  998. }
  999. #define DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE(WHAT) \
  1000. DEFINE_SYNCTEX_DATA_INT_GETSET(WHAT) \
  1001. DEFINE_SYNCTEX_DATA_INT_DECODE(WHAT)
  1002. #define DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE_v(WHAT) \
  1003. DEFINE_SYNCTEX_DATA_INT_GETSET(WHAT) \
  1004. DEFINE_SYNCTEX_DATA_INT_DECODE_v(WHAT)
  1005. #define DEFINE_SYNCTEX_DATA_STR_GETSET_DECODE(WHAT) \
  1006. DEFINE_SYNCTEX_DATA_STR_GETSET(WHAT) \
  1007. DEFINE_SYNCTEX_DATA_STR_DECODE(WHAT)
  1008. # ifdef SYNCTEX_NOTHING
  1009. # pragma mark -
  1010. # pragma mark OBJECTS, their creators and destructors.
  1011. # endif
  1012. # ifdef SYNCTEX_NOTHING
  1013. # pragma mark input.
  1014. # endif
  1015. DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE(tag)
  1016. DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE(line)
  1017. DEFINE_SYNCTEX_DATA_STR_GETSET_DECODE(name)
  1018. /* Input nodes only know about their sibling, which is another input node.
  1019. * The synctex information is the _synctex_data_tag and _synctex_data_name
  1020. * note: the input owns its name. */
  1021. # define SYNCTEX_INPUT_MARK "Input:"
  1022. static const synctex_tree_model_s synctex_tree_model_input = {
  1023. synctex_tree_sibling_idx, /* sibling */
  1024. -1, /* parent */
  1025. -1, /* child */
  1026. -1, /* friend */
  1027. -1, /* last */
  1028. -1, /* next_hbox */
  1029. -1, /* arg_sibling */
  1030. -1, /* target */
  1031. synctex_tree_s_input_max
  1032. };
  1033. static const synctex_data_model_s synctex_data_model_input = {
  1034. synctex_data_input_tag_idx, /* tag */
  1035. synctex_data_input_line_idx,/* line */
  1036. -1, /* column */
  1037. -1, /* h */
  1038. -1, /* v */
  1039. -1, /* width */
  1040. -1, /* height */
  1041. -1, /* depth */
  1042. -1, /* mean_line */
  1043. -1, /* weight */
  1044. -1, /* h_V */
  1045. -1, /* v_V */
  1046. -1, /* width_V */
  1047. -1, /* height_V */
  1048. -1, /* depth_V */
  1049. synctex_data_input_name_idx, /* name */
  1050. -1, /* page */
  1051. synctex_data_input_tln_max
  1052. };
  1053. #define SYNCTEX_INSPECTOR_GETTER_F(WHAT)\
  1054. &_synctex_data_##WHAT, &_synctex_data_set_##WHAT
  1055. static synctex_node_p _synctex_new_input(synctex_scanner_p scanner);
  1056. static void _synctex_free_input(synctex_node_p node);
  1057. static void _synctex_log_input(synctex_node_p node);
  1058. static char * _synctex_abstract_input(synctex_node_p node);
  1059. static void _synctex_display_input(synctex_node_p node);
  1060. static const synctex_tlcpector_s synctex_tlcpector_input = {
  1061. &_synctex_data_tag, /* tag */
  1062. &_synctex_int_none, /* line */
  1063. &_synctex_int_none, /* column */
  1064. };
  1065. static synctex_class_s synctex_class_input = {
  1066. NULL, /* No scanner yet */
  1067. synctex_node_type_input, /* Node type */
  1068. &_synctex_new_input, /* creator */
  1069. &_synctex_free_input, /* destructor */
  1070. &_synctex_log_input, /* log */
  1071. &_synctex_display_input, /* display */
  1072. &_synctex_abstract_input, /* abstract */
  1073. &synctex_tree_model_input, /* tree model */
  1074. &synctex_data_model_input, /* data model */
  1075. &synctex_tlcpector_input, /* inspector */
  1076. &synctex_inspector_none, /* inspector */
  1077. &synctex_vispector_none, /* vispector */
  1078. };
  1079. typedef struct {
  1080. SYNCTEX_DECLARE_CHARINDEX
  1081. synctex_class_p class_;
  1082. synctex_data_u data[synctex_tree_s_input_max+synctex_data_input_tln_max];
  1083. } synctex_input_s;
  1084. static synctex_node_p _synctex_new_input(synctex_scanner_p scanner) {
  1085. if (scanner) {
  1086. synctex_node_p node = _synctex_malloc(sizeof(synctex_input_s));
  1087. if (node) {
  1088. node->class_ = scanner->class_+synctex_node_type_input;
  1089. SYNCTEX_DID_NEW(node);
  1090. SYNCTEX_IMPLEMENT_CHARINDEX(node,0);
  1091. SYNCTEX_REGISTER_HANDLE_TO(node);
  1092. }
  1093. return node;
  1094. }
  1095. return NULL;
  1096. }
  1097. static void _synctex_free_input(synctex_node_p node){
  1098. if (node) {
  1099. SYNCTEX_SCANNER_REMOVE_HANDLE_TO(node);
  1100. SYNCTEX_WILL_FREE(node);
  1101. synctex_node_free(__synctex_tree_sibling(node));
  1102. _synctex_free(_synctex_data_name(node));
  1103. _synctex_free(node);
  1104. }
  1105. }
  1106. /* The sheet is a first level node.
  1107. * It has no parent (the owner is the scanner itself)
  1108. * Its sibling points to another sheet.
  1109. * Its child points to its first child, in general a box.
  1110. * A sheet node contains only one synctex information: the page.
  1111. * This is the 1 based page index as given by TeX.
  1112. */
  1113. # ifdef SYNCTEX_NOTHING
  1114. # pragma mark sheet.
  1115. # endif
  1116. /**
  1117. * Every node has the same structure, but not the same size.
  1118. */
  1119. DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE(page)
  1120. typedef struct {
  1121. SYNCTEX_DECLARE_CHARINDEX
  1122. synctex_class_p class_;
  1123. synctex_data_u data[synctex_tree_scn_sheet_max+synctex_data_p_sheet_max];
  1124. } synctex_node_sheet_s;
  1125. /* sheet node creator */
  1126. #define DEFINE_synctex_new_scanned_NODE(NAME)\
  1127. static synctex_node_p _synctex_new_##NAME(synctex_scanner_p scanner) {\
  1128. if (scanner) {\
  1129. ++SYNCTEX_CUR;\
  1130. synctex_node_p node = _synctex_malloc(sizeof(synctex_node_##NAME##_s));\
  1131. if (node) {\
  1132. node->class_ = scanner->class_+synctex_node_type_##NAME;\
  1133. SYNCTEX_DID_NEW(node); \
  1134. SYNCTEX_IMPLEMENT_CHARINDEX(node,-1);\
  1135. SYNCTEX_REGISTER_HANDLE_TO(node); \
  1136. }\
  1137. return node;\
  1138. }\
  1139. return NULL;\
  1140. }
  1141. /* NB: -1 in SYNCTEX_IMPLEMENT_CHARINDEX above because
  1142. * the first char of the line has been scanned
  1143. */
  1144. DEFINE_synctex_new_scanned_NODE(sheet)
  1145. static void _synctex_log_sheet(synctex_node_p node);
  1146. static char * _synctex_abstract_sheet(synctex_node_p node);
  1147. static void _synctex_display_sheet(synctex_node_p node);
  1148. static const synctex_tree_model_s synctex_tree_model_sheet = {
  1149. synctex_tree_sibling_idx, /* sibling */
  1150. -1, /* parent */
  1151. synctex_tree_s_child_idx, /* child */
  1152. -1, /* friend */
  1153. -1, /* last */
  1154. synctex_tree_sc_next_hbox_idx, /* next_hbox */
  1155. -1, /* arg_sibling */
  1156. -1, /* target */
  1157. synctex_tree_scn_sheet_max
  1158. };
  1159. static const synctex_data_model_s synctex_data_model_sheet = {
  1160. -1, /* tag */
  1161. -1, /* line */
  1162. -1, /* column */
  1163. -1, /* h */
  1164. -1, /* v */
  1165. -1, /* width */
  1166. -1, /* height */
  1167. -1, /* depth */
  1168. -1, /* mean_line */
  1169. -1, /* weight */
  1170. -1, /* h_V */
  1171. -1, /* v_V */
  1172. -1, /* width_V */
  1173. -1, /* height_V */
  1174. -1, /* depth_V */
  1175. -1, /* name */
  1176. synctex_data_sheet_page_idx, /* page */
  1177. synctex_data_p_sheet_max
  1178. };
  1179. static synctex_class_s synctex_class_sheet = {
  1180. NULL, /* No scanner yet */
  1181. synctex_node_type_sheet, /* Node type */
  1182. &_synctex_new_sheet, /* creator */
  1183. &_synctex_free_node, /* destructor */
  1184. &_synctex_log_sheet, /* log */
  1185. &_synctex_display_sheet, /* display */
  1186. &_synctex_abstract_sheet, /* abstract */
  1187. &synctex_tree_model_sheet, /* tree model */
  1188. &synctex_data_model_sheet, /* data model */
  1189. &synctex_tlcpector_none, /* tlcpector */
  1190. &synctex_inspector_none, /* inspector */
  1191. &synctex_vispector_none, /* vispector */
  1192. };
  1193. # ifdef SYNCTEX_NOTHING
  1194. # pragma mark form.
  1195. # endif
  1196. /**
  1197. * Every node has the same structure, but not the same size.
  1198. */
  1199. typedef struct {
  1200. SYNCTEX_DECLARE_CHARINDEX
  1201. synctex_class_p class_;
  1202. synctex_data_u data[synctex_tree_sct_form_max+synctex_data_t_form_max];
  1203. } synctex_node_form_s;
  1204. DEFINE_synctex_new_scanned_NODE(form)
  1205. static char * _synctex_abstract_form(synctex_node_p node);
  1206. static void _synctex_display_form(synctex_node_p node);
  1207. static void _synctex_log_form(synctex_node_p node);
  1208. static const synctex_tree_model_s synctex_tree_model_form = {
  1209. synctex_tree_sibling_idx, /* sibling */
  1210. -1, /* parent */
  1211. synctex_tree_s_child_idx, /* child */
  1212. -1, /* friend */
  1213. -1, /* last */
  1214. -1, /* next_hbox */
  1215. -1, /* arg_sibling */
  1216. synctex_tree_sc_target_idx, /* target */
  1217. synctex_tree_sct_form_max
  1218. };
  1219. static const synctex_data_model_s synctex_data_model_form = {
  1220. synctex_data_form_tag_idx, /* tag */
  1221. -1, /* line */
  1222. -1, /* column */
  1223. -1, /* h */
  1224. -1, /* v */
  1225. -1, /* width */
  1226. -1, /* height */
  1227. -1, /* depth */
  1228. -1, /* mean_line */
  1229. -1, /* weight */
  1230. -1, /* h_V */
  1231. -1, /* v_V */
  1232. -1, /* width_V */
  1233. -1, /* height_V */
  1234. -1, /* depth_V */
  1235. -1, /* name */
  1236. -1, /* page */
  1237. synctex_data_t_form_max
  1238. };
  1239. static synctex_class_s synctex_class_form = {
  1240. NULL, /* No scanner yet */
  1241. synctex_node_type_form, /* Node type */
  1242. &_synctex_new_form, /* creator */
  1243. &_synctex_free_node, /* destructor */
  1244. &_synctex_log_form, /* log */
  1245. &_synctex_display_form, /* display */
  1246. &_synctex_abstract_form, /* abstract */
  1247. &synctex_tree_model_form, /* tree model */
  1248. &synctex_data_model_form, /* data model */
  1249. &synctex_tlcpector_none, /* tlcpector */
  1250. &synctex_inspector_none, /* inspector */
  1251. &synctex_vispector_none, /* vispector */
  1252. };
  1253. # ifdef SYNCTEX_NOTHING
  1254. # pragma mark vbox.
  1255. # endif
  1256. /* A box node contains navigation and synctex information
  1257. * There are different kinds of boxes.
  1258. * Only horizontal boxes are treated differently because of their visible size.
  1259. */
  1260. typedef struct {
  1261. SYNCTEX_DECLARE_CHARINDEX
  1262. synctex_class_p class_;
  1263. synctex_data_u data[synctex_tree_spcfl_vbox_max+synctex_data_box_max];
  1264. } synctex_node_vbox_s;
  1265. /* vertical box node creator */
  1266. DEFINE_synctex_new_scanned_NODE(vbox)
  1267. static char * _synctex_abstract_vbox(synctex_node_p node);
  1268. static void _synctex_display_vbox(synctex_node_p node);
  1269. static void _synctex_log_vbox(synctex_node_p node);
  1270. static const synctex_tree_model_s synctex_tree_model_vbox = {
  1271. synctex_tree_sibling_idx, /* sibling */
  1272. synctex_tree_s_parent_idx, /* parent */
  1273. synctex_tree_sp_child_idx, /* child */
  1274. synctex_tree_spc_friend_idx, /* friend */
  1275. synctex_tree_spcf_last_idx, /* last */
  1276. -1, /* next_hbox */
  1277. -1, /* arg_sibling */
  1278. -1, /* target */
  1279. synctex_tree_spcfl_vbox_max
  1280. };
  1281. #define SYNCTEX_DFLT_COLUMN -1
  1282. DEFINE_SYNCTEX_DATA_INT_GETSET(column)
  1283. static synctex_status_t _synctex_data_decode_column(synctex_node_p node) {
  1284. if (_synctex_data_has_column(node)) {
  1285. synctex_is_s is = _synctex_decode_int_opt(node->class_->scanner,
  1286. SYNCTEX_DFLT_COLUMN);
  1287. if (is.status == SYNCTEX_STATUS_OK) {
  1288. _synctex_data_set_column(node,is.integer);
  1289. }
  1290. return is.status;
  1291. }
  1292. return SYNCTEX_STATUS_BAD_ARGUMENT;
  1293. }
  1294. DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE(h)
  1295. DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE_v(v)
  1296. DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE(width)
  1297. DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE(height)
  1298. DEFINE_SYNCTEX_DATA_INT_GETSET_DECODE(depth)
  1299. SYNCTEX_INLINE static void _synctex_data_set_tlc(synctex_node_p node, synctex_node_p model) {
  1300. _synctex_data_set_tag(node, _synctex_data_tag(model));
  1301. _synctex_data_set_line(node, _synctex_data_line(model));
  1302. _synctex_data_set_column(node, _synctex_data_column(model));
  1303. }
  1304. SYNCTEX_INLINE static void _synctex_data_set_tlchv(synctex_node_p node, synctex_node_p model) {
  1305. _synctex_data_set_tlc(node,model);
  1306. _synctex_data_set_h(node, _synctex_data_h(model));
  1307. _synctex_data_set_v(node, _synctex_data_v(model));
  1308. }
  1309. static const synctex_data_model_s synctex_data_model_box = {
  1310. synctex_data_tag_idx, /* tag */
  1311. synctex_data_line_idx, /* line */
  1312. synctex_data_column_idx,/* column */
  1313. synctex_data_h_idx, /* h */
  1314. synctex_data_v_idx, /* v */
  1315. synctex_data_width_idx, /* width */
  1316. synctex_data_height_idx,/* height */
  1317. synctex_data_depth_idx, /* depth */
  1318. -1, /* mean_line */
  1319. -1, /* weight */
  1320. -1, /* h_V */
  1321. -1, /* v_V */
  1322. -1, /* width_V */
  1323. -1, /* height_V */
  1324. -1, /* depth_V */
  1325. -1, /* name */
  1326. -1, /* page */
  1327. synctex_data_box_max
  1328. };
  1329. static const synctex_tlcpector_s synctex_tlcpector_default = {
  1330. &_synctex_data_tag, /* tag */
  1331. &_synctex_data_line, /* line */
  1332. &_synctex_data_column, /* column */
  1333. };
  1334. static const synctex_inspector_s synctex_inspector_box = {
  1335. &_synctex_data_h,
  1336. &_synctex_data_v,
  1337. &_synctex_data_width,
  1338. &_synctex_data_height,
  1339. &_synctex_data_depth,
  1340. };
  1341. static float __synctex_node_visible_h(synctex_node_p node);
  1342. static float __synctex_node_visible_v(synctex_node_p node);
  1343. static float __synctex_node_visible_width(synctex_node_p node);
  1344. static float __synctex_node_visible_height(synctex_node_p node);
  1345. static float __synctex_node_visible_depth(synctex_node_p node);
  1346. static synctex_vispector_s synctex_vispector_box = {
  1347. &__synctex_node_visible_h,
  1348. &__synctex_node_visible_v,
  1349. &__synctex_node_visible_width,
  1350. &__synctex_node_visible_height,
  1351. &__synctex_node_visible_depth,
  1352. };
  1353. /* These are static class objects, each scanner will make a copy of them and setup the scanner field.
  1354. */
  1355. static synctex_class_s synctex_class_vbox = {
  1356. NULL, /* No scanner yet */
  1357. synctex_node_type_vbox, /* Node type */
  1358. &_synctex_new_vbox, /* creator */
  1359. &_synctex_free_node, /* destructor */
  1360. &_synctex_log_vbox, /* log */
  1361. &_synctex_display_vbox, /* display */
  1362. &_synctex_abstract_vbox, /* abstract */
  1363. &synctex_tree_model_vbox, /* tree model */
  1364. &synctex_data_model_box, /* data model */
  1365. &synctex_tlcpector_default, /* tlcpector */
  1366. &synctex_inspector_box, /* inspector */
  1367. &synctex_vispector_box, /* vispector */
  1368. };
  1369. # ifdef SYNCTEX_NOTHING
  1370. # pragma mark hbox.
  1371. # endif
  1372. /* Horizontal boxes must contain visible size, because 0 width does not mean emptiness.
  1373. * They also contain an average of the line numbers of the containing nodes. */
  1374. static const synctex_tree_model_s synctex_tree_model_hbox = {
  1375. synctex_tree_sibling_idx, /* sibling */
  1376. synctex_tree_s_parent_idx, /* parent */
  1377. synctex_tree_sp_child_idx, /* child */
  1378. synctex_tree_spc_friend_idx, /* friend */
  1379. synctex_tree_spcf_last_idx, /* last */
  1380. synctex_tree_spcfl_next_hbox_idx, /* next_hbox */
  1381. -1, /* arg_sibling */
  1382. -1, /* target */
  1383. synctex_tree_spcfln_hbox_max
  1384. };
  1385. DEFINE_SYNCTEX_DATA_INT_GETSET(mean_line)
  1386. DEFINE_SYNCTEX_DATA_INT_GETSET(weight)
  1387. DEFINE_SYNCTEX_DATA_INT_GETSET(h_V)
  1388. DEFINE_SYNCTEX_DATA_INT_GETSET(v_V)
  1389. DEFINE_SYNCTEX_DATA_INT_GETSET(width_V)
  1390. DEFINE_SYNCTEX_DATA_INT_GETSET(height_V)
  1391. DEFINE_SYNCTEX_DATA_INT_GETSET(depth_V)
  1392. /**
  1393. * The hbox model.
  1394. * It contains V variants of geometrical information.
  1395. * It happens that hboxes contain material that is not used to compute
  1396. * the bounding box. Some letters may appear out of the box given by TeX.
  1397. * In such a situation, the visible bouding box is bigger ence the V variant.
  1398. * Only hboxes have such variant. It does not make sense for void boxes
  1399. * and it is not used here for vboxes.
  1400. * - author: JL
  1401. */
  1402. static const synctex_data_model_s synctex_data_model_hbox = {
  1403. synctex_data_tag_idx, /* tag */
  1404. synctex_data_line_idx, /* line */
  1405. synctex_data_column_idx,/* column */
  1406. synctex_data_h_idx, /* h */
  1407. synctex_data_v_idx, /* v */
  1408. synctex_data_width_idx, /* width */
  1409. synctex_data_height_idx,/* height */
  1410. synctex_data_depth_idx, /* depth */
  1411. synctex_data_mean_line_idx, /* mean_line */
  1412. synctex_data_weight_idx, /* weight */
  1413. synctex_data_h_V_idx, /* h_V */
  1414. synctex_data_v_V_idx, /* v_V */
  1415. synctex_data_width_V_idx, /* width_V */
  1416. synctex_data_height_V_idx, /* height_V */
  1417. synctex_data_depth_V_idx, /* depth_V */
  1418. -1, /* name */
  1419. -1, /* page */
  1420. synctex_data_hbox_max
  1421. };
  1422. typedef struct {
  1423. SYNCTEX_DECLARE_CHARINDEX
  1424. synctex_class_p class_;
  1425. synctex_data_u data[synctex_tree_spcfln_hbox_max+synctex_data_hbox_max];
  1426. } synctex_node_hbox_s;
  1427. /* horizontal box node creator */
  1428. DEFINE_synctex_new_scanned_NODE(hbox)
  1429. static void _synctex_log_hbox(synctex_node_p node);
  1430. static char * _synctex_abstract_hbox(synctex_node_p node);
  1431. static void _synctex_display_hbox(synctex_node_p node);
  1432. static synctex_class_s synctex_class_hbox = {
  1433. NULL, /* No scanner yet */
  1434. synctex_node_type_hbox, /* Node type */
  1435. &_synctex_new_hbox, /* creator */
  1436. &_synctex_free_node, /* destructor */
  1437. &_synctex_log_hbox, /* log */
  1438. &_synctex_display_hbox, /* display */
  1439. &_synctex_abstract_hbox, /* abstract */
  1440. &synctex_tree_model_hbox, /* tree model */
  1441. &synctex_data_model_hbox, /* data model */
  1442. &synctex_tlcpector_default, /* tlcpector */
  1443. &synctex_inspector_box, /* inspector */
  1444. &synctex_vispector_box, /* vispector */
  1445. };
  1446. # ifdef SYNCTEX_NOTHING
  1447. # pragma mark void vbox.
  1448. # endif
  1449. /* This void box node implementation is either horizontal or vertical
  1450. * It does not contain a child field.
  1451. */
  1452. static const synctex_tree_model_s synctex_tree_model_spf = {
  1453. synctex_tree_sibling_idx, /* sibling */
  1454. synctex_tree_s_parent_idx, /* parent */
  1455. -1, /* child */
  1456. synctex_tree_sp_friend_idx, /* friend */
  1457. -1, /* last */
  1458. -1, /* next_hbox */
  1459. -1, /* arg_sibling */
  1460. -1, /* target */
  1461. synctex_tree_spf_max
  1462. };
  1463. typedef struct {
  1464. SYNCTEX_DECLARE_CHARINDEX
  1465. synctex_class_p class_;
  1466. synctex_data_u data[synctex_tree_spf_max+synctex_data_box_max];
  1467. } synctex_node_void_vbox_s;
  1468. /* vertical void box node creator */
  1469. DEFINE_synctex_new_scanned_NODE(void_vbox)
  1470. static void _synctex_log_void_box(synctex_node_p node);
  1471. static char * _synctex_abstract_void_vbox(synctex_node_p node);
  1472. static void _synctex_display_void_vbox(synctex_node_p node);
  1473. static synctex_class_s synctex_class_void_vbox = {
  1474. NULL, /* No scanner yet */
  1475. synctex_node_type_void_vbox,/* Node type */
  1476. &_synctex_new_void_vbox, /* creator */
  1477. &_synctex_free_leaf, /* destructor */
  1478. &_synctex_log_void_box, /* log */
  1479. &_synctex_display_void_vbox,/* display */
  1480. &_synctex_abstract_void_vbox,/* abstract */
  1481. &synctex_tree_model_spf, /* tree model */
  1482. &synctex_data_model_box, /* data model */
  1483. &synctex_tlcpector_default, /* tlcpector */
  1484. &synctex_inspector_box, /* inspector */
  1485. &synctex_vispector_box, /* vispector */
  1486. };
  1487. # ifdef SYNCTEX_NOTHING
  1488. # pragma mark void hbox.
  1489. # endif
  1490. typedef synctex_node_void_vbox_s synctex_node_void_hbox_s;
  1491. /* horizontal void box node creator */
  1492. DEFINE_synctex_new_scanned_NODE(void_hbox)
  1493. static char * _synctex_abstract_void_hbox(synctex_node_p node);
  1494. static void _synctex_display_void_hbox(synctex_node_p node);
  1495. static synctex_class_s synctex_class_void_hbox = {
  1496. NULL, /* No scanner yet */
  1497. synctex_node_type_void_hbox,/* Node type */
  1498. &_synctex_new_void_hbox, /* creator */
  1499. &_synctex_free_leaf, /* destructor */
  1500. &_synctex_log_void_box, /* log */
  1501. &_synctex_display_void_hbox,/* display */
  1502. &_synctex_abstract_void_hbox,/* abstract */
  1503. &synctex_tree_model_spf, /* tree model */
  1504. &synctex_data_model_box, /* data model */
  1505. &synctex_tlcpector_default, /* tlcpector */
  1506. &synctex_inspector_box, /* inspector */
  1507. &synctex_vispector_box, /* vispector */
  1508. };
  1509. # ifdef SYNCTEX_NOTHING
  1510. # pragma mark form ref.
  1511. # endif
  1512. /* The form ref node. */
  1513. typedef struct {
  1514. SYNCTEX_DECLARE_CHARINDEX
  1515. synctex_class_p class_;
  1516. synctex_data_u data[synctex_tree_spfa_max+synctex_data_ref_thv_max];
  1517. } synctex_node_ref_s;
  1518. /* form ref node creator */
  1519. DEFINE_synctex_new_scanned_NODE(ref)
  1520. static void _synctex_log_ref(synctex_node_p node);
  1521. static char * _synctex_abstract_ref(synctex_node_p node);
  1522. static void _synctex_display_ref(synctex_node_p node);
  1523. static const synctex_tree_model_s synctex_tree_model_spfa = {
  1524. synctex_tree_sibling_idx, /* sibling */
  1525. synctex_tree_s_parent_idx, /* parent */
  1526. -1, /* child */
  1527. synctex_tree_sp_friend_idx, /* friend */
  1528. -1, /* last */
  1529. -1, /* next_hbox */
  1530. synctex_tree_spf_arg_sibling_idx, /* arg_sibling */
  1531. -1, /* target */
  1532. synctex_tree_spfa_max
  1533. };
  1534. static const synctex_data_model_s synctex_data_model_ref = {
  1535. synctex_data_tag_idx, /* tag */
  1536. -1, /* line */
  1537. -1, /* column */
  1538. synctex_data_ref_h_idx, /* h */
  1539. synctex_data_ref_v_idx, /* v */
  1540. -1, /* width */
  1541. -1, /* height */
  1542. -1, /* depth */
  1543. -1, /* mean_line */
  1544. -1, /* weight */
  1545. -1, /* h_V */
  1546. -1, /* v_V */
  1547. -1, /* width_V */
  1548. -1, /* height_V */
  1549. -1, /* depth_V */
  1550. -1, /* name */
  1551. -1, /* page */
  1552. synctex_data_ref_thv_max /* size */
  1553. };
  1554. static synctex_class_s synctex_class_ref = {
  1555. NULL, /* No scanner yet */
  1556. synctex_node_type_ref, /* Node type */
  1557. &_synctex_new_ref, /* creator */
  1558. &_synctex_free_leaf, /* destructor */
  1559. &_synctex_log_ref, /* log */
  1560. &_synctex_display_ref, /* display */
  1561. &_synctex_abstract_ref, /* abstract */
  1562. &synctex_tree_model_spfa, /* navigator */
  1563. &synctex_data_model_ref, /* data model */
  1564. &synctex_tlcpector_none, /* tlcpector */
  1565. &synctex_inspector_none, /* inspector */
  1566. &synctex_vispector_none, /* vispector */
  1567. };
  1568. # ifdef SYNCTEX_NOTHING
  1569. # pragma mark small node.
  1570. # endif
  1571. /* The small nodes correspond to glue, penalty, math and boundary nodes. */
  1572. static const synctex_data_model_s synctex_data_model_tlchv = {
  1573. synctex_data_tag_idx, /* tag */
  1574. synctex_data_line_idx, /* line */
  1575. synctex_data_column_idx, /* column */
  1576. synctex_data_h_idx, /* h */
  1577. synctex_data_v_idx, /* v */
  1578. -1, /* width */
  1579. -1, /* height */
  1580. -1, /* depth */
  1581. -1, /* mean_line */
  1582. -1, /* weight */
  1583. -1, /* h_V */
  1584. -1, /* v_V */
  1585. -1, /* width_V */
  1586. -1, /* height_V */
  1587. -1, /* depth_V */
  1588. -1, /* name */
  1589. -1, /* page */
  1590. synctex_data_tlchv_max
  1591. };
  1592. typedef struct {
  1593. SYNCTEX_DECLARE_CHARINDEX
  1594. synctex_class_p class_;
  1595. synctex_data_u data[synctex_tree_spf_max+synctex_data_tlchv_max];
  1596. } synctex_node_tlchv_s;
  1597. static void _synctex_log_tlchv_node(synctex_node_p node);
  1598. # ifdef SYNCTEX_NOTHING
  1599. # pragma mark math.
  1600. # endif
  1601. typedef synctex_node_tlchv_s synctex_node_math_s;
  1602. /* math node creator */
  1603. DEFINE_synctex_new_scanned_NODE(math)
  1604. static char * _synctex_abstract_math(synctex_node_p node);
  1605. static void _synctex_display_math(synctex_node_p node);
  1606. static synctex_inspector_s synctex_inspector_hv = {
  1607. &_synctex_data_h,
  1608. &_synctex_data_v,
  1609. &_synctex_int_none,
  1610. &_synctex_int_none,
  1611. &_synctex_int_none,
  1612. };
  1613. static synctex_vispector_s synctex_vispector_hv = {
  1614. &__synctex_node_visible_h,
  1615. &__synctex_node_visible_v,
  1616. &_synctex_float_none,
  1617. &_synctex_float_none,
  1618. &_synctex_float_none,
  1619. };
  1620. static synctex_class_s synctex_class_math = {
  1621. NULL, /* No scanner yet */
  1622. synctex_node_type_math, /* Node type */
  1623. &_synctex_new_math, /* creator */
  1624. &_synctex_free_leaf, /* destructor */
  1625. &_synctex_log_tlchv_node, /* log */
  1626. &_synctex_display_math, /* display */
  1627. &_synctex_abstract_math, /* abstract */
  1628. &synctex_tree_model_spf, /* tree model */
  1629. &synctex_data_model_tlchv, /* data model */
  1630. &synctex_tlcpector_default, /* tlcpector */
  1631. &synctex_inspector_hv, /* inspector */
  1632. &synctex_vispector_hv, /* vispector */
  1633. };
  1634. # ifdef SYNCTEX_NOTHING
  1635. # pragma mark kern node.
  1636. # endif
  1637. static const synctex_data_model_s synctex_data_model_tlchvw = {
  1638. synctex_data_tag_idx, /* tag */
  1639. synctex_data_line_idx, /* line */
  1640. synctex_data_column_idx,/* column */
  1641. synctex_data_h_idx, /* h */
  1642. synctex_data_v_idx, /* v */
  1643. synctex_data_width_idx, /* width */
  1644. -1, /* height */
  1645. -1, /* depth */
  1646. -1, /* mean_line */
  1647. -1, /* weight */
  1648. -1, /* h_V */
  1649. -1, /* v_V */
  1650. -1, /* width_V */
  1651. -1, /* height_V */
  1652. -1, /* depth_V */
  1653. -1, /* name */
  1654. -1, /* page */
  1655. synctex_data_tlchvw_max
  1656. };
  1657. typedef struct {
  1658. SYNCTEX_DECLARE_CHARINDEX
  1659. synctex_class_p class_;
  1660. synctex_data_u data[synctex_tree_spf_max+synctex_data_tlchvw_max];
  1661. } synctex_node_kern_s;
  1662. /* kern node creator */
  1663. DEFINE_synctex_new_scanned_NODE(kern)
  1664. static void _synctex_log_kern_node(synctex_node_p node);
  1665. static char * _synctex_abstract_kern(synctex_node_p node);
  1666. static void _synctex_display_kern(synctex_node_p node);
  1667. static synctex_inspector_s synctex_inspector_kern = {
  1668. &_synctex_data_h,
  1669. &_synctex_data_v,
  1670. &_synctex_data_width,
  1671. &_synctex_int_none,
  1672. &_synctex_int_none,
  1673. };
  1674. static float __synctex_kern_visible_h(synctex_node_p node);
  1675. static float __synctex_kern_visible_width(synctex_node_p node);
  1676. static synctex_vispector_s synctex_vispector_kern = {
  1677. &__synctex_kern_visible_h,
  1678. &__synctex_node_visible_v,
  1679. &__synctex_kern_visible_width,
  1680. &_synctex_float_none,
  1681. &_synctex_float_none,
  1682. };
  1683. static synctex_class_s synctex_class_kern = {
  1684. NULL, /* No scanner yet */
  1685. synctex_node_type_kern, /* Node type */
  1686. &_synctex_new_kern, /* creator */
  1687. &_synctex_free_leaf, /* destructor */
  1688. &_synctex_log_kern_node, /* log */
  1689. &_synctex_display_kern, /* display */
  1690. &_synctex_abstract_kern, /* abstract */
  1691. &synctex_tree_model_spf, /* tree model */
  1692. &synctex_data_model_tlchvw, /* data model */
  1693. &synctex_tlcpector_default, /* tlcpector */
  1694. &synctex_inspector_kern, /* inspector */
  1695. &synctex_vispector_kern, /* vispector */
  1696. };
  1697. # ifdef SYNCTEX_NOTHING
  1698. # pragma mark glue.
  1699. # endif
  1700. /* glue node creator */
  1701. typedef synctex_node_tlchv_s synctex_node_glue_s;
  1702. DEFINE_synctex_new_scanned_NODE(glue)
  1703. static char * _synctex_abstract_glue(synctex_node_p node);
  1704. static void _synctex_display_glue(synctex_node_p node);
  1705. static synctex_class_s synctex_class_glue = {
  1706. NULL, /* No scanner yet */
  1707. synctex_node_type_glue, /* Node type */
  1708. &_synctex_new_glue, /* creator */
  1709. &_synctex_free_leaf, /* destructor */
  1710. &_synctex_log_tlchv_node, /* log */
  1711. &_synctex_display_glue, /* display */
  1712. &_synctex_abstract_glue, /* abstract */
  1713. &synctex_tree_model_spf, /* tree model */
  1714. &synctex_data_model_tlchv, /* data model */
  1715. &synctex_tlcpector_default, /* tlcpector */
  1716. &synctex_inspector_hv, /* inspector */
  1717. &synctex_vispector_hv, /* vispector */
  1718. };
  1719. /* The small nodes correspond to glue and boundary nodes. */
  1720. # ifdef SYNCTEX_NOTHING
  1721. # pragma mark rule.
  1722. # endif
  1723. typedef struct {
  1724. SYNCTEX_DECLARE_CHARINDEX
  1725. synctex_class_p class_;
  1726. synctex_data_u data[synctex_tree_spf_max+synctex_data_box_max];
  1727. } synctex_node_rule_s;
  1728. DEFINE_synctex_new_scanned_NODE(rule)
  1729. static void _synctex_log_rule(synctex_node_p node);
  1730. static char * _synctex_abstract_rule(synctex_node_p node);
  1731. static void _synctex_display_rule(synctex_node_p node);
  1732. static float __synctex_rule_visible_h(synctex_node_p node);
  1733. static float __synctex_rule_visible_v(synctex_node_p node);
  1734. static float __synctex_rule_visible_width(synctex_node_p node);
  1735. static float __synctex_rule_visible_height(synctex_node_p node);
  1736. static float __synctex_rule_visible_depth(synctex_node_p node);
  1737. static synctex_vispector_s synctex_vispector_rule = {
  1738. &__synctex_rule_visible_h,
  1739. &__synctex_rule_visible_v,
  1740. &__synctex_rule_visible_width,
  1741. &__synctex_rule_visible_height,
  1742. &__synctex_rule_visible_depth,
  1743. };
  1744. static synctex_class_s synctex_class_rule = {
  1745. NULL, /* No scanner yet */
  1746. synctex_node_type_rule, /* Node type */
  1747. &_synctex_new_rule, /* creator */
  1748. &_synctex_free_leaf, /* destructor */
  1749. &_synctex_log_rule, /* log */
  1750. &_synctex_display_rule, /* display */
  1751. &_synctex_abstract_rule, /* abstract */
  1752. &synctex_tree_model_spf, /* tree model */
  1753. &synctex_data_model_box, /* data model */
  1754. &synctex_tlcpector_default, /* tlcpector */
  1755. &synctex_inspector_box, /* inspector */
  1756. &synctex_vispector_rule, /* vispector */
  1757. };
  1758. # ifdef SYNCTEX_NOTHING
  1759. # pragma mark boundary.
  1760. # endif
  1761. /* boundary node creator */
  1762. typedef synctex_node_tlchv_s synctex_node_boundary_s;
  1763. DEFINE_synctex_new_scanned_NODE(boundary)
  1764. static char * _synctex_abstract_boundary(synctex_node_p node);
  1765. static void _synctex_display_boundary(synctex_node_p node);
  1766. static synctex_class_s synctex_class_boundary = {
  1767. NULL, /* No scanner yet */
  1768. synctex_node_type_boundary, /* Node type */
  1769. &_synctex_new_boundary, /* creator */
  1770. &_synctex_free_leaf, /* destructor */
  1771. &_synctex_log_tlchv_node, /* log */
  1772. &_synctex_display_boundary, /* display */
  1773. &_synctex_abstract_boundary,/* abstract */
  1774. &synctex_tree_model_spf, /* tree model */
  1775. &synctex_data_model_tlchv, /* data model */
  1776. &synctex_tlcpector_default, /* tlcpector */
  1777. &synctex_inspector_hv, /* inspector */
  1778. &synctex_vispector_hv, /* vispector */
  1779. };
  1780. # ifdef SYNCTEX_NOTHING
  1781. # pragma mark box boundary.
  1782. # endif
  1783. typedef struct {
  1784. SYNCTEX_DECLARE_CHARINDEX
  1785. synctex_class_p class_;
  1786. synctex_data_u data[synctex_tree_spfa_max+synctex_data_tlchv_max];
  1787. } synctex_node_box_bdry_s;
  1788. #define DEFINE_synctex_new_unscanned_NODE(NAME)\
  1789. SYNCTEX_INLINE static synctex_node_p _synctex_new_##NAME(synctex_scanner_p scanner) {\
  1790. if (scanner) {\
  1791. synctex_node_p node = _synctex_malloc(sizeof(synctex_node_##NAME##_s));\
  1792. if (node) {\
  1793. node->class_ = scanner->class_+synctex_node_type_##NAME;\
  1794. SYNCTEX_DID_NEW(node); \
  1795. }\
  1796. return node;\
  1797. }\
  1798. return NULL;\
  1799. }
  1800. DEFINE_synctex_new_unscanned_NODE(box_bdry)
  1801. static char * _synctex_abstract_box_bdry(synctex_node_p node);
  1802. static void _synctex_display_box_bdry(synctex_node_p node);
  1803. static synctex_class_s synctex_class_box_bdry = {
  1804. NULL, /* No scanner yet */
  1805. synctex_node_type_box_bdry, /* Node type */
  1806. &_synctex_new_box_bdry, /* creator */
  1807. &_synctex_free_leaf, /* destructor */
  1808. &_synctex_log_tlchv_node, /* log */
  1809. &_synctex_display_box_bdry, /* display */
  1810. &_synctex_abstract_box_bdry,/* display */
  1811. &synctex_tree_model_spfa, /* tree model */
  1812. &synctex_data_model_tlchv, /* data model */
  1813. &synctex_tlcpector_default, /* tlcpector */
  1814. &synctex_inspector_hv, /* inspector */
  1815. &synctex_vispector_hv, /* vispector */
  1816. };
  1817. # ifdef SYNCTEX_NOTHING
  1818. # pragma mark hbox proxy.
  1819. # endif
  1820. /**
  1821. * Standard nodes refer to TeX nodes: math, kern, boxes...
  1822. * Proxy nodes are used to support forms.
  1823. * A form is parsed as a tree of standard nodes starting
  1824. * at the top left position.
  1825. * When a reference is used, the form is duplicated
  1826. * to the location specified by the reference.
  1827. * As the same form can be duplicated at different locations,
  1828. * the geometrical information is relative to its own top left point.
  1829. * As we need absolute locations, we use proxy nodes.
  1830. * A proxy node records an offset and the target node.
  1831. * The target partly acts as a delegate.
  1832. * The h and v position of the proxy node is the h and v
  1833. * position of the target shifted by the proxy's offset.
  1834. * The width, height and depth are not sensitive to offsets.
  1835. * When are proxies created ?
  1836. * 1) when the synctex file has been parsed, all the form refs
  1837. * are replaced by proxies to the content of a form.
  1838. * This content is a node with siblings (actually none).
  1839. * Those root proxies have the parent of the ref they replace,
  1840. * so their parents exist and are no proxy.
  1841. * Moreover, if they have no sibling, it means that their target have no
  1842. * sibling as well.
  1843. * Such nodes are called root proxies.
  1844. * 2) On the fly, when a proxy is asked for its child
  1845. * (or sibling) and has none, a proxy to its target's child
  1846. * (or sibling) is created if any. There are only 2 possible situations:
  1847. * either the newly created proxy is the child of a proxy,
  1848. * or it is the sibling of a proxy created on the fly.
  1849. * In both cases, the parent is a proxy with children.
  1850. * Such nodes are called child proxies.
  1851. * How to compute the offset of a proxy ?
  1852. * The offset of root proxy objects is exactly
  1853. * the offset of the ref they replace.
  1854. * The offset of other proxies is their owner's,
  1855. * except when pointing to a root proxy.
  1856. * What happens for cascading forms ?
  1857. * Here is an example diagram
  1858. *
  1859. * At parse time, the arrow means "owns":
  1860. * sheet0 -> ref_to1
  1861. *
  1862. * target1 -> ref_to2
  1863. *
  1864. * target2 -> child22
  1865. *
  1866. * After replacing the refs:
  1867. * sheet0 -> proxy00 -> proxy01 -> proxy02
  1868. * | | |
  1869. * target1 -> proxy11 -> proxy12
  1870. * | |
  1871. * target2 -> proxy22
  1872. *
  1873. * proxy00, proxy11 and proxy22 are root proxies.
  1874. * Their offset is the one of the ref they replace
  1875. * proxy01, proxy02 and proxy12 are child proxies.
  1876. * Their proxy is the one of their parent.
  1877. * Optimization.
  1878. * After all the refs are replaced, there are only root nodes
  1879. * targeting standard node. We make sure that each child proxy
  1880. * also targets a standard node.
  1881. * It is possible for a proxy to have a standard sibling
  1882. * whereas its target has no sibling at all. Root proxies
  1883. * are such nodes, and are the only ones.
  1884. * The consequence is that proxies created on the fly
  1885. * must take into account this situation.
  1886. */
  1887. /* A proxy to a hbox.
  1888. * A proxy do have a target, which can be a proxy
  1889. */
  1890. static const synctex_tree_model_s synctex_tree_model_proxy_hbox = {
  1891. synctex_tree_sibling_idx, /* sibling */
  1892. synctex_tree_s_parent_idx, /* parent */
  1893. synctex_tree_sp_child_idx, /* child */
  1894. synctex_tree_spc_friend_idx, /* friend */
  1895. synctex_tree_spcf_last_idx, /* last */
  1896. synctex_tree_spcfl_next_hbox_idx, /* next_hbox */
  1897. -1, /* arg_sibling */
  1898. synctex_tree_spcfln_target_idx, /* target */
  1899. synctex_tree_spcflnt_proxy_hbox_max
  1900. };
  1901. static const synctex_data_model_s synctex_data_model_proxy = {
  1902. -1, /* tag */
  1903. -1, /* line */
  1904. -1, /* column */
  1905. synctex_data_proxy_h_idx, /* h */
  1906. synctex_data_proxy_v_idx, /* v */
  1907. -1, /* width */
  1908. -1, /* height */
  1909. -1, /* depth */
  1910. -1, /* mean_line */
  1911. -1, /* weight */
  1912. -1, /* h_V */
  1913. -1, /* v_V */
  1914. -1, /* width_V */
  1915. -1, /* height_V */
  1916. -1, /* depth_V */
  1917. -1, /* name */
  1918. -1, /* page */
  1919. synctex_data_proxy_hv_max
  1920. };
  1921. typedef struct {
  1922. SYNCTEX_DECLARE_CHARINDEX
  1923. synctex_class_p class_;
  1924. synctex_data_u data[synctex_tree_spcflnt_proxy_hbox_max+synctex_data_proxy_hv_max];
  1925. } synctex_node_proxy_hbox_s;
  1926. /* box proxy node creator */
  1927. DEFINE_synctex_new_unscanned_NODE(proxy_hbox)
  1928. static void _synctex_log_proxy(synctex_node_p node);
  1929. static char * _synctex_abstract_proxy_hbox(synctex_node_p node);
  1930. static void _synctex_display_proxy_hbox(synctex_node_p node);
  1931. static int _synctex_proxy_tag(synctex_node_p);
  1932. static int _synctex_proxy_line(synctex_node_p);
  1933. static int _synctex_proxy_column(synctex_node_p);
  1934. static synctex_tlcpector_s synctex_tlcpector_proxy = {
  1935. &_synctex_proxy_tag,
  1936. &_synctex_proxy_line,
  1937. &_synctex_proxy_column,
  1938. };
  1939. static int _synctex_proxy_h(synctex_node_p);
  1940. static int _synctex_proxy_v(synctex_node_p);
  1941. static int _synctex_proxy_width(synctex_node_p);
  1942. static int _synctex_proxy_height(synctex_node_p);
  1943. static int _synctex_proxy_depth(synctex_node_p);
  1944. static synctex_inspector_s synctex_inspector_proxy_box = {
  1945. &_synctex_proxy_h,
  1946. &_synctex_proxy_v,
  1947. &_synctex_proxy_width,
  1948. &_synctex_proxy_height,
  1949. &_synctex_proxy_depth,
  1950. };
  1951. static float __synctex_proxy_visible_h(synctex_node_p);
  1952. static float __synctex_proxy_visible_v(synctex_node_p);
  1953. static float __synctex_proxy_visible_width(synctex_node_p);
  1954. static float __synctex_proxy_visible_height(synctex_node_p);
  1955. static float __synctex_proxy_visible_depth(synctex_node_p);
  1956. static synctex_vispector_s synctex_vispector_proxy_box = {
  1957. &__synctex_proxy_visible_h,
  1958. &__synctex_proxy_visible_v,
  1959. &__synctex_proxy_visible_width,
  1960. &__synctex_proxy_visible_height,
  1961. &__synctex_proxy_visible_depth,
  1962. };
  1963. static synctex_class_s synctex_class_proxy_hbox = {
  1964. NULL, /* No scanner yet */
  1965. synctex_node_type_proxy_hbox, /* Node type */
  1966. &_synctex_new_proxy_hbox, /* creator */
  1967. &_synctex_free_node, /* destructor */
  1968. &_synctex_log_proxy, /* log */
  1969. &_synctex_display_proxy_hbox, /* display */
  1970. &_synctex_abstract_proxy_hbox, /* abstract */
  1971. &synctex_tree_model_proxy_hbox, /* tree model */
  1972. &synctex_data_model_proxy, /* data model */
  1973. &synctex_tlcpector_proxy, /* tlcpector */
  1974. &synctex_inspector_proxy_box, /* inspector */
  1975. &synctex_vispector_proxy_box, /* vispector */
  1976. };
  1977. # ifdef SYNCTEX_NOTHING
  1978. # pragma mark vbox proxy.
  1979. # endif
  1980. /* A proxy to a vbox. */
  1981. static const synctex_tree_model_s synctex_tree_model_proxy_vbox = {
  1982. synctex_tree_sibling_idx, /* sibling */
  1983. synctex_tree_s_parent_idx, /* parent */
  1984. synctex_tree_sp_child_idx, /* child */
  1985. synctex_tree_spc_friend_idx, /* friend */
  1986. synctex_tree_spcf_last_idx, /* last */
  1987. -1, /* next_hbox */
  1988. -1, /* arg_sibling */
  1989. synctex_tree_spcfl_target_idx, /* target */
  1990. synctex_tree_spcflt_proxy_vbox_max
  1991. };
  1992. typedef struct {
  1993. SYNCTEX_DECLARE_CHARINDEX
  1994. synctex_class_p class_;
  1995. synctex_data_u data[synctex_tree_spcflt_proxy_vbox_max+synctex_data_proxy_hv_max];
  1996. } synctex_node_proxy_vbox_s;
  1997. /* box proxy node creator */
  1998. DEFINE_synctex_new_unscanned_NODE(proxy_vbox)
  1999. static void _synctex_log_proxy(synctex_node_p node);
  2000. static char * _synctex_abstract_proxy_vbox(synctex_node_p node);
  2001. static void _synctex_display_proxy_vbox(synctex_node_p node);
  2002. static synctex_class_s synctex_class_proxy_vbox = {
  2003. NULL, /* No scanner yet */
  2004. synctex_node_type_proxy_vbox, /* Node type */
  2005. &_synctex_new_proxy_vbox, /* creator */
  2006. &_synctex_free_node, /* destructor */
  2007. &_synctex_log_proxy, /* log */
  2008. &_synctex_display_proxy_vbox, /* display */
  2009. &_synctex_abstract_proxy_vbox, /* abstract */
  2010. &synctex_tree_model_proxy_vbox, /* tree model */
  2011. &synctex_data_model_proxy, /* data model */
  2012. &synctex_tlcpector_proxy, /* tlcpector */
  2013. &synctex_inspector_proxy_box, /* inspector */
  2014. &synctex_vispector_proxy_box, /* vispector */
  2015. };
  2016. # ifdef SYNCTEX_NOTHING
  2017. # pragma mark proxy.
  2018. # endif
  2019. /**
  2020. * A proxy to a node but a box.
  2021. */
  2022. static const synctex_tree_model_s synctex_tree_model_proxy = {
  2023. synctex_tree_sibling_idx, /* sibling */
  2024. synctex_tree_s_parent_idx, /* parent */
  2025. -1, /* child */
  2026. synctex_tree_sp_friend_idx, /* friend */
  2027. -1, /* last */
  2028. -1, /* next_hbox */
  2029. -1, /* arg_sibling */
  2030. synctex_tree_spf_target_idx,/* target */
  2031. synctex_tree_spft_proxy_max
  2032. };
  2033. typedef struct {
  2034. SYNCTEX_DECLARE_CHARINDEX
  2035. synctex_class_p class_;
  2036. synctex_data_u data[synctex_tree_spft_proxy_max+synctex_data_proxy_hv_max];
  2037. } synctex_node_proxy_s;
  2038. /* proxy node creator */
  2039. DEFINE_synctex_new_unscanned_NODE(proxy)
  2040. static void _synctex_log_proxy(synctex_node_p node);
  2041. static char * _synctex_abstract_proxy(synctex_node_p node);
  2042. static void _synctex_display_proxy(synctex_node_p node);
  2043. static synctex_vispector_s synctex_vispector_proxy = {
  2044. &__synctex_proxy_visible_h,
  2045. &__synctex_proxy_visible_v,
  2046. &__synctex_proxy_visible_width,
  2047. &_synctex_float_none,
  2048. &_synctex_float_none,
  2049. };
  2050. static synctex_class_s synctex_class_proxy = {
  2051. NULL, /* No scanner yet */
  2052. synctex_node_type_proxy, /* Node type */
  2053. &_synctex_new_proxy, /* creator */
  2054. &_synctex_free_leaf, /* destructor */
  2055. &_synctex_log_proxy, /* log */
  2056. &_synctex_display_proxy, /* display */
  2057. &_synctex_abstract_proxy, /* abstract */
  2058. &synctex_tree_model_proxy, /* tree model */
  2059. &synctex_data_model_proxy, /* data model */
  2060. &synctex_tlcpector_proxy, /* tlcpector */
  2061. &synctex_inspector_proxy_box, /* inspector */
  2062. &synctex_vispector_proxy, /* vispector */
  2063. };
  2064. # ifdef SYNCTEX_NOTHING
  2065. # pragma mark last proxy.
  2066. # endif
  2067. /**
  2068. * A proxy to the last proxy/box boundary.
  2069. */
  2070. static const synctex_tree_model_s synctex_tree_model_proxy_last = {
  2071. synctex_tree_sibling_idx, /* sibling */
  2072. synctex_tree_s_parent_idx, /* parent */
  2073. -1, /* child */
  2074. synctex_tree_sp_friend_idx, /* friend */
  2075. -1, /* last */
  2076. -1, /* next_hbox */
  2077. synctex_tree_spf_arg_sibling_idx, /* arg_sibling */
  2078. synctex_tree_spfa_target_idx, /* target */
  2079. synctex_tree_spfat_proxy_last_max
  2080. };
  2081. typedef struct {
  2082. SYNCTEX_DECLARE_CHARINDEX
  2083. synctex_class_p class_;
  2084. synctex_data_u data[synctex_tree_spfat_proxy_last_max+synctex_data_proxy_hv_max];
  2085. } synctex_node_proxy_last_s;
  2086. /* proxy node creator */
  2087. DEFINE_synctex_new_unscanned_NODE(proxy_last)
  2088. static void _synctex_log_proxy(synctex_node_p node);
  2089. static char * _synctex_abstract_proxy(synctex_node_p node);
  2090. static void _synctex_display_proxy(synctex_node_p node);
  2091. static synctex_class_s synctex_class_proxy_last = {
  2092. NULL, /* No scanner yet */
  2093. synctex_node_type_proxy_last, /* Node type */
  2094. &_synctex_new_proxy, /* creator */
  2095. &_synctex_free_leaf, /* destructor */
  2096. &_synctex_log_proxy, /* log */
  2097. &_synctex_display_proxy, /* display */
  2098. &_synctex_abstract_proxy, /* abstract */
  2099. &synctex_tree_model_proxy_last, /* tree model */
  2100. &synctex_data_model_proxy, /* data model */
  2101. &synctex_tlcpector_proxy, /* tlcpector */
  2102. &synctex_inspector_proxy_box, /* inspector */
  2103. &synctex_vispector_proxy, /* vispector */
  2104. };
  2105. # ifdef SYNCTEX_NOTHING
  2106. # pragma mark handle.
  2107. # endif
  2108. /**
  2109. * A handle node.
  2110. * A handle is never the target of a proxy
  2111. * or another handle.
  2112. * The child of a handle is always a handle if any.
  2113. * The sibling of a handle is always a handle if any.
  2114. * The parent of a handle is always a handle if any.
  2115. */
  2116. static const synctex_tree_model_s synctex_tree_model_handle = {
  2117. synctex_tree_sibling_idx, /* sibling */
  2118. synctex_tree_s_parent_idx, /* parent */
  2119. synctex_tree_sp_child_idx, /* child */
  2120. -1, /* friend */
  2121. -1, /* last */
  2122. -1, /* next_hbox */
  2123. -1, /* arg_sibling */
  2124. synctex_tree_spc_target_idx,/* target */
  2125. synctex_tree_spct_handle_max
  2126. };
  2127. static const synctex_data_model_s synctex_data_model_handle = {
  2128. -1, /* tag */
  2129. -1, /* line */
  2130. -1, /* column */
  2131. -1, /* h */
  2132. -1, /* v */
  2133. -1, /* width */
  2134. -1, /* height */
  2135. -1, /* depth */
  2136. -1, /* mean_line */
  2137. synctex_data_handle_w_idx, /* weight */
  2138. -1, /* h_V */
  2139. -1, /* v_V */
  2140. -1, /* width_V */
  2141. -1, /* height_V */
  2142. -1, /* depth_V */
  2143. -1, /* name */
  2144. -1, /* page */
  2145. synctex_data_handle_w_max
  2146. };
  2147. typedef struct {
  2148. SYNCTEX_DECLARE_CHARINDEX
  2149. synctex_class_p class_;
  2150. synctex_data_u data[synctex_tree_spct_handle_max+synctex_data_handle_w_max];
  2151. } synctex_node_handle_s;
  2152. /* handle node creator */
  2153. DEFINE_synctex_new_unscanned_NODE(handle)
  2154. static void _synctex_log_handle(synctex_node_p node);
  2155. static char * _synctex_abstract_handle(synctex_node_p node);
  2156. static void _synctex_display_handle(synctex_node_p node);
  2157. static synctex_class_s synctex_class_handle = {
  2158. NULL, /* No scanner yet */
  2159. synctex_node_type_handle, /* Node type */
  2160. &_synctex_new_handle, /* creator */
  2161. &_synctex_free_handle, /* destructor */
  2162. &_synctex_log_handle, /* log */
  2163. &_synctex_display_handle, /* display */
  2164. &_synctex_abstract_handle, /* abstract */
  2165. &synctex_tree_model_handle, /* tree model */
  2166. &synctex_data_model_handle, /* data model */
  2167. &synctex_tlcpector_proxy, /* tlcpector */
  2168. &synctex_inspector_proxy_box, /* inspector */
  2169. &synctex_vispector_proxy_box, /* vispector */
  2170. };
  2171. SYNCTEX_INLINE static synctex_node_p _synctex_new_handle_with_target(synctex_node_p target) {
  2172. if (target) {
  2173. synctex_node_p result = _synctex_new_handle(target->class_->scanner);
  2174. if (result) {
  2175. _synctex_tree_set_target(result,target);
  2176. return result;
  2177. }
  2178. }
  2179. return NULL;
  2180. }
  2181. SYNCTEX_INLINE static synctex_node_p _synctex_new_handle_with_child(synctex_node_p child) {
  2182. if (child) {
  2183. synctex_node_p result = _synctex_new_handle(child->class_->scanner);
  2184. if (result) {
  2185. _synctex_tree_set_child(result,child);
  2186. return result;
  2187. }
  2188. }
  2189. return NULL;
  2190. }
  2191. # ifdef SYNCTEX_NOTHING
  2192. # pragma mark -
  2193. # pragma mark Navigation
  2194. # endif
  2195. synctex_node_p synctex_node_parent(synctex_node_p node)
  2196. {
  2197. return _synctex_tree_parent(node);
  2198. }
  2199. synctex_node_p synctex_node_parent_sheet(synctex_node_p node)
  2200. {
  2201. while(node && synctex_node_type(node) != synctex_node_type_sheet) {
  2202. node = _synctex_tree_parent(node);
  2203. }
  2204. /* exit the while loop either when node is NULL or node is a sheet */
  2205. return node;
  2206. }
  2207. synctex_node_p synctex_node_parent_form(synctex_node_p node)
  2208. {
  2209. while(node && synctex_node_type(node) != synctex_node_type_form) {
  2210. node = _synctex_tree_parent(node);
  2211. }
  2212. /* exit the while loop either when node is NULL or node is a form */
  2213. return node;
  2214. }
  2215. /**
  2216. * The returned proxy will be the child or a sibling of source.
  2217. * The returned proxy has no parent, child nor sibling.
  2218. * Used only by __synctex_replace_ref.
  2219. * argument to_node: a box, not a proxy nor anything else.
  2220. */
  2221. SYNCTEX_INLINE static synctex_node_p __synctex_new_proxy_from_ref_to(synctex_node_p ref, synctex_node_p to_node) {
  2222. synctex_node_p proxy = NULL;
  2223. if (!ref || !to_node) {
  2224. return NULL;
  2225. }
  2226. switch(synctex_node_type(to_node)) {
  2227. case synctex_node_type_vbox:
  2228. proxy = _synctex_new_proxy_vbox(ref->class_->scanner);
  2229. break;
  2230. case synctex_node_type_hbox:
  2231. proxy = _synctex_new_proxy_hbox(ref->class_->scanner);
  2232. break;
  2233. default:
  2234. _synctex_error("! __synctex_new_proxy_from_ref_to. Unexpected form child (%s). Please report.", synctex_node_isa(to_node));
  2235. return NULL;
  2236. }
  2237. if (!proxy) {
  2238. _synctex_error("! __synctex_new_proxy_from_ref_to. Internal error. Please report.");
  2239. return NULL;
  2240. }
  2241. _synctex_data_set_h(proxy, _synctex_data_h(ref));
  2242. _synctex_data_set_v(proxy, _synctex_data_v(ref)-_synctex_data_height(to_node));
  2243. _synctex_tree_set_target(proxy,to_node);
  2244. # if defined(SYNCTEX_USE_CHARINDEX)
  2245. proxy->line_index=to_node?to_node->line_index:0;
  2246. proxy->char_index=to_node?to_node->char_index:0;
  2247. # endif
  2248. return proxy;
  2249. }
  2250. /**
  2251. * The returned proxy will be the child or a sibling of owning_proxy.
  2252. * The returned proxy has no parent, nor child.
  2253. * Used only by synctex_node_child and synctex_node_sibling
  2254. * to create proxies on the fly.
  2255. * If the to_node has an already computed sibling,
  2256. * then the returned proxy has itself a sibling
  2257. * pointing to that already computed sibling.
  2258. */
  2259. SYNCTEX_INLINE static synctex_node_p __synctex_new_child_proxy_to(synctex_node_p owner, synctex_node_p to_node) {
  2260. synctex_node_p proxy = NULL;
  2261. synctex_node_p target = to_node;
  2262. if (!owner) {
  2263. return NULL;
  2264. }
  2265. switch(synctex_node_type(target)) {
  2266. case synctex_node_type_vbox:
  2267. if ((proxy = _synctex_new_proxy_vbox(owner->class_->scanner))) {
  2268. exit_standard:
  2269. _synctex_data_set_h(proxy, _synctex_data_h(owner));
  2270. _synctex_data_set_v(proxy, _synctex_data_v(owner));
  2271. exit0:
  2272. _synctex_tree_set_target(proxy,target);
  2273. # if defined(SYNCTEX_USE_CHARINDEX)
  2274. proxy->line_index=to_node?to_node->line_index:0;
  2275. proxy->char_index=to_node?to_node->char_index:0;
  2276. # endif
  2277. return proxy;
  2278. };
  2279. break;
  2280. case synctex_node_type_proxy_vbox:
  2281. if ((proxy = _synctex_new_proxy_vbox(owner->class_->scanner))) {
  2282. exit_proxy:
  2283. target = _synctex_tree_target(to_node);
  2284. _synctex_data_set_h(proxy, _synctex_data_h(owner)+_synctex_data_h(to_node));
  2285. _synctex_data_set_v(proxy, _synctex_data_v(owner)+_synctex_data_v(to_node));
  2286. goto exit0;
  2287. };
  2288. break;
  2289. case synctex_node_type_hbox:
  2290. if ((proxy = _synctex_new_proxy_hbox(owner->class_->scanner))) {
  2291. goto exit_standard;
  2292. };
  2293. break;
  2294. case synctex_node_type_proxy_hbox:
  2295. if ((proxy = _synctex_new_proxy_hbox(owner->class_->scanner))) {
  2296. goto exit_proxy;
  2297. };
  2298. break;
  2299. case synctex_node_type_proxy:
  2300. case synctex_node_type_proxy_last:
  2301. if ((proxy = _synctex_new_proxy(owner->class_->scanner))) {
  2302. goto exit_proxy;
  2303. };
  2304. break;
  2305. default:
  2306. if ((proxy = _synctex_new_proxy(owner->class_->scanner))) {
  2307. goto exit_standard;
  2308. };
  2309. break;
  2310. }
  2311. _synctex_error("! __synctex_new_child_proxy_to. "
  2312. "Internal error. "
  2313. "Please report.");
  2314. return NULL;
  2315. }
  2316. SYNCTEX_INLINE static synctex_node_p _synctex_tree_set_sibling(synctex_node_p node, synctex_node_p new_sibling);
  2317. typedef struct synctex_nns_t {
  2318. synctex_node_p first;
  2319. synctex_node_p last;
  2320. synctex_status_t status;
  2321. } synctex_nns_s;
  2322. /**
  2323. * Given a target node, create a list of proxies.
  2324. * The first proxy points to the target node,
  2325. * its sibling points to the target's sibling and so on.
  2326. * Returns the first created proxy, the last one and
  2327. * an error status.
  2328. */
  2329. SYNCTEX_INLINE static synctex_nns_s _synctex_new_child_proxies_to(synctex_node_p owner, synctex_node_p to_node) {
  2330. synctex_nns_s nns = {NULL,NULL,SYNCTEX_STATUS_OK};
  2331. if ((nns.first = nns.last = __synctex_new_child_proxy_to(owner,to_node))) {
  2332. synctex_node_p to_next_sibling = __synctex_tree_sibling(to_node);
  2333. synctex_node_p to_sibling;
  2334. while ((to_sibling = to_next_sibling)) {
  2335. synctex_node_p sibling;
  2336. if ((to_next_sibling = __synctex_tree_sibling(to_sibling))) {
  2337. /* This is not the last sibling */
  2338. if((sibling = __synctex_new_child_proxy_to(owner,to_sibling))) {
  2339. _synctex_tree_set_sibling(nns.last,sibling);
  2340. nns.last = sibling;
  2341. continue;
  2342. } else {
  2343. _synctex_error("! _synctex_new_child_proxy_to. "
  2344. "Internal error (1). "
  2345. "Please report.");
  2346. nns.status = SYNCTEX_STATUS_ERROR;
  2347. }
  2348. } else if((sibling = _synctex_new_proxy_last(owner->class_->scanner))) {
  2349. _synctex_tree_set_sibling(nns.last,sibling);
  2350. nns.last = sibling;
  2351. _synctex_data_set_h(nns.last, _synctex_data_h(nns.first));
  2352. _synctex_data_set_v(nns.last, _synctex_data_v(nns.first));
  2353. _synctex_tree_set_target(nns.last,to_sibling);
  2354. # if defined(SYNCTEX_USE_CHARINDEX)
  2355. nns.last->line_index=to_sibling->line_index;
  2356. nns.last->char_index=to_sibling->char_index;
  2357. # endif
  2358. } else {
  2359. _synctex_error("! _synctex_new_child_proxy_to. "
  2360. "Internal error (2). "
  2361. "Please report.");
  2362. nns.status = SYNCTEX_STATUS_ERROR;
  2363. }
  2364. break;
  2365. }
  2366. }
  2367. return nns;
  2368. }
  2369. static char * _synctex_node_abstract(synctex_node_p node);
  2370. SYNCTEX_INLINE static synctex_node_p synctex_tree_set_friend(synctex_node_p node,synctex_node_p new_friend) {
  2371. #if SYNCTEX_DEBUG
  2372. synctex_node_p F = new_friend;
  2373. while (F) {
  2374. if (node == F) {
  2375. printf("THIS IS AN ERROR\n");
  2376. F = new_friend;
  2377. while (F) {
  2378. printf("%s\n",_synctex_node_abstract(F));
  2379. if (node == F) {
  2380. return NULL;
  2381. }
  2382. F = _synctex_tree_friend(F);
  2383. }
  2384. return NULL;
  2385. }
  2386. F = _synctex_tree_friend(F);
  2387. }
  2388. #endif
  2389. return new_friend?_synctex_tree_set_friend(node,new_friend):_synctex_tree_reset_friend(node);
  2390. }
  2391. /**
  2392. *
  2393. */
  2394. SYNCTEX_INLINE static synctex_node_p __synctex_node_make_friend(synctex_node_p node, int i) {
  2395. synctex_node_p old = NULL;
  2396. if (i>=0) {
  2397. i = i%(node->class_->scanner->number_of_lists);
  2398. old = synctex_tree_set_friend(node,(node->class_->scanner->lists_of_friends)[i]);
  2399. (node->class_->scanner->lists_of_friends)[i] = node;
  2400. #if SYNCTEX_DEBUG>500
  2401. printf("tl(%i)=>",i);
  2402. synctex_node_log(node);
  2403. if (synctex_node_parent_form(node)) {
  2404. printf("! ERROR. No registration expected!\n");
  2405. }
  2406. #endif
  2407. }
  2408. return old;
  2409. }
  2410. /**
  2411. * All proxies have tlc attributes, on behalf of their target.
  2412. * The purpose is to register all af them.
  2413. * - argument node: is the proxy, must not be NULL
  2414. */
  2415. SYNCTEX_INLINE static synctex_node_p __synctex_proxy_make_friend_and_next_hbox(synctex_node_p node) {
  2416. synctex_node_p old = NULL;
  2417. synctex_node_p target = _synctex_tree_target(node);
  2418. if (target) {
  2419. int i = _synctex_data_tag(target)+_synctex_data_line(target);
  2420. old = __synctex_node_make_friend(node,i);
  2421. } else {
  2422. old = __synctex_tree_reset_friend(node);
  2423. }
  2424. if (synctex_node_type(node) == synctex_node_type_proxy_hbox) {
  2425. synctex_node_p sheet = synctex_node_parent_sheet(node);
  2426. if (sheet) {
  2427. _synctex_tree_set_next_hbox(node,_synctex_tree_next_hbox(sheet));
  2428. _synctex_tree_set_next_hbox(sheet,node);
  2429. }
  2430. }
  2431. return old;
  2432. }
  2433. /**
  2434. * Register a node which have tag, line and column.
  2435. * - argument node: the node
  2436. */
  2437. SYNCTEX_INLINE static synctex_node_p __synctex_node_make_friend_tlc(synctex_node_p node) {
  2438. int i = synctex_node_tag(node)+synctex_node_line(node);
  2439. return __synctex_node_make_friend(node,i);
  2440. }
  2441. /**
  2442. * Register a node which have tag, line and column.
  2443. * Does nothing if the argument is NULL.
  2444. * Calls __synctex_node_make_friend_tlc.
  2445. * - argument node: the node
  2446. */
  2447. SYNCTEX_INLINE static void _synctex_node_make_friend_tlc(synctex_node_p node) {
  2448. if (node) {
  2449. __synctex_node_make_friend_tlc(node);
  2450. }
  2451. }
  2452. static synctex_node_p _synctex_node_set_child(synctex_node_p node, synctex_node_p new_child);
  2453. /**
  2454. * The (first) child of the node, if any, NULL otherwise.
  2455. * At parse time, non void box nodes have children.
  2456. * All other nodes have no children.
  2457. * In order to support pdf forms, proxies are created
  2458. * to place form nodes at real locations.
  2459. * Ref nodes are replaced by root proxies targeting
  2460. * form contents. If root proxies have no children,
  2461. * they are created on the fly as proxies to the
  2462. * children of the targeted box.
  2463. * As such, proxies created here are targeting a
  2464. * node that belongs to a form.
  2465. * This is the only place where child proxies are created.
  2466. */
  2467. synctex_node_p synctex_node_child(synctex_node_p node) {
  2468. synctex_node_p child = NULL;
  2469. synctex_node_p target = NULL;
  2470. if ((child = _synctex_tree_child(node))) {
  2471. return child;
  2472. } else if ((target = _synctex_tree_target(node))) {
  2473. if ((child = synctex_node_child(target))) {
  2474. /* This is a proxy with no child
  2475. * which target does have a child. */
  2476. synctex_nns_s nns = _synctex_new_child_proxies_to(node, child);
  2477. if (nns.first) {
  2478. _synctex_node_set_child(node,nns.first);
  2479. return nns.first;
  2480. } else {
  2481. _synctex_error("! synctex_node_child. Internal inconsistency. Please report.");
  2482. }
  2483. }
  2484. }
  2485. return NULL;
  2486. }
  2487. /*
  2488. * Set the parent/child bound.
  2489. * Things get complicated when new_child has siblings.
  2490. * The caller is responsible for releasing the returned value.
  2491. */
  2492. static synctex_node_p _synctex_node_set_child(synctex_node_p parent, synctex_node_p new_child) {
  2493. if (parent) {
  2494. synctex_node_p old = _synctex_tree_set_child(parent,new_child);
  2495. synctex_node_p last_child = NULL;
  2496. synctex_node_p child;
  2497. if ((child = old)) {
  2498. do {
  2499. _synctex_tree_reset_parent(child);
  2500. } while ((child = __synctex_tree_sibling(child)));
  2501. }
  2502. if ((child = new_child)) {
  2503. do {
  2504. _synctex_tree_set_parent(child,parent);
  2505. last_child = child;
  2506. } while ((child = __synctex_tree_sibling(child)));
  2507. }
  2508. _synctex_tree_set_last(parent,last_child);
  2509. return old;
  2510. }
  2511. return NULL;
  2512. }
  2513. /* The last child of the given node, or NULL.
  2514. */
  2515. synctex_node_p synctex_node_last_child(synctex_node_p node) {
  2516. return _synctex_tree_last(node);
  2517. }
  2518. /**
  2519. * All nodes siblings are properly set up at parse time
  2520. * except for non root proxies.
  2521. */
  2522. synctex_node_p synctex_node_sibling(synctex_node_p node) {
  2523. return node? __synctex_tree_sibling(node): NULL;
  2524. }
  2525. /**
  2526. * All the _synctex_tree_... methods refer to the tree model.
  2527. * __synctex_tree_... methods are low level.
  2528. */
  2529. /**
  2530. * Replace the sibling.
  2531. * Connect to the arg_sibling of the new_sibling if relevant.
  2532. * - returns the old sibling.
  2533. * The caller is responsible for releasing the old sibling.
  2534. * The bound to the parent is managed below.
  2535. */
  2536. SYNCTEX_INLINE static synctex_node_p _synctex_tree_set_sibling(synctex_node_p node, synctex_node_p new_sibling) {
  2537. if (node == new_sibling) {
  2538. printf("BOF\n");
  2539. }
  2540. synctex_node_p old = node? __synctex_tree_set_sibling(node,new_sibling): NULL;
  2541. _synctex_tree_set_arg_sibling(new_sibling,node);
  2542. return old;
  2543. }
  2544. /**
  2545. * Replace the sibling.
  2546. * Set the parent of the new sibling (and further siblings)
  2547. * to the parent of the receiver.
  2548. * Also set the last sibling of parent.
  2549. * - argument new_sibling: must not be NULL.
  2550. * - returns the old sibling.
  2551. * The caller is responsible for releasing the old sibling.
  2552. */
  2553. static synctex_node_p _synctex_node_set_sibling(synctex_node_p node, synctex_node_p new_sibling) {
  2554. if (node && new_sibling) {
  2555. synctex_node_p old = _synctex_tree_set_sibling(node,new_sibling);
  2556. if (_synctex_tree_has_parent(node)) {
  2557. synctex_node_p parent = __synctex_tree_parent(node);
  2558. if (parent) {
  2559. synctex_node_p N = new_sibling;
  2560. while (synctex_YES) {
  2561. if (_synctex_tree_has_parent(N)) {
  2562. __synctex_tree_set_parent(N,parent);
  2563. _synctex_tree_set_last(parent,N);
  2564. N = __synctex_tree_sibling(N);
  2565. continue;
  2566. } else if (N) {
  2567. _synctex_error("! synctex_node_sibling. "
  2568. "Internal inconsistency. "
  2569. "Please report.");
  2570. }
  2571. break;
  2572. }
  2573. }
  2574. }
  2575. return old;
  2576. }
  2577. return NULL;
  2578. }
  2579. /**
  2580. * The last sibling of the given node, or NULL with node.
  2581. */
  2582. synctex_node_p synctex_node_last_sibling(synctex_node_p node) {
  2583. synctex_node_p sibling;
  2584. do {
  2585. sibling = node;
  2586. } while((node = synctex_node_sibling(node)));
  2587. return sibling;
  2588. }
  2589. /**
  2590. * The next nodes corresponds to a deep first tree traversal.
  2591. * Does not create child proxies as side effect contrary to
  2592. * the synctex_node_next method above.
  2593. * May loop infinitely many times if the tree
  2594. * is not properly built (contains loops).
  2595. */
  2596. SYNCTEX_INLINE static synctex_node_p _synctex_node_sibling_or_parents(synctex_node_p node) {
  2597. while (node) {
  2598. synctex_node_p N;
  2599. if ((N = __synctex_tree_sibling(node))) {
  2600. return N;
  2601. } else if ((node = _synctex_tree_parent(node))) {
  2602. if (synctex_node_type(node) == synctex_node_type_sheet) {/* EXC_BAD_ACCESS? */
  2603. return NULL;
  2604. } else if (synctex_node_type(node) == synctex_node_type_form) {
  2605. return NULL;
  2606. }
  2607. } else {
  2608. return NULL;
  2609. }
  2610. }
  2611. return NULL;
  2612. }
  2613. /**
  2614. * The next nodes corresponds to a deep first tree traversal.
  2615. * Creates child proxies as side effect.
  2616. * May loop infinitely many times if the tree
  2617. * is not properly built (contains loops).
  2618. */
  2619. synctex_node_p synctex_node_next(synctex_node_p node) {
  2620. synctex_node_p N = synctex_node_child(node);
  2621. if (N) {
  2622. return N;
  2623. }
  2624. return _synctex_node_sibling_or_parents(node);
  2625. }
  2626. /**
  2627. * The node which argument is the sibling.
  2628. * - return: NULL if the argument has no parent or
  2629. * is the first child of its parent.
  2630. * - Input nodes have no arg siblings
  2631. */
  2632. synctex_node_p synctex_node_arg_sibling(synctex_node_p node) {
  2633. #if 1
  2634. return _synctex_tree_arg_sibling(node);
  2635. #else
  2636. synctex_node_p N = _synctex_tree_parent(node);
  2637. if ((N = _synctex_tree_child(N))) {
  2638. do {
  2639. synctex_node_p NN = __synctex_tree_sibling(N);
  2640. if (NN == node) {
  2641. return N;
  2642. }
  2643. N = NN;
  2644. } while (N);
  2645. }
  2646. return N;
  2647. #endif
  2648. }
  2649. # ifdef SYNCTEX_NOTHING
  2650. # pragma mark -
  2651. # pragma mark CLASS
  2652. # endif
  2653. /* Public node accessor: the type */
  2654. synctex_node_type_t synctex_node_type(synctex_node_p node) {
  2655. return node? node->class_->type: synctex_node_type_none;
  2656. }
  2657. /* Public node accessor: the type */
  2658. synctex_node_type_t synctex_node_target_type(synctex_node_p node) {
  2659. synctex_node_p target = _synctex_tree_target(node);
  2660. if (target) {
  2661. return (((target)->class_))->type;
  2662. } else if (node) {
  2663. return (((node)->class_))->type;
  2664. }
  2665. return synctex_node_type_none;
  2666. }
  2667. /* Public node accessor: the human readable type */
  2668. const char * synctex_node_isa(synctex_node_p node) {
  2669. static const char * isa[synctex_node_number_of_types] =
  2670. {"Not a node",
  2671. "input",
  2672. "sheet",
  2673. "form",
  2674. "ref",
  2675. "vbox",
  2676. "void vbox",
  2677. "hbox",
  2678. "void hbox",
  2679. "kern",
  2680. "glue",
  2681. "rule",
  2682. "math",
  2683. "boundary",
  2684. "box_bdry",
  2685. "proxy",
  2686. "last proxy",
  2687. "vbox proxy",
  2688. "hbox proxy",
  2689. "handle"};
  2690. return isa[synctex_node_type(node)];
  2691. }
  2692. # ifdef SYNCTEX_NOTHING
  2693. # pragma mark -
  2694. # pragma mark LOG
  2695. # endif
  2696. /* Public node logger */
  2697. void synctex_node_log(synctex_node_p node) {
  2698. SYNCTEX_MSG_SEND(node,log);
  2699. }
  2700. static void _synctex_log_input(synctex_node_p node) {
  2701. if (node) {
  2702. printf("%s:%i,%s(%i)\n",synctex_node_isa(node),
  2703. _synctex_data_tag(node),
  2704. _synctex_data_name(node),
  2705. _synctex_data_line(node));
  2706. printf("SELF:%p\n",(void *)node);
  2707. printf(" SIBLING:%p\n",
  2708. (void *)__synctex_tree_sibling(node));
  2709. }
  2710. }
  2711. static void _synctex_log_sheet(synctex_node_p node) {
  2712. if (node) {
  2713. printf("%s:%i",synctex_node_isa(node),_synctex_data_page(node));
  2714. SYNCTEX_PRINT_CHARINDEX_NL;
  2715. printf("SELF:%p\n",(void *)node);
  2716. printf(" SIBLING:%p\n",(void *)__synctex_tree_sibling(node));
  2717. printf(" PARENT:%p\n",(void *)_synctex_tree_parent(node));
  2718. printf(" CHILD:%p\n",(void *)_synctex_tree_child(node));
  2719. printf(" LEFT:%p\n",(void *)_synctex_tree_friend(node));
  2720. printf(" NEXT_hbox:%p\n",(void *)_synctex_tree_next_hbox(node));
  2721. }
  2722. }
  2723. static void _synctex_log_form(synctex_node_p node) {
  2724. if (node) {
  2725. printf("%s:%i",synctex_node_isa(node),_synctex_data_tag(node));
  2726. SYNCTEX_PRINT_CHARINDEX_NL;
  2727. printf("SELF:%p\n",(void *)node);
  2728. printf(" SIBLING:%p\n",(void *)__synctex_tree_sibling(node));
  2729. printf(" PARENT:%p\n",(void *)_synctex_tree_parent(node));
  2730. printf(" CHILD:%p\n",(void *)_synctex_tree_child(node));
  2731. printf(" LEFT:%p\n",(void *)_synctex_tree_friend(node));
  2732. }
  2733. }
  2734. static void _synctex_log_ref(synctex_node_p node) {
  2735. if (node) {
  2736. printf("%s:%i:%i,%i",
  2737. synctex_node_isa(node),
  2738. _synctex_data_tag(node),
  2739. _synctex_data_h(node),
  2740. _synctex_data_v(node));
  2741. SYNCTEX_PRINT_CHARINDEX_NL;
  2742. printf("SELF:%p\n",(void *)node);
  2743. printf(" SIBLING:%p\n",(void *)__synctex_tree_sibling(node));
  2744. printf(" PARENT:%p\n",(void *)_synctex_tree_parent(node));
  2745. }
  2746. }
  2747. static void _synctex_log_tlchv_node(synctex_node_p node) {
  2748. if (node) {
  2749. printf("%s:%i,%i,%i:%i,%i",
  2750. synctex_node_isa(node),
  2751. _synctex_data_tag(node),
  2752. _synctex_data_line(node),
  2753. _synctex_data_column(node),
  2754. _synctex_data_h(node),
  2755. _synctex_data_v(node));
  2756. SYNCTEX_PRINT_CHARINDEX_NL;
  2757. printf("SELF:%p\n",(void *)node);
  2758. printf(" SIBLING:%p\n",(void *)__synctex_tree_sibling(node));
  2759. printf(" PARENT:%p\n",(void *)_synctex_tree_parent(node));
  2760. printf(" CHILD:%p\n",(void *)_synctex_tree_child(node));
  2761. printf(" LEFT:%p\n",(void *)_synctex_tree_friend(node));
  2762. }
  2763. }
  2764. static void _synctex_log_kern_node(synctex_node_p node) {
  2765. if (node) {
  2766. printf("%s:%i,%i,%i:%i,%i:%i",
  2767. synctex_node_isa(node),
  2768. _synctex_data_tag(node),
  2769. _synctex_data_line(node),
  2770. _synctex_data_column(node),
  2771. _synctex_data_h(node),
  2772. _synctex_data_v(node),
  2773. _synctex_data_width(node));
  2774. SYNCTEX_PRINT_CHARINDEX_NL;
  2775. printf("SELF:%p\n",(void *)node);
  2776. printf(" SIBLING:%p\n",(void *)__synctex_tree_sibling(node));
  2777. printf(" PARENT:%p\n",(void *)_synctex_tree_parent(node));
  2778. printf(" CHILD:%p\n",(void *)_synctex_tree_child(node));
  2779. printf(" LEFT:%p\n",(void *)_synctex_tree_friend(node));
  2780. }
  2781. }
  2782. static void _synctex_log_rule(synctex_node_p node) {
  2783. if (node) {
  2784. printf("%s:%i,%i,%i:%i,%i",
  2785. synctex_node_isa(node),
  2786. _synctex_data_tag(node),
  2787. _synctex_data_line(node),
  2788. _synctex_data_column(node),
  2789. _synctex_data_h(node),
  2790. _synctex_data_v(node));
  2791. printf(":%i",_synctex_data_width(node));
  2792. printf(",%i",_synctex_data_height(node));
  2793. printf(",%i",_synctex_data_depth(node));
  2794. SYNCTEX_PRINT_CHARINDEX_NL;
  2795. printf("SELF:%p\n",(void *)node);
  2796. printf(" SIBLING:%p\n",(void *)__synctex_tree_sibling(node));
  2797. printf(" PARENT:%p\n",(void *)_synctex_tree_parent(node));
  2798. printf(" LEFT:%p\n",(void *)_synctex_tree_friend(node));
  2799. }
  2800. }
  2801. static void _synctex_log_void_box(synctex_node_p node) {
  2802. if (node) {
  2803. printf("%s",synctex_node_isa(node));
  2804. printf(":%i",_synctex_data_tag(node));
  2805. printf(",%i",_synctex_data_line(node));
  2806. printf(",%i",_synctex_data_column(node));
  2807. printf(":%i",_synctex_data_h(node));
  2808. printf(",%i",_synctex_data_v(node));
  2809. printf(":%i",_synctex_data_width(node));
  2810. printf(",%i",_synctex_data_height(node));
  2811. printf(",%i",_synctex_data_depth(node));
  2812. SYNCTEX_PRINT_CHARINDEX_NL;
  2813. printf("SELF:%p\n",(void *)node);
  2814. printf(" SIBLING:%p\n",(void *)__synctex_tree_sibling(node));
  2815. printf(" PARENT:%p\n",(void *)_synctex_tree_parent(node));
  2816. printf(" CHILD:%p\n",(void *)_synctex_tree_child(node));
  2817. printf(" LEFT:%p\n",(void *)_synctex_tree_friend(node));
  2818. }
  2819. }
  2820. static void _synctex_log_vbox(synctex_node_p node) {
  2821. if (node) {
  2822. printf("%s",synctex_node_isa(node));
  2823. printf(":%i",_synctex_data_tag(node));
  2824. printf(",%i",_synctex_data_line(node));
  2825. printf(",%i",_synctex_data_column(node));
  2826. printf(":%i",_synctex_data_h(node));
  2827. printf(",%i",_synctex_data_v(node));
  2828. printf(":%i",_synctex_data_width(node));
  2829. printf(",%i",_synctex_data_height(node));
  2830. printf(",%i",_synctex_data_depth(node));
  2831. SYNCTEX_PRINT_CHARINDEX_NL;
  2832. printf("SELF:%p\n",(void *)node);
  2833. printf(" SIBLING:%p\n",(void *)__synctex_tree_sibling(node));
  2834. printf(" PARENT:%p\n",(void *)_synctex_tree_parent(node));
  2835. printf(" CHILD:%p\n",(void *)_synctex_tree_child(node));
  2836. printf(" LEFT:%p\n",(void *)_synctex_tree_friend(node));
  2837. printf(" NEXT_hbox:%p\n",(void *)_synctex_tree_next_hbox(node));
  2838. }
  2839. }
  2840. static void _synctex_log_hbox(synctex_node_p node) {
  2841. if (node) {
  2842. printf("%s",synctex_node_isa(node));
  2843. printf(":%i",_synctex_data_tag(node));
  2844. printf(",%i~%i*%i",_synctex_data_line(node),_synctex_data_mean_line(node),_synctex_data_weight(node));
  2845. printf(",%i",_synctex_data_column(node));
  2846. printf(":%i",_synctex_data_h(node));
  2847. printf(",%i",_synctex_data_v(node));
  2848. printf(":%i",_synctex_data_width(node));
  2849. printf(",%i",_synctex_data_height(node));
  2850. printf(",%i",_synctex_data_depth(node));
  2851. printf("/%i",_synctex_data_h_V(node));
  2852. printf(",%i",_synctex_data_v_V(node));
  2853. printf(":%i",_synctex_data_width_V(node));
  2854. printf(",%i",_synctex_data_height_V(node));
  2855. printf(",%i",_synctex_data_depth_V(node));
  2856. SYNCTEX_PRINT_CHARINDEX_NL;
  2857. printf("SELF:%p\n",(void *)node);
  2858. printf(" SIBLING:%p\n",(void *)__synctex_tree_sibling(node));
  2859. printf(" PARENT:%p\n",(void *)_synctex_tree_parent(node));
  2860. printf(" CHILD:%p\n",(void *)_synctex_tree_child(node));
  2861. printf(" LEFT:%p\n",(void *)_synctex_tree_friend(node));
  2862. printf(" NEXT_hbox:%p\n",(void *)_synctex_tree_next_hbox(node));
  2863. }
  2864. }
  2865. static void _synctex_log_proxy(synctex_node_p node) {
  2866. if (node) {
  2867. synctex_node_p N = _synctex_tree_target(node);
  2868. printf("%s",synctex_node_isa(node));
  2869. printf(":%i",_synctex_data_h(node));
  2870. printf(",%i",_synctex_data_v(node));
  2871. SYNCTEX_PRINT_CHARINDEX_NL;
  2872. printf("SELF:%p\n",(void *)node);
  2873. printf(" SIBLING:%p\n",(void *)__synctex_tree_sibling(node));
  2874. printf(" LEFT:%p\n",(void *)_synctex_tree_friend(node));
  2875. printf(" ->%s\n",_synctex_node_abstract(N));
  2876. }
  2877. }
  2878. static void _synctex_log_handle(synctex_node_p node) {
  2879. if (node) {
  2880. synctex_node_p N = _synctex_tree_target(node);
  2881. printf("%s",synctex_node_isa(node));
  2882. SYNCTEX_PRINT_CHARINDEX_NL;
  2883. printf("SELF:%p\n",(void *)node);
  2884. printf(" SIBLING:%p\n",(void *)__synctex_tree_sibling(node));
  2885. printf(" ->%s\n",_synctex_node_abstract(N));
  2886. }
  2887. }
  2888. # ifdef SYNCTEX_NOTHING
  2889. # pragma mark -
  2890. # pragma mark SYNCTEX_DISPLAY
  2891. # endif
  2892. int synctex_scanner_display_switcher(synctex_scanner_p scanR) {
  2893. return scanR->display_switcher;
  2894. }
  2895. void synctex_scanner_set_display_switcher(synctex_scanner_p scanR, int switcher) {
  2896. scanR->display_switcher = switcher;
  2897. }
  2898. static const char * const _synctex_display_prompt = "................................";
  2899. static char * _synctex_scanner_display_prompt_down(synctex_scanner_p scanR) {
  2900. if (scanR->display_prompt>_synctex_display_prompt) {
  2901. --scanR->display_prompt;
  2902. }
  2903. return scanR->display_prompt;
  2904. }
  2905. static char * _synctex_scanner_display_prompt_up(synctex_scanner_p scanR) {
  2906. if (scanR->display_prompt+1<_synctex_display_prompt+strlen(_synctex_display_prompt)) {
  2907. ++scanR->display_prompt;
  2908. }
  2909. return scanR->display_prompt;
  2910. }
  2911. void synctex_node_display(synctex_node_p node) {
  2912. if (node) {
  2913. synctex_scanner_p scanR = node->class_->scanner;
  2914. if (scanR) {
  2915. if (scanR->display_switcher<0) {
  2916. SYNCTEX_MSG_SEND(node, display);
  2917. } else if (scanR->display_switcher>0 && --scanR->display_switcher>0) {
  2918. SYNCTEX_MSG_SEND(node, display);
  2919. } else if (scanR->display_switcher-->=0) {
  2920. printf("%s Next display skipped. Reset display switcher.\n",node->class_->scanner->display_prompt);
  2921. }
  2922. } else {
  2923. SYNCTEX_MSG_SEND(node, display);
  2924. }
  2925. }
  2926. }
  2927. static char * _synctex_node_abstract(synctex_node_p node) {
  2928. SYNCTEX_PARAMETER_ASSERT(node || node->class_);
  2929. return (node && node->class_->abstract)? node->class_->abstract(node):"none";
  2930. }
  2931. SYNCTEX_INLINE static void _synctex_display_child(synctex_node_p node) {
  2932. synctex_node_p N = _synctex_tree_child(node);
  2933. if (N) {
  2934. _synctex_scanner_display_prompt_down(N->class_->scanner);
  2935. synctex_node_display(N);
  2936. _synctex_scanner_display_prompt_up(N->class_->scanner);
  2937. }
  2938. }
  2939. SYNCTEX_INLINE static void _synctex_display_sibling(synctex_node_p node) {
  2940. synctex_node_display(__synctex_tree_sibling(node));
  2941. }
  2942. #define SYNCTEX_ABSTRACT_MAX 128
  2943. static char * _synctex_abstract_input(synctex_node_p node) {
  2944. static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
  2945. if (node) {
  2946. snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"Input:%i:%s(%i)" SYNCTEX_PRINT_CHARINDEX_FMT,
  2947. _synctex_data_tag(node),
  2948. _synctex_data_name(node),
  2949. _synctex_data_line(node)
  2950. SYNCTEX_PRINT_CHARINDEX_WHAT);
  2951. }
  2952. return abstract;
  2953. }
  2954. static void _synctex_display_input(synctex_node_p node) {
  2955. if (node) {
  2956. printf("Input:%i:%s(%i)"
  2957. SYNCTEX_PRINT_CHARINDEX_FMT
  2958. "\n",
  2959. _synctex_data_tag(node),
  2960. _synctex_data_name(node),
  2961. _synctex_data_line(node)
  2962. SYNCTEX_PRINT_CHARINDEX_WHAT);
  2963. synctex_node_display(__synctex_tree_sibling(node));
  2964. }
  2965. }
  2966. static char * _synctex_abstract_sheet(synctex_node_p node) {
  2967. static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
  2968. if (node) {
  2969. snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"{%i...}" SYNCTEX_PRINT_CHARINDEX_FMT,
  2970. _synctex_data_page(node)
  2971. SYNCTEX_PRINT_CHARINDEX_WHAT);
  2972. }
  2973. return abstract;
  2974. }
  2975. static void _synctex_display_sheet(synctex_node_p node) {
  2976. if (node) {
  2977. printf("%s{%i"
  2978. SYNCTEX_PRINT_CHARINDEX_FMT
  2979. "\n",
  2980. node->class_->scanner->display_prompt,
  2981. _synctex_data_page(node)
  2982. SYNCTEX_PRINT_CHARINDEX_WHAT);
  2983. _synctex_display_child(node);
  2984. printf("%s}\n",node->class_->scanner->display_prompt);
  2985. _synctex_display_sibling(node);
  2986. }
  2987. }
  2988. static char * _synctex_abstract_form(synctex_node_p node) {
  2989. static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
  2990. if (node) {
  2991. snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"<%i...>" SYNCTEX_PRINT_CHARINDEX_FMT,
  2992. _synctex_data_tag(node)
  2993. SYNCTEX_PRINT_CHARINDEX_WHAT);
  2994. SYNCTEX_PRINT_CHARINDEX;
  2995. }
  2996. return abstract;
  2997. }
  2998. static void _synctex_display_form(synctex_node_p node) {
  2999. if (node) {
  3000. printf("%s<%i"
  3001. SYNCTEX_PRINT_CHARINDEX_FMT
  3002. "\n",
  3003. node->class_->scanner->display_prompt,
  3004. _synctex_data_tag(node)
  3005. SYNCTEX_PRINT_CHARINDEX_WHAT);
  3006. _synctex_display_child(node);
  3007. printf("%s>\n",node->class_->scanner->display_prompt);
  3008. _synctex_display_sibling(node);
  3009. }
  3010. }
  3011. static char * _synctex_abstract_vbox(synctex_node_p node) {
  3012. static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
  3013. if (node) {
  3014. snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"[%i,%i:%i,%i:%i,%i,%i...]"
  3015. SYNCTEX_PRINT_CHARINDEX_FMT,
  3016. _synctex_data_tag(node),
  3017. _synctex_data_line(node),
  3018. _synctex_data_h(node),
  3019. _synctex_data_v(node),
  3020. _synctex_data_width(node),
  3021. _synctex_data_height(node),
  3022. _synctex_data_depth(node)
  3023. SYNCTEX_PRINT_CHARINDEX_WHAT);
  3024. }
  3025. return abstract;
  3026. }
  3027. static void _synctex_display_vbox(synctex_node_p node) {
  3028. if (node) {
  3029. printf("%s[%i,%i:%i,%i:%i,%i,%i"
  3030. SYNCTEX_PRINT_CHARINDEX_FMT
  3031. "\n",
  3032. node->class_->scanner->display_prompt,
  3033. _synctex_data_tag(node),
  3034. _synctex_data_line(node),
  3035. _synctex_data_h(node),
  3036. _synctex_data_v(node),
  3037. _synctex_data_width(node),
  3038. _synctex_data_height(node),
  3039. _synctex_data_depth(node)
  3040. SYNCTEX_PRINT_CHARINDEX_WHAT);
  3041. _synctex_display_child(node);
  3042. printf("%s]\n%slast:%s\n",
  3043. node->class_->scanner->display_prompt,
  3044. node->class_->scanner->display_prompt,
  3045. _synctex_node_abstract(_synctex_tree_last(node)));
  3046. _synctex_display_sibling(node);
  3047. }
  3048. }
  3049. static char * _synctex_abstract_hbox(synctex_node_p node) {
  3050. static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
  3051. if (node) {
  3052. snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"(%i,%i~%i*%i:%i,%i:%i,%i,%i...)"
  3053. SYNCTEX_PRINT_CHARINDEX_FMT,
  3054. _synctex_data_tag(node),
  3055. _synctex_data_line(node),
  3056. _synctex_data_mean_line(node),
  3057. _synctex_data_weight(node),
  3058. _synctex_data_h(node),
  3059. _synctex_data_v(node),
  3060. _synctex_data_width(node),
  3061. _synctex_data_height(node),
  3062. _synctex_data_depth(node)
  3063. SYNCTEX_PRINT_CHARINDEX_WHAT);
  3064. }
  3065. return abstract;
  3066. }
  3067. static void _synctex_display_hbox(synctex_node_p node) {
  3068. if (node) {
  3069. printf("%s(%i,%i~%i*%i:%i,%i:%i,%i,%i"
  3070. SYNCTEX_PRINT_CHARINDEX_FMT
  3071. "\n",
  3072. node->class_->scanner->display_prompt,
  3073. _synctex_data_tag(node),
  3074. _synctex_data_line(node),
  3075. _synctex_data_mean_line(node),
  3076. _synctex_data_weight(node),
  3077. _synctex_data_h(node),
  3078. _synctex_data_v(node),
  3079. _synctex_data_width(node),
  3080. _synctex_data_height(node),
  3081. _synctex_data_depth(node)
  3082. SYNCTEX_PRINT_CHARINDEX_WHAT);
  3083. _synctex_display_child(node);
  3084. printf("%s)\n%slast:%s\n",
  3085. node->class_->scanner->display_prompt,
  3086. node->class_->scanner->display_prompt,
  3087. _synctex_node_abstract(_synctex_tree_last(node)));
  3088. _synctex_display_sibling(node);
  3089. }
  3090. }
  3091. static char * _synctex_abstract_void_vbox(synctex_node_p node) {
  3092. static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
  3093. if (node) {
  3094. snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"v%i,%i;%i,%i:%i,%i,%i"
  3095. SYNCTEX_PRINT_CHARINDEX_FMT
  3096. "\n",
  3097. _synctex_data_tag(node),
  3098. _synctex_data_line(node),
  3099. _synctex_data_h(node),
  3100. _synctex_data_v(node),
  3101. _synctex_data_width(node),
  3102. _synctex_data_height(node),
  3103. _synctex_data_depth(node)
  3104. SYNCTEX_PRINT_CHARINDEX_WHAT);
  3105. }
  3106. return abstract;
  3107. }
  3108. static void _synctex_display_void_vbox(synctex_node_p node) {
  3109. if (node) {
  3110. printf("%sv%i,%i;%i,%i:%i,%i,%i"
  3111. SYNCTEX_PRINT_CHARINDEX_FMT
  3112. "\n",
  3113. node->class_->scanner->display_prompt,
  3114. _synctex_data_tag(node),
  3115. _synctex_data_line(node),
  3116. _synctex_data_h(node),
  3117. _synctex_data_v(node),
  3118. _synctex_data_width(node),
  3119. _synctex_data_height(node),
  3120. _synctex_data_depth(node)
  3121. SYNCTEX_PRINT_CHARINDEX_WHAT);
  3122. _synctex_display_sibling(node);
  3123. }
  3124. }
  3125. static char * _synctex_abstract_void_hbox(synctex_node_p node) {
  3126. static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
  3127. if (node) {
  3128. snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"h%i,%i:%i,%i:%i,%i,%i"
  3129. SYNCTEX_PRINT_CHARINDEX_FMT,
  3130. _synctex_data_tag(node),
  3131. _synctex_data_line(node),
  3132. _synctex_data_h(node),
  3133. _synctex_data_v(node),
  3134. _synctex_data_width(node),
  3135. _synctex_data_height(node),
  3136. _synctex_data_depth(node)
  3137. SYNCTEX_PRINT_CHARINDEX_WHAT);
  3138. }
  3139. return abstract;
  3140. }
  3141. static void _synctex_display_void_hbox(synctex_node_p node) {
  3142. if (node) {
  3143. printf("%sh%i,%i:%i,%i:%i,%i,%i"
  3144. SYNCTEX_PRINT_CHARINDEX_FMT
  3145. "\n",
  3146. node->class_->scanner->display_prompt,
  3147. _synctex_data_tag(node),
  3148. _synctex_data_line(node),
  3149. _synctex_data_h(node),
  3150. _synctex_data_v(node),
  3151. _synctex_data_width(node),
  3152. _synctex_data_height(node),
  3153. _synctex_data_depth(node)
  3154. SYNCTEX_PRINT_CHARINDEX_WHAT);
  3155. _synctex_display_sibling(node);
  3156. }
  3157. }
  3158. static char * _synctex_abstract_glue(synctex_node_p node) {
  3159. static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
  3160. if (node) {
  3161. snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"glue:%i,%i:%i,%i"
  3162. SYNCTEX_PRINT_CHARINDEX_FMT,
  3163. _synctex_data_tag(node),
  3164. _synctex_data_line(node),
  3165. _synctex_data_h(node),
  3166. _synctex_data_v(node)
  3167. SYNCTEX_PRINT_CHARINDEX_WHAT);
  3168. }
  3169. return abstract;
  3170. }
  3171. static void _synctex_display_glue(synctex_node_p node) {
  3172. if (node) {
  3173. printf("%sglue:%i,%i:%i,%i"
  3174. SYNCTEX_PRINT_CHARINDEX_FMT
  3175. "\n",
  3176. node->class_->scanner->display_prompt,
  3177. _synctex_data_tag(node),
  3178. _synctex_data_line(node),
  3179. _synctex_data_h(node),
  3180. _synctex_data_v(node)
  3181. SYNCTEX_PRINT_CHARINDEX_WHAT);
  3182. _synctex_display_sibling(node);
  3183. }
  3184. }
  3185. static char * _synctex_abstract_rule(synctex_node_p node) {
  3186. static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
  3187. if (node) {
  3188. snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"rule:%i,%i:%i,%i:%i,%i,%i"
  3189. SYNCTEX_PRINT_CHARINDEX_FMT,
  3190. _synctex_data_tag(node),
  3191. _synctex_data_line(node),
  3192. _synctex_data_h(node),
  3193. _synctex_data_v(node),
  3194. _synctex_data_width(node),
  3195. _synctex_data_height(node),
  3196. _synctex_data_depth(node)
  3197. SYNCTEX_PRINT_CHARINDEX_WHAT);
  3198. }
  3199. return abstract;
  3200. }
  3201. static void _synctex_display_rule(synctex_node_p node) {
  3202. if (node) {
  3203. printf("%srule:%i,%i:%i,%i:%i,%i,%i"
  3204. SYNCTEX_PRINT_CHARINDEX_FMT
  3205. "\n",
  3206. node->class_->scanner->display_prompt,
  3207. _synctex_data_tag(node),
  3208. _synctex_data_line(node),
  3209. _synctex_data_h(node),
  3210. _synctex_data_v(node),
  3211. _synctex_data_width(node),
  3212. _synctex_data_height(node),
  3213. _synctex_data_depth(node)
  3214. SYNCTEX_PRINT_CHARINDEX_WHAT);
  3215. _synctex_display_sibling(node);
  3216. }
  3217. }
  3218. static char * _synctex_abstract_math(synctex_node_p node) {
  3219. static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
  3220. if (node) {
  3221. snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"math:%i,%i:%i,%i"
  3222. SYNCTEX_PRINT_CHARINDEX_FMT,
  3223. _synctex_data_tag(node),
  3224. _synctex_data_line(node),
  3225. _synctex_data_h(node),
  3226. _synctex_data_v(node)
  3227. SYNCTEX_PRINT_CHARINDEX_WHAT);
  3228. }
  3229. return abstract;
  3230. }
  3231. static void _synctex_display_math(synctex_node_p node) {
  3232. if (node) {
  3233. printf("%smath:%i,%i:%i,%i"
  3234. SYNCTEX_PRINT_CHARINDEX_FMT
  3235. "\n",
  3236. node->class_->scanner->display_prompt,
  3237. _synctex_data_tag(node),
  3238. _synctex_data_line(node),
  3239. _synctex_data_h(node),
  3240. _synctex_data_v(node)
  3241. SYNCTEX_PRINT_CHARINDEX_WHAT);
  3242. _synctex_display_sibling(node);
  3243. }
  3244. }
  3245. static char * _synctex_abstract_kern(synctex_node_p node) {
  3246. static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
  3247. if (node) {
  3248. snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"kern:%i,%i:%i,%i:%i"
  3249. SYNCTEX_PRINT_CHARINDEX_FMT,
  3250. _synctex_data_tag(node),
  3251. _synctex_data_line(node),
  3252. _synctex_data_h(node),
  3253. _synctex_data_v(node),
  3254. _synctex_data_width(node)
  3255. SYNCTEX_PRINT_CHARINDEX_WHAT);
  3256. }
  3257. return abstract;
  3258. }
  3259. static void _synctex_display_kern(synctex_node_p node) {
  3260. if (node) {
  3261. printf("%skern:%i,%i:%i,%i:%i"
  3262. SYNCTEX_PRINT_CHARINDEX_FMT
  3263. "\n",
  3264. node->class_->scanner->display_prompt,
  3265. _synctex_data_tag(node),
  3266. _synctex_data_line(node),
  3267. _synctex_data_h(node),
  3268. _synctex_data_v(node),
  3269. _synctex_data_width(node)
  3270. SYNCTEX_PRINT_CHARINDEX_WHAT);
  3271. _synctex_display_sibling(node);
  3272. }
  3273. }
  3274. static char * _synctex_abstract_boundary(synctex_node_p node) {
  3275. static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
  3276. if (node) {
  3277. snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"boundary:%i,%i:%i,%i"
  3278. SYNCTEX_PRINT_CHARINDEX_FMT,
  3279. _synctex_data_tag(node),
  3280. _synctex_data_line(node),
  3281. _synctex_data_h(node),
  3282. _synctex_data_v(node)
  3283. SYNCTEX_PRINT_CHARINDEX_WHAT);
  3284. }
  3285. return abstract;
  3286. }
  3287. static void _synctex_display_boundary(synctex_node_p node) {
  3288. if (node) {
  3289. printf("%sboundary:%i,%i:%i,%i"
  3290. SYNCTEX_PRINT_CHARINDEX_FMT
  3291. "\n",
  3292. node->class_->scanner->display_prompt,
  3293. _synctex_data_tag(node),
  3294. _synctex_data_line(node),
  3295. _synctex_data_h(node),
  3296. _synctex_data_v(node)
  3297. SYNCTEX_PRINT_CHARINDEX_WHAT);
  3298. _synctex_display_sibling(node);
  3299. }
  3300. }
  3301. static char * _synctex_abstract_box_bdry(synctex_node_p node) {
  3302. static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
  3303. if (node) {
  3304. snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"box bdry:%i,%i:%i,%i" SYNCTEX_PRINT_CHARINDEX_FMT,
  3305. _synctex_data_tag(node),
  3306. _synctex_data_line(node),
  3307. _synctex_data_h(node),
  3308. _synctex_data_v(node)
  3309. SYNCTEX_PRINT_CHARINDEX_WHAT);
  3310. }
  3311. return abstract;
  3312. }
  3313. static void _synctex_display_box_bdry(synctex_node_p node) {
  3314. if (node) {
  3315. printf("%sbox bdry:%i,%i:%i,%i",
  3316. node->class_->scanner->display_prompt,
  3317. _synctex_data_tag(node),
  3318. _synctex_data_line(node),
  3319. _synctex_data_h(node),
  3320. _synctex_data_v(node));
  3321. SYNCTEX_PRINT_CHARINDEX_NL;
  3322. _synctex_display_sibling(node);
  3323. }
  3324. }
  3325. static char * _synctex_abstract_ref(synctex_node_p node) {
  3326. static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
  3327. if (node) {
  3328. snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"form ref:%i:%i,%i" SYNCTEX_PRINT_CHARINDEX_FMT,
  3329. _synctex_data_tag(node),
  3330. _synctex_data_h(node),
  3331. _synctex_data_v(node)
  3332. SYNCTEX_PRINT_CHARINDEX_WHAT);
  3333. }
  3334. return abstract;
  3335. }
  3336. static void _synctex_display_ref(synctex_node_p node) {
  3337. if (node) {
  3338. printf("%sform ref:%i:%i,%i",
  3339. node->class_->scanner->display_prompt,
  3340. _synctex_data_tag(node),
  3341. _synctex_data_h(node),
  3342. _synctex_data_v(node));
  3343. SYNCTEX_PRINT_CHARINDEX_NL;
  3344. _synctex_display_sibling(node);
  3345. }
  3346. }
  3347. static char * _synctex_abstract_proxy(synctex_node_p node) {
  3348. static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
  3349. if (node) {
  3350. synctex_node_p N = _synctex_tree_target(node);
  3351. snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"%s:%i,%i:%i,%i/%p%s",
  3352. synctex_node_isa(node),
  3353. synctex_node_tag(node),
  3354. synctex_node_line(node),
  3355. _synctex_data_h(node),
  3356. _synctex_data_v(node),
  3357. node,
  3358. _synctex_node_abstract(N));
  3359. }
  3360. return abstract;
  3361. }
  3362. static void _synctex_display_proxy(synctex_node_p node) {
  3363. if (node) {
  3364. synctex_node_p N = _synctex_tree_target(node);
  3365. printf("%s%s:%i,%i:%i,%i",
  3366. node->class_->scanner->display_prompt,
  3367. synctex_node_isa(node),
  3368. synctex_node_tag(node),
  3369. synctex_node_line(node),
  3370. _synctex_data_h(node),
  3371. _synctex_data_v(node));
  3372. if (N) {
  3373. printf("=%i,%i:%i,%i,%i->%s",
  3374. synctex_node_h(node),
  3375. synctex_node_v(node),
  3376. synctex_node_width(node),
  3377. synctex_node_height(node),
  3378. synctex_node_depth(node),
  3379. _synctex_node_abstract(N));
  3380. }
  3381. printf("\n");
  3382. _synctex_display_child(node);
  3383. _synctex_display_sibling(node);
  3384. }
  3385. }
  3386. static char * _synctex_abstract_proxy_vbox(synctex_node_p node) {
  3387. static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
  3388. if (node) {
  3389. snprintf(abstract,SYNCTEX_ABSTRACT_MAX,
  3390. "[*%i,%i:%i,%i:%i,%i,%i...*]"
  3391. SYNCTEX_PRINT_CHARINDEX_FMT,
  3392. synctex_node_tag(node),
  3393. synctex_node_line(node),
  3394. synctex_node_h(node),
  3395. synctex_node_v(node),
  3396. synctex_node_width(node),
  3397. synctex_node_height(node),
  3398. synctex_node_depth(node)
  3399. SYNCTEX_PRINT_CHARINDEX_WHAT);
  3400. }
  3401. return abstract;
  3402. }
  3403. static void _synctex_display_proxy_vbox(synctex_node_p node) {
  3404. if (node) {
  3405. printf("%s[*%i,%i:%i,%i:%i,%i,%i"
  3406. SYNCTEX_PRINT_CHARINDEX_FMT
  3407. "\n",
  3408. node->class_->scanner->display_prompt,
  3409. synctex_node_tag(node),
  3410. synctex_node_line(node),
  3411. synctex_node_h(node),
  3412. synctex_node_v(node),
  3413. synctex_node_width(node),
  3414. synctex_node_height(node),
  3415. synctex_node_depth(node)
  3416. SYNCTEX_PRINT_CHARINDEX_WHAT);
  3417. _synctex_display_child(node);
  3418. printf("%s*]\n%slast:%s\n",
  3419. node->class_->scanner->display_prompt,
  3420. node->class_->scanner->display_prompt,
  3421. _synctex_node_abstract(_synctex_tree_last(node)));
  3422. _synctex_display_sibling(node);
  3423. }
  3424. }
  3425. static char * _synctex_abstract_proxy_hbox(synctex_node_p node) {
  3426. static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
  3427. if (node) {
  3428. snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"(*%i,%i~%i*%i:%i,%i:%i,%i,%i...*)/%p"
  3429. SYNCTEX_PRINT_CHARINDEX_FMT,
  3430. synctex_node_tag(node),
  3431. synctex_node_line(node),
  3432. synctex_node_mean_line(node),
  3433. synctex_node_weight(node),
  3434. synctex_node_h(node),
  3435. synctex_node_v(node),
  3436. synctex_node_width(node),
  3437. synctex_node_height(node),
  3438. synctex_node_depth(node),
  3439. node
  3440. SYNCTEX_PRINT_CHARINDEX_WHAT);
  3441. }
  3442. return abstract;
  3443. }
  3444. static void _synctex_display_proxy_hbox(synctex_node_p node) {
  3445. if (node) {
  3446. printf("%s(*%i,%i~%i*%i:%i,%i:%i,%i,%i"
  3447. SYNCTEX_PRINT_CHARINDEX_FMT
  3448. "\n",
  3449. node->class_->scanner->display_prompt,
  3450. synctex_node_tag(node),
  3451. synctex_node_line(node),
  3452. synctex_node_mean_line(node),
  3453. synctex_node_weight(node),
  3454. synctex_node_h(node),
  3455. synctex_node_v(node),
  3456. synctex_node_width(node),
  3457. synctex_node_height(node),
  3458. synctex_node_depth(node)
  3459. SYNCTEX_PRINT_CHARINDEX_WHAT);
  3460. _synctex_display_child(node);
  3461. printf("%s*)\n%slast:%s\n",
  3462. node->class_->scanner->display_prompt,
  3463. node->class_->scanner->display_prompt,
  3464. _synctex_node_abstract(_synctex_tree_last(node)));
  3465. _synctex_display_sibling(node);
  3466. }
  3467. }
  3468. static char * _synctex_abstract_handle(synctex_node_p node) {
  3469. static char abstract[SYNCTEX_ABSTRACT_MAX] = "none";
  3470. if (node) {
  3471. synctex_node_p N = _synctex_tree_target(node);
  3472. if (N && !N->class_) {
  3473. exit(1);
  3474. }
  3475. snprintf(abstract,SYNCTEX_ABSTRACT_MAX,"%s:%s",
  3476. synctex_node_isa(node),
  3477. (N?_synctex_node_abstract(N):""));
  3478. }
  3479. return abstract;
  3480. }
  3481. static void _synctex_display_handle(synctex_node_p node) {
  3482. if (node) {
  3483. synctex_node_p N = _synctex_tree_target(node);
  3484. printf("%s%s(%i):->%s\n",
  3485. node->class_->scanner->display_prompt,
  3486. synctex_node_isa(node),
  3487. _synctex_data_weight(N),
  3488. _synctex_node_abstract(N));
  3489. _synctex_display_child(node);
  3490. _synctex_display_sibling(node);
  3491. }
  3492. }
  3493. # ifdef SYNCTEX_NOTHING
  3494. # pragma mark -
  3495. # pragma mark STATUS
  3496. # endif
  3497. # ifdef SYNCTEX_NOTHING
  3498. # pragma mark -
  3499. # pragma mark Prototypes
  3500. # endif
  3501. typedef struct {
  3502. size_t size;
  3503. synctex_status_t status;
  3504. } synctex_zs_s;
  3505. static synctex_zs_s _synctex_buffer_get_available_size(synctex_scanner_p scanner, size_t size);
  3506. static synctex_status_t _synctex_next_line(synctex_scanner_p scanner);
  3507. static synctex_status_t _synctex_match_string(synctex_scanner_p scanner, const char * the_string);
  3508. typedef struct synctex_ns_t {
  3509. synctex_node_p node;
  3510. synctex_status_t status;
  3511. } synctex_ns_s;
  3512. static synctex_ns_s __synctex_parse_new_input(synctex_scanner_p scanner);
  3513. static synctex_status_t _synctex_scan_preamble(synctex_scanner_p scanner);
  3514. typedef struct {
  3515. float value;
  3516. synctex_status_t status;
  3517. } synctex_fs_s;
  3518. static synctex_fs_s _synctex_scan_float_and_dimension(synctex_scanner_p scanner);
  3519. static synctex_status_t _synctex_scan_post_scriptum(synctex_scanner_p scanner);
  3520. static synctex_status_t _synctex_scan_postamble(synctex_scanner_p scanner);
  3521. static synctex_status_t _synctex_setup_visible_hbox(synctex_node_p box);
  3522. static synctex_status_t _synctex_scan_content(synctex_scanner_p scanner);
  3523. int synctex_scanner_pre_x_offset(synctex_scanner_p scanner);
  3524. int synctex_scanner_pre_y_offset(synctex_scanner_p scanner);
  3525. const char * synctex_scanner_get_output_fmt(synctex_scanner_p scanner);
  3526. # ifdef SYNCTEX_NOTHING
  3527. # pragma mark -
  3528. # pragma mark SCANNER UTILITIES
  3529. # endif
  3530. # define SYNCTEX_FILE (scanner->reader->file)
  3531. /**
  3532. * Try to ensure that the buffer contains at least size bytes.
  3533. * Passing a huge size argument means the whole buffer length.
  3534. * Passing a 0 size argument means return the available buffer length, without reading the file.
  3535. * In that case, the return status is always SYNCTEX_STATUS_OK unless the given scanner is NULL.
  3536. * The size_t value returned is the number of bytes now available in the buffer. This is a nonnegative integer, it may take the value 0.
  3537. * It is the responsibility of the caller to test whether this size is conforming to its needs.
  3538. * Negative values may return in case of error, actually
  3539. * when there was an error reading the synctex file.
  3540. * - parameter scanner: The owning scanner. When NULL, returns SYNCTEX_STATUS_BAD_ARGUMENT.
  3541. * - parameter expected: expected number of bytes.
  3542. * - returns: a size and a status.
  3543. */
  3544. static synctex_zs_s _synctex_buffer_get_available_size(synctex_scanner_p scanner, size_t expected) {
  3545. size_t size = 0;
  3546. if (NULL == scanner) {
  3547. return (synctex_zs_s){0,SYNCTEX_STATUS_BAD_ARGUMENT};
  3548. }
  3549. if (expected>scanner->reader->size){
  3550. expected = scanner->reader->size;
  3551. }
  3552. size = SYNCTEX_END - SYNCTEX_CUR; /* available is the number of unparsed chars in the buffer */
  3553. if (expected<=size) {
  3554. /* There are already sufficiently many characters in the buffer */
  3555. return (synctex_zs_s){size,SYNCTEX_STATUS_OK};
  3556. }
  3557. if (SYNCTEX_FILE) {
  3558. /* Copy the remaining part of the buffer to the beginning,
  3559. * then read the next part of the file */
  3560. int already_read = 0;
  3561. # if defined(SYNCTEX_USE_CHARINDEX)
  3562. scanner->reader->charindex_offset += SYNCTEX_CUR - SYNCTEX_START;
  3563. # endif
  3564. if (size) {
  3565. memmove(SYNCTEX_START, SYNCTEX_CUR, size);
  3566. }
  3567. SYNCTEX_CUR = SYNCTEX_START + size; /* the next character after the move, will change. */
  3568. /* Fill the buffer up to its end */
  3569. already_read = gzread(SYNCTEX_FILE,(void *)SYNCTEX_CUR,(int)(SYNCTEX_BUFFER_SIZE - size));
  3570. if (already_read>0) {
  3571. /* We assume that 0<already_read<=SYNCTEX_BUFFER_SIZE - size, such that
  3572. * SYNCTEX_CUR + already_read = SYNCTEX_START + size + already_read <= SYNCTEX_START + SYNCTEX_BUFFER_SIZE */
  3573. SYNCTEX_END = SYNCTEX_CUR + already_read;
  3574. /* If the end of the file was reached, all the required SYNCTEX_BUFFER_SIZE - available
  3575. * may not be filled with values from the file.
  3576. * In that case, the buffer should stop properly after already_read characters. */
  3577. * SYNCTEX_END = '\0'; /* there is enough room */
  3578. SYNCTEX_CUR = SYNCTEX_START;
  3579. /* May be available is less than size, the caller will have to test. */
  3580. return (synctex_zs_s){SYNCTEX_END - SYNCTEX_CUR,SYNCTEX_STATUS_OK};
  3581. } else if (0>already_read) {
  3582. /* There is a possible error in reading the file */
  3583. int errnum = 0;
  3584. const char * error_string = gzerror(SYNCTEX_FILE, &errnum);
  3585. if (Z_ERRNO == errnum) {
  3586. /* There is an error in zlib caused by the file system */
  3587. _synctex_error("gzread error from the file system (%i)",errno);
  3588. return (synctex_zs_s){0,SYNCTEX_STATUS_ERROR};
  3589. } else if (errnum) {
  3590. _synctex_error("gzread error (%i:%i,%s)",already_read,errnum,error_string);
  3591. return (synctex_zs_s){0,SYNCTEX_STATUS_ERROR};
  3592. }
  3593. }
  3594. /* Nothing was read, we are at the end of the file. */
  3595. gzclose(SYNCTEX_FILE);
  3596. SYNCTEX_FILE = NULL;
  3597. SYNCTEX_END = SYNCTEX_CUR;
  3598. SYNCTEX_CUR = SYNCTEX_START;
  3599. * SYNCTEX_END = '\0';/* Terminate the string properly.*/
  3600. /* there might be a bit of text left */
  3601. return (synctex_zs_s){SYNCTEX_END - SYNCTEX_CUR,SYNCTEX_STATUS_EOF};
  3602. }
  3603. /* We cannot enlarge the buffer because the end of the file was reached. */
  3604. return (synctex_zs_s){size,SYNCTEX_STATUS_EOF};
  3605. }
  3606. /* Used when parsing the synctex file.
  3607. * Advance to the next character starting a line.
  3608. * Actually, only '\n' is recognized as end of line marker.
  3609. * On normal completion, the returned value is the number of unparsed characters available in the buffer.
  3610. * In general, it is a positive value, 0 meaning that the end of file was reached.
  3611. * -1 is returned in case of error, actually because there was an error while feeding the buffer.
  3612. * When the function returns with no error, SYNCTEX_CUR points to the first character of the next line, if any.
  3613. * J. Laurens: Sat May 10 07:52:31 UTC 2008
  3614. */
  3615. static synctex_status_t _synctex_next_line(synctex_scanner_p scanner) {
  3616. synctex_status_t status = SYNCTEX_STATUS_OK;
  3617. if (NULL == scanner) {
  3618. return SYNCTEX_STATUS_BAD_ARGUMENT;
  3619. }
  3620. infinite_loop:
  3621. while(SYNCTEX_CUR<SYNCTEX_END) {
  3622. if (*SYNCTEX_CUR == '\n') {
  3623. ++SYNCTEX_CUR;
  3624. ++scanner->reader->line_number;
  3625. return _synctex_buffer_get_available_size(scanner, 1).status;
  3626. }
  3627. ++SYNCTEX_CUR;
  3628. }
  3629. /* Here, we have SYNCTEX_CUR == SYNCTEX_END, such that the next call to _synctex_buffer_get_available_size
  3630. * will read another bunch of synctex file. Little by little, we advance to the end of the file. */
  3631. status = _synctex_buffer_get_available_size(scanner, 1).status;
  3632. if (status<=SYNCTEX_STATUS_EOF) {
  3633. return status;
  3634. }
  3635. goto infinite_loop;
  3636. }
  3637. /* Scan the given string.
  3638. * Both scanner and the_string must not be NULL, and the_string must not be 0 length.
  3639. * SYNCTEX_STATUS_OK is returned if the string is found,
  3640. * SYNCTEX_STATUS_EOF is returned when the EOF is reached,
  3641. * SYNCTEX_STATUS_NOT_OK is returned is the string is not found,
  3642. * an error status is returned otherwise.
  3643. * This is a critical method because buffering renders things more difficult.
  3644. * The given string might be as long as the maximum size_t value.
  3645. * As side effect, the buffer state may have changed if the given argument string can't fit into the buffer.
  3646. */
  3647. static synctex_status_t _synctex_match_string(synctex_scanner_p scanner, const char * the_string) {
  3648. size_t tested_len = 0; /* the number of characters at the beginning of the_string that match */
  3649. size_t remaining_len = 0; /* the number of remaining characters of the_string that should match */
  3650. size_t available = 0;
  3651. synctex_zs_s zs = {0,0};
  3652. if (NULL == scanner || NULL == the_string) {
  3653. return SYNCTEX_STATUS_BAD_ARGUMENT;
  3654. }
  3655. remaining_len = strlen(the_string); /* All the_string should match */
  3656. if (0 == remaining_len) {
  3657. return SYNCTEX_STATUS_BAD_ARGUMENT;
  3658. }
  3659. /* How many characters available in the buffer? */
  3660. zs = _synctex_buffer_get_available_size(scanner,remaining_len);
  3661. if (zs.status<SYNCTEX_STATUS_EOF) {
  3662. return zs.status;
  3663. }
  3664. /* Maybe we have less characters than expected because the buffer is too small. */
  3665. if (zs.size>=remaining_len) {
  3666. /* The buffer is sufficiently big to hold the expected number of characters. */
  3667. if (strncmp((char *)SYNCTEX_CUR,the_string,remaining_len)) {
  3668. return SYNCTEX_STATUS_NOT_OK;
  3669. }
  3670. return_OK:
  3671. /* Advance SYNCTEX_CUR to the next character after the_string. */
  3672. SYNCTEX_CUR += remaining_len;
  3673. return SYNCTEX_STATUS_OK;
  3674. } else if (strncmp((char *)SYNCTEX_CUR,the_string,zs.size)) {
  3675. /* No need to go further, this is not the expected string in the buffer. */
  3676. return SYNCTEX_STATUS_NOT_OK;
  3677. } else if (SYNCTEX_FILE) {
  3678. /* The buffer was too small to contain remaining_len characters.
  3679. * We have to cut the string into pieces. */
  3680. z_off_t offset = 0L;
  3681. /* the first part of the string is found, advance the_string to the next untested character. */
  3682. the_string += zs.size;
  3683. /* update the remaining length and the parsed length. */
  3684. remaining_len -= zs.size;
  3685. tested_len += zs.size;
  3686. SYNCTEX_CUR += zs.size; /* We validate the tested characters. */
  3687. if (0 == remaining_len) {
  3688. /* Nothing left to test, we have found the given string. */
  3689. return SYNCTEX_STATUS_OK;
  3690. }
  3691. /* We also have to record the current state of the file cursor because
  3692. * if the_string does not match, all this should be a totally blank operation,
  3693. * for which the file and buffer states should not be modified at all.
  3694. * In fact, the states of the buffer before and after this function are in general different
  3695. * but they are totally equivalent as long as the values of the buffer before SYNCTEX_CUR
  3696. * can be safely discarded. */
  3697. offset = gztell(SYNCTEX_FILE);
  3698. /* offset now corresponds to the first character of the file that was not buffered. */
  3699. /* SYNCTEX_CUR - SYNCTEX_START is the number of chars that where already buffered and
  3700. * that match the head of the_string. If in fine the_string does not match, all these chars must be recovered
  3701. * because the whole buffer contents is replaced in _synctex_buffer_get_available_size.
  3702. * They were buffered from offset-len location in the file. */
  3703. offset -= SYNCTEX_CUR - SYNCTEX_START;
  3704. more_characters:
  3705. /* There is still some work to be done, so read another bunch of file.
  3706. * This is the second call to _synctex_buffer_get_available_size,
  3707. * which means that the actual contents of the buffer will be discarded.
  3708. * We will definitely have to recover the previous state in case we do not find the expected string. */
  3709. zs = _synctex_buffer_get_available_size(scanner,remaining_len);
  3710. if (zs.status<SYNCTEX_STATUS_EOF) {
  3711. return zs.status; /* This is an error, no need to go further. */
  3712. }
  3713. if (zs.size==0) {
  3714. /* Missing characters: recover the initial state of the file and return. */
  3715. return_NOT_OK:
  3716. if (offset != gzseek(SYNCTEX_FILE,offset,SEEK_SET)) {
  3717. /* This is a critical error, we could not recover the previous state. */
  3718. _synctex_error("Can't seek file");
  3719. return SYNCTEX_STATUS_ERROR;
  3720. }
  3721. /* Next time we are asked to fill the buffer,
  3722. * we will read a complete bunch of text from the file. */
  3723. SYNCTEX_CUR = SYNCTEX_END;
  3724. return SYNCTEX_STATUS_NOT_OK;
  3725. }
  3726. if (zs.size<remaining_len) {
  3727. /* We'll have to loop one more time. */
  3728. if (strncmp((char *)SYNCTEX_CUR,the_string,zs.size)) {
  3729. /* This is not the expected string, recover the previous state and return. */
  3730. goto return_NOT_OK;
  3731. }
  3732. /* Advance the_string to the first untested character. */
  3733. the_string += available;
  3734. /* update the remaining length and the parsed length. */
  3735. remaining_len -= zs.size;
  3736. tested_len += zs.size;
  3737. SYNCTEX_CUR += zs.size; /* We validate the tested characters. */
  3738. goto more_characters;
  3739. }
  3740. /* This is the last step. */
  3741. if (strncmp((char *)SYNCTEX_CUR,the_string,remaining_len)) {
  3742. /* This is not the expected string, recover the previous state and return. */
  3743. goto return_NOT_OK;
  3744. }
  3745. goto return_OK;
  3746. } else {
  3747. /* The buffer can't contain the given string argument, and the EOF was reached */
  3748. return SYNCTEX_STATUS_EOF;
  3749. }
  3750. }
  3751. /* Used when parsing the synctex file.
  3752. * Decode an integer.
  3753. * First, field separators, namely ':' and ',' characters are skipped
  3754. * The returned value is negative if there is an unrecoverable error.
  3755. * It is SYNCTEX_STATUS_NOT_OK if an integer could not be parsed, for example
  3756. * if the characters at the current cursor position are not digits or
  3757. * if the end of the file has been reached.
  3758. * It is SYNCTEX_STATUS_OK if an int has been successfully parsed.
  3759. * The given scanner argument must not be NULL, on the contrary, value_ref may be NULL.
  3760. */
  3761. static synctex_is_s _synctex_decode_int(synctex_scanner_p scanner) {
  3762. char * ptr = NULL;
  3763. char * end = NULL;
  3764. synctex_zs_s zs = {0,0};
  3765. int result;
  3766. if (NULL == scanner) {
  3767. return (synctex_is_s){0, SYNCTEX_STATUS_BAD_ARGUMENT};
  3768. }
  3769. zs = _synctex_buffer_get_available_size(scanner, SYNCTEX_BUFFER_MIN_SIZE);
  3770. if (zs.status<SYNCTEX_STATUS_EOF) {
  3771. return (synctex_is_s){0,zs.status};
  3772. }
  3773. if (zs.size==0) {
  3774. return (synctex_is_s){0,SYNCTEX_STATUS_NOT_OK};
  3775. }
  3776. ptr = SYNCTEX_CUR;
  3777. /* Optionally parse the separator */
  3778. if (*ptr==':' || *ptr==',') {
  3779. ++ptr;
  3780. --zs.size;
  3781. if (zs.size==0) {
  3782. return (synctex_is_s){0,SYNCTEX_STATUS_NOT_OK};
  3783. }
  3784. }
  3785. result = (int)strtol(ptr, &end, 10);
  3786. if (end>ptr) {
  3787. SYNCTEX_CUR = end;
  3788. return (synctex_is_s){result,SYNCTEX_STATUS_OK};
  3789. }
  3790. return (synctex_is_s){result,SYNCTEX_STATUS_NOT_OK};
  3791. }
  3792. static synctex_is_s _synctex_decode_int_opt(synctex_scanner_p scanner, int default_value) {
  3793. char * ptr = NULL;
  3794. char * end = NULL;
  3795. synctex_zs_s zs = {0, 0};
  3796. if (NULL == scanner) {
  3797. return (synctex_is_s){default_value, SYNCTEX_STATUS_BAD_ARGUMENT};
  3798. }
  3799. zs = _synctex_buffer_get_available_size(scanner, SYNCTEX_BUFFER_MIN_SIZE);
  3800. if (zs.status<SYNCTEX_STATUS_EOF) {
  3801. return (synctex_is_s){default_value,zs.status};
  3802. }
  3803. if (zs.size==0) {
  3804. return (synctex_is_s){default_value,SYNCTEX_STATUS_OK};
  3805. }
  3806. ptr = SYNCTEX_CUR;
  3807. /* Comma separator required */
  3808. if (*ptr==',') {
  3809. int result;
  3810. ++ptr;
  3811. --zs.size;
  3812. if (zs.size==0) {
  3813. return (synctex_is_s){default_value,SYNCTEX_STATUS_NOT_OK};
  3814. }
  3815. result = (int)strtol(ptr, &end, 10);
  3816. if (end>ptr) {
  3817. SYNCTEX_CUR = end;
  3818. return (synctex_is_s){result,SYNCTEX_STATUS_OK};
  3819. }
  3820. return (synctex_is_s){default_value,SYNCTEX_STATUS_NOT_OK};
  3821. }
  3822. return (synctex_is_s){default_value,SYNCTEX_STATUS_OK};
  3823. }
  3824. /* Used when parsing the synctex file.
  3825. * Decode an integer for a v field.
  3826. * Try the _synctex_decode_int version and set the last v field scanned.
  3827. * If it does not succeed, tries to match an '=' sign,
  3828. * which is a shortcut for the last v field scanned.
  3829. */
  3830. # define SYNCTEX_INPUT_COMEQUALS ",="
  3831. static synctex_is_s _synctex_decode_int_v(synctex_scanner_p scanner) {
  3832. synctex_is_s is = _synctex_decode_int(scanner);
  3833. if (SYNCTEX_STATUS_OK == is.status) {
  3834. scanner->reader->lastv = is.integer;
  3835. return is;
  3836. }
  3837. is.status = _synctex_match_string(scanner,SYNCTEX_INPUT_COMEQUALS);
  3838. if (is.status<SYNCTEX_STATUS_OK) {
  3839. return is;
  3840. }
  3841. is.integer = scanner->reader->lastv;
  3842. return is;
  3843. }
  3844. /* The purpose of this function is to read a string.
  3845. * A string is an array of characters from the current parser location
  3846. * and before the next '\n' character.
  3847. * If a string was properly decoded, it is returned in value_ref and
  3848. * the cursor points to the new line marker.
  3849. * The returned string was alloced on the heap, the caller is the owner and
  3850. * is responsible to free it in due time,
  3851. * unless it transfers the ownership to another object.
  3852. * If no string is parsed, * value_ref is undefined.
  3853. * The maximum length of a string that a scanner can decode is platform dependent, namely UINT_MAX.
  3854. * If you just want to blindly parse the file up to the end of the current line,
  3855. * use _synctex_next_line instead.
  3856. * On return, the scanner cursor is unchanged if a string could not be scanned or
  3857. * points to the terminating '\n' character otherwise. As a consequence,
  3858. * _synctex_next_line is necessary after.
  3859. * If either scanner or value_ref is NULL, it is considered as an error and
  3860. * SYNCTEX_STATUS_BAD_ARGUMENT is returned.
  3861. */
  3862. static synctex_ss_s _synctex_decode_string(synctex_scanner_p scanner) {
  3863. char * end = NULL;
  3864. size_t len = 0;/* The number of bytes to copy */
  3865. size_t already_len = 0;
  3866. synctex_zs_s zs = {0,0};
  3867. char * string = NULL;
  3868. if (NULL == scanner) {
  3869. return (synctex_ss_s){NULL,SYNCTEX_STATUS_BAD_ARGUMENT};
  3870. }
  3871. /* The buffer must at least contain one character: the '\n' end of line marker */
  3872. if (SYNCTEX_CUR>=SYNCTEX_END) {
  3873. more_characters:
  3874. zs = _synctex_buffer_get_available_size(scanner,1);
  3875. if (zs.status < SYNCTEX_STATUS_EOF) {
  3876. return (synctex_ss_s){NULL,zs.status};
  3877. } else if (0 == zs.size) {
  3878. return (synctex_ss_s){NULL,SYNCTEX_STATUS_EOF};
  3879. }
  3880. }
  3881. /* Now we are sure that there is at least one available character, either because
  3882. * SYNCTEX_CUR was already < SYNCTEX_END, or because the buffer has been properly filled. */
  3883. /* end will point to the next unparsed '\n' character in the file, when mapped to the buffer. */
  3884. end = SYNCTEX_CUR;
  3885. /* We scan all the characters up to the next '\n' */
  3886. while (end<SYNCTEX_END && *end != '\n') {
  3887. ++end;
  3888. }
  3889. /* OK, we found where to stop:
  3890. * either end == SYNCTEX_END
  3891. * or *end == '\n' */
  3892. len = end - SYNCTEX_CUR;
  3893. if (len<UINT_MAX-already_len) {
  3894. if ((string = realloc(string,len+already_len+1)) != NULL) {
  3895. if (memcpy(string+already_len,SYNCTEX_CUR,len)) {
  3896. already_len += len;
  3897. string[already_len]='\0'; /* Terminate the string */
  3898. SYNCTEX_CUR += len;/* Eventually advance to the terminating '\n' */
  3899. if (SYNCTEX_CUR==SYNCTEX_END) {
  3900. /* No \n found*/
  3901. goto more_characters;
  3902. }
  3903. /* trim the trailing whites */
  3904. len = already_len;
  3905. while (len>0) {
  3906. already_len = len--;
  3907. if (string[len]!=' ') {
  3908. break;
  3909. }
  3910. }
  3911. string[already_len] = '\0';
  3912. return (synctex_ss_s){string,SYNCTEX_STATUS_OK};
  3913. }
  3914. free(string);
  3915. _synctex_error("could not copy memory (1).");
  3916. return (synctex_ss_s){NULL,SYNCTEX_STATUS_ERROR};
  3917. }
  3918. }
  3919. _synctex_error("could not (re)allocate memory (1).");
  3920. return (synctex_ss_s){NULL,SYNCTEX_STATUS_ERROR};
  3921. }
  3922. /* Used when parsing the synctex file.
  3923. * Read an Input record.
  3924. * - parameter scanner: non NULL scanner
  3925. * - returns SYNCTEX_STATUS_OK on successful completions, others values otherwise.
  3926. */
  3927. static synctex_ns_s __synctex_parse_new_input(synctex_scanner_p scanner) {
  3928. synctex_node_p input = NULL;
  3929. synctex_status_t status = SYNCTEX_STATUS_BAD_ARGUMENT;
  3930. synctex_zs_s zs = {0,0};
  3931. if (NULL == scanner) {
  3932. return (synctex_ns_s){NULL,status};
  3933. }
  3934. if ((status=_synctex_match_string(scanner,SYNCTEX_INPUT_MARK))<SYNCTEX_STATUS_OK) {
  3935. return (synctex_ns_s){NULL,status};
  3936. }
  3937. /* Create a node */
  3938. if (NULL == (input = _synctex_new_input(scanner))) {
  3939. _synctex_error("Could not create an input node.");
  3940. return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
  3941. }
  3942. /* Decode the tag */
  3943. if ((status=_synctex_data_decode_tag(input))<SYNCTEX_STATUS_OK) {
  3944. _synctex_error("Bad format of input node.");
  3945. synctex_node_free(input);
  3946. return (synctex_ns_s){NULL,status};
  3947. }
  3948. /* The next character is a field separator, we expect one character in the buffer. */
  3949. zs = _synctex_buffer_get_available_size(scanner, 1);
  3950. if (zs.status<=SYNCTEX_STATUS_ERROR) {
  3951. return (synctex_ns_s){NULL,status};
  3952. }
  3953. if (0 == zs.size) {
  3954. return (synctex_ns_s){NULL,SYNCTEX_STATUS_EOF};
  3955. }
  3956. /* We can now safely advance to the next character, stepping over the field separator. */
  3957. ++SYNCTEX_CUR;
  3958. --zs.size;
  3959. /* Then we scan the file name */
  3960. if ((status=_synctex_data_decode_name(input))<SYNCTEX_STATUS_OK) {
  3961. synctex_node_free(input);
  3962. _synctex_next_line(scanner);/* Ignore this whole line */
  3963. return (synctex_ns_s){NULL,status};
  3964. }
  3965. /* Prepend this input node to the input linked list of the scanner */
  3966. __synctex_tree_set_sibling(input,scanner->input);/* input has no parent */
  3967. scanner->input = input;
  3968. # if SYNCTEX_VERBOSE
  3969. synctex_node_log(input);
  3970. # endif
  3971. return (synctex_ns_s){input,_synctex_next_line(scanner)};/* read the line termination character, if any */
  3972. }
  3973. typedef synctex_is_s (*synctex_decoder_t)(synctex_scanner_p);
  3974. /* Used when parsing the synctex file.
  3975. * Read one of the settings.
  3976. * On normal completion, returns SYNCTEX_STATUS_OK.
  3977. * On error, returns SYNCTEX_STATUS_ERROR.
  3978. * Both arguments must not be NULL.
  3979. * On return, the scanner points to the next character after the decoded object whatever it is.
  3980. * It is the responsibility of the caller to prepare the scanner for the next line.
  3981. */
  3982. static synctex_status_t _synctex_scan_named(synctex_scanner_p scanner,const char * name) {
  3983. synctex_status_t status = 0;
  3984. if (NULL == scanner || NULL == name) {
  3985. return SYNCTEX_STATUS_BAD_ARGUMENT;
  3986. }
  3987. not_found:
  3988. status = _synctex_match_string(scanner,name);
  3989. if (status<SYNCTEX_STATUS_NOT_OK) {
  3990. return status;
  3991. } else if (status == SYNCTEX_STATUS_NOT_OK) {
  3992. status = _synctex_next_line(scanner);
  3993. if (status<SYNCTEX_STATUS_OK) {
  3994. return status;
  3995. }
  3996. goto not_found;
  3997. }
  3998. return SYNCTEX_STATUS_OK;
  3999. }
  4000. /* Used when parsing the synctex file.
  4001. * Read the preamble.
  4002. */
  4003. static synctex_status_t _synctex_scan_preamble(synctex_scanner_p scanner) {
  4004. synctex_status_t status = 0;
  4005. synctex_is_s is = {0,0};
  4006. synctex_ss_s ss = {NULL,0};
  4007. if (NULL == scanner) {
  4008. return SYNCTEX_STATUS_BAD_ARGUMENT;
  4009. }
  4010. status = _synctex_scan_named(scanner,"SyncTeX Version:");
  4011. if (status<SYNCTEX_STATUS_OK) {
  4012. return status;
  4013. }
  4014. is = _synctex_decode_int(scanner);
  4015. if (is.status<SYNCTEX_STATUS_OK) {
  4016. return is.status;
  4017. }
  4018. status = _synctex_next_line(scanner);
  4019. if (status<SYNCTEX_STATUS_OK) {
  4020. return status;
  4021. }
  4022. scanner->version = is.integer;
  4023. /* Read all the input records */
  4024. do {
  4025. status = __synctex_parse_new_input(scanner).status;
  4026. if (status<SYNCTEX_STATUS_NOT_OK) {
  4027. return status;
  4028. }
  4029. } while(status == SYNCTEX_STATUS_OK);
  4030. /* the loop exits when status == SYNCTEX_STATUS_NOT_OK */
  4031. /* Now read all the required settings. */
  4032. if ((status=_synctex_scan_named(scanner,"Output:"))<SYNCTEX_STATUS_OK) {
  4033. return status;
  4034. }
  4035. if ((ss=_synctex_decode_string(scanner)).status<SYNCTEX_STATUS_OK) {
  4036. return is.status;
  4037. }
  4038. if ((status=_synctex_next_line(scanner))<SYNCTEX_STATUS_OK) {
  4039. return status;
  4040. }
  4041. scanner->output_fmt = ss.string;
  4042. if ((status=_synctex_scan_named(scanner,"Magnification:"))<SYNCTEX_STATUS_OK) {
  4043. return status;
  4044. }
  4045. if ((is=_synctex_decode_int(scanner)).status<SYNCTEX_STATUS_OK) {
  4046. return is.status;
  4047. }
  4048. if ((status=_synctex_next_line(scanner))<SYNCTEX_STATUS_OK) {
  4049. return status;
  4050. }
  4051. scanner->pre_magnification = is.integer;
  4052. if ((status=_synctex_scan_named(scanner,"Unit:"))<SYNCTEX_STATUS_OK) {
  4053. return status;
  4054. }
  4055. if ((is=_synctex_decode_int(scanner)).status<SYNCTEX_STATUS_OK) {
  4056. return is.status;
  4057. }
  4058. if ((status=_synctex_next_line(scanner))<SYNCTEX_STATUS_OK) {
  4059. return status;
  4060. }
  4061. scanner->pre_unit = is.integer;
  4062. if ((status=_synctex_scan_named(scanner,"X Offset:"))<SYNCTEX_STATUS_OK) {
  4063. return status;
  4064. }
  4065. if ((is=_synctex_decode_int(scanner)).status<SYNCTEX_STATUS_OK) {
  4066. return is.status;
  4067. }
  4068. if ((status=_synctex_next_line(scanner))<SYNCTEX_STATUS_OK) {
  4069. return status;
  4070. }
  4071. scanner->pre_x_offset = is.integer;
  4072. if ((status=_synctex_scan_named(scanner,"Y Offset:"))<SYNCTEX_STATUS_OK) {
  4073. return status;
  4074. }
  4075. if ((is=_synctex_decode_int(scanner)).status<SYNCTEX_STATUS_OK) {
  4076. return is.status;
  4077. }
  4078. if ((status=_synctex_next_line(scanner))<SYNCTEX_STATUS_OK) {
  4079. return status;
  4080. }
  4081. scanner->pre_y_offset = is.integer;
  4082. return SYNCTEX_STATUS_OK;
  4083. }
  4084. /* parse a float with a dimension */
  4085. static synctex_fs_s _synctex_scan_float_and_dimension(synctex_scanner_p scanner) {
  4086. synctex_fs_s fs = {0,0};
  4087. synctex_zs_s zs = {0,0};
  4088. char * endptr = NULL;
  4089. #ifdef HAVE_SETLOCALE
  4090. char * loc = setlocale(LC_NUMERIC, NULL);
  4091. #endif
  4092. if (NULL == scanner) {
  4093. return (synctex_fs_s){0,SYNCTEX_STATUS_BAD_ARGUMENT};
  4094. }
  4095. zs = _synctex_buffer_get_available_size(scanner, SYNCTEX_BUFFER_MIN_SIZE);
  4096. if (zs.status<SYNCTEX_STATUS_EOF) {
  4097. _synctex_error("Problem with float.");
  4098. return (synctex_fs_s){0,zs.status};
  4099. }
  4100. #ifdef HAVE_SETLOCALE
  4101. setlocale(LC_NUMERIC, "C");
  4102. #endif
  4103. fs.value = strtod(SYNCTEX_CUR,&endptr);
  4104. #ifdef HAVE_SETLOCALE
  4105. setlocale(LC_NUMERIC, loc);
  4106. #endif
  4107. if (endptr == SYNCTEX_CUR) {
  4108. _synctex_error("A float was expected.");
  4109. return (synctex_fs_s){0,SYNCTEX_STATUS_ERROR};
  4110. }
  4111. SYNCTEX_CUR = endptr;
  4112. if ((fs.status = _synctex_match_string(scanner,"in")) >= SYNCTEX_STATUS_OK) {
  4113. fs.value *= 72.27f*65536;
  4114. } else if (fs.status<SYNCTEX_STATUS_EOF) {
  4115. report_unit_error:
  4116. _synctex_error("problem with unit.");
  4117. return fs;
  4118. } else if ((fs.status = _synctex_match_string(scanner,"cm")) >= SYNCTEX_STATUS_OK) {
  4119. fs.value *= 72.27f*65536/2.54f;
  4120. } else if (fs.status<SYNCTEX_STATUS_EOF) {
  4121. goto report_unit_error;
  4122. } else if ((fs.status = _synctex_match_string(scanner,"mm")) >= SYNCTEX_STATUS_OK) {
  4123. fs.value *= 72.27f*65536/25.4f;
  4124. } else if (fs.status<SYNCTEX_STATUS_EOF) {
  4125. goto report_unit_error;
  4126. } else if ((fs.status = _synctex_match_string(scanner,"pt")) >= SYNCTEX_STATUS_OK) {
  4127. fs.value *= 65536.0f;
  4128. } else if (fs.status<SYNCTEX_STATUS_EOF) {
  4129. goto report_unit_error;
  4130. } else if ((fs.status = _synctex_match_string(scanner,"bp")) >= SYNCTEX_STATUS_OK) {
  4131. fs.value *= 72.27f/72*65536.0f;
  4132. } else if (fs.status<SYNCTEX_STATUS_EOF) {
  4133. goto report_unit_error;
  4134. } else if ((fs.status = _synctex_match_string(scanner,"pc")) >= SYNCTEX_STATUS_OK) {
  4135. fs.value *= 12.0*65536.0f;
  4136. } else if (fs.status<SYNCTEX_STATUS_EOF) {
  4137. goto report_unit_error;
  4138. } else if ((fs.status = _synctex_match_string(scanner,"sp")) >= SYNCTEX_STATUS_OK) {
  4139. fs.value *= 1.0f;
  4140. } else if (fs.status<SYNCTEX_STATUS_EOF) {
  4141. goto report_unit_error;
  4142. } else if ((fs.status = _synctex_match_string(scanner,"dd")) >= SYNCTEX_STATUS_OK) {
  4143. fs.value *= 1238.0f/1157*65536.0f;
  4144. } else if (fs.status<SYNCTEX_STATUS_EOF) {
  4145. goto report_unit_error;
  4146. } else if ((fs.status = _synctex_match_string(scanner,"cc")) >= SYNCTEX_STATUS_OK) {
  4147. fs.value *= 14856.0f/1157*65536;
  4148. } else if (fs.status<SYNCTEX_STATUS_EOF) {
  4149. goto report_unit_error;
  4150. } else if ((fs.status = _synctex_match_string(scanner,"nd")) >= SYNCTEX_STATUS_OK) {
  4151. fs.value *= 685.0f/642*65536;
  4152. } else if (fs.status<SYNCTEX_STATUS_EOF) {
  4153. goto report_unit_error;
  4154. } else if ((fs.status = _synctex_match_string(scanner,"nc")) >= SYNCTEX_STATUS_OK) {
  4155. fs.value *= 1370.0f/107*65536;
  4156. } else if (fs.status<SYNCTEX_STATUS_EOF) {
  4157. goto report_unit_error;
  4158. }
  4159. return fs;
  4160. }
  4161. /* parse the post scriptum
  4162. * SYNCTEX_STATUS_OK is returned on completion
  4163. * a negative error is returned otherwise */
  4164. static synctex_status_t _synctex_scan_post_scriptum(synctex_scanner_p scanner) {
  4165. synctex_status_t status = 0;
  4166. synctex_fs_s fs = {0,0};
  4167. char * endptr = NULL;
  4168. #ifdef HAVE_SETLOCALE
  4169. char * loc = setlocale(LC_NUMERIC, NULL);
  4170. #endif
  4171. if (NULL == scanner) {
  4172. return SYNCTEX_STATUS_BAD_ARGUMENT;
  4173. }
  4174. /* Scan the file until a post scriptum line is found */
  4175. post_scriptum_not_found:
  4176. status = _synctex_match_string(scanner,"Post scriptum:");
  4177. if (status<SYNCTEX_STATUS_NOT_OK) {
  4178. return status;
  4179. }
  4180. if (status == SYNCTEX_STATUS_NOT_OK) {
  4181. status = _synctex_next_line(scanner);
  4182. if (status<SYNCTEX_STATUS_EOF) {
  4183. return status;
  4184. } else if (status<SYNCTEX_STATUS_OK) {
  4185. return SYNCTEX_STATUS_OK;/* The EOF is found, we have properly scanned the file */
  4186. }
  4187. goto post_scriptum_not_found;
  4188. }
  4189. /* We found the name, advance to the next line. */
  4190. next_line:
  4191. status = _synctex_next_line(scanner);
  4192. if (status<SYNCTEX_STATUS_EOF) {
  4193. return status;
  4194. } else if (status<SYNCTEX_STATUS_OK) {
  4195. return SYNCTEX_STATUS_OK;/* The EOF is found, we have properly scanned the file */
  4196. }
  4197. /* Scanning the information */
  4198. status = _synctex_match_string(scanner,"Magnification:");
  4199. if (status == SYNCTEX_STATUS_OK ) {
  4200. #ifdef HAVE_SETLOCALE
  4201. setlocale(LC_NUMERIC, "C");
  4202. #endif
  4203. scanner->unit = strtod(SYNCTEX_CUR,&endptr);
  4204. #ifdef HAVE_SETLOCALE
  4205. setlocale(LC_NUMERIC, loc);
  4206. #endif
  4207. if (endptr == SYNCTEX_CUR) {
  4208. _synctex_error("bad magnification in the post scriptum, a float was expected.");
  4209. return SYNCTEX_STATUS_ERROR;
  4210. }
  4211. if (scanner->unit<=0) {
  4212. _synctex_error("bad magnification in the post scriptum, a positive float was expected.");
  4213. return SYNCTEX_STATUS_ERROR;
  4214. }
  4215. SYNCTEX_CUR = endptr;
  4216. goto next_line;
  4217. }
  4218. if (status<SYNCTEX_STATUS_EOF){
  4219. report_record_problem:
  4220. _synctex_error("Problem reading the Post Scriptum records");
  4221. return status; /* echo the error. */
  4222. }
  4223. status = _synctex_match_string(scanner,"X Offset:");
  4224. if (status == SYNCTEX_STATUS_OK) {
  4225. fs = _synctex_scan_float_and_dimension(scanner);
  4226. if (fs.status<SYNCTEX_STATUS_OK) {
  4227. _synctex_error("Problem with X offset in the Post Scriptum.");
  4228. return fs.status;
  4229. }
  4230. scanner->x_offset = fs.value;
  4231. goto next_line;
  4232. } else if (status<SYNCTEX_STATUS_EOF){
  4233. goto report_record_problem;
  4234. }
  4235. status = _synctex_match_string(scanner,"Y Offset:");
  4236. if (status==SYNCTEX_STATUS_OK) {
  4237. fs = _synctex_scan_float_and_dimension(scanner);
  4238. if (fs.status<SYNCTEX_STATUS_OK) {
  4239. _synctex_error("Problem with Y offset in the Post Scriptum.");
  4240. return fs.status;
  4241. }
  4242. scanner->x_offset = fs.value;
  4243. goto next_line;
  4244. } else if (status<SYNCTEX_STATUS_EOF){
  4245. goto report_record_problem;
  4246. }
  4247. goto next_line;
  4248. }
  4249. /* SYNCTEX_STATUS_OK is returned if the postamble is read
  4250. * SYNCTEX_STATUS_NOT_OK is returned if the postamble is not at the current location
  4251. * a negative error otherwise
  4252. * The postamble comprises the post scriptum section.
  4253. */
  4254. static synctex_status_t _synctex_scan_postamble(synctex_scanner_p scanner) {
  4255. synctex_status_t status = 0;
  4256. synctex_is_s is = {0,0};
  4257. if (NULL == scanner) {
  4258. return SYNCTEX_STATUS_BAD_ARGUMENT;
  4259. }
  4260. if (!scanner->flags.postamble && (status=_synctex_match_string(scanner,"Postamble:"))<SYNCTEX_STATUS_OK) {
  4261. return status;
  4262. }
  4263. count_again:
  4264. if ((status=_synctex_next_line(scanner))<SYNCTEX_STATUS_OK) {
  4265. return status;
  4266. }
  4267. if ((status=_synctex_scan_named(scanner,"Count:"))< SYNCTEX_STATUS_EOF) {
  4268. return status; /* forward the error */
  4269. } else if (status < SYNCTEX_STATUS_OK) { /* No Count record found */
  4270. goto count_again;
  4271. }
  4272. if ((is=_synctex_decode_int(scanner)).status<SYNCTEX_STATUS_OK) {
  4273. return is.status;
  4274. }
  4275. if ((status=_synctex_next_line(scanner))<SYNCTEX_STATUS_OK) {
  4276. return status;
  4277. }
  4278. scanner->count = is.integer;
  4279. /* Now we scan the last part of the SyncTeX file: the Post Scriptum section. */
  4280. return _synctex_scan_post_scriptum(scanner);
  4281. }
  4282. /* Horizontal boxes also have visible size.
  4283. * Visible size are bigger than real size.
  4284. * For example 0 width boxes may contain text.
  4285. * At creation time, the visible size is set to the values of the real size.
  4286. */
  4287. static synctex_status_t _synctex_setup_visible_hbox(synctex_node_p box) {
  4288. if (box) {
  4289. switch(synctex_node_type(box)) {
  4290. case synctex_node_type_hbox:
  4291. _synctex_data_set_h_V(box,_synctex_data_h(box));
  4292. _synctex_data_set_v_V(box,_synctex_data_v(box));
  4293. _synctex_data_set_width_V(box,_synctex_data_width(box));
  4294. _synctex_data_set_height_V(box,_synctex_data_height(box));
  4295. _synctex_data_set_depth_V(box,_synctex_data_depth(box));
  4296. return SYNCTEX_STATUS_OK;
  4297. default:
  4298. break;
  4299. }
  4300. }
  4301. return SYNCTEX_STATUS_BAD_ARGUMENT;
  4302. }
  4303. /* This method is sent to an horizontal box to setup the visible size
  4304. * Some box have 0 width but do contain text material.
  4305. * With this method, one can enlarge the box to contain the given point (h,v).
  4306. */
  4307. static synctex_status_t _synctex_make_hbox_contain_point(synctex_node_p node,synctex_point_s point) {
  4308. int min, max, n;
  4309. if (NULL == node || synctex_node_type(node) != synctex_node_type_hbox) {
  4310. return SYNCTEX_STATUS_BAD_ARGUMENT;
  4311. }
  4312. if ((n = _synctex_data_width_V(node))<0) {
  4313. max = _synctex_data_h_V(node);
  4314. min = max+n;
  4315. if (point.h<min) {
  4316. _synctex_data_set_width_V(node,point.h-max);
  4317. } else if (point.h>max) {
  4318. _synctex_data_set_h_V(node,point.h);
  4319. _synctex_data_set_width_V(node,min-point.h);
  4320. }
  4321. } else {
  4322. min = _synctex_data_h_V(node);
  4323. max = min+n;
  4324. if (point.h<min) {
  4325. _synctex_data_set_h_V(node,point.h);
  4326. _synctex_data_set_width_V(node,max - point.h);
  4327. } else if (point.h>max) {
  4328. _synctex_data_set_width_V(node,point.h - min);
  4329. }
  4330. }
  4331. n = _synctex_data_v_V(node);
  4332. min = n - _synctex_data_height_V(node);
  4333. max = n + _synctex_data_depth_V(node);
  4334. if (point.v<min) {
  4335. _synctex_data_set_height_V(node,n-point.v);
  4336. } else if (point.v>max) {
  4337. _synctex_data_set_depth_V(node,point.v-n);
  4338. }
  4339. return SYNCTEX_STATUS_OK;
  4340. }
  4341. static synctex_status_t _synctex_make_hbox_contain_box(synctex_node_p node,synctex_box_s box) {
  4342. int min, max, n;
  4343. if (NULL == node || synctex_node_type(node) != synctex_node_type_hbox) {
  4344. return SYNCTEX_STATUS_BAD_ARGUMENT;
  4345. }
  4346. if ((n = _synctex_data_width_V(node))<0) {
  4347. max = _synctex_data_h_V(node);
  4348. min = max+n;
  4349. if (box.min.h <min) {
  4350. _synctex_data_set_width_V(node,box.min.h-max);
  4351. } else if (box.max.h>max) {
  4352. _synctex_data_set_h_V(node,box.max.h);
  4353. _synctex_data_set_width_V(node,min-box.max.h);
  4354. }
  4355. } else {
  4356. min = _synctex_data_h_V(node);
  4357. max = min+n;
  4358. if (box.min.h<min) {
  4359. _synctex_data_set_h_V(node,box.min.h);
  4360. _synctex_data_set_width_V(node,max - box.min.h);
  4361. } else if (box.max.h>max) {
  4362. _synctex_data_set_width_V(node,box.max.h - min);
  4363. }
  4364. }
  4365. n = _synctex_data_v_V(node);
  4366. min = n - _synctex_data_height_V(node);
  4367. max = n + _synctex_data_depth_V(node);
  4368. if (box.min.v<min) {
  4369. _synctex_data_set_height_V(node,n-box.min.v);
  4370. } else if (box.max.v>max) {
  4371. _synctex_data_set_depth_V(node,box.max.v-n);
  4372. }
  4373. return SYNCTEX_STATUS_OK;
  4374. }
  4375. # ifdef SYNCTEX_NOTHING
  4376. # pragma mark -
  4377. # pragma mark SPECIAL CHARACTERS
  4378. # endif
  4379. /* Here are the control characters that strat each line of the synctex output file.
  4380. * Their values define the meaning of the line.
  4381. */
  4382. # define SYNCTEX_CHAR_BEGIN_SHEET '{'
  4383. # define SYNCTEX_CHAR_END_SHEET '}'
  4384. # define SYNCTEX_CHAR_BEGIN_FORM '<'
  4385. # define SYNCTEX_CHAR_END_FORM '>'
  4386. # define SYNCTEX_CHAR_BEGIN_VBOX '['
  4387. # define SYNCTEX_CHAR_END_VBOX ']'
  4388. # define SYNCTEX_CHAR_BEGIN_HBOX '('
  4389. # define SYNCTEX_CHAR_END_HBOX ')'
  4390. # define SYNCTEX_CHAR_ANCHOR '!'
  4391. # define SYNCTEX_CHAR_VOID_VBOX 'v'
  4392. # define SYNCTEX_CHAR_VOID_HBOX 'h'
  4393. # define SYNCTEX_CHAR_KERN 'k'
  4394. # define SYNCTEX_CHAR_GLUE 'g'
  4395. # define SYNCTEX_CHAR_RULE 'r'
  4396. # define SYNCTEX_CHAR_MATH '$'
  4397. # define SYNCTEX_CHAR_FORM_REF 'f'
  4398. # define SYNCTEX_CHAR_BOUNDARY 'x'
  4399. # define SYNCTEX_CHAR_CHARACTER 'c'
  4400. # define SYNCTEX_CHAR_COMMENT '%'
  4401. # ifdef SYNCTEX_NOTHING
  4402. # pragma mark -
  4403. # pragma mark SCANNERS & PARSERS
  4404. # endif
  4405. # define SYNCTEX_DECODE_FAILED(NODE,WHAT) \
  4406. (_synctex_data_decode_##WHAT(NODE)<SYNCTEX_STATUS_OK)
  4407. # define SYNCTEX_DECODE_FAILED_V(NODE,WHAT) \
  4408. (_synctex_data_decode_##WHAT##_v(NODE)<SYNCTEX_STATUS_OK)
  4409. #define SYNCTEX_NS_NULL (synctex_ns_s){NULL,SYNCTEX_STATUS_NOT_OK}
  4410. static synctex_ns_s _synctex_parse_new_sheet(synctex_scanner_p scanner) {
  4411. synctex_node_p node;
  4412. if ((node = _synctex_new_sheet(scanner))) {
  4413. if (
  4414. SYNCTEX_DECODE_FAILED(node,page)) {
  4415. _synctex_error("Bad sheet record.");
  4416. } else if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
  4417. _synctex_error("Missing end of sheet.");
  4418. } else {
  4419. /* Now set the owner */
  4420. if (scanner->sheet) {
  4421. synctex_node_p last_sheet = scanner->sheet;
  4422. synctex_node_p next_sheet = NULL;
  4423. while ((next_sheet = __synctex_tree_sibling(last_sheet))) {
  4424. last_sheet = next_sheet;
  4425. }
  4426. /* sheets have no parent */
  4427. __synctex_tree_set_sibling(last_sheet,node);
  4428. } else {
  4429. scanner->sheet = node;
  4430. }
  4431. return (synctex_ns_s){node,SYNCTEX_STATUS_OK};
  4432. }
  4433. _synctex_free_node(node);
  4434. }
  4435. return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
  4436. }
  4437. /**
  4438. * - requirement: scanner != NULL
  4439. */
  4440. static synctex_ns_s _synctex_parse_new_form(synctex_scanner_p scanner) {
  4441. synctex_node_p node;
  4442. if ((node = _synctex_new_form(scanner))) {
  4443. if (
  4444. SYNCTEX_DECODE_FAILED(node,tag)) {
  4445. _synctex_error("Bad sheet record.");
  4446. } else if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
  4447. _synctex_error("Missing end of form.");
  4448. } else {
  4449. /* Now set the owner */
  4450. if (scanner->form) {
  4451. synctex_node_p last_form = scanner->form;
  4452. synctex_node_p next_form = NULL;
  4453. while ((next_form = __synctex_tree_sibling(last_form))) {
  4454. last_form = next_form;
  4455. }
  4456. __synctex_tree_set_sibling(last_form,node);
  4457. } else {
  4458. scanner->form = node;
  4459. }
  4460. return (synctex_ns_s){node,SYNCTEX_STATUS_OK};
  4461. }
  4462. _synctex_free_node(node);
  4463. }
  4464. return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
  4465. }
  4466. # define SYNCTEX_SHOULD_DECODE_FAILED(NODE,WHAT) \
  4467. (_synctex_data_has_##WHAT(NODE) &&(_synctex_data_decode_##WHAT(NODE)<SYNCTEX_STATUS_OK))
  4468. # define SYNCTEX_SHOULD_DECODE_FAILED_V(NODE,WHAT) \
  4469. (_synctex_data_has_##WHAT(NODE) &&(_synctex_data_decode_##WHAT##_v(NODE)<SYNCTEX_STATUS_OK))
  4470. static synctex_status_t _synctex_data_decode_tlchvwhd(synctex_node_p node) {
  4471. return SYNCTEX_SHOULD_DECODE_FAILED(node,tag)
  4472. || SYNCTEX_SHOULD_DECODE_FAILED(node,line)
  4473. || SYNCTEX_SHOULD_DECODE_FAILED(node,column)
  4474. || SYNCTEX_SHOULD_DECODE_FAILED(node,h)
  4475. || SYNCTEX_SHOULD_DECODE_FAILED_V(node,v)
  4476. || SYNCTEX_SHOULD_DECODE_FAILED(node,width)
  4477. || SYNCTEX_SHOULD_DECODE_FAILED(node,height)
  4478. || SYNCTEX_SHOULD_DECODE_FAILED(node,depth);
  4479. }
  4480. static synctex_ns_s _synctex_parse_new_vbox(synctex_scanner_p scanner) {
  4481. synctex_node_p node;
  4482. if ((node = _synctex_new_vbox(scanner))) {
  4483. if (_synctex_data_decode_tlchvwhd(node)) {
  4484. _synctex_error("Bad vbox record.");
  4485. _synctex_next_line(scanner);
  4486. out:
  4487. _synctex_free_node(node);
  4488. return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
  4489. }
  4490. if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
  4491. _synctex_error("Missing end of vbox.");
  4492. goto out;
  4493. }
  4494. return (synctex_ns_s){node,SYNCTEX_STATUS_OK};
  4495. }
  4496. _synctex_next_line(scanner);
  4497. return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
  4498. }
  4499. SYNCTEX_INLINE static synctex_node_p __synctex_node_make_friend_tlc(synctex_node_p node);
  4500. static synctex_ns_s _synctex_parse_new_hbox(synctex_scanner_p scanner) {
  4501. synctex_node_p node;
  4502. if ((node = _synctex_new_hbox(scanner))) {
  4503. if (_synctex_data_decode_tlchvwhd(node)) {
  4504. _synctex_error("Bad hbox record.");
  4505. _synctex_next_line(scanner);
  4506. out:
  4507. _synctex_free_node(node);
  4508. return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
  4509. }
  4510. if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
  4511. _synctex_error("Missing end of hbox.");
  4512. goto out;
  4513. }
  4514. if (_synctex_setup_visible_hbox(node)<SYNCTEX_STATUS_OK) {
  4515. _synctex_error("Unexpected error (_synctex_parse_new_hbox).");
  4516. goto out;
  4517. }
  4518. return (synctex_ns_s){node,SYNCTEX_STATUS_OK};
  4519. }
  4520. _synctex_next_line(scanner);
  4521. return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
  4522. }
  4523. static synctex_ns_s _synctex_parse_new_void_vbox(synctex_scanner_p scanner) {
  4524. synctex_node_p node;
  4525. if ((node = _synctex_new_void_vbox(scanner))) {
  4526. if (_synctex_data_decode_tlchvwhd(node)) {
  4527. _synctex_error("Bad void vbox record.");
  4528. _synctex_next_line(scanner);
  4529. out:
  4530. _synctex_free_node(node);
  4531. return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
  4532. }
  4533. if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
  4534. _synctex_error("Missing end of container.");
  4535. goto out;
  4536. }
  4537. return (synctex_ns_s){node,SYNCTEX_STATUS_OK};
  4538. }
  4539. _synctex_next_line(scanner);
  4540. return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
  4541. }
  4542. static synctex_ns_s _synctex_parse_new_void_hbox(synctex_scanner_p scanner) {
  4543. synctex_node_p node;
  4544. if ((node = _synctex_new_void_hbox(scanner))) {
  4545. if (_synctex_data_decode_tlchvwhd(node)) {
  4546. _synctex_error("Bad void hbox record.");
  4547. _synctex_next_line(scanner);
  4548. out:
  4549. _synctex_free_node(node);
  4550. return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
  4551. }
  4552. if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
  4553. _synctex_error("Missing end of container.");
  4554. goto out;
  4555. }
  4556. return (synctex_ns_s){node,SYNCTEX_STATUS_OK};
  4557. }
  4558. _synctex_next_line(scanner);
  4559. return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
  4560. }
  4561. static synctex_ns_s _synctex_parse_new_kern(synctex_scanner_p scanner) {
  4562. synctex_node_p node;
  4563. if ((node = _synctex_new_kern(scanner))) {
  4564. if (_synctex_data_decode_tlchvwhd(node)) {
  4565. _synctex_error("Bad kern record.");
  4566. _synctex_next_line(scanner);
  4567. out:
  4568. _synctex_free_node(node);
  4569. return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
  4570. }
  4571. if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
  4572. _synctex_error("Missing end of container.");
  4573. goto out;
  4574. }
  4575. return (synctex_ns_s){node,SYNCTEX_STATUS_OK};
  4576. }
  4577. _synctex_next_line(scanner);
  4578. return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
  4579. }
  4580. static synctex_ns_s _synctex_parse_new_glue(synctex_scanner_p scanner) {
  4581. synctex_node_p node;
  4582. if ((node = _synctex_new_glue(scanner))) {
  4583. if (_synctex_data_decode_tlchvwhd(node)) {
  4584. _synctex_error("Bad glue record.");
  4585. _synctex_next_line(scanner);
  4586. out:
  4587. _synctex_free_node(node);
  4588. return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
  4589. }
  4590. if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
  4591. _synctex_error("Missing end of container.");
  4592. goto out;
  4593. }
  4594. return (synctex_ns_s){node,SYNCTEX_STATUS_OK};
  4595. }
  4596. _synctex_next_line(scanner);
  4597. return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
  4598. }
  4599. static synctex_ns_s _synctex_parse_new_rule(synctex_scanner_p scanner) {
  4600. synctex_node_p node;
  4601. if ((node = _synctex_new_rule(scanner))) {
  4602. if (_synctex_data_decode_tlchvwhd(node)) {
  4603. _synctex_error("Bad rule record.");
  4604. _synctex_next_line(scanner);
  4605. out:
  4606. _synctex_free_node(node);
  4607. return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
  4608. }
  4609. if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
  4610. _synctex_error("Missing end of container.");
  4611. goto out;
  4612. }
  4613. return (synctex_ns_s){node,SYNCTEX_STATUS_OK};
  4614. }
  4615. _synctex_next_line(scanner);
  4616. return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
  4617. }
  4618. static synctex_ns_s _synctex_parse_new_math(synctex_scanner_p scanner) {
  4619. synctex_node_p node;
  4620. if ((node = _synctex_new_math(scanner))) {
  4621. if (_synctex_data_decode_tlchvwhd(node)) {
  4622. _synctex_error("Bad math record.");
  4623. _synctex_next_line(scanner);
  4624. out:
  4625. _synctex_free_node(node);
  4626. return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
  4627. }
  4628. if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
  4629. _synctex_error("Missing end of container.");
  4630. goto out;
  4631. }
  4632. return (synctex_ns_s){node,SYNCTEX_STATUS_OK};
  4633. }
  4634. _synctex_next_line(scanner);
  4635. return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
  4636. }
  4637. static synctex_ns_s _synctex_parse_new_boundary(synctex_scanner_p scanner) {
  4638. synctex_node_p node;
  4639. if ((node = _synctex_new_boundary(scanner))) {
  4640. if (_synctex_data_decode_tlchvwhd(node)) {
  4641. _synctex_error("Bad boundary record.");
  4642. _synctex_next_line(scanner);
  4643. out:
  4644. _synctex_free_node(node);
  4645. return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
  4646. }
  4647. if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
  4648. _synctex_error("Missing end of container.");
  4649. goto out;
  4650. }
  4651. return (synctex_ns_s){node,SYNCTEX_STATUS_OK};
  4652. }
  4653. _synctex_next_line(scanner);
  4654. return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
  4655. }
  4656. SYNCTEX_INLINE static synctex_ns_s _synctex_parse_new_ref(synctex_scanner_p scanner) {
  4657. synctex_node_p node;
  4658. if ((node = _synctex_new_ref(scanner))) {
  4659. if (SYNCTEX_DECODE_FAILED(node,tag)
  4660. || SYNCTEX_DECODE_FAILED(node,h)
  4661. || SYNCTEX_DECODE_FAILED_V(node,v)) {
  4662. _synctex_error("Bad form ref record.");
  4663. _synctex_next_line(scanner);
  4664. out:
  4665. _synctex_free_node(node);
  4666. return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
  4667. }
  4668. if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
  4669. _synctex_error("Missing end of container.");
  4670. goto out;
  4671. }
  4672. return (synctex_ns_s){node,SYNCTEX_STATUS_OK};
  4673. }
  4674. _synctex_next_line(scanner);
  4675. return (synctex_ns_s){NULL,SYNCTEX_STATUS_ERROR};
  4676. }
  4677. # undef SYNCTEX_DECODE_FAILED
  4678. # undef SYNCTEX_DECODE_FAILED_V
  4679. SYNCTEX_INLINE static synctex_point_s _synctex_data_point(synctex_node_p node);
  4680. SYNCTEX_INLINE static synctex_point_s _synctex_data_point_V(synctex_node_p node);
  4681. SYNCTEX_INLINE static synctex_point_s _synctex_data_set_point(synctex_node_p node, synctex_point_s point);
  4682. SYNCTEX_INLINE static synctex_box_s _synctex_data_box(synctex_node_p node);
  4683. SYNCTEX_INLINE static synctex_box_s _synctex_data_xob(synctex_node_p node);
  4684. SYNCTEX_INLINE static synctex_box_s _synctex_data_box_V(synctex_node_p node);
  4685. SYNCTEX_INLINE static synctex_node_p _synctex_input_register_line(synctex_node_p input,synctex_node_p node) {
  4686. if (node && _synctex_data_tag(input) != _synctex_data_tag(node)) {
  4687. input = synctex_scanner_input_with_tag(node->class_->scanner,_synctex_data_tag(node));
  4688. }
  4689. if (_synctex_data_line(node)>_synctex_data_line(input)) {
  4690. _synctex_data_set_line(input,_synctex_data_line(node));
  4691. }
  4692. return input;
  4693. }
  4694. /**
  4695. * Free node and its siblings and return its detached child.
  4696. */
  4697. SYNCTEX_INLINE static synctex_node_p _synctex_handle_pop_child(synctex_node_p handle) {
  4698. synctex_node_p child = _synctex_tree_reset_child(handle);
  4699. synctex_node_free(handle);
  4700. return child;
  4701. }
  4702. /**
  4703. * Set the tlc of all the x nodes that are targets of
  4704. * x_handle and its sibling.
  4705. * Reset the target of x_handle and deletes its siblings.
  4706. * child is a node that has just been parsed and is not a boundary node.
  4707. */
  4708. SYNCTEX_INLINE static void _synctex_handle_set_tlc(synctex_node_p x_handle, synctex_node_p child, synctex_bool_t make_friend) {
  4709. if (x_handle) {
  4710. synctex_node_p sibling = x_handle;
  4711. if (child) {
  4712. synctex_node_p target;
  4713. while ((target = synctex_node_target(sibling))) {
  4714. _synctex_data_set_tlc(target,child);
  4715. if (make_friend) {
  4716. _synctex_node_make_friend_tlc(target);
  4717. }
  4718. if ((sibling = __synctex_tree_sibling(sibling))) {
  4719. continue;
  4720. } else {
  4721. break;
  4722. }
  4723. }
  4724. }
  4725. _synctex_tree_reset_target(x_handle);
  4726. sibling = __synctex_tree_reset_sibling(x_handle);
  4727. synctex_node_free(sibling);
  4728. }
  4729. }
  4730. /**
  4731. * When we have parsed a box, we must register
  4732. * all the contained heading boundary nodes
  4733. * that have not yet been registered.
  4734. * Those handles will be deleted when poping.
  4735. */
  4736. SYNCTEX_INLINE static void _synctex_handle_make_friend_tlc(synctex_node_p node) {
  4737. while (node) {
  4738. synctex_node_p target = _synctex_tree_reset_target(node);
  4739. _synctex_node_make_friend_tlc(target);
  4740. node = __synctex_tree_sibling(node);
  4741. }
  4742. }
  4743. /**
  4744. * Scan sheets, forms and input records.
  4745. * - parameter scanner: owning scanner
  4746. * - returns: status
  4747. */
  4748. static synctex_status_t __synctex_parse_sfi(synctex_scanner_p scanner) {
  4749. synctex_status_t status = SYNCTEX_STATUS_OK;
  4750. synctex_zs_s zs = {0,0};
  4751. synctex_ns_s input = SYNCTEX_NS_NULL;
  4752. synctex_node_p sheet = NULL;
  4753. synctex_node_p form = NULL;
  4754. synctex_node_p parent = NULL;
  4755. synctex_node_p child = NULL;
  4756. /*
  4757. * Experimentations lead to the forthcoming conclusion:
  4758. * Sometimes, the first nodes of a box have the wrong line number.
  4759. * These are only boundary (x) nodes.
  4760. * We observed that boundary nodes do have the proper line number
  4761. * if they follow a node with a different type.
  4762. * We keep track of these leading x nodes in a handle tree.
  4763. */
  4764. synctex_node_p x_handle = NULL;
  4765. # define SYNCTEX_RETURN(STATUS) \
  4766. synctex_node_free(x_handle);\
  4767. return STATUS
  4768. synctex_node_p last_k = NULL;
  4769. synctex_node_p last_g = NULL;
  4770. synctex_ns_s ns = SYNCTEX_NS_NULL;
  4771. int form_depth = 0;
  4772. int ignored_form_depth = 0;
  4773. synctex_bool_t try_input = synctex_YES;
  4774. if (!(x_handle = _synctex_new_handle(scanner))) {
  4775. SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR);
  4776. }
  4777. # ifdef SYNCTEX_NOTHING
  4778. # pragma mark MAIN LOOP
  4779. # endif
  4780. main_loop:
  4781. status = SYNCTEX_STATUS_OK;
  4782. sheet = form = parent = child = NULL;
  4783. # define SYNCTEX_START_SCAN(WHAT)\
  4784. (*SYNCTEX_CUR == SYNCTEX_CHAR_##WHAT)
  4785. if (SYNCTEX_CUR<SYNCTEX_END) {
  4786. if (SYNCTEX_START_SCAN(BEGIN_FORM)) {
  4787. # ifdef SYNCTEX_NOTHING
  4788. # pragma mark + SCAN FORM
  4789. # endif
  4790. scan_form:
  4791. ns = _synctex_parse_new_form(scanner);
  4792. if (ns.status == SYNCTEX_STATUS_OK) {
  4793. ++form_depth;
  4794. if (_synctex_tree_parent(form)) {
  4795. /* This form is already being parsed */
  4796. ++ignored_form_depth;
  4797. goto ignore_loop;
  4798. }
  4799. _synctex_tree_set_parent(ns.node,form);
  4800. form = ns.node;
  4801. parent = form;
  4802. child = NULL;
  4803. last_k = last_g = NULL;
  4804. goto content_loop;
  4805. }
  4806. if (form || sheet) {
  4807. last_k = last_g = NULL;
  4808. goto content_loop;
  4809. }
  4810. try_input = synctex_YES;
  4811. goto main_loop;
  4812. } else if (SYNCTEX_START_SCAN(BEGIN_SHEET)) {
  4813. # ifdef SYNCTEX_NOTHING
  4814. # pragma mark + SCAN SHEET
  4815. # endif
  4816. try_input = synctex_YES;
  4817. ns = _synctex_parse_new_sheet(scanner);
  4818. if (ns.status == SYNCTEX_STATUS_OK) {
  4819. sheet = ns.node;
  4820. parent = sheet;
  4821. last_k = last_g = NULL;
  4822. goto content_loop;
  4823. }
  4824. goto main_loop;
  4825. } else if (SYNCTEX_START_SCAN(ANCHOR)) {
  4826. # ifdef SYNCTEX_NOTHING
  4827. # pragma mark + SCAN ANCHOR
  4828. # endif
  4829. scan_anchor:
  4830. ++SYNCTEX_CUR;
  4831. if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
  4832. _synctex_error("Missing anchor.");
  4833. SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR);
  4834. }
  4835. if (form || sheet) {
  4836. last_k = last_g = NULL;
  4837. goto content_loop;
  4838. }
  4839. try_input = synctex_YES;
  4840. goto main_loop;
  4841. } else if (SYNCTEX_START_SCAN(ANCHOR)) {
  4842. # ifdef SYNCTEX_NOTHING
  4843. # pragma mark + SCAN COMMENT
  4844. # endif
  4845. ++SYNCTEX_CUR;
  4846. _synctex_next_line(scanner);
  4847. try_input = synctex_YES;
  4848. goto main_loop;
  4849. } else if (try_input) {
  4850. # ifdef SYNCTEX_NOTHING
  4851. # pragma mark + SCAN INPUT
  4852. # endif
  4853. try_input = synctex_NO;
  4854. do {
  4855. input = __synctex_parse_new_input(scanner);
  4856. } while (input.status == SYNCTEX_STATUS_OK);
  4857. goto main_loop;
  4858. }
  4859. status = _synctex_match_string(scanner,"Postamble:");
  4860. if (status==SYNCTEX_STATUS_OK) {
  4861. scanner->flags.postamble = 1;
  4862. SYNCTEX_RETURN(status);
  4863. }
  4864. status = _synctex_next_line(scanner);
  4865. if (status<SYNCTEX_STATUS_OK) {
  4866. SYNCTEX_RETURN(status);
  4867. }
  4868. }
  4869. /* At least 1 more character */
  4870. zs = _synctex_buffer_get_available_size(scanner,1);
  4871. if (zs.size == 0){
  4872. _synctex_error("Uncomplete synctex file, postamble missing.");
  4873. SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR);
  4874. }
  4875. goto main_loop;
  4876. /* Unreachable. */
  4877. # ifdef SYNCTEX_NOTHING
  4878. # pragma mark IGNORE LOOP
  4879. # endif
  4880. ignore_loop:
  4881. ns = SYNCTEX_NS_NULL;
  4882. if (SYNCTEX_CUR<SYNCTEX_END) {
  4883. if (SYNCTEX_START_SCAN(BEGIN_FORM)) {
  4884. ++ignored_form_depth;
  4885. } else if (SYNCTEX_START_SCAN(END_FORM)) {
  4886. --ignored_form_depth;
  4887. }
  4888. if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
  4889. _synctex_error("Uncomplete container.");
  4890. SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR);
  4891. }
  4892. } else {
  4893. zs = _synctex_buffer_get_available_size(scanner,1);
  4894. if (zs.size == 0){
  4895. _synctex_error("Uncomplete synctex file, postamble missing.");
  4896. SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR);
  4897. }
  4898. }
  4899. if (ignored_form_depth) {
  4900. goto ignore_loop;
  4901. } else {
  4902. last_k = last_g = NULL;
  4903. goto content_loop;
  4904. }
  4905. # ifdef SYNCTEX_NOTHING
  4906. # pragma mark CONTENT LOOP
  4907. # endif
  4908. content_loop:
  4909. /* Either in a form, a sheet or a box.
  4910. * - in a sheet, "{" is not possible, only boxes and "}" at top level.
  4911. * - in a form, "{" is not possible, only boxes, "<" and ">" at top level.
  4912. * - in a box, the unique possibility is '<', '[', '(' or ">".
  4913. * We still keep the '(' for a sheet, because that dos not cost too much.
  4914. * We must also consider void boxes as children.
  4915. */
  4916. /* forms are everywhere */
  4917. ns = SYNCTEX_NS_NULL;
  4918. #if SYNCTEX_VERBOSE
  4919. synctex_scanner_set_display_switcher(scanner,-1);
  4920. printf("NEW CONTENT LOOP\n");
  4921. #if SYNCTEX_DEBUG>500
  4922. synctex_node_display(sheet);
  4923. #endif
  4924. #endif
  4925. if (SYNCTEX_CUR<SYNCTEX_END) {
  4926. if (SYNCTEX_START_SCAN(BEGIN_FORM)) {
  4927. goto scan_form;
  4928. } else if (SYNCTEX_START_SCAN(BEGIN_VBOX)) {
  4929. # ifdef SYNCTEX_NOTHING
  4930. # pragma mark + SCAN VBOX
  4931. # endif
  4932. ns = _synctex_parse_new_vbox(scanner);
  4933. if (ns.status == SYNCTEX_STATUS_OK) {
  4934. x_handle = _synctex_new_handle_with_child(x_handle);
  4935. if (child) {
  4936. _synctex_node_set_sibling(child,ns.node);
  4937. } else {
  4938. _synctex_node_set_child(parent,ns.node);
  4939. }
  4940. parent = ns.node;
  4941. child = _synctex_tree_last(parent);
  4942. # if SYNCTEX_VERBOSE
  4943. synctex_node_log(parent);
  4944. # endif
  4945. input.node = _synctex_input_register_line(input.node,parent);
  4946. last_k = last_g = NULL;
  4947. goto content_loop;
  4948. }
  4949. } else if (SYNCTEX_START_SCAN(END_VBOX)) {
  4950. if (synctex_node_type(parent) == synctex_node_type_vbox) {
  4951. # ifdef SYNCTEX_NOTHING
  4952. # pragma mark + SCAN XOBV
  4953. # endif
  4954. ++SYNCTEX_CUR;
  4955. if (NULL == _synctex_tree_child(parent) && !form) {
  4956. /* only void v boxes are friends */
  4957. _synctex_node_make_friend_tlc(parent);
  4958. }
  4959. child = parent;
  4960. parent = _synctex_tree_parent(child);
  4961. if (!form) {
  4962. _synctex_handle_make_friend_tlc(x_handle);
  4963. }
  4964. x_handle = _synctex_handle_pop_child(x_handle);
  4965. _synctex_handle_set_tlc(x_handle,child,!form);
  4966. # if SYNCTEX_VERBOSE
  4967. synctex_node_log(child);
  4968. # endif
  4969. if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
  4970. _synctex_error("Uncomplete container.");
  4971. SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR);
  4972. }
  4973. last_k = last_g = NULL;
  4974. goto content_loop;
  4975. }
  4976. } else if (SYNCTEX_START_SCAN(BEGIN_HBOX)) {
  4977. # ifdef SYNCTEX_NOTHING
  4978. # pragma mark + SCAN HBOX
  4979. # endif
  4980. # if defined(SYNCTEX_USE_CHARINDEX)
  4981. synctex_charindex_t char_index = (synctex_charindex_t)(scanner->reader->charindex_offset+SYNCTEX_CUR-SYNCTEX_START);
  4982. synctex_lineindex_t line_index = scanner->reader->line_number;
  4983. # endif
  4984. ns = _synctex_parse_new_hbox(scanner);
  4985. if (ns.status == SYNCTEX_STATUS_OK) {
  4986. x_handle = _synctex_new_handle_with_child(x_handle);
  4987. if (child) {
  4988. _synctex_node_set_sibling(child,ns.node);
  4989. } else {
  4990. _synctex_node_set_child(parent,ns.node);
  4991. }
  4992. parent = ns.node;
  4993. /* add a box boundary node at the start */
  4994. if ((child = _synctex_new_box_bdry(scanner))) {
  4995. # if defined(SYNCTEX_USE_CHARINDEX)
  4996. child->line_index=line_index;
  4997. child->char_index=char_index;
  4998. # endif
  4999. _synctex_node_set_child(parent,child);
  5000. _synctex_data_set_tlchv(child,parent);
  5001. if (!form) {
  5002. __synctex_node_make_friend_tlc(child);
  5003. }
  5004. } else {
  5005. _synctex_error("Can't create box bdry record.");
  5006. }
  5007. # if SYNCTEX_VERBOSE
  5008. synctex_node_log(parent);
  5009. # endif
  5010. input.node = _synctex_input_register_line(input.node,parent);
  5011. last_k = last_g = NULL;
  5012. goto content_loop;
  5013. }
  5014. } else if (SYNCTEX_START_SCAN(END_HBOX)) {
  5015. if (synctex_node_type(parent) == synctex_node_type_hbox) {
  5016. # ifdef SYNCTEX_NOTHING
  5017. # pragma mark + SCAN XOBH
  5018. # endif
  5019. ++SYNCTEX_CUR;
  5020. /* setting the next horizontal box at the end ensures
  5021. * that a child is recorded before any of its ancestors.
  5022. */
  5023. if (form == NULL /* && sheet != NULL*/ ) {
  5024. _synctex_tree_set_next_hbox(parent,_synctex_tree_next_hbox(sheet));
  5025. _synctex_tree_set_next_hbox(sheet,parent);
  5026. }
  5027. {
  5028. /* Update the mean line number */
  5029. synctex_node_p node = _synctex_tree_child(parent);
  5030. synctex_node_p sibling = NULL;
  5031. /* Ignore the first node (a box_bdry) */
  5032. if (node && (sibling = __synctex_tree_sibling(node))) {
  5033. unsigned int node_weight = 0;
  5034. unsigned int cumulated_line_numbers = 0;
  5035. _synctex_data_set_line(node, _synctex_data_line(sibling));
  5036. node = sibling;
  5037. do {
  5038. if (synctex_node_type(node)==synctex_node_type_hbox) {
  5039. if (_synctex_data_weight(node)) {
  5040. node_weight += _synctex_data_weight(node);
  5041. cumulated_line_numbers += _synctex_data_mean_line(node)*_synctex_data_weight(node);
  5042. } else {
  5043. ++node_weight;
  5044. cumulated_line_numbers += _synctex_data_mean_line(node);
  5045. }
  5046. } else {
  5047. ++node_weight;
  5048. cumulated_line_numbers += synctex_node_line(node);
  5049. }
  5050. } while ((node = __synctex_tree_sibling(node)));
  5051. _synctex_data_set_mean_line(parent,(cumulated_line_numbers + node_weight/2)/node_weight);
  5052. _synctex_data_set_weight(parent,node_weight);
  5053. } else {
  5054. _synctex_data_set_mean_line(parent,_synctex_data_line(parent));
  5055. _synctex_data_set_weight(parent,1);
  5056. }
  5057. if ((sibling = _synctex_new_box_bdry(scanner))) {
  5058. # if defined(SYNCTEX_USE_CHARINDEX)
  5059. sibling->line_index=child->line_index;
  5060. sibling->char_index=child->char_index;
  5061. # endif
  5062. _synctex_node_set_sibling(child,sibling);
  5063. {
  5064. synctex_node_p N = child;
  5065. while (synctex_node_type(N) == synctex_node_type_ref) {
  5066. N = _synctex_tree_arg_sibling(N);
  5067. }
  5068. _synctex_data_set_tlc(sibling,N);
  5069. }
  5070. _synctex_data_set_h(sibling,_synctex_data_h_V(parent)+_synctex_data_width_V(parent));
  5071. _synctex_data_set_v(sibling,_synctex_data_v_V(parent));
  5072. child = sibling;
  5073. } else {
  5074. _synctex_error("Can't create box bdry record.");
  5075. }
  5076. sibling = _synctex_tree_child(parent);
  5077. _synctex_data_set_point(sibling,_synctex_data_point_V(parent));
  5078. if (last_k && last_g && (child = synctex_node_child(parent))) {
  5079. /* Find the node preceeding last_k */
  5080. synctex_node_p next;
  5081. while ((next = __synctex_tree_sibling(child))) {
  5082. if (next == last_k) {
  5083. _synctex_data_set_tlc(last_k,child);
  5084. _synctex_data_set_tlc(last_g,child);
  5085. break;
  5086. }
  5087. child = next;
  5088. }
  5089. }
  5090. child = parent;
  5091. parent = _synctex_tree_parent(child);
  5092. if (!form) {
  5093. _synctex_handle_make_friend_tlc(x_handle);
  5094. }
  5095. x_handle = _synctex_handle_pop_child(x_handle);
  5096. _synctex_handle_set_tlc(x_handle,child,!form);
  5097. _synctex_make_hbox_contain_box(parent, _synctex_data_box_V(child));
  5098. # if SYNCTEX_VERBOSE
  5099. synctex_node_log(child);
  5100. # endif
  5101. }
  5102. if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
  5103. _synctex_error("Uncomplete container.");
  5104. SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR);
  5105. }
  5106. last_k = last_g = NULL;
  5107. goto content_loop;
  5108. }
  5109. } else if (SYNCTEX_START_SCAN(VOID_VBOX)) {
  5110. # ifdef SYNCTEX_NOTHING
  5111. # pragma mark + SCAN VOID VBOX
  5112. # endif
  5113. ns = _synctex_parse_new_void_vbox(scanner);
  5114. if (ns.status == SYNCTEX_STATUS_OK) {
  5115. if (child) {
  5116. _synctex_node_set_sibling(child,ns.node);
  5117. } else {
  5118. _synctex_node_set_child(parent,ns.node);
  5119. }
  5120. child = ns.node;
  5121. _synctex_handle_set_tlc(x_handle, child,!form);
  5122. # if SYNCTEX_VERBOSE
  5123. synctex_node_log(child);
  5124. # endif
  5125. input.node = _synctex_input_register_line(input.node,child);
  5126. last_k = last_g = NULL;
  5127. goto content_loop;
  5128. }
  5129. } else if (SYNCTEX_START_SCAN(VOID_HBOX)) {
  5130. # ifdef SYNCTEX_NOTHING
  5131. # pragma mark + SCAN VOID HBOX
  5132. # endif
  5133. ns = _synctex_parse_new_void_hbox(scanner);
  5134. if (ns.status == SYNCTEX_STATUS_OK) {
  5135. if (_synctex_data_width(ns.node)<0) {
  5136. printf("Negative width\n");
  5137. }
  5138. if (child) {
  5139. _synctex_node_set_sibling(child,ns.node);
  5140. } else {
  5141. _synctex_node_set_child(parent,ns.node);
  5142. }
  5143. child = ns.node;
  5144. _synctex_handle_set_tlc(x_handle, child,!form);
  5145. _synctex_make_hbox_contain_box(parent,_synctex_data_box(child));
  5146. # if SYNCTEX_VERBOSE
  5147. synctex_node_log(child);
  5148. # endif
  5149. input.node = _synctex_input_register_line(input.node,child);
  5150. last_k = last_g = NULL;
  5151. goto content_loop;
  5152. }
  5153. } else if (SYNCTEX_START_SCAN(KERN)) {
  5154. # ifdef SYNCTEX_NOTHING
  5155. # pragma mark + SCAN KERN
  5156. # endif
  5157. ns = _synctex_parse_new_kern(scanner);
  5158. //continue_scan:
  5159. if (ns.status == SYNCTEX_STATUS_OK) {
  5160. if (child) {
  5161. _synctex_node_set_sibling(child,ns.node);
  5162. } else {
  5163. _synctex_node_set_child(parent,ns.node);
  5164. }
  5165. child = ns.node;
  5166. if (!form) {
  5167. __synctex_node_make_friend_tlc(child);
  5168. }
  5169. _synctex_handle_set_tlc(x_handle, child,!form);
  5170. _synctex_make_hbox_contain_box(parent,_synctex_data_xob(child));
  5171. # if SYNCTEX_VERBOSE
  5172. synctex_node_log(child);
  5173. # endif
  5174. input.node = _synctex_input_register_line(input.node,child);
  5175. last_k = child;
  5176. last_g = NULL;
  5177. goto content_loop;
  5178. }
  5179. } else if (SYNCTEX_START_SCAN(GLUE)) {
  5180. # ifdef SYNCTEX_NOTHING
  5181. # pragma mark + SCAN GLUE
  5182. # endif
  5183. ns = _synctex_parse_new_glue(scanner);
  5184. if (ns.status == SYNCTEX_STATUS_OK) {
  5185. if (child) {
  5186. _synctex_node_set_sibling(child,ns.node);
  5187. } else {
  5188. _synctex_node_set_child(parent,ns.node);
  5189. }
  5190. child = ns.node;
  5191. if (!form) {
  5192. __synctex_node_make_friend_tlc(child);
  5193. }
  5194. _synctex_handle_set_tlc(x_handle, child,!form);
  5195. _synctex_make_hbox_contain_point(parent,_synctex_data_point(child));
  5196. # if SYNCTEX_VERBOSE
  5197. synctex_node_log(child);
  5198. # endif
  5199. input.node = _synctex_input_register_line(input.node,child);
  5200. if (last_k) {
  5201. last_g = child;
  5202. } else {
  5203. last_k = last_g = NULL;
  5204. }
  5205. goto content_loop;
  5206. }
  5207. } else if (SYNCTEX_START_SCAN(RULE)) {
  5208. # ifdef SYNCTEX_NOTHING
  5209. # pragma mark + SCAN RULE
  5210. # endif
  5211. ns = _synctex_parse_new_rule(scanner);
  5212. if (ns.status == SYNCTEX_STATUS_OK) {
  5213. if (child) {
  5214. _synctex_node_set_sibling(child,ns.node);
  5215. } else {
  5216. _synctex_node_set_child(parent,ns.node);
  5217. }
  5218. child = ns.node;
  5219. if (!form) {
  5220. __synctex_node_make_friend_tlc(child);
  5221. }
  5222. _synctex_handle_set_tlc(x_handle, child,!form);
  5223. /* Rules are sometimes far too big
  5224. _synctex_make_hbox_contain_box(parent,_synctex_data_box(child));
  5225. */
  5226. # if SYNCTEX_VERBOSE
  5227. synctex_node_log(child);
  5228. # endif
  5229. input.node = _synctex_input_register_line(input.node,child);
  5230. last_k = last_g = NULL;
  5231. goto content_loop;
  5232. }
  5233. } else if (SYNCTEX_START_SCAN(MATH)) {
  5234. # ifdef SYNCTEX_NOTHING
  5235. # pragma mark + SCAN MATH
  5236. # endif
  5237. ns = _synctex_parse_new_math(scanner);
  5238. if (ns.status == SYNCTEX_STATUS_OK) {
  5239. if (child) {
  5240. _synctex_node_set_sibling(child,ns.node);
  5241. } else {
  5242. _synctex_node_set_child(parent,ns.node);
  5243. }
  5244. child = ns.node;
  5245. if (!form) {
  5246. __synctex_node_make_friend_tlc(child);
  5247. }
  5248. _synctex_handle_set_tlc(x_handle, child,!form);
  5249. _synctex_make_hbox_contain_point(parent,_synctex_data_point(child));
  5250. # if SYNCTEX_VERBOSE
  5251. synctex_node_log(child);
  5252. # endif
  5253. input.node = _synctex_input_register_line(input.node,child);
  5254. last_k = last_g = NULL;
  5255. goto content_loop;
  5256. }
  5257. } else if (SYNCTEX_START_SCAN(FORM_REF)) {
  5258. # ifdef SYNCTEX_NOTHING
  5259. # pragma mark + SCAN FORM REF
  5260. # endif
  5261. #if SYNCTEX_DEBUG>500
  5262. synctex_node_display(parent);
  5263. synctex_node_display(child);
  5264. #endif
  5265. ns = _synctex_parse_new_ref(scanner);
  5266. if (ns.status == SYNCTEX_STATUS_OK) {
  5267. if (child) {
  5268. _synctex_node_set_sibling(child,ns.node);
  5269. } else {
  5270. _synctex_node_set_child(parent,ns.node);
  5271. }
  5272. child = ns.node;
  5273. if (form) {
  5274. if (scanner->ref_in_form) {
  5275. synctex_tree_set_friend(child,scanner->ref_in_form);
  5276. }
  5277. scanner->ref_in_form = child;
  5278. } else {
  5279. if (scanner->ref_in_sheet) {
  5280. synctex_tree_set_friend(child,scanner->ref_in_sheet);
  5281. }
  5282. scanner->ref_in_sheet = child;
  5283. }
  5284. # if SYNCTEX_VERBOSE
  5285. synctex_node_log(child);
  5286. # endif
  5287. last_k = last_g = NULL;
  5288. goto content_loop;
  5289. }
  5290. } else if (SYNCTEX_START_SCAN(BOUNDARY)) {
  5291. # ifdef SYNCTEX_NOTHING
  5292. # pragma mark + SCAN BOUNDARY
  5293. # endif
  5294. ns = _synctex_parse_new_boundary(scanner);
  5295. if (ns.status == SYNCTEX_STATUS_OK) {
  5296. if (child) {
  5297. _synctex_node_set_sibling(child,ns.node);
  5298. } else {
  5299. _synctex_node_set_child(parent,ns.node);
  5300. }
  5301. if (synctex_node_type(child)==synctex_node_type_box_bdry
  5302. || _synctex_tree_target(x_handle)) {
  5303. child = _synctex_tree_reset_child(x_handle);
  5304. child = _synctex_new_handle_with_child(child);
  5305. __synctex_tree_set_sibling(child, x_handle);
  5306. x_handle = child;
  5307. _synctex_tree_set_target(x_handle,ns.node);
  5308. } else if (!form) {
  5309. __synctex_node_make_friend_tlc(ns.node);
  5310. }
  5311. child = ns.node;
  5312. _synctex_make_hbox_contain_point(parent,_synctex_data_point(child));
  5313. # if SYNCTEX_VERBOSE
  5314. synctex_node_log(child);
  5315. # endif
  5316. input.node = _synctex_input_register_line(input.node,child);
  5317. last_k = last_g = NULL;
  5318. goto content_loop;
  5319. }
  5320. } else if (SYNCTEX_START_SCAN(CHARACTER)) {
  5321. # ifdef SYNCTEX_NOTHING
  5322. # pragma mark + SCAN CHARACTER
  5323. # endif
  5324. ++SYNCTEX_CUR;
  5325. if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
  5326. _synctex_error("Missing end of container.");
  5327. SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR);
  5328. }
  5329. last_k = last_g = NULL;
  5330. goto content_loop;
  5331. } else if (SYNCTEX_START_SCAN(ANCHOR)) {
  5332. # ifdef SYNCTEX_NOTHING
  5333. # pragma mark + SCAN ANCHOR
  5334. # endif
  5335. goto scan_anchor;
  5336. } else if (SYNCTEX_START_SCAN(END_SHEET)) {
  5337. if (sheet && parent == sheet) {
  5338. # ifdef SYNCTEX_NOTHING
  5339. # pragma mark + SCAN TEEHS
  5340. # endif
  5341. ++SYNCTEX_CUR;
  5342. if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
  5343. _synctex_error("Missing anchor.");
  5344. }
  5345. parent = sheet = NULL;
  5346. goto main_loop;
  5347. }
  5348. } else if (SYNCTEX_START_SCAN(END_FORM)) {
  5349. if (parent == form && form_depth > 0) {
  5350. # ifdef SYNCTEX_NOTHING
  5351. # pragma mark + SCAN MROF
  5352. # endif
  5353. ++SYNCTEX_CUR;
  5354. --form_depth;
  5355. if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK
  5356. && (form_depth || sheet)) {
  5357. _synctex_error("Missing end of container.");
  5358. SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR);
  5359. }
  5360. if ((parent = _synctex_tree_parent(form))) {
  5361. _synctex_tree_reset_parent(form);
  5362. child = form;
  5363. form = parent;
  5364. goto content_loop;
  5365. } else if (sheet) {
  5366. form = NULL;
  5367. parent = sheet;
  5368. child = synctex_node_last_sibling(child);
  5369. goto content_loop;
  5370. }
  5371. goto main_loop;
  5372. }
  5373. }
  5374. _synctex_error("Ignored record <%.20s...>(line %i)\n",SYNCTEX_CUR, scanner->reader->line_number+1);
  5375. if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
  5376. _synctex_error("Missing end of sheet/form.");
  5377. SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR);
  5378. }
  5379. last_k = last_g = NULL;
  5380. goto content_loop;
  5381. }
  5382. zs = _synctex_buffer_get_available_size(scanner,1);
  5383. if (zs.size == 0){
  5384. _synctex_error("Uncomplete synctex file, postamble missing.");
  5385. SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR);
  5386. }
  5387. last_k = last_g = NULL;
  5388. goto content_loop;
  5389. }
  5390. #undef SYNCTEX_RETURN
  5391. /**
  5392. * Replace ref in its tree hierarchy by a single box
  5393. * proxy to the contents of the associated form.
  5394. * - argument ref: a ref node with no friend
  5395. * - return the proxy created.
  5396. * - note: Does nothing if ref is not owned.
  5397. * - note: On return, ref will have no parent nor sibling.
  5398. * The caller is responsible for releasing ref.
  5399. * - note: this is where root proxies are created.
  5400. * - note: the target of the root proxy is the content
  5401. * of a form.
  5402. */
  5403. SYNCTEX_INLINE static synctex_ns_s __synctex_replace_ref(synctex_node_p ref) {
  5404. synctex_ns_s ns = {NULL,SYNCTEX_STATUS_OK};
  5405. synctex_node_p parent;
  5406. if ((parent = _synctex_tree_parent(ref))) {
  5407. synctex_node_p sibling = __synctex_tree_reset_sibling(ref);
  5408. synctex_node_p arg_sibling = synctex_node_arg_sibling(ref);
  5409. /* arg_sibling != NULL because the child of a box
  5410. * is always a box boundary, not a ref. */
  5411. synctex_node_p target = synctex_form_content(ref->class_->scanner, _synctex_data_tag(ref));
  5412. /* The target is a single node (box)
  5413. * with children and no siblings. */
  5414. if ((ns.node = __synctex_new_proxy_from_ref_to(ref, target))) {
  5415. /* Insert this proxy instead of ref. */
  5416. _synctex_node_set_sibling(arg_sibling,ns.node);
  5417. /* Then append the original sibling of ref. */
  5418. _synctex_node_set_sibling(ns.node,sibling);
  5419. # if defined(SYNCTEX_USE_CHARINDEX)
  5420. if (synctex_node_type(sibling) == synctex_node_type_box_bdry) {
  5421. /* The sibling is the last box boundary
  5422. * which may have a less accurate information */
  5423. sibling->char_index = arg_sibling->char_index;
  5424. sibling->line_index = arg_sibling->line_index;
  5425. }
  5426. #endif
  5427. #if SYNCTEX_DEBUG>500
  5428. printf("! Ref replacement:\n");
  5429. synctex_node_log(ref);
  5430. synctex_node_display(synctex_node_sibling(ref));
  5431. #endif
  5432. } else /* simply remove ref */ {
  5433. _synctex_tree_set_sibling(arg_sibling,sibling);
  5434. }
  5435. __synctex_tree_reset_parent(ref);
  5436. } else {
  5437. _synctex_error("! Missing parent in __synctex_replace_ref. "
  5438. "Please report.");
  5439. ns.status = SYNCTEX_STATUS_BAD_ARGUMENT;
  5440. }
  5441. return ns;
  5442. }
  5443. /**
  5444. * - argument ref: is the starting point of a linked list
  5445. * of refs. The link is made through the friend field.
  5446. * - returns: the status and the list of all the proxies
  5447. * created. The link is made through the friend field.
  5448. * - note: All refs are freed
  5449. */
  5450. SYNCTEX_INLINE static synctex_ns_s _synctex_post_process_ref(synctex_node_p ref) {
  5451. synctex_ns_s ns = {NULL, SYNCTEX_STATUS_OK};
  5452. while (ref) {
  5453. synctex_node_p next_ref = _synctex_tree_reset_friend(ref);
  5454. synctex_ns_s sub_ns = __synctex_replace_ref(ref);
  5455. if (sub_ns.status < ns.status) {
  5456. ns.status = sub_ns.status;
  5457. } else {
  5458. /* Insert all the created proxies in the list
  5459. * sub_ns.node is the last friend,
  5460. */
  5461. synctex_tree_set_friend(sub_ns.node,ns.node);
  5462. ns.node = sub_ns.node;
  5463. }
  5464. synctex_node_free(ref);
  5465. ref = next_ref;
  5466. }
  5467. return ns;
  5468. }
  5469. typedef synctex_node_p (* synctex_processor_f)(synctex_node_p node);
  5470. /**
  5471. * Apply the processor f to the tree hierarchy rooted at proxy.
  5472. * proxy has replaced a form ref, no children yet.
  5473. * As a side effect all the hierarchy of nodes will be created.
  5474. */
  5475. SYNCTEX_INLINE static synctex_status_t _synctex_post_process_proxy(synctex_node_p proxy, synctex_processor_f f) {
  5476. while(proxy) {
  5477. synctex_node_p next_proxy = _synctex_tree_friend(proxy);
  5478. synctex_node_p halt = __synctex_tree_sibling(proxy);
  5479. /* if proxy is the last sibling, halt is NULL.
  5480. * Find what should be a next node,
  5481. * without creating new nodes. */
  5482. if (!halt) {
  5483. synctex_node_p parent = _synctex_tree_parent(proxy);
  5484. halt = __synctex_tree_sibling(parent);
  5485. while (!halt && parent) {
  5486. parent = _synctex_tree_parent(parent);
  5487. halt = __synctex_tree_sibling(parent);
  5488. }
  5489. }
  5490. do {
  5491. #if SYNCTEX_DEBUG>500
  5492. printf("POST PROCESSING %s\n",_synctex_node_abstract(proxy));
  5493. {
  5494. int i,j = 0;
  5495. for (i=0;i<proxy->class_->scanner->number_of_lists;++i) {
  5496. synctex_node_p N = proxy->class_->scanner->lists_of_friends[i];
  5497. do {
  5498. if (N==proxy) {
  5499. ++j;
  5500. printf("%s",_synctex_node_abstract(N));
  5501. }
  5502. } while ((N = _synctex_tree_friend(N)));
  5503. }
  5504. if (j) {
  5505. printf("\nBeforehand %i match\n",j);
  5506. }
  5507. }
  5508. #endif
  5509. f(proxy);
  5510. #if SYNCTEX_DEBUG>500
  5511. {
  5512. int i,j = 0;
  5513. for (i=0;i<proxy->class_->scanner->number_of_lists;++i) {
  5514. synctex_node_p N = proxy->class_->scanner->lists_of_friends[i];
  5515. do {
  5516. if (N==proxy) {
  5517. ++j;
  5518. printf("%s",_synctex_node_abstract(N));
  5519. }
  5520. } while ((N = _synctex_tree_friend(N)));
  5521. }
  5522. if (j) {
  5523. printf("\n%i match\n",j);
  5524. }
  5525. }
  5526. #endif
  5527. /* Side effect: create the hierarchy on the fly */
  5528. proxy = synctex_node_next(proxy); /* Change is here */
  5529. #if SYNCTEX_DEBUG>500
  5530. if (proxy) {
  5531. int i,j = 0;
  5532. for (i=0;i<proxy->class_->scanner->number_of_lists;++i) {
  5533. synctex_node_p N = proxy->class_->scanner->lists_of_friends[i];
  5534. do {
  5535. if (N==proxy) {
  5536. ++j;
  5537. printf("%s",_synctex_node_abstract(N));
  5538. }
  5539. } while ((N = _synctex_tree_friend(N)));
  5540. }
  5541. if (j) {
  5542. printf("\nnext %i match\n",j);
  5543. }
  5544. }
  5545. #endif
  5546. } while (proxy && proxy != halt);
  5547. proxy = next_proxy;
  5548. }
  5549. return SYNCTEX_STATUS_OK;
  5550. }
  5551. /**
  5552. * Replace all the form refs by root box proxies.
  5553. * Create the node hierarchy and update the friends.
  5554. * On entry, the refs are collected as a friend list
  5555. * in either a form or a sheet
  5556. * - parameter: the owning scanner
  5557. */
  5558. SYNCTEX_INLINE static synctex_status_t _synctex_post_process(synctex_scanner_p scanner) {
  5559. synctex_status_t status = SYNCTEX_STATUS_OK;
  5560. synctex_ns_s ns = {NULL,SYNCTEX_STATUS_NOT_OK};
  5561. #if SYNCTEX_DEBUG>500
  5562. printf("! entering _synctex_post_process.\n");
  5563. synctex_node_display(scanner->sheet);
  5564. synctex_node_display(scanner->form);
  5565. #endif
  5566. /* replace form refs inside forms by box proxies */
  5567. ns = _synctex_post_process_ref(scanner->ref_in_form);
  5568. scanner->ref_in_form = NULL;/* it was just released */
  5569. if (ns.status<status) {
  5570. status = ns.status;
  5571. }
  5572. #if SYNCTEX_DEBUG>500
  5573. printf("! ref replaced in form _synctex_post_process.\n");
  5574. synctex_node_display(scanner->form);
  5575. #endif
  5576. /* Create all the form proxy nodes on the fly.
  5577. * ns.node is the root of the list of
  5578. * newly created proxies.
  5579. * There might be a problem with cascading proxies.
  5580. * In order to be properly managed, the data must
  5581. * be organized in the right way.
  5582. * The inserted form must be defined before
  5583. * the inserting one. *TeX will take care of that. */
  5584. ns.status = _synctex_post_process_proxy(ns.node,&_synctex_tree_reset_friend);
  5585. if (ns.status<status) {
  5586. status = ns.status;
  5587. }
  5588. /* replace form refs inside sheets by box proxies */
  5589. ns = _synctex_post_process_ref(scanner->ref_in_sheet);
  5590. if (ns.status<status) {
  5591. status = ns.status;
  5592. }
  5593. scanner->ref_in_sheet = NULL;
  5594. #if SYNCTEX_DEBUG>500
  5595. printf("! ref replaced in sheet _synctex_post_process.\n");
  5596. synctex_node_display(scanner->sheet);
  5597. #endif
  5598. #if 0
  5599. {
  5600. int i;
  5601. for (i=0;i<scanner->number_of_lists;++i) {
  5602. synctex_node_p P = ns.node;
  5603. do {
  5604. synctex_node_p N = scanner->lists_of_friends[i];
  5605. do {
  5606. if (P == N) {
  5607. printf("Already registered.\n");
  5608. synctex_node_display(N);
  5609. break;
  5610. }
  5611. } while ((N = _synctex_tree_friend(N)));
  5612. } while((P = _synctex_tree_friend(P)));
  5613. }
  5614. }
  5615. #endif
  5616. #if SYNCTEX_DEBUG>10000
  5617. {
  5618. int i;
  5619. for (i=0;i<scanner->number_of_lists;++i) {
  5620. synctex_node_p P = scanner->lists_of_friends[i];
  5621. int j = 0;
  5622. while (P) {
  5623. ++j;
  5624. synctex_node_log(P);
  5625. P = _synctex_tree_friend(P);
  5626. }
  5627. if (j) {
  5628. printf("friends %i -> # %i\n",i,j);
  5629. }
  5630. }
  5631. }
  5632. #endif
  5633. ns.status = _synctex_post_process_proxy(ns.node,&__synctex_proxy_make_friend_and_next_hbox);
  5634. if (ns.status<status) {
  5635. status = ns.status;
  5636. }
  5637. #if SYNCTEX_DEBUG>500
  5638. printf("! exiting _synctex_post_process.\n");
  5639. synctex_node_display(scanner->sheet);
  5640. synctex_node_display(scanner->form);
  5641. printf("! display all.\n");
  5642. synctex_node_display(scanner->sheet);
  5643. synctex_node_display(scanner->form);
  5644. #endif
  5645. return status;
  5646. }
  5647. /* Used when parsing the synctex file
  5648. */
  5649. static synctex_status_t _synctex_scan_content(synctex_scanner_p scanner) {
  5650. scanner->reader->lastv = -1;
  5651. synctex_status_t status = 0;
  5652. if (NULL == scanner) {
  5653. return SYNCTEX_STATUS_BAD_ARGUMENT;
  5654. }
  5655. /* Find where this section starts */
  5656. content_not_found:
  5657. status = _synctex_match_string(scanner,"Content:");
  5658. if (status<SYNCTEX_STATUS_EOF) {
  5659. return status;
  5660. }
  5661. if (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) {
  5662. _synctex_error("Uncomplete Content.");
  5663. return SYNCTEX_STATUS_ERROR;
  5664. }
  5665. if (status == SYNCTEX_STATUS_NOT_OK) {
  5666. goto content_not_found;
  5667. }
  5668. status = __synctex_parse_sfi(scanner);
  5669. if (status == SYNCTEX_STATUS_OK) {
  5670. status = _synctex_post_process(scanner);
  5671. }
  5672. return status;
  5673. }
  5674. synctex_scanner_p synctex_scanner_new() {
  5675. synctex_scanner_p scanner =(synctex_scanner_p)_synctex_malloc(sizeof(synctex_scanner_s));
  5676. if (scanner) {
  5677. if (!(scanner->reader = _synctex_malloc(sizeof(synctex_reader_s)))) {
  5678. _synctex_free(scanner);
  5679. return NULL;
  5680. }
  5681. # ifdef SYNCTEX_NOTHING
  5682. # pragma mark -
  5683. # endif
  5684. # define DEFINE_synctex_scanner_class(NAME)\
  5685. scanner->class_[synctex_node_type_##NAME] = synctex_class_##NAME;\
  5686. (scanner->class_[synctex_node_type_##NAME]).scanner = scanner
  5687. DEFINE_synctex_scanner_class(input);
  5688. DEFINE_synctex_scanner_class(sheet);
  5689. DEFINE_synctex_scanner_class(form);
  5690. DEFINE_synctex_scanner_class(hbox);
  5691. DEFINE_synctex_scanner_class(void_hbox);
  5692. DEFINE_synctex_scanner_class(vbox);
  5693. DEFINE_synctex_scanner_class(void_vbox);
  5694. DEFINE_synctex_scanner_class(kern);
  5695. DEFINE_synctex_scanner_class(glue);
  5696. DEFINE_synctex_scanner_class(rule);
  5697. DEFINE_synctex_scanner_class(math);
  5698. DEFINE_synctex_scanner_class(boundary);
  5699. DEFINE_synctex_scanner_class(box_bdry);
  5700. DEFINE_synctex_scanner_class(ref);
  5701. DEFINE_synctex_scanner_class(proxy_hbox);
  5702. DEFINE_synctex_scanner_class(proxy_vbox);
  5703. DEFINE_synctex_scanner_class(proxy);
  5704. DEFINE_synctex_scanner_class(proxy_last);
  5705. DEFINE_synctex_scanner_class(handle);
  5706. /* set up the lists of friends */
  5707. scanner->number_of_lists = 1024;
  5708. scanner->lists_of_friends = (synctex_node_r)_synctex_malloc(scanner->number_of_lists*sizeof(synctex_node_p));
  5709. if (NULL == scanner->lists_of_friends) {
  5710. synctex_scanner_free(scanner);
  5711. _synctex_error("malloc:2");
  5712. return NULL;
  5713. }
  5714. scanner->display_switcher = 100;
  5715. scanner->display_prompt = (char *)_synctex_display_prompt+strlen(_synctex_display_prompt)-1;
  5716. }
  5717. return scanner;
  5718. }
  5719. /* Where the synctex scanner is created. */
  5720. synctex_scanner_p synctex_scanner_new_with_output_file(const char * output, const char * build_directory, int parse) {
  5721. synctex_scanner_p scanner = synctex_scanner_new();
  5722. if (NULL == scanner) {
  5723. _synctex_error("malloc problem");
  5724. return NULL;
  5725. }
  5726. if ((scanner->reader = synctex_reader_init_with_output_file(scanner->reader, output, build_directory))) {
  5727. return parse? synctex_scanner_parse(scanner):scanner;
  5728. }
  5729. _synctex_error("No file?");
  5730. return NULL;
  5731. }
  5732. /* The scanner destructor
  5733. */
  5734. int synctex_scanner_free(synctex_scanner_p scanner) {
  5735. int node_count = 0;
  5736. if (scanner) {
  5737. if (SYNCTEX_FILE) {
  5738. gzclose(SYNCTEX_FILE);
  5739. SYNCTEX_FILE = NULL;
  5740. }
  5741. synctex_node_free(scanner->sheet);
  5742. synctex_node_free(scanner->form);
  5743. synctex_node_free(scanner->input);
  5744. synctex_reader_free(scanner->reader);
  5745. SYNCTEX_SCANNER_FREE_HANDLE(scanner);
  5746. synctex_iterator_free(scanner->iterator);
  5747. free(scanner->output_fmt);
  5748. free(scanner->lists_of_friends);
  5749. #if SYNCTEX_USE_NODE_COUNT>0
  5750. node_count = scanner->node_count;
  5751. #endif
  5752. free(scanner);
  5753. }
  5754. return node_count;
  5755. }
  5756. /* Where the synctex scanner parses the contents of the file. */
  5757. synctex_scanner_p synctex_scanner_parse(synctex_scanner_p scanner) {
  5758. synctex_status_t status = 0;
  5759. if (!scanner || scanner->flags.has_parsed) {
  5760. return scanner;
  5761. }
  5762. scanner->flags.has_parsed=1;
  5763. scanner->pre_magnification = 1000;
  5764. scanner->pre_unit = 8192;
  5765. scanner->pre_x_offset = scanner->pre_y_offset = 578;
  5766. /* initialize the offset with a fake unprobable value,
  5767. * If there is a post scriptum section, this value will be overriden by the real life value */
  5768. scanner->x_offset = scanner->y_offset = 6.027e23f;
  5769. scanner->reader->line_number = 1;
  5770. SYNCTEX_START = (char *)malloc(SYNCTEX_BUFFER_SIZE+1); /* one more character for null termination */
  5771. if (NULL == SYNCTEX_START) {
  5772. _synctex_error("! malloc error in synctex_scanner_parse.");
  5773. bailey:
  5774. #ifdef SYNCTEX_DEBUG
  5775. return scanner;
  5776. #else
  5777. synctex_scanner_free(scanner);
  5778. return NULL;
  5779. #endif
  5780. }
  5781. synctex_scanner_set_display_switcher(scanner, 1000);
  5782. SYNCTEX_END = SYNCTEX_START+SYNCTEX_BUFFER_SIZE;
  5783. /* SYNCTEX_END always points to a null terminating character.
  5784. * Maybe there is another null terminating character between SYNCTEX_CUR and SYNCTEX_END-1.
  5785. * At least, we are sure that SYNCTEX_CUR points to a string covering a valid part of the memory. */
  5786. *SYNCTEX_END = '\0';
  5787. SYNCTEX_CUR = SYNCTEX_END;
  5788. # if defined(SYNCTEX_USE_CHARINDEX)
  5789. scanner->reader->charindex_offset = -SYNCTEX_BUFFER_SIZE;
  5790. # endif
  5791. status = _synctex_scan_preamble(scanner);
  5792. if (status<SYNCTEX_STATUS_OK) {
  5793. _synctex_error("Bad preamble\n");
  5794. goto bailey;
  5795. }
  5796. status = _synctex_scan_content(scanner);
  5797. if (status<SYNCTEX_STATUS_OK) {
  5798. _synctex_error("Bad content\n");
  5799. goto bailey;
  5800. }
  5801. status = _synctex_scan_postamble(scanner);
  5802. if (status<SYNCTEX_STATUS_OK) {
  5803. _synctex_error("Bad postamble. Ignored\n");
  5804. }
  5805. #if SYNCTEX_DEBUG>500
  5806. synctex_scanner_set_display_switcher(scanner, 100);
  5807. synctex_node_display(scanner->sheet);
  5808. synctex_node_display(scanner->form);
  5809. #endif
  5810. synctex_scanner_set_display_switcher(scanner, 1000);
  5811. /* Everything is finished, free the buffer, close the file */
  5812. free((void *)SYNCTEX_START);
  5813. SYNCTEX_START = SYNCTEX_CUR = SYNCTEX_END = NULL;
  5814. gzclose(SYNCTEX_FILE);
  5815. SYNCTEX_FILE = NULL;
  5816. /* Final tuning: set the default values for various parameters */
  5817. /* 1 pre_unit = (scanner->pre_unit)/65536 pt = (scanner->pre_unit)/65781.76 bp
  5818. * 1 pt = 65536 sp */
  5819. if (scanner->pre_unit<=0) {
  5820. scanner->pre_unit = 8192;
  5821. }
  5822. if (scanner->pre_magnification<=0) {
  5823. scanner->pre_magnification = 1000;
  5824. }
  5825. if (scanner->unit <= 0) {
  5826. /* no post magnification */
  5827. scanner->unit = scanner->pre_unit / 65781.76;/* 65781.76 or 65536.0*/
  5828. } else {
  5829. /* post magnification */
  5830. scanner->unit *= scanner->pre_unit / 65781.76;
  5831. }
  5832. scanner->unit *= scanner->pre_magnification / 1000.0;
  5833. if (scanner->x_offset > 6e23) {
  5834. /* no post offset */
  5835. scanner->x_offset = scanner->pre_x_offset * (scanner->pre_unit / 65781.76);
  5836. scanner->y_offset = scanner->pre_y_offset * (scanner->pre_unit / 65781.76);
  5837. } else {
  5838. /* post offset */
  5839. scanner->x_offset /= 65781.76f;
  5840. scanner->y_offset /= 65781.76f;
  5841. }
  5842. return scanner;
  5843. #undef SYNCTEX_FILE
  5844. }
  5845. /* Scanner accessors.
  5846. */
  5847. int synctex_scanner_pre_x_offset(synctex_scanner_p scanner){
  5848. return scanner?scanner->pre_x_offset:0;
  5849. }
  5850. int synctex_scanner_pre_y_offset(synctex_scanner_p scanner){
  5851. return scanner?scanner->pre_y_offset:0;
  5852. }
  5853. int synctex_scanner_x_offset(synctex_scanner_p scanner){
  5854. return scanner?scanner->x_offset:0;
  5855. }
  5856. int synctex_scanner_y_offset(synctex_scanner_p scanner){
  5857. return scanner?scanner->y_offset:0;
  5858. }
  5859. float synctex_scanner_magnification(synctex_scanner_p scanner){
  5860. return scanner?scanner->unit:1;
  5861. }
  5862. void synctex_scanner_display(synctex_scanner_p scanner) {
  5863. if (NULL == scanner) {
  5864. return;
  5865. }
  5866. printf("The scanner:\noutput:%s\noutput_fmt:%s\nversion:%i\n",scanner->reader->output,scanner->output_fmt,scanner->version);
  5867. printf("pre_unit:%i\nx_offset:%i\ny_offset:%i\n",scanner->pre_unit,scanner->pre_x_offset,scanner->pre_y_offset);
  5868. printf("count:%i\npost_magnification:%f\npost_x_offset:%f\npost_y_offset:%f\n",
  5869. scanner->count,scanner->unit,scanner->x_offset,scanner->y_offset);
  5870. printf("The input:\n");
  5871. synctex_node_display(scanner->input);
  5872. if (scanner->count<1000) {
  5873. printf("The sheets:\n");
  5874. synctex_node_display(scanner->sheet);
  5875. printf("The friends:\n");
  5876. if (scanner->lists_of_friends) {
  5877. int i = scanner->number_of_lists;
  5878. synctex_node_p node;
  5879. while(i--) {
  5880. printf("Friend index:%i\n",i);
  5881. node = (scanner->lists_of_friends)[i];
  5882. while(node) {
  5883. printf("%s:%i,%i\n",
  5884. synctex_node_isa(node),
  5885. _synctex_data_tag(node),
  5886. _synctex_data_line(node)
  5887. );
  5888. node = _synctex_tree_friend(node);
  5889. }
  5890. }
  5891. }
  5892. } else {
  5893. printf("SyncTeX Warning: Too many objects\n");
  5894. }
  5895. }
  5896. /* Public */
  5897. const char * synctex_scanner_get_name(synctex_scanner_p scanner,int tag) {
  5898. synctex_node_p input = NULL;
  5899. if (NULL == scanner) {
  5900. return NULL;
  5901. }
  5902. if ((input = scanner->input)) {;
  5903. do {
  5904. if (tag == _synctex_data_tag(input)) {
  5905. return (_synctex_data_name(input));
  5906. }
  5907. } while((input = __synctex_tree_sibling(input)));
  5908. }
  5909. return NULL;
  5910. }
  5911. const char * synctex_node_get_name(synctex_node_p node) {
  5912. if (node) {
  5913. return synctex_scanner_get_name(node->class_->scanner,_synctex_data_tag(node));
  5914. }
  5915. return NULL;
  5916. }
  5917. static int _synctex_scanner_get_tag(synctex_scanner_p scanner,const char * name);
  5918. static int _synctex_scanner_get_tag(synctex_scanner_p scanner,const char * name) {
  5919. synctex_node_p input = NULL;
  5920. if (NULL == scanner) {
  5921. return 0;
  5922. }
  5923. if ((input = scanner->input)) {
  5924. do {
  5925. if (_synctex_is_equivalent_file_name(name,(_synctex_data_name(input)))) {
  5926. return _synctex_data_tag(input);
  5927. }
  5928. } while((input = __synctex_tree_sibling(input)));
  5929. }
  5930. // 2011 version
  5931. name = _synctex_base_name(name);
  5932. if ((input = scanner->input)) {
  5933. do {
  5934. if (_synctex_is_equivalent_file_name(name,_synctex_base_name(_synctex_data_name(input)))) {
  5935. synctex_node_p other_input = input;
  5936. while((other_input = __synctex_tree_sibling(other_input))) {
  5937. if (_synctex_is_equivalent_file_name(name,_synctex_base_name(_synctex_data_name(other_input)))
  5938. && (strlen(_synctex_data_name(input))!=strlen(_synctex_data_name(other_input))
  5939. || strncmp(_synctex_data_name(other_input),_synctex_data_name(input),strlen(_synctex_data_name(input))))) {
  5940. // There is a second possible candidate
  5941. return 0;
  5942. }
  5943. }
  5944. return _synctex_data_tag(input);
  5945. }
  5946. } while((input = __synctex_tree_sibling(input)));
  5947. }
  5948. return 0;
  5949. }
  5950. int synctex_scanner_get_tag(synctex_scanner_p scanner,const char * name) {
  5951. size_t char_index = strlen(name);
  5952. if ((scanner = synctex_scanner_parse(scanner)) && (0 < char_index)) {
  5953. /* the name is not void */
  5954. char_index -= 1;
  5955. if (!SYNCTEX_IS_PATH_SEPARATOR(name[char_index])) {
  5956. /* the last character of name is not a path separator */
  5957. int result = _synctex_scanner_get_tag(scanner,name);
  5958. if (result) {
  5959. return result;
  5960. } else {
  5961. /* the given name was not the one known by TeX
  5962. * try a name relative to the enclosing directory of the scanner->output file */
  5963. const char * relative = name;
  5964. const char * ptr = scanner->reader->output;
  5965. while((strlen(relative) > 0) && (strlen(ptr) > 0) && (*relative == *ptr))
  5966. {
  5967. relative += 1;
  5968. ptr += 1;
  5969. }
  5970. /* Find the last path separator before relative */
  5971. while(relative > name) {
  5972. if (SYNCTEX_IS_PATH_SEPARATOR(*(relative-1))) {
  5973. break;
  5974. }
  5975. relative -= 1;
  5976. }
  5977. if ((relative > name) && (result = _synctex_scanner_get_tag(scanner,relative))) {
  5978. return result;
  5979. }
  5980. if (SYNCTEX_IS_PATH_SEPARATOR(name[0])) {
  5981. /* No tag found for the given absolute name,
  5982. * Try each relative path starting from the shortest one */
  5983. while(0<char_index) {
  5984. char_index -= 1;
  5985. if (SYNCTEX_IS_PATH_SEPARATOR(name[char_index])
  5986. && (result = _synctex_scanner_get_tag(scanner,name+char_index+1))) {
  5987. return result;
  5988. }
  5989. }
  5990. }
  5991. }
  5992. return result;
  5993. }
  5994. }
  5995. return 0;
  5996. }
  5997. synctex_node_p synctex_scanner_input(synctex_scanner_p scanner) {
  5998. return scanner?scanner->input:NULL;
  5999. }
  6000. synctex_node_p synctex_scanner_input_with_tag(synctex_scanner_p scanner, int tag) {
  6001. synctex_node_p input = scanner?scanner->input:NULL;
  6002. while (_synctex_data_tag(input)!=tag) {
  6003. if ((input = __synctex_tree_sibling(input))) {
  6004. continue;
  6005. }
  6006. break;
  6007. }
  6008. return input;
  6009. }
  6010. const char * synctex_scanner_get_output_fmt(synctex_scanner_p scanner) {
  6011. return NULL != scanner && scanner->output_fmt?scanner->output_fmt:"";
  6012. }
  6013. const char * synctex_scanner_get_output(synctex_scanner_p scanner) {
  6014. return NULL != scanner && scanner->reader->output?scanner->reader->output:"";
  6015. }
  6016. const char * synctex_scanner_get_synctex(synctex_scanner_p scanner) {
  6017. return NULL != scanner && scanner->reader->synctex?scanner->reader->synctex:"";
  6018. }
  6019. # ifdef SYNCTEX_NOTHING
  6020. # pragma mark -
  6021. # pragma mark Public node attributes
  6022. # endif
  6023. # define SYNCTEX_DEFINE_NODE_HVWHD(WHAT) \
  6024. int synctex_node_##WHAT(synctex_node_p node) { \
  6025. return (node && node->class_->inspector->WHAT)? \
  6026. node->class_->inspector->WHAT(node): 0; \
  6027. }
  6028. # define SYNCTEX_DEFINE_PROXY_HV(WHAT) \
  6029. static int _synctex_proxy_##WHAT(synctex_proxy_p proxy) { \
  6030. synctex_node_p target = _synctex_tree_target(proxy); \
  6031. if (target) { \
  6032. return _synctex_data_##WHAT(proxy)+synctex_node_##WHAT(target); \
  6033. } else { \
  6034. return proxy? _synctex_data_##WHAT(proxy): 0; \
  6035. } \
  6036. }
  6037. #define SYNCTEX_DEFINE_PROXY_TLCWVD(WHAT) \
  6038. static int _synctex_proxy_##WHAT(synctex_proxy_p proxy) { \
  6039. synctex_node_p target = _synctex_tree_target(proxy); \
  6040. return target? synctex_node_##WHAT(target): 0; \
  6041. }
  6042. /**
  6043. * The horizontal location of the node.
  6044. * Idem for v, width, height and depth.
  6045. * - parameter node: a node with geometrical information.
  6046. * - returns: an integer.
  6047. * - requires: every proxy node has a target.
  6048. * - note: recursive call if the parameter has a proxy.
  6049. * - author: JL
  6050. */
  6051. SYNCTEX_DEFINE_NODE_HVWHD(h)
  6052. SYNCTEX_DEFINE_NODE_HVWHD(v)
  6053. SYNCTEX_DEFINE_NODE_HVWHD(width)
  6054. SYNCTEX_DEFINE_NODE_HVWHD(height)
  6055. SYNCTEX_DEFINE_NODE_HVWHD(depth)
  6056. SYNCTEX_DEFINE_PROXY_TLCWVD(tag)
  6057. SYNCTEX_DEFINE_PROXY_TLCWVD(line)
  6058. SYNCTEX_DEFINE_PROXY_TLCWVD(column)
  6059. SYNCTEX_DEFINE_PROXY_HV(h)
  6060. SYNCTEX_DEFINE_PROXY_HV(v)
  6061. SYNCTEX_DEFINE_PROXY_TLCWVD(width)
  6062. SYNCTEX_DEFINE_PROXY_TLCWVD(height)
  6063. SYNCTEX_DEFINE_PROXY_TLCWVD(depth)
  6064. /**
  6065. * Whether the argument is a box,
  6066. * either vertical or horizontal,
  6067. * either void or not,
  6068. * or a proxy to such a box.
  6069. * - parameter NODE: of type synctex_node_p
  6070. * - returns: yorn
  6071. */
  6072. SYNCTEX_INLINE static synctex_bool_t _synctex_node_is_box(synctex_node_p node) {
  6073. return node &&
  6074. (node->class_->type == synctex_node_type_hbox
  6075. || node->class_->type == synctex_node_type_void_hbox
  6076. || node->class_->type == synctex_node_type_vbox
  6077. || node->class_->type == synctex_node_type_void_vbox
  6078. || _synctex_node_is_box(_synctex_tree_target(node)));
  6079. }
  6080. /**
  6081. * Whether the argument is a handle.
  6082. * Handles are similar to proxies because they have a target.
  6083. * They are used for query results.
  6084. * - parameter NODE: of type synctex_node_p
  6085. * - returns: yorn
  6086. */
  6087. SYNCTEX_INLINE static synctex_bool_t _synctex_node_is_handle(synctex_node_p node) {
  6088. return node &&
  6089. (node->class_->type == synctex_node_type_handle);
  6090. }
  6091. /**
  6092. * Resolves handle indirection.
  6093. * - parameter node: of type synctex_node_p
  6094. * - returns: node if it is not a handle,
  6095. * its target otherwise.
  6096. */
  6097. SYNCTEX_INLINE static synctex_node_p _synctex_node_or_handle_target(synctex_node_p node) {
  6098. return _synctex_node_is_handle(node)?
  6099. _synctex_tree_target(node):node;
  6100. }
  6101. /**
  6102. * Whether the argument is an hbox.
  6103. * - parameter NODE: of type synctex_node_p
  6104. * - returns: yorn
  6105. */
  6106. SYNCTEX_INLINE static synctex_bool_t _synctex_node_is_hbox(synctex_node_p node) {
  6107. return node &&
  6108. (node->class_->type == synctex_node_type_hbox
  6109. || node->class_->type == synctex_node_type_void_hbox
  6110. || _synctex_node_is_hbox(_synctex_tree_target(node)));
  6111. }
  6112. /**
  6113. * The horizontal location of the first box enclosing node.
  6114. * - parameter node: a node with geometrical information.
  6115. * - returns: an integer.
  6116. * - author: JL
  6117. */
  6118. int synctex_node_box_h(synctex_node_p node) {
  6119. if (_synctex_node_is_box(node) || (node = _synctex_tree_parent(node))) {
  6120. return synctex_node_h(node);
  6121. }
  6122. return 0;
  6123. }
  6124. /**
  6125. * The vertical location of the first box enclosing node.
  6126. * - parameter node: a node with geometrical information.
  6127. * - returns: an integer.
  6128. * - author: JL
  6129. */
  6130. int synctex_node_box_v(synctex_node_p node) {
  6131. if (_synctex_node_is_box(node) || (node = _synctex_tree_parent(node))) {
  6132. return synctex_node_v(node);
  6133. }
  6134. return 0;
  6135. }
  6136. /**
  6137. * The width of the first box enclosing node.
  6138. * - parameter node: a node with geometrical information.
  6139. * - returns: an integer.
  6140. * - author: JL
  6141. */
  6142. int synctex_node_box_width(synctex_node_p node) {
  6143. if (_synctex_node_is_box(node) || (node = _synctex_tree_parent(node))) {
  6144. return synctex_node_width(node);
  6145. }
  6146. return 0;
  6147. }
  6148. /**
  6149. * The height of the first box enclosing node.
  6150. * - parameter node: a node with geometrical information.
  6151. * - returns: an integer.
  6152. * - author: JL
  6153. */
  6154. int synctex_node_box_height(synctex_node_p node) {
  6155. if (_synctex_node_is_box(node) || (node = _synctex_tree_parent(node))) {
  6156. return synctex_node_height(node);
  6157. }
  6158. return 0;
  6159. }
  6160. /**
  6161. * The depth of the first box enclosing node.
  6162. * - parameter node: a node with geometrical information.
  6163. * - returns: an integer.
  6164. * - author: JL
  6165. */
  6166. int synctex_node_box_depth(synctex_node_p node) {
  6167. if (_synctex_node_is_box(node) || (node = _synctex_tree_parent(node))) {
  6168. return synctex_node_depth(node);
  6169. }
  6170. return 0;
  6171. }
  6172. /**
  6173. * The horizontal location of an hbox, corrected with contents.
  6174. * - parameter node: an hbox node.
  6175. * - returns: an integer, 0 if node is not an hbox or an hbox proxy.
  6176. * - note: recursive call when node is an hbox proxy.
  6177. * - author: JL
  6178. */
  6179. int synctex_node_hbox_h(synctex_node_p node) {
  6180. switch(synctex_node_type(node)) {
  6181. case synctex_node_type_hbox:
  6182. return _synctex_data_h_V(node);
  6183. case synctex_node_type_proxy_hbox:
  6184. return _synctex_data_h(node)+synctex_node_hbox_h(_synctex_tree_target(node));
  6185. default:
  6186. return 0;
  6187. }
  6188. }
  6189. /**
  6190. * The vertical location of an hbox, corrected with contents.
  6191. * - parameter node: an hbox node.
  6192. * - returns: an integer, 0 if node is not an hbox or an hbox proxy.
  6193. * - note: recursive call when node is an hbox proxy.
  6194. * - author: JL
  6195. */
  6196. int synctex_node_hbox_v(synctex_node_p node) {
  6197. switch(synctex_node_type(node)) {
  6198. case synctex_node_type_hbox:
  6199. return _synctex_data_v_V(node);
  6200. case synctex_node_type_proxy_hbox:
  6201. return _synctex_data_v(node)+synctex_node_hbox_v(_synctex_tree_target(node));
  6202. default:
  6203. return 0;
  6204. }
  6205. }
  6206. /**
  6207. * The width of an hbox, corrected with contents.
  6208. * - parameter node: an hbox node, 0 if node is not an hbox or an hbox proxy.
  6209. * - returns: an integer.
  6210. * - author: JL
  6211. */
  6212. int synctex_node_hbox_width(synctex_node_p node) {
  6213. synctex_node_p target = _synctex_tree_target(node);
  6214. if (target) {
  6215. node = target;
  6216. }
  6217. return synctex_node_type(node) == synctex_node_type_hbox?
  6218. _synctex_data_width_V(node): 0;
  6219. }
  6220. /**
  6221. * The height of an hbox, corrected with contents.
  6222. * - parameter node: an hbox node.
  6223. * - returns: an integer, 0 if node is not an hbox or an hbox proxy.
  6224. * - author: JL
  6225. */
  6226. int synctex_node_hbox_height(synctex_node_p node) {
  6227. synctex_node_p target = _synctex_tree_target(node);
  6228. if (target) {
  6229. node = target;
  6230. }
  6231. return synctex_node_type(node) == synctex_node_type_hbox?
  6232. _synctex_data_height_V(node): 0;
  6233. }
  6234. /**
  6235. * The depth of an hbox, corrected with contents.
  6236. * - parameter node: an hbox node.
  6237. * - returns: an integer, 0 if node is not an hbox or an hbox proxy.
  6238. * - note: recursive call when node is an hbox proxy.
  6239. * - author: JL
  6240. */
  6241. int synctex_node_hbox_depth(synctex_node_p node) {
  6242. synctex_node_p target = _synctex_tree_target(node);
  6243. if (target) {
  6244. node = target;
  6245. }
  6246. return synctex_node_type(node) == synctex_node_type_hbox?
  6247. _synctex_data_depth_V(node): 0;
  6248. }
  6249. # ifdef SYNCTEX_NOTHING
  6250. # pragma mark -
  6251. # pragma mark Public node visible attributes
  6252. # endif
  6253. #define SYNCTEX_VISIBLE_SIZE(node,s) \
  6254. (s)*node->class_->scanner->unit
  6255. #define SYNCTEX_VISIBLE_DISTANCE_h(node,d) \
  6256. ((d)*node->class_->scanner->unit+node->class_->scanner->x_offset)
  6257. #define SYNCTEX_VISIBLE_DISTANCE_v(node,d) \
  6258. ((d)*node->class_->scanner->unit+node->class_->scanner->y_offset)
  6259. static float __synctex_node_visible_h(synctex_node_p node) {
  6260. return SYNCTEX_VISIBLE_DISTANCE_h(node,synctex_node_h(node));
  6261. }
  6262. static float __synctex_node_visible_v(synctex_node_p node) {
  6263. return SYNCTEX_VISIBLE_DISTANCE_v(node,synctex_node_v(node));
  6264. }
  6265. static float __synctex_node_visible_width(synctex_node_p node) {
  6266. return SYNCTEX_VISIBLE_SIZE(node,synctex_node_width(node));
  6267. }
  6268. static float __synctex_node_visible_height(synctex_node_p node) {
  6269. return SYNCTEX_VISIBLE_SIZE(node,synctex_node_height(node));
  6270. }
  6271. static float __synctex_node_visible_depth(synctex_node_p node) {
  6272. return SYNCTEX_VISIBLE_SIZE(node,synctex_node_depth(node));
  6273. }
  6274. static float __synctex_proxy_visible_h(synctex_node_p node) {
  6275. return SYNCTEX_VISIBLE_DISTANCE_h(node,synctex_node_h(node));
  6276. }
  6277. static float __synctex_proxy_visible_v(synctex_node_p node) {
  6278. return SYNCTEX_VISIBLE_DISTANCE_v(node,synctex_node_v(node));
  6279. }
  6280. static float __synctex_proxy_visible_width(synctex_node_p node) {
  6281. synctex_node_p target = _synctex_tree_target(node);
  6282. return __synctex_node_visible_width(target);
  6283. }
  6284. static float __synctex_proxy_visible_height(synctex_node_p node) {
  6285. synctex_node_p target = _synctex_tree_target(node);
  6286. return __synctex_node_visible_height(target);
  6287. }
  6288. static float __synctex_proxy_visible_depth(synctex_node_p node) {
  6289. synctex_node_p target = _synctex_tree_target(node);
  6290. return __synctex_node_visible_depth(target);
  6291. }
  6292. static float __synctex_kern_visible_h(synctex_noxy_p noxy) {
  6293. int h = _synctex_data_h(noxy);
  6294. int width = _synctex_data_width(noxy);
  6295. return SYNCTEX_VISIBLE_DISTANCE_h(noxy, width>0?h-width:h);
  6296. }
  6297. static float __synctex_kern_visible_width(synctex_noxy_p noxy) {
  6298. int width = _synctex_data_width(noxy);
  6299. return SYNCTEX_VISIBLE_SIZE(noxy, width>0?width:-width);
  6300. }
  6301. static float __synctex_rule_visible_h(synctex_noxy_p noxy) {
  6302. int h = _synctex_data_h(noxy);
  6303. int width = _synctex_data_width(noxy);
  6304. return SYNCTEX_VISIBLE_DISTANCE_h(noxy, width>0?h:h-width);
  6305. }
  6306. static float __synctex_rule_visible_width(synctex_noxy_p noxy) {
  6307. int width = _synctex_data_width(noxy);
  6308. return SYNCTEX_VISIBLE_SIZE(noxy, width>0?width:-width);
  6309. }
  6310. static float __synctex_rule_visible_v(synctex_noxy_p noxy) {
  6311. return __synctex_node_visible_v(noxy);
  6312. }
  6313. static float __synctex_rule_visible_height(synctex_noxy_p noxy) {
  6314. return __synctex_node_visible_height(noxy);
  6315. }
  6316. static float __synctex_rule_visible_depth(synctex_noxy_p noxy) {
  6317. return __synctex_node_visible_depth(noxy);
  6318. }
  6319. /**
  6320. * The horizontal location of node, in page coordinates.
  6321. * - parameter node: a node.
  6322. * - returns: a float.
  6323. * - author: JL
  6324. */
  6325. float synctex_node_visible_h(synctex_node_p node){
  6326. return node? node->class_->vispector->h(node): 0;
  6327. }
  6328. /**
  6329. * The vertical location of node, in page coordinates.
  6330. * - parameter node: a node.
  6331. * - returns: a float.
  6332. * - author: JL
  6333. */
  6334. float synctex_node_visible_v(synctex_node_p node){
  6335. return node? node->class_->vispector->v(node): 0;
  6336. }
  6337. /**
  6338. * The width of node, in page coordinates.
  6339. * - parameter node: a node.
  6340. * - returns: a float.
  6341. * - author: JL
  6342. */
  6343. float synctex_node_visible_width(synctex_node_p node){
  6344. return node? node->class_->vispector->width(node): 0;
  6345. }
  6346. /**
  6347. * The height of node, in page coordinates.
  6348. * - parameter node: a node.
  6349. * - returns: a float.
  6350. * - author: JL
  6351. */
  6352. float synctex_node_visible_height(synctex_node_p node){
  6353. return node? node->class_->vispector->height(node): 0;
  6354. }
  6355. /**
  6356. * The depth of node, in page coordinates.
  6357. * - parameter node: a node.
  6358. * - returns: a float.
  6359. * - author: JL
  6360. */
  6361. float synctex_node_visible_depth(synctex_node_p node){
  6362. return node? node->class_->vispector->depth(node): 0;
  6363. }
  6364. /**
  6365. * The V variant of geometrical information.
  6366. * - parameter node: a node.
  6367. * - returns: an integer.
  6368. * - author: JL
  6369. */
  6370. #define SYNCTEX_DEFINE_V(WHAT)\
  6371. SYNCTEX_INLINE static int _synctex_node_##WHAT##_V(synctex_node_p node) { \
  6372. synctex_node_p target = _synctex_tree_target(node); \
  6373. if (target) { \
  6374. return _synctex_data_##WHAT(node)+_synctex_node_##WHAT##_V(target); \
  6375. } else if (_synctex_data_has_##WHAT##_V(node)) { \
  6376. return _synctex_data_##WHAT##_V(node); \
  6377. } else { \
  6378. return _synctex_data_##WHAT(node); \
  6379. } \
  6380. }
  6381. SYNCTEX_DEFINE_V(h)
  6382. SYNCTEX_DEFINE_V(v)
  6383. SYNCTEX_DEFINE_V(width)
  6384. SYNCTEX_DEFINE_V(height)
  6385. SYNCTEX_DEFINE_V(depth)
  6386. SYNCTEX_INLINE static synctex_point_s _synctex_data_point(synctex_node_p node) {
  6387. return (synctex_point_s){synctex_node_h(node),synctex_node_v(node)};
  6388. }
  6389. SYNCTEX_INLINE static synctex_point_s _synctex_data_point_V(synctex_node_p node) {
  6390. return (synctex_point_s){_synctex_node_h_V(node),_synctex_node_v_V(node)};
  6391. }
  6392. SYNCTEX_INLINE static synctex_point_s _synctex_data_set_point(synctex_node_p node, synctex_point_s point) {
  6393. synctex_point_s old = _synctex_data_point(node);
  6394. _synctex_data_set_h(node,point.h);
  6395. _synctex_data_set_v(node,point.v);
  6396. return old;
  6397. }
  6398. SYNCTEX_INLINE static synctex_box_s _synctex_data_box(synctex_node_p node) {
  6399. synctex_box_s box = {{0,0},{0,0}};
  6400. int n;
  6401. n = synctex_node_width(node);
  6402. if (n<0) {
  6403. box.max.h = synctex_node_h(node);
  6404. box.min.h = box.max.h + n;
  6405. } else {
  6406. box.min.h = synctex_node_h(node);
  6407. box.max.h = box.min.h + n;
  6408. }
  6409. n = synctex_node_v(node);
  6410. box.min.v = n - synctex_node_height(node);
  6411. box.max.v = n + synctex_node_depth(node);
  6412. return box;
  6413. }
  6414. SYNCTEX_INLINE static synctex_box_s _synctex_data_xob(synctex_node_p node) {
  6415. synctex_box_s box = {{0,0},{0,0}};
  6416. int n;
  6417. n = synctex_node_width(node);
  6418. if (n>0) {
  6419. box.max.h = synctex_node_h(node);
  6420. box.min.h = box.max.h - n;
  6421. } else {
  6422. box.min.h = synctex_node_h(node);
  6423. box.max.h = box.min.h - n;
  6424. }
  6425. n = synctex_node_v(node);
  6426. box.min.v = n - synctex_node_height(node);
  6427. box.max.v = n + synctex_node_depth(node);
  6428. return box;
  6429. }
  6430. SYNCTEX_INLINE static synctex_box_s _synctex_data_box_V(synctex_node_p node) {
  6431. synctex_box_s box = {{0,0},{0,0}};
  6432. int n;
  6433. n = _synctex_node_width_V(node);
  6434. if (n<0) {
  6435. box.max.h = _synctex_node_h_V(node);
  6436. box.min.h = box.max.h + n;
  6437. } else {
  6438. box.min.h = _synctex_node_h_V(node);
  6439. box.max.h = box.min.h + n;
  6440. }
  6441. n = _synctex_node_v_V(node);
  6442. box.min.v = n - _synctex_node_height_V(node);
  6443. box.max.v = n + _synctex_node_depth_V(node);
  6444. return box;
  6445. }
  6446. /**
  6447. * The higher box node in the parent hierarchy which
  6448. * mean line number is the one of node ±1.
  6449. * This enclosing box is computed as follows
  6450. * 1) get the first hbox in the parent linked list
  6451. * starting at node.
  6452. * If there is none, simply return the parent of node.
  6453. * 2) compute the mean line number
  6454. * 3) scans up the tree for the higher hbox with
  6455. * the same mean line number, ±1 eventually
  6456. * - parameter node: a node.
  6457. * - returns: a (proxy to a) box node.
  6458. * - author: JL
  6459. */
  6460. static synctex_node_p _synctex_node_box_visible(synctex_node_p node) {
  6461. if ((node = _synctex_node_or_handle_target(node))) {
  6462. int mean = 0;
  6463. int bound = 1500000/(node->class_->scanner->pre_magnification/1000.0);
  6464. synctex_node_p parent = NULL;
  6465. /* get the first enclosing parent
  6466. * then get the highest enclosing parent with the same mean line ±1 */
  6467. node = _synctex_node_or_handle_target(node);
  6468. if (!_synctex_node_is_box(node)) {
  6469. if ((parent = _synctex_tree_parent(node))) {
  6470. node = parent;
  6471. } else if ((node = _synctex_tree_target(node))) {
  6472. if (!_synctex_node_is_box(node)) {
  6473. if ((parent = _synctex_tree_parent(node))) {
  6474. node = parent;
  6475. } else {
  6476. return NULL;
  6477. }
  6478. }
  6479. }
  6480. }
  6481. parent = node;
  6482. mean = synctex_node_mean_line(node);
  6483. while ((parent = _synctex_tree_parent(parent))) {
  6484. if (_synctex_node_is_hbox(parent)) {
  6485. if (_synctex_abs(mean-synctex_node_mean_line(parent))>1) {
  6486. return node;
  6487. } else if (synctex_node_width(parent)>bound) {
  6488. return parent;
  6489. } else if (synctex_node_height(parent)+synctex_node_depth(parent)>bound) {
  6490. return parent;
  6491. }
  6492. node = parent;
  6493. }
  6494. }
  6495. }
  6496. return node;
  6497. }
  6498. /**
  6499. * The horizontal location of the first box enclosing node, in page coordinates.
  6500. * - parameter node: a node.
  6501. * - returns: a float.
  6502. * - author: JL
  6503. */
  6504. float synctex_node_box_visible_h(synctex_node_p node) {
  6505. return SYNCTEX_VISIBLE_DISTANCE_h(node,_synctex_node_h_V(_synctex_node_box_visible(node)));
  6506. }
  6507. /**
  6508. * The vertical location of the first box enclosing node, in page coordinates.
  6509. * - parameter node: a node.
  6510. * - returns: a float.
  6511. * - author: JL
  6512. */
  6513. float synctex_node_box_visible_v(synctex_node_p node) {
  6514. return SYNCTEX_VISIBLE_DISTANCE_v(node,_synctex_node_v_V(_synctex_node_box_visible(node)));
  6515. }
  6516. /**
  6517. * The width of the first box enclosing node, in page coordinates.
  6518. * - parameter node: a node.
  6519. * - returns: a float.
  6520. * - author: JL
  6521. */
  6522. float synctex_node_box_visible_width(synctex_node_p node) {
  6523. return SYNCTEX_VISIBLE_SIZE(node,_synctex_node_width_V(_synctex_node_box_visible(node)));
  6524. }
  6525. /**
  6526. * The height of the first box enclosing node, in page coordinates.
  6527. * - parameter node: a node.
  6528. * - returns: a float.
  6529. * - author: JL
  6530. */
  6531. float synctex_node_box_visible_height(synctex_node_p node) {
  6532. return SYNCTEX_VISIBLE_SIZE(node,_synctex_node_height_V(_synctex_node_box_visible(node)));
  6533. }
  6534. /**
  6535. * The depth of the first box enclosing node, in page coordinates.
  6536. * - parameter node: a node.
  6537. * - returns: a float.
  6538. * - author: JL
  6539. */
  6540. float synctex_node_box_visible_depth(synctex_node_p node) {
  6541. return SYNCTEX_VISIBLE_SIZE(node,_synctex_node_depth_V(_synctex_node_box_visible(node)));
  6542. }
  6543. # ifdef SYNCTEX_NOTHING
  6544. # pragma mark -
  6545. # pragma mark Other public node attributes
  6546. # endif
  6547. /**
  6548. * The page number of the sheet enclosing node.
  6549. * - parameter node: a node.
  6550. * - returns: the page number or -1 if node does not belong to a sheet tree.
  6551. * - note: a proxy target does not belong to a sheet
  6552. * but a form, its page number is always -1.
  6553. * - note: a handles does not belong to a sheet not a form.
  6554. * its page number is -1.
  6555. * - author: JL
  6556. */
  6557. int synctex_node_page(synctex_node_p node){
  6558. synctex_node_p parent = NULL;
  6559. while((parent = _synctex_tree_parent(node))) {
  6560. node = parent;
  6561. }
  6562. if (synctex_node_type(node) == synctex_node_type_sheet) {
  6563. return _synctex_data_page(node);
  6564. }
  6565. return -1;
  6566. }
  6567. /**
  6568. * The page number of the target.
  6569. * - author: JL
  6570. */
  6571. SYNCTEX_INLINE static int _synctex_node_target_page(synctex_node_p node){
  6572. return synctex_node_page(_synctex_tree_target(node));
  6573. }
  6574. #if defined (SYNCTEX_USE_CHARINDEX)
  6575. synctex_charindex_t synctex_node_charindex(synctex_node_p node) {
  6576. synctex_node_p target = _synctex_tree_target(node);
  6577. return target? SYNCTEX_CHARINDEX(target):(node?SYNCTEX_CHARINDEX(node):0);
  6578. }
  6579. #endif
  6580. /**
  6581. * The tag of the node.
  6582. * - parameter node: a node.
  6583. * - returns: the tag or -1 if node is NULL.
  6584. * - author: JL
  6585. */
  6586. int synctex_node_tag(synctex_node_p node) {
  6587. return node? node->class_->tlcpector->tag(node): -1;
  6588. }
  6589. /**
  6590. * The line of the node.
  6591. * - parameter node: a node.
  6592. * - returns: the line or -1 if node is NULL.
  6593. * - author: JL
  6594. */
  6595. int synctex_node_line(synctex_node_p node) {
  6596. return node? node->class_->tlcpector->line(node): -1;
  6597. }
  6598. /**
  6599. * The column of the node.
  6600. * - parameter node: a node.
  6601. * - returns: the column or -1 if node is NULL.
  6602. * - author: JL
  6603. */
  6604. int synctex_node_column(synctex_node_p node) {
  6605. return node? node->class_->tlcpector->column(node): -1;
  6606. }
  6607. /**
  6608. * The mean line number of the node.
  6609. * - parameter node: a node.
  6610. * - returns: the mean line or -1 if node is NULL.
  6611. * - author: JL
  6612. */
  6613. int synctex_node_mean_line(synctex_node_p node) {
  6614. synctex_node_p other = _synctex_tree_target(node);
  6615. if (other) {
  6616. node = other;
  6617. }
  6618. if (_synctex_data_has_mean_line(node)) {
  6619. return _synctex_data_mean_line(node);
  6620. }
  6621. if ((other = synctex_node_parent(node))) {
  6622. if (_synctex_data_has_mean_line(other)) {
  6623. return _synctex_data_mean_line(other);
  6624. }
  6625. }
  6626. return synctex_node_line(node);
  6627. }
  6628. /**
  6629. * The weight of the node.
  6630. * - parameter node: a node.
  6631. * - returns: the weight or -1 if node is NULL.
  6632. * - author: JL
  6633. */
  6634. int synctex_node_weight(synctex_node_p node) {
  6635. synctex_node_p target = _synctex_tree_target(node);
  6636. if (target) {
  6637. node = target;
  6638. }
  6639. return node?(synctex_node_type(node)==synctex_node_type_hbox?_synctex_data_weight(node):0):-1;
  6640. }
  6641. /**
  6642. * The number of children of the node.
  6643. * - parameter node: a node.
  6644. * - returns: the count or -1 if node is NULL.
  6645. * - author: JL
  6646. */
  6647. int synctex_node_child_count(synctex_node_p node) {
  6648. synctex_node_p target = _synctex_tree_target(node);
  6649. if (target) {
  6650. node = target;
  6651. }
  6652. return node?(synctex_node_type(node)==synctex_node_type_hbox?_synctex_data_weight(node):0):-1;
  6653. }
  6654. # ifdef SYNCTEX_NOTHING
  6655. # pragma mark -
  6656. # pragma mark Sheet & Form
  6657. # endif
  6658. /**
  6659. * The sheet of the scanner with a given page number.
  6660. * - parameter scanner: a scanner.
  6661. * - parameter page: a 1 based page number.
  6662. * If page == 0, returns the first sheet.
  6663. * - returns: a sheet or NULL.
  6664. * - author: JL
  6665. */
  6666. synctex_node_p synctex_sheet(synctex_scanner_p scanner,int page) {
  6667. if (scanner) {
  6668. synctex_node_p sheet = scanner->sheet;
  6669. while(sheet) {
  6670. if (page == _synctex_data_page(sheet)) {
  6671. return sheet;
  6672. }
  6673. sheet = __synctex_tree_sibling(sheet);
  6674. }
  6675. if (page == 0) {
  6676. return scanner->sheet;
  6677. }
  6678. }
  6679. return NULL;
  6680. }
  6681. /**
  6682. * The form of the scanner with a given tag.
  6683. * - parameter scanner: a scanner.
  6684. * - parameter tag: an integer identifier.
  6685. * If tag == 0, returns the first form.
  6686. * - returns: a form.
  6687. * - author: JL
  6688. */
  6689. synctex_node_p synctex_form(synctex_scanner_p scanner,int tag) {
  6690. if (scanner) {
  6691. synctex_node_p form = scanner->form;
  6692. while(form) {
  6693. if (tag == _synctex_data_tag(form)) {
  6694. return form;
  6695. }
  6696. form = __synctex_tree_sibling(form);
  6697. }
  6698. if (tag == 0) {
  6699. return scanner->form;
  6700. }
  6701. }
  6702. return NULL;
  6703. }
  6704. /**
  6705. * The content of the sheet with given page number.
  6706. * - parameter scanner: a scanner.
  6707. * - parameter page: a 1 based page number.
  6708. * - returns: a (vertical) box node.
  6709. * - author: JL
  6710. */
  6711. synctex_node_p synctex_sheet_content(synctex_scanner_p scanner,int page) {
  6712. if (scanner) {
  6713. return _synctex_tree_child(synctex_sheet(scanner,page));
  6714. }
  6715. return NULL;
  6716. }
  6717. /**
  6718. * The content of the sheet with given page number.
  6719. * - parameter scanner: a scanner.
  6720. * - parameter tag: an integer identifier.
  6721. * - returns: a box node.
  6722. * - author: JL
  6723. */
  6724. synctex_node_p synctex_form_content(synctex_scanner_p scanner,int tag) {
  6725. if (scanner) {
  6726. return _synctex_tree_child(synctex_form(scanner,tag));
  6727. }
  6728. return NULL;
  6729. }
  6730. SYNCTEX_INLINE static synctex_node_p _synctex_scanner_friend(synctex_scanner_p scanner,int i) {
  6731. if (i>=0) {
  6732. i = _synctex_abs(i)%(scanner->number_of_lists);
  6733. return (scanner->lists_of_friends)[i];
  6734. }
  6735. return NULL;
  6736. }
  6737. SYNCTEX_INLINE static synctex_bool_t _synctex_nodes_are_friend(synctex_node_p left, synctex_node_p right) {
  6738. return synctex_node_tag(left) == synctex_node_tag(right) && synctex_node_line(left) == synctex_node_line(right);
  6739. }
  6740. /**
  6741. * The sibling argument is a parent/child list of nodes of the same page.
  6742. */
  6743. typedef struct {
  6744. int count;
  6745. synctex_node_p node;
  6746. } synctex_counted_node_s;
  6747. SYNCTEX_INLINE static synctex_counted_node_s _synctex_vertically_sorted_v2(synctex_node_p sibling) {
  6748. /* Clean the weights of the parents */
  6749. synctex_counted_node_s result = {0, NULL};
  6750. synctex_node_p h = NULL;
  6751. synctex_node_p next_h = NULL;
  6752. synctex_node_p parent = NULL;
  6753. int weight = 0;
  6754. synctex_node_p N = NULL;
  6755. h = sibling;
  6756. do {
  6757. N = _synctex_tree_target(h);
  6758. parent = _synctex_tree_parent(N);
  6759. _synctex_data_set_weight(parent, 0);
  6760. } while((h = _synctex_tree_child(h)));
  6761. /* Compute the weights of the nodes */
  6762. h = sibling;
  6763. do {
  6764. N = _synctex_tree_target(h);
  6765. parent = _synctex_tree_parent(N);
  6766. weight = _synctex_data_weight(parent);
  6767. if (weight==0) {
  6768. N = _synctex_tree_child(parent);
  6769. do {
  6770. if (_synctex_nodes_are_friend(N,sibling)) {
  6771. ++ weight;
  6772. }
  6773. } while ((N = __synctex_tree_sibling(N)));
  6774. _synctex_data_set_weight(h,weight);
  6775. _synctex_data_set_weight(parent,weight);
  6776. }
  6777. } while((h = _synctex_tree_child(h)));
  6778. /* Order handle nodes according to the weight */
  6779. h = _synctex_tree_reset_child(sibling);
  6780. result.node = sibling;
  6781. weight = 0;
  6782. while((h)) {
  6783. N = result.node;
  6784. if (_synctex_data_weight(h)>_synctex_data_weight(N)) {
  6785. next_h = _synctex_tree_set_child(h,N);
  6786. result.node = h;
  6787. } else if (_synctex_data_weight(h) == 0) {
  6788. ++ weight;
  6789. next_h = _synctex_tree_reset_child(h);
  6790. synctex_node_free(h);
  6791. } else {
  6792. synctex_node_p next_N = NULL;
  6793. while((next_N = _synctex_tree_child(N))) {
  6794. N = next_N;
  6795. if (_synctex_data_weight(h)<_synctex_data_weight(next_N)) {
  6796. continue;
  6797. }
  6798. break;
  6799. }
  6800. next_h = _synctex_tree_set_child(h,_synctex_tree_set_child(N,h));
  6801. }
  6802. h = next_h;
  6803. };
  6804. h = result.node;
  6805. weight = 0;
  6806. do {
  6807. ++weight;
  6808. } while((h = _synctex_tree_child(h)));
  6809. result.count = 1;
  6810. h = result.node;
  6811. while((next_h = _synctex_tree_child(h))) {
  6812. if (_synctex_data_weight(next_h)==0) {
  6813. _synctex_tree_reset_child(h);
  6814. weight = 1;
  6815. h = next_h;
  6816. while((h = _synctex_tree_child(h))) {
  6817. ++weight;
  6818. }
  6819. synctex_node_free(next_h);
  6820. break;
  6821. }
  6822. ++result.count;
  6823. h = next_h;
  6824. }
  6825. return result;
  6826. }
  6827. SYNCTEX_INLINE static synctex_bool_t _synctex_point_in_box_v2(synctex_point_p hitP, synctex_node_p node);
  6828. /* This struct records distances, the left one is non negative and the right one is non positive.
  6829. * When comparing the locations of 2 different graphical objects on the page, we will have to also record the
  6830. * horizontal distance as signed to keep track of the typesetting order.*/
  6831. typedef struct {
  6832. synctex_node_p node;
  6833. int distance;
  6834. } synctex_nd_s;
  6835. #define SYNCTEX_ND_0 (synctex_nd_s){NULL,INT_MAX}
  6836. typedef synctex_nd_s * synctex_nd_p;
  6837. typedef struct {
  6838. synctex_nd_s l;
  6839. synctex_nd_s r;
  6840. } synctex_nd_lr_s;
  6841. /* The best container is the deeper box that contains the hit point (H,V).
  6842. * _synctex_eq_deepest_container_v2 starts with node whereas
  6843. * _synctex_box_child_deepest starts with node's children, if any
  6844. * if node is not a box, or a void box, NULL is returned.
  6845. * We traverse the node tree in a deep first manner and stop as soon as a result is found. */
  6846. static synctex_node_p _synctex_eq_deepest_container_v2(synctex_point_p hitP, synctex_node_p node);
  6847. SYNCTEX_INLINE static synctex_nd_lr_s _synctex_eq_get_closest_children_in_box_v2(synctex_point_p hitP, synctex_node_p node);
  6848. /* Closest child, recursive. */
  6849. static synctex_nd_s __synctex_closest_deep_child_v2(synctex_point_p hitP, synctex_node_p node);
  6850. /* The smallest container between two has the smallest width or height.
  6851. * This comparison is used when there are 2 overlapping boxes that contain the hit point.
  6852. * For ConTeXt, the problem appears at each page.
  6853. * The chosen box is the one with the smallest height, then the smallest width. */
  6854. SYNCTEX_INLINE static synctex_node_p _synctex_smallest_container_v2(synctex_node_p node, synctex_node_p other_node);
  6855. /* Returns the distance between the hit point hit point=(H,V) and the given node. */
  6856. static int _synctex_point_node_distance_v2(synctex_point_p hitP, synctex_node_p node);
  6857. /* The closest container is the box that is the one closest to the given point.
  6858. * The "visible" version takes into account the visible dimensions instead of the real ones given by TeX. */
  6859. static synctex_nd_s _synctex_eq_closest_child_v2(synctex_point_p hitP, synctex_node_p node);
  6860. # ifdef SYNCTEX_NOTHING
  6861. # pragma mark -
  6862. # pragma mark Queries
  6863. # endif
  6864. /**
  6865. * iterator for a deep first tree traversal.
  6866. */
  6867. struct synctex_iterator_t {
  6868. synctex_node_p seed;
  6869. synctex_node_p top;
  6870. synctex_node_p next;
  6871. int count0;
  6872. int count;
  6873. };
  6874. SYNCTEX_INLINE static synctex_iterator_p _synctex_iterator_new(synctex_node_p result, int count) {
  6875. synctex_iterator_p iterator;
  6876. if ((iterator = _synctex_malloc(sizeof(synctex_iterator_s)))) {
  6877. iterator->seed = iterator->top = iterator->next = result;
  6878. iterator->count0 = iterator->count = count;
  6879. }
  6880. return iterator;
  6881. };
  6882. void synctex_iterator_free(synctex_iterator_p iterator) {
  6883. if (iterator) {
  6884. synctex_node_free(iterator->seed);
  6885. _synctex_free(iterator);
  6886. }
  6887. }
  6888. synctex_bool_t synctex_iterator_has_next(synctex_iterator_p iterator) {
  6889. return iterator?iterator->count>0:0;
  6890. }
  6891. int synctex_iterator_count(synctex_iterator_p iterator) {
  6892. return iterator? iterator->count: 0;
  6893. }
  6894. /**
  6895. * The next result of the iterator.
  6896. * Internally, the iterator stores handles to nodes.
  6897. * Externally, it returns the targets,
  6898. * such that the caller only sees nodes.
  6899. */
  6900. synctex_node_p synctex_iterator_next_result(synctex_iterator_p iterator) {
  6901. if (iterator && iterator->count>0) {
  6902. synctex_node_p N = iterator->next;
  6903. if(!(iterator->next = _synctex_tree_child(N))) {
  6904. iterator->next = iterator->top = __synctex_tree_sibling(iterator->top);
  6905. }
  6906. --iterator->count;
  6907. return _synctex_tree_target(N);
  6908. }
  6909. return NULL;
  6910. }
  6911. int synctex_iterator_reset(synctex_iterator_p iterator) {
  6912. if (iterator) {
  6913. iterator->next = iterator->top = iterator->seed;
  6914. return iterator->count = iterator->count0;
  6915. }
  6916. return 0;
  6917. }
  6918. synctex_iterator_p synctex_iterator_new_edit(synctex_scanner_p scanner,int page,float h,float v){
  6919. if (scanner) {
  6920. synctex_node_p sheet = NULL;
  6921. synctex_point_s hit;
  6922. synctex_node_p node = NULL;
  6923. synctex_nd_lr_s nds = {{NULL,0},{NULL,0}};
  6924. if (NULL == (scanner = synctex_scanner_parse(scanner)) || 0 >= scanner->unit) {/* scanner->unit must be >0 */
  6925. return NULL;
  6926. }
  6927. /* Find the proper sheet */
  6928. sheet = synctex_sheet(scanner,page);
  6929. if (NULL == sheet) {
  6930. return NULL;
  6931. }
  6932. /* Now sheet points to the sheet node with proper page number. */
  6933. /* Now that scanner has been initialized, we can convert
  6934. * the given point to scanner integer coordinates */
  6935. hit = (synctex_point_s)
  6936. {(h-scanner->x_offset)/scanner->unit,
  6937. (v-scanner->y_offset)/scanner->unit};
  6938. /* At first, we browse all the horizontal boxes of the sheet
  6939. * until we find one containing the hit point. */
  6940. if ((node = _synctex_tree_next_hbox(sheet))) {
  6941. do {
  6942. if (_synctex_point_in_box_v2(&hit,node)) {
  6943. /* Maybe the hit point belongs to a contained vertical box.
  6944. * This is the most likely situation.
  6945. */
  6946. synctex_node_p next = node;
  6947. #if defined(SYNCTEX_DEBUG)
  6948. printf("--- We are lucky\n");
  6949. #endif
  6950. /* This trick is for catching overlapping boxes */
  6951. while ((next = _synctex_tree_next_hbox(next))) {
  6952. if (_synctex_point_in_box_v2(&hit,next)) {
  6953. node = _synctex_smallest_container_v2(next,node);
  6954. }
  6955. }
  6956. /* node is the smallest horizontal box that contains hit,
  6957. * unless there is no hbox at all.
  6958. */
  6959. node = _synctex_eq_deepest_container_v2(&hit, node);
  6960. nds = _synctex_eq_get_closest_children_in_box_v2(&hit, node);
  6961. end:
  6962. if (nds.r.node && nds.l.node) {
  6963. if ((_synctex_data_tag(nds.r.node)!=_synctex_data_tag(nds.l.node))
  6964. || (_synctex_data_line(nds.r.node)!=_synctex_data_line(nds.l.node))
  6965. || (_synctex_data_column(nds.r.node)!=_synctex_data_column(nds.l.node))) {
  6966. if (_synctex_data_line(nds.r.node)<_synctex_data_line(nds.l.node)) {
  6967. node = nds.r.node;
  6968. nds.r.node = nds.l.node;
  6969. nds.l.node = node;
  6970. } else if (_synctex_data_line(nds.r.node)==_synctex_data_line(nds.l.node)) {
  6971. if (nds.l.distance>nds.r.distance) {
  6972. node = nds.r.node;
  6973. nds.r.node = nds.l.node;
  6974. nds.l.node = node;
  6975. }
  6976. }
  6977. if((node = _synctex_new_handle_with_target(nds.l.node))) {
  6978. synctex_node_p other_handle;
  6979. if((other_handle = _synctex_new_handle_with_target(nds.r.node))) {
  6980. _synctex_tree_set_sibling(node,other_handle);
  6981. return _synctex_iterator_new(node,2);
  6982. }
  6983. return _synctex_iterator_new(node,1);
  6984. }
  6985. return NULL;
  6986. }
  6987. /* both nodes have the same input coordinates
  6988. * We choose the one closest to the hit point */
  6989. if (nds.l.distance>nds.r.distance) {
  6990. nds.l.node = nds.r.node;
  6991. }
  6992. nds.r.node = NULL;
  6993. } else if (nds.r.node) {
  6994. nds.l = nds.r;
  6995. } else if (!nds.l.node) {
  6996. nds.l.node = node;
  6997. }
  6998. if((node = _synctex_new_handle_with_target(nds.l.node))) {
  6999. return _synctex_iterator_new(node,1);
  7000. }
  7001. return 0;
  7002. }
  7003. } while ((node = _synctex_tree_next_hbox(node)));
  7004. /* All the horizontal boxes have been tested,
  7005. * None of them contains the hit point.
  7006. */
  7007. }
  7008. /* We are not lucky,
  7009. * we test absolutely all the node
  7010. * to find the closest... */
  7011. if ((node = _synctex_tree_child(sheet))) {
  7012. #if defined(SYNCTEX_DEBUG)
  7013. printf("--- We are not lucky\n");
  7014. #endif
  7015. nds.l = __synctex_closest_deep_child_v2(&hit, node);
  7016. #if defined(SYNCTEX_DEBUG)
  7017. printf("Edit query best: %i\n", nds.l.distance);
  7018. #endif
  7019. goto end;
  7020. }
  7021. }
  7022. return NULL;
  7023. }
  7024. /**
  7025. * Loop the candidate friendly list to find the ones with the proper
  7026. * tag and line.
  7027. * Returns a tree of results targeting the found candidates.
  7028. * At the top level each sibling has its own page number.
  7029. * All the results with the same page number are linked by child/parent entry.
  7030. * - parameter candidate: a friendly list of candidates
  7031. */
  7032. static synctex_node_p _synctex_display_query_v2(synctex_node_p target, int tag, int line, synctex_bool_t exclude_box) {
  7033. synctex_node_p first_handle = NULL;
  7034. /* Search the first match */
  7035. if (target == NULL) {
  7036. return first_handle;
  7037. }
  7038. do {
  7039. int page;
  7040. if ((exclude_box
  7041. && _synctex_node_is_box(target))
  7042. || (tag != synctex_node_tag(target))
  7043. || (line != synctex_node_line(target))) {
  7044. continue;
  7045. }
  7046. /* We found a first match, create
  7047. * a result handle targeting that candidate. */
  7048. first_handle = _synctex_new_handle_with_target(target);
  7049. if (first_handle == NULL) {
  7050. return first_handle;
  7051. }
  7052. /* target is either a node,
  7053. * or a proxy to some node, in which case,
  7054. * the target's target belongs to a form,
  7055. * not a sheet. */
  7056. page = synctex_node_page(target);
  7057. /* Now create all the other results */
  7058. while ((target = _synctex_tree_friend(target))) {
  7059. synctex_node_p result = NULL;
  7060. if ((exclude_box
  7061. && _synctex_node_is_box(target))
  7062. || (tag != synctex_node_tag(target))
  7063. || (line != synctex_node_line(target))) {
  7064. continue;
  7065. }
  7066. /* Another match, same page number ? */
  7067. result = _synctex_new_handle_with_target(target);
  7068. if (NULL == result ) {
  7069. return first_handle;
  7070. }
  7071. /* is it the same page number ? */
  7072. if (synctex_node_page(target) == page) {
  7073. __synctex_tree_set_child(result, first_handle);
  7074. first_handle = result;
  7075. } else {
  7076. /* We have 2 page numbers involved */
  7077. __synctex_tree_set_sibling(first_handle, result);
  7078. while ((target = _synctex_tree_friend(target))) {
  7079. synctex_node_p same_page_node;
  7080. if ((exclude_box
  7081. && _synctex_node_is_box(target))
  7082. || (tag != synctex_node_tag(target))
  7083. || (line != synctex_node_line(target))) {
  7084. continue;
  7085. }
  7086. /* New match found, which page? */
  7087. result = _synctex_new_handle_with_target(target);
  7088. if (NULL == result) {
  7089. return first_handle;
  7090. }
  7091. same_page_node = first_handle;
  7092. page = synctex_node_page(target);
  7093. /* Find a result with the same page number */;
  7094. do {
  7095. if (_synctex_node_target_page(same_page_node) == page) {
  7096. /* Insert result between same_page_node and its child */
  7097. _synctex_tree_set_child(result,_synctex_tree_set_child(same_page_node,result));
  7098. } else if ((same_page_node = __synctex_tree_sibling(same_page_node))) {
  7099. continue;
  7100. } else {
  7101. /* This is a new page number */
  7102. __synctex_tree_set_sibling(result,first_handle);
  7103. first_handle = result;
  7104. }
  7105. break;
  7106. } while (synctex_YES);
  7107. }
  7108. return first_handle;
  7109. }
  7110. }
  7111. } while ((target = _synctex_tree_friend(target)));
  7112. return first_handle;
  7113. }
  7114. synctex_iterator_p synctex_iterator_new_display(synctex_scanner_p scanner,const char * name,int line,int column, int page_hint) {
  7115. SYNCTEX_UNUSED(column)
  7116. if (scanner) {
  7117. int tag = synctex_scanner_get_tag(scanner,name);/* parse if necessary */
  7118. int max_line = 0;
  7119. int line_offset = 1;
  7120. int try_count = 100;
  7121. synctex_node_p node = NULL;
  7122. synctex_node_p result = NULL;
  7123. if (tag == 0) {
  7124. printf("SyncTeX Warning: No tag for %s\n",name);
  7125. return NULL;
  7126. }
  7127. node = synctex_scanner_input_with_tag(scanner, tag);
  7128. max_line = _synctex_data_line(node);
  7129. /* node = NULL; */
  7130. if (line>max_line) {
  7131. line = max_line;
  7132. }
  7133. while(try_count--) {
  7134. if (line<=max_line) {
  7135. /* This loop will only be performed once for advanced viewers */
  7136. synctex_node_p friend = _synctex_scanner_friend(scanner,tag+line);
  7137. if ((node = friend)) {
  7138. result = _synctex_display_query_v2(node,tag,line,synctex_YES);
  7139. if (!result) {
  7140. /* We did not find any matching boundary, retry including boxes */
  7141. node = friend;/* no need to test it again, already done */
  7142. result = _synctex_display_query_v2(node,tag,line,synctex_NO);
  7143. }
  7144. /* Now reverse the order to have nodes in display order, and then keep just a few nodes.
  7145. * Order first the best node. */
  7146. /* The result is a tree. At the root level, all nodes
  7147. * correspond to different page numbers.
  7148. * Each node has a child which corresponds to the same
  7149. * page number if relevant.
  7150. * Then reorder the nodes to put first the one which fits best.
  7151. * The idea is to count the number of nodes
  7152. * with the same tag and line number in the parents
  7153. * and choose the ones with the biggest count.
  7154. */
  7155. if (result) {
  7156. /* navigate through siblings, then children */
  7157. synctex_node_p next_sibling = __synctex_tree_reset_sibling(result);
  7158. int best_match = abs(page_hint-_synctex_node_target_page(result));
  7159. synctex_node_p sibling;
  7160. int match;
  7161. synctex_counted_node_s cn = _synctex_vertically_sorted_v2(result);
  7162. int count = cn.count;
  7163. result = cn.node;
  7164. while((sibling = next_sibling)) {
  7165. /* What is next? Do not miss that step! */
  7166. next_sibling = __synctex_tree_reset_sibling(sibling);
  7167. cn = _synctex_vertically_sorted_v2(sibling);
  7168. count += cn.count;
  7169. sibling = cn.node;
  7170. match = abs(page_hint-_synctex_node_target_page(sibling));
  7171. if (match<best_match) {
  7172. /* Order this node first */
  7173. __synctex_tree_set_sibling(sibling,result);
  7174. result = sibling;
  7175. best_match = match;
  7176. } else /*if (match>=best_match)*/ {
  7177. __synctex_tree_set_sibling(sibling,__synctex_tree_sibling(result));
  7178. __synctex_tree_set_sibling(result,sibling);
  7179. }
  7180. }
  7181. return _synctex_iterator_new(result,count);
  7182. }
  7183. }
  7184. # if defined(__SYNCTEX_STRONG_DISPLAY_QUERY__)
  7185. break;
  7186. # else
  7187. line += line_offset;
  7188. line_offset=line_offset<0?-(line_offset-1):-(line_offset+1);
  7189. if (line <= 0) {
  7190. line += line_offset;
  7191. line_offset=line_offset<0?-(line_offset-1):-(line_offset+1);
  7192. }
  7193. # endif
  7194. }
  7195. }
  7196. }
  7197. return NULL;
  7198. }
  7199. synctex_status_t synctex_display_query(synctex_scanner_p scanner,const char * name,int line,int column, int page_hint) {
  7200. if (scanner) {
  7201. synctex_iterator_free(scanner->iterator);
  7202. scanner->iterator = synctex_iterator_new_display(scanner, name,line,column, page_hint);
  7203. return synctex_iterator_count(scanner->iterator);
  7204. }
  7205. return SYNCTEX_STATUS_ERROR;
  7206. }
  7207. synctex_status_t synctex_edit_query(synctex_scanner_p scanner,int page,float h,float v) {
  7208. if (scanner) {
  7209. synctex_iterator_free(scanner->iterator);
  7210. scanner->iterator = synctex_iterator_new_edit(scanner, page, h, v);
  7211. return synctex_iterator_count(scanner->iterator);
  7212. }
  7213. return SYNCTEX_STATUS_ERROR;
  7214. }
  7215. /**
  7216. * The next result of a query.
  7217. */
  7218. synctex_node_p synctex_scanner_next_result(synctex_scanner_p scanner) {
  7219. return scanner? synctex_iterator_next_result(scanner->iterator): NULL;
  7220. }
  7221. synctex_status_t synctex_scanner_reset_result(synctex_scanner_p scanner) {
  7222. return scanner? synctex_iterator_reset(scanner->iterator): SYNCTEX_STATUS_ERROR;
  7223. }
  7224. synctex_node_p synctex_node_target(synctex_node_p node) {
  7225. return _synctex_tree_target(node);
  7226. }
  7227. # ifdef SYNCTEX_NOTHING
  7228. # pragma mark -
  7229. # pragma mark Geometric utilities
  7230. # endif
  7231. /** Rougly speaking, this is:
  7232. * node's h coordinate - hit point's h coordinate.
  7233. * If node is to the right of the hit point, then this distance is positive,
  7234. * if node is to the left of the hit point, this distance is negative.
  7235. * If the argument is a pdf form reference, then the child is used and returned instead.
  7236. * Last Revision: Mon Apr 24 07:05:27 UTC 2017
  7237. */
  7238. static synctex_nd_s _synctex_point_h_ordered_distance_v2
  7239. (synctex_point_p hit, synctex_node_p node) {
  7240. synctex_nd_s nd = {node,INT_MAX};
  7241. if (node) {
  7242. int min,med,max,width;
  7243. switch(synctex_node_type(node)) {
  7244. /* The distance between a point and a box is special.
  7245. * It is not the euclidian distance, nor something similar.
  7246. * We have to take into account the particular layout,
  7247. * and the box hierarchy.
  7248. * Given a box, there are 9 regions delimited by the lines of the edges of the box.
  7249. * The origin being at the top left corner of the page,
  7250. * we also give names to the vertices of the box.
  7251. *
  7252. * 1 | 2 | 3
  7253. * ---A---B--->
  7254. * 4 | 5 | 6
  7255. * ---C---D--->
  7256. * 7 | 8 | 9
  7257. * v v
  7258. */
  7259. case synctex_node_type_vbox:
  7260. case synctex_node_type_void_vbox:
  7261. case synctex_node_type_void_hbox:
  7262. /* getting the box bounds, taking into account negative width, height and depth. */
  7263. width = _synctex_data_width(node);
  7264. min = _synctex_data_h(node);
  7265. max = min + (width>0?width:-width);
  7266. /* We allways have min <= max */
  7267. if (hit->h<min) {
  7268. nd.distance = min - hit->h; /* regions 1+4+7, result is > 0 */
  7269. } else if (hit->h>max) {
  7270. nd.distance = max - hit->h; /* regions 3+6+9, result is < 0 */
  7271. } else {
  7272. nd.distance = 0; /* regions 2+5+8, inside the box, except for vertical coordinates */
  7273. }
  7274. break;
  7275. case synctex_node_type_proxy_vbox:
  7276. /* getting the box bounds, taking into account negative width, height and depth. */
  7277. width = synctex_node_width(node);
  7278. min = synctex_node_h(node);
  7279. max = min + (width>0?width:-width);
  7280. /* We allways have min <= max */
  7281. if (hit->h<min) {
  7282. nd.distance = min - hit->h; /* regions 1+4+7, result is > 0 */
  7283. } else if (hit->h>max) {
  7284. nd.distance = max - hit->h; /* regions 3+6+9, result is < 0 */
  7285. } else {
  7286. nd.distance = 0; /* regions 2+5+8, inside the box, except for vertical coordinates */
  7287. }
  7288. break;
  7289. case synctex_node_type_hbox:
  7290. case synctex_node_type_proxy_hbox:
  7291. /* getting the box bounds, taking into account negative width, height and depth. */
  7292. width = synctex_node_hbox_width(node);
  7293. min = synctex_node_hbox_h(node);
  7294. max = min + (width>0?width:-width);
  7295. /* We allways have min <= max */
  7296. if (hit->h<min) {
  7297. nd.distance = min - hit->h; /* regions 1+4+7, result is > 0 */
  7298. } else if (hit->h>max) {
  7299. nd.distance = max - hit->h; /* regions 3+6+9, result is < 0 */
  7300. } else {
  7301. nd.distance = 0; /* regions 2+5+8, inside the box, except for vertical coordinates */
  7302. }
  7303. break;
  7304. case synctex_node_type_kern:
  7305. /* IMPORTANT NOTICE: the location of the kern is recorded AFTER the move.
  7306. * The distance to the kern is very special,
  7307. * in general, there is no text material in the kern,
  7308. * this is why we compute the offset relative to the closest edge of the kern.*/
  7309. max = _synctex_data_width(node);
  7310. if (max<0) {
  7311. min = _synctex_data_h(node);
  7312. max = min - max;
  7313. } else {
  7314. min = -max;
  7315. max = _synctex_data_h(node);
  7316. min += max;
  7317. }
  7318. med = (min+max)/2;
  7319. /* positive kern: '.' means text, '>' means kern offset
  7320. * .............
  7321. * min>>>>med>>>>max
  7322. * ...............
  7323. * negative kern: '.' means text, '<' means kern offset
  7324. * ............................
  7325. * min<<<<med<<<<max
  7326. * .................................
  7327. * Actually, we do not take into account negative widths.
  7328. * There is a problem for such situation when there is effectively overlapping text.
  7329. * But this should be extremely rare. I guess that in that case, many different choices
  7330. * could be made, one being in contradiction with the other.
  7331. * It means that the best choice should be made according to the situation that occurs
  7332. * most frequently.
  7333. */
  7334. if (hit->h<min) {
  7335. nd.distance = min - hit->h + 1; /* penalty to ensure other nodes are chosen first in case of overlapping ones */
  7336. } else if (hit->h>max) {
  7337. nd.distance = max - hit->h - 1; /* same kind of penalty */
  7338. } else if (hit->h>med) {
  7339. /* do things like if the node had 0 width and was placed at the max edge + 1*/
  7340. nd.distance = max - hit->h + 1; /* positive, the kern is to the right of the hit point */
  7341. } else {
  7342. nd.distance = min - hit->h - 1; /* negative, the kern is to the left of the hit point */
  7343. }
  7344. break;
  7345. case synctex_node_type_rule:/* to do: special management */
  7346. case synctex_node_type_glue:
  7347. case synctex_node_type_math:
  7348. case synctex_node_type_boundary:
  7349. case synctex_node_type_box_bdry:
  7350. nd.distance = _synctex_data_h(node) - hit->h;
  7351. break;
  7352. case synctex_node_type_ref:
  7353. nd.node = synctex_node_child(node);
  7354. nd = _synctex_point_h_ordered_distance_v2(hit,nd.node);
  7355. break;
  7356. case synctex_node_type_proxy:
  7357. case synctex_node_type_proxy_last:
  7358. {
  7359. /* shift the hit point to be relative to the proxy origin,
  7360. * then compute the distance to the target
  7361. */
  7362. synctex_point_s otherHit = *hit;
  7363. otherHit.h -= _synctex_data_h(node);
  7364. otherHit.v -= _synctex_data_v(node);
  7365. nd.node = _synctex_tree_target(node);
  7366. nd = _synctex_point_h_ordered_distance_v2(&otherHit,nd.node);
  7367. nd.node = node;
  7368. }
  7369. default:
  7370. break;
  7371. }
  7372. }
  7373. return nd;
  7374. }
  7375. /** Rougly speaking, this is:
  7376. * node's v coordinate - hit point's v coordinate.
  7377. * If node is at the top of the hit point, then this distance is positive,
  7378. * if node is at the bottom of the hit point, this distance is negative.
  7379. */
  7380. static synctex_nd_s _synctex_point_v_ordered_distance_v2
  7381. (synctex_point_p hit, synctex_node_p node) {
  7382. synctex_nd_s nd = {node, INT_MAX};
  7383. int min,max,depth,height;
  7384. switch(synctex_node_type(node)) {
  7385. /* The distance between a point and a box is special.
  7386. * It is not the euclidian distance, nor something similar.
  7387. * We have to take into account the particular layout,
  7388. * and the box hierarchy.
  7389. * Given a box, there are 9 regions delimited by the lines of the edges of the box.
  7390. * The origin being at the top left corner of the page,
  7391. * we also give names to the vertices of the box.
  7392. *
  7393. * 1 | 2 | 3
  7394. * ---A---B--->
  7395. * 4 | 5 | 6
  7396. * ---C---D--->
  7397. * 7 | 8 | 9
  7398. * v v
  7399. */
  7400. case synctex_node_type_vbox:
  7401. case synctex_node_type_void_vbox:
  7402. case synctex_node_type_void_hbox:
  7403. /* getting the box bounds, taking into account negative width, height and depth. */
  7404. min = synctex_node_v(node);
  7405. max = min + _synctex_abs(_synctex_data_depth(node));
  7406. min -= _synctex_abs(_synctex_data_height(node));
  7407. /* We allways have min <= max */
  7408. if (hit->v<min) {
  7409. nd.distance = min - hit->v; /* regions 1+2+3, result is > 0 */
  7410. } else if (hit->v>max) {
  7411. nd.distance = max - hit->v; /* regions 7+8+9, result is < 0 */
  7412. } else {
  7413. nd.distance = 0; /* regions 4.5.6, inside the box, except for horizontal coordinates */
  7414. }
  7415. break;
  7416. case synctex_node_type_proxy_vbox:
  7417. /* getting the box bounds, taking into account negative width, height and depth. */
  7418. min = synctex_node_v(node);
  7419. max = min + _synctex_abs(synctex_node_depth(node));
  7420. min -= _synctex_abs(synctex_node_height(node));
  7421. /* We allways have min <= max */
  7422. if (hit->v<min) {
  7423. nd.distance = min - hit->v; /* regions 1+2+3, result is > 0 */
  7424. } else if (hit->v>max) {
  7425. nd.distance = max - hit->v; /* regions 7+8+9, result is < 0 */
  7426. } else {
  7427. nd.distance = 0; /* regions 4.5.6, inside the box, except for horizontal coordinates */
  7428. }
  7429. break;
  7430. case synctex_node_type_hbox:
  7431. case synctex_node_type_proxy_hbox:
  7432. /* getting the box bounds, taking into account negative height and depth. */
  7433. min = synctex_node_hbox_v(node);
  7434. depth = synctex_node_hbox_depth(node);
  7435. max = min + (depth>0?depth:-depth);
  7436. height = synctex_node_hbox_height(node);
  7437. min -= (height>0?height:-height);
  7438. /* We allways have min <= max */
  7439. if (hit->v<min) {
  7440. nd.distance = min - hit->v; /* regions 1+2+3, result is > 0 */
  7441. } else if (hit->v>max) {
  7442. nd.distance = max - hit->v; /* regions 7+8+9, result is < 0 */
  7443. } else {
  7444. nd.distance = 0; /* regions 4.5.6, inside the box, except for horizontal coordinates */
  7445. }
  7446. break;
  7447. case synctex_node_type_rule:/* to do: special management */
  7448. case synctex_node_type_kern:
  7449. case synctex_node_type_glue:
  7450. case synctex_node_type_math:
  7451. min = _synctex_data_v(node);
  7452. max = min + _synctex_abs(_synctex_data_depth(_synctex_tree_parent(node)));
  7453. min -= _synctex_abs(_synctex_data_height(_synctex_tree_parent(node)));
  7454. /* We allways have min <= max */
  7455. if (hit->v<min) {
  7456. nd.distance = min - hit->v; /* regions 1+2+3, result is > 0 */
  7457. } else if (hit->v>max) {
  7458. nd.distance = max - hit->v; /* regions 7+8+9, result is < 0 */
  7459. } else {
  7460. nd.distance = 0; /* regions 4.5.6, inside the box, except for horizontal coordinates */
  7461. }
  7462. break;
  7463. case synctex_node_type_ref:
  7464. nd.node = synctex_node_child(node);
  7465. nd = _synctex_point_v_ordered_distance_v2(hit,nd.node);
  7466. break;
  7467. case synctex_node_type_proxy:
  7468. case synctex_node_type_proxy_last:
  7469. {
  7470. synctex_point_s otherHit = *hit;
  7471. otherHit.h -= _synctex_data_h(node);
  7472. otherHit.v -= _synctex_data_v(node);
  7473. nd.node = _synctex_tree_target(node);
  7474. nd = _synctex_point_v_ordered_distance_v2(&otherHit,nd.node);
  7475. nd.node = node;
  7476. }
  7477. default: break;
  7478. }
  7479. return nd;
  7480. }
  7481. /**
  7482. * The best is the one with the smallest area.
  7483. * The area is width*height where width and height may be big.
  7484. * So there is a real risk of overflow if we stick with ints.
  7485. */
  7486. SYNCTEX_INLINE static synctex_node_p _synctex_smallest_container_v2(synctex_node_p node, synctex_node_p other_node) {
  7487. long total_height, other_total_height;
  7488. unsigned long area, other_area;
  7489. long width = synctex_node_hbox_width(node);
  7490. long other_width = synctex_node_hbox_width(other_node);
  7491. if (width<0) {
  7492. width = -width;
  7493. }
  7494. if (other_width<0) {
  7495. other_width = -other_width;
  7496. }
  7497. total_height = _synctex_abs(synctex_node_hbox_depth(node)) + _synctex_abs(synctex_node_hbox_height(node));
  7498. other_total_height = _synctex_abs(synctex_node_hbox_depth(other_node)) + _synctex_abs(synctex_node_hbox_height(other_node));
  7499. area = total_height*width;
  7500. other_area = other_total_height*other_width;
  7501. if (area<other_area) {
  7502. return node;
  7503. }
  7504. if (area>other_area) {
  7505. return other_node;
  7506. }
  7507. if (_synctex_abs(_synctex_data_width(node))>_synctex_abs(_synctex_data_width(other_node))) {
  7508. return node;
  7509. }
  7510. if (_synctex_abs(_synctex_data_width(node))<_synctex_abs(_synctex_data_width(other_node))) {
  7511. return other_node;
  7512. }
  7513. if (total_height<other_total_height) {
  7514. return node;
  7515. }
  7516. if (total_height>other_total_height) {
  7517. return other_node;
  7518. }
  7519. return node;
  7520. }
  7521. SYNCTEX_INLINE static synctex_bool_t _synctex_point_in_box_v2(synctex_point_p hit, synctex_node_p node) {
  7522. if (node) {
  7523. if (0 == _synctex_point_h_ordered_distance_v2(hit,node).distance
  7524. && 0 == _synctex_point_v_ordered_distance_v2(hit,node).distance) {
  7525. return synctex_YES;
  7526. }
  7527. }
  7528. return synctex_NO;
  7529. }
  7530. static int _synctex_distance_to_box_v2(synctex_point_p hit,synctex_box_p box) {
  7531. /* The distance between a point and a box is special.
  7532. * It is not the euclidian distance, nor something similar.
  7533. * We have to take into account the particular layout,
  7534. * and the box hierarchy.
  7535. * Given a box, there are 9 regions delimited by the lines of the edges of the box.
  7536. * The origin being at the top left corner of the page,
  7537. * we also give names to the vertices of the box.
  7538. *
  7539. * 1 | 2 | 3
  7540. * ---A---B--->
  7541. * 4 | 5 | 6
  7542. * ---C---D--->
  7543. * 7 | 8 | 9
  7544. * v v
  7545. * In each region, there is a different formula.
  7546. * In the end we have a continuous distance which may not be a mathematical distance but who cares. */
  7547. if (hit->v<box->min.v) {
  7548. /* Regions 1, 2 or 3 */
  7549. if (hit->h<box->min.h) {
  7550. /* This is region 1. The distance to the box is the L1 distance PA. */
  7551. return box->min.v - hit->v + box->min.h - hit->h;/* Integer overflow? probability epsilon */
  7552. } else if (hit->h<=box->max.h) {
  7553. /* This is region 2. The distance to the box is the geometrical distance to the top edge. */
  7554. return box->min.v - hit->v;
  7555. } else {
  7556. /* This is region 3. The distance to the box is the L1 distance PB. */
  7557. return box->min.v - hit->v + hit->h - box->max.h;
  7558. }
  7559. } else if (hit->v<=box->max.v) {
  7560. /* Regions 4, 5 or 6 */
  7561. if (hit->h<box->min.h) {
  7562. /* This is region 4. The distance to the box is the geometrical distance to the left edge. */
  7563. return box->min.h - hit->h;
  7564. } else if (hit->h<=box->max.h) {
  7565. /* This is region 5. We are inside the box. */
  7566. return 0;
  7567. } else {
  7568. /* This is region 6. The distance to the box is the geometrical distance to the right edge. */
  7569. return hit->h - box->max.h;
  7570. }
  7571. } else {
  7572. /* Regions 7, 8 or 9 */
  7573. if (hit->h<box->min.h) {
  7574. /* This is region 7. The distance to the box is the L1 distance PC. */
  7575. return hit->v - box->max.v + box->min.h - hit->h;
  7576. } else if (hit->h<=box->max.h) {
  7577. /* This is region 8. The distance to the box is the geometrical distance to the top edge. */
  7578. return hit->v - box->max.v;
  7579. } else {
  7580. /* This is region 9. The distance to the box is the L1 distance PD. */
  7581. return hit->v - box->max.v + hit->h - box->max.h;
  7582. }
  7583. }
  7584. }
  7585. /**
  7586. * The distance from the hit point to the node.
  7587. */
  7588. static int _synctex_point_node_distance_v2(synctex_point_p hit, synctex_node_p node) {
  7589. int d = INT_MAX;
  7590. if (node) {
  7591. synctex_box_s box = {{0,0},{0,0}};
  7592. int dd = INT_MAX;
  7593. switch(synctex_node_type(node)) {
  7594. case synctex_node_type_vbox:
  7595. box.min.h = _synctex_data_h(node);
  7596. box.max.h = box.min.h + _synctex_abs(_synctex_data_width(node));
  7597. box.min.v = synctex_node_v(node);
  7598. box.max.v = box.min.v + _synctex_abs(_synctex_data_depth(node));
  7599. box.min.v -= _synctex_abs(_synctex_data_height(node));
  7600. return _synctex_distance_to_box_v2(hit,&box);
  7601. case synctex_node_type_proxy_vbox:
  7602. box.min.h = synctex_node_h(node);
  7603. box.max.h = box.min.h + _synctex_abs(synctex_node_width(node));
  7604. box.min.v = synctex_node_v(node);
  7605. box.max.v = box.min.v + _synctex_abs(synctex_node_depth(node));
  7606. box.min.v -= _synctex_abs(synctex_node_height(node));
  7607. return _synctex_distance_to_box_v2(hit,&box);
  7608. case synctex_node_type_hbox:
  7609. case synctex_node_type_proxy_hbox:
  7610. box.min.h = synctex_node_hbox_h(node);
  7611. box.max.h = box.min.h + _synctex_abs(synctex_node_hbox_width(node));
  7612. box.min.v = synctex_node_hbox_v(node);
  7613. box.max.v = box.min.v + _synctex_abs(synctex_node_hbox_depth(node));
  7614. box.min.v -= _synctex_abs(synctex_node_hbox_height(node));
  7615. return _synctex_distance_to_box_v2(hit,&box);
  7616. case synctex_node_type_void_vbox:
  7617. case synctex_node_type_void_hbox:
  7618. /* best of distances from the left edge and right edge*/
  7619. box.min.h = _synctex_data_h(node);
  7620. box.max.h = box.min.h;
  7621. box.min.v = _synctex_data_v(node);
  7622. box.max.v = box.min.v + _synctex_abs(_synctex_data_depth(node));
  7623. box.min.v -= _synctex_abs(_synctex_data_height(node));
  7624. d = _synctex_distance_to_box_v2(hit,&box);
  7625. box.min.h = box.min.h + _synctex_abs(_synctex_data_width(node));
  7626. box.max.h = box.min.h;
  7627. dd = _synctex_distance_to_box_v2(hit,&box);
  7628. return d<dd ? d:dd;
  7629. case synctex_node_type_kern:
  7630. box.min.h = _synctex_data_h(node);
  7631. box.max.h = box.min.h;
  7632. box.max.v = _synctex_data_v(node);
  7633. box.min.v = box.max.v - _synctex_abs(_synctex_data_height(_synctex_tree_parent(node)));
  7634. d = _synctex_distance_to_box_v2(hit,&box);
  7635. box.min.h -= _synctex_data_width(node);
  7636. box.max.h = box.min.h;
  7637. dd = _synctex_distance_to_box_v2(hit,&box);
  7638. return d<dd ? d:dd;
  7639. case synctex_node_type_glue:
  7640. case synctex_node_type_math:
  7641. case synctex_node_type_boundary:
  7642. case synctex_node_type_box_bdry:
  7643. box.min.h = _synctex_data_h(node);
  7644. box.max.h = box.min.h;
  7645. box.max.v = _synctex_data_v(node);
  7646. box.min.v = box.max.v - _synctex_abs(_synctex_data_height(_synctex_tree_parent(node)));
  7647. return _synctex_distance_to_box_v2(hit,&box);
  7648. case synctex_node_type_proxy:
  7649. case synctex_node_type_proxy_last:
  7650. {
  7651. synctex_point_s otherHit = *hit;
  7652. otherHit.h -= _synctex_data_h(node);
  7653. otherHit.v -= _synctex_data_v(node);
  7654. return _synctex_point_node_distance_v2(&otherHit, _synctex_tree_target(node));
  7655. }
  7656. default: break;
  7657. }
  7658. }
  7659. return d;
  7660. }
  7661. static synctex_node_p _synctex_eq_deepest_container_v2(synctex_point_p hit, synctex_node_p node) {
  7662. if (node) {
  7663. /**/
  7664. synctex_node_p child;
  7665. if ((child = synctex_node_child(node))) {
  7666. /* Non void hbox or vbox, form ref or proxy */
  7667. /* We go deep first because some boxes have 0 dimensions
  7668. * despite they do contain some black material.
  7669. */
  7670. do {
  7671. if ((_synctex_point_in_box_v2(hit,child))) {
  7672. synctex_node_p deep = _synctex_eq_deepest_container_v2(hit,child);
  7673. if (deep) {
  7674. /* One of the children contains the hit. */
  7675. return deep;
  7676. }
  7677. }
  7678. } while((child = synctex_node_sibling(child)));
  7679. /* is the hit point inside the box? */
  7680. if (synctex_node_type(node) == synctex_node_type_vbox
  7681. || synctex_node_type(node) == synctex_node_type_proxy_vbox) {
  7682. /* For vboxes we try to use some node inside.
  7683. * Walk through the list of siblings until we find the closest one.
  7684. * Only consider siblings with children inside. */
  7685. if ((child = _synctex_tree_child(node))) {
  7686. synctex_nd_s best = SYNCTEX_ND_0;
  7687. do {
  7688. if (_synctex_tree_child(child)) {
  7689. int d = _synctex_point_node_distance_v2(hit,child);
  7690. if (d <= best.distance) {
  7691. best = (synctex_nd_s){child, d};
  7692. }
  7693. }
  7694. } while((child = __synctex_tree_sibling(child)));
  7695. if (best.node) {
  7696. return best.node;
  7697. }
  7698. }
  7699. }
  7700. if (_synctex_point_in_box_v2(hit,node)) {
  7701. return node;
  7702. }
  7703. }
  7704. }
  7705. return NULL;
  7706. }
  7707. static synctex_nd_s _synctex_eq_deepest_container_v3(synctex_point_p hit, synctex_node_p node) {
  7708. if (node) {
  7709. synctex_node_p child = NULL;
  7710. if ((child = synctex_node_child(node))) {
  7711. /* Non void hbox, vbox, box proxy or form ref */
  7712. /* We go deep first because some boxes have 0 dimensions
  7713. * despite they do contain some black material.
  7714. */
  7715. do {
  7716. synctex_nd_s deep = _synctex_eq_deepest_container_v3(hit, child);
  7717. if (deep.node) {
  7718. /* One of the children contains the hit-> */
  7719. return deep;
  7720. }
  7721. } while((child = synctex_node_sibling(child)));
  7722. /* For vboxes we try to use some node inside.
  7723. * Walk through the list of siblings until we find the closest one.
  7724. * Only consider siblings with children inside. */
  7725. if (synctex_node_type(node) == synctex_node_type_vbox
  7726. || synctex_node_type(node) == synctex_node_type_proxy_vbox) {
  7727. if ((child = synctex_node_child(node))) {
  7728. synctex_nd_s best = SYNCTEX_ND_0;
  7729. do {
  7730. if (synctex_node_child(child)) {
  7731. int d = _synctex_point_node_distance_v2(hit,child);
  7732. if (d < best.distance) {
  7733. best = (synctex_nd_s){child,d};
  7734. }
  7735. }
  7736. } while((child = synctex_node_sibling(child)));
  7737. if (best.node) {
  7738. return best;
  7739. }
  7740. }
  7741. }
  7742. /* is the hit point inside the box? */
  7743. if (_synctex_point_in_box_v2(hit,node)) {
  7744. return (synctex_nd_s){node, 0};
  7745. }
  7746. }
  7747. }
  7748. return SYNCTEX_ND_0;
  7749. }
  7750. /* Compares the locations of the hit point with the locations of
  7751. * the various nodes contained in the box.
  7752. * As it is an horizontal box, we only compare horizontal coordinates.
  7753. */
  7754. SYNCTEX_INLINE static synctex_nd_lr_s __synctex_eq_get_closest_children_in_hbox_v2(synctex_point_p hitP, synctex_node_p node) {
  7755. synctex_nd_s childd = SYNCTEX_ND_0;
  7756. synctex_nd_lr_s nds = {SYNCTEX_ND_0,SYNCTEX_ND_0};
  7757. if ((childd.node = synctex_node_child(node))) {
  7758. synctex_nd_s nd = SYNCTEX_ND_0;
  7759. do {
  7760. childd = _synctex_point_h_ordered_distance_v2(hitP,childd.node);
  7761. if (childd.distance > 0) {
  7762. /* node is to the right of the hit point.
  7763. * We compare node and the previously recorded one, through the recorded distance.
  7764. * If the nodes have the same tag, prefer the one with the smallest line number,
  7765. * if the nodes also have the same line number, prefer the one with the smallest column. */
  7766. if (nds.r.distance > childd.distance) {
  7767. nds.r = childd;
  7768. } else if (nds.r.distance == childd.distance && nds.r.node) {
  7769. if (_synctex_data_tag(nds.r.node) == _synctex_data_tag(childd.node)
  7770. && (_synctex_data_line(nds.r.node) > _synctex_data_line(childd.node)
  7771. || (_synctex_data_line(nds.r.node) == _synctex_data_line(childd.node)
  7772. && _synctex_data_column(nds.r.node) > _synctex_data_column(childd.node)))) {
  7773. nds.r = childd;
  7774. }
  7775. }
  7776. } else if (childd.distance == 0) {
  7777. /* hit point is inside node. */
  7778. if (_synctex_tree_child(childd.node)) {
  7779. return _synctex_eq_get_closest_children_in_box_v2(hitP, childd.node);
  7780. }
  7781. nds.l = childd;
  7782. } else { /* here childd.distance < 0, the hit point is to the right of node */
  7783. childd.distance = -childd.distance;
  7784. if (nds.l.distance > childd.distance) {
  7785. nds.l = childd;
  7786. } else if (nds.l.distance == childd.distance && nds.l.node) {
  7787. if (_synctex_data_tag(nds.l.node) == _synctex_data_tag(childd.node)
  7788. && (_synctex_data_line(nds.l.node) > _synctex_data_line(childd.node)
  7789. || (_synctex_data_line(nds.l.node) == _synctex_data_line(childd.node)
  7790. && _synctex_data_column(nds.l.node) > _synctex_data_column(childd.node)))) {
  7791. nds.l = childd;
  7792. }
  7793. }
  7794. }
  7795. } while((childd.node = synctex_node_sibling(childd.node)));
  7796. if (nds.l.node) {
  7797. /* the left node is new, try to narrow the result */
  7798. if ((nd = _synctex_eq_deepest_container_v3(hitP,nds.l.node)).node) {
  7799. nds.l = nd;
  7800. }
  7801. if((nd = __synctex_closest_deep_child_v2(hitP,nds.l.node)).node) {
  7802. nds.l.node = nd.node;
  7803. }
  7804. }
  7805. if (nds.r.node) {
  7806. /* the right node is new, try to narrow the result */
  7807. if ((nd = _synctex_eq_deepest_container_v3(hitP,nds.r.node)).node) {
  7808. nds.r = nd;
  7809. }
  7810. if((nd = __synctex_closest_deep_child_v2(hitP,nds.r.node)).node) {
  7811. nds.r.node = nd.node;
  7812. }
  7813. }
  7814. }
  7815. return nds;
  7816. }
  7817. #if 0
  7818. SYNCTEX_INLINE static synctex_nd_lr_s __synctex_eq_get_closest_children_in_hbox_v3(synctex_point_p hitP, synctex_node_p nodeP) {
  7819. synctex_nd_s nd = SYNCTEX_ND_0;
  7820. synctex_nd_lr_s nds = {SYNCTEX_ND_0,SYNCTEX_ND_0};
  7821. if ((nd.node = _synctex_tree_child(nodeP))) {
  7822. do {
  7823. nd = _synctex_point_h_ordered_distance_v2(hitP,nd.node);
  7824. if (nd.distance > 0) {
  7825. /* node is to the right of the hit point.
  7826. * We compare node and the previously recorded one, through the recorded distance.
  7827. * If the nodes have the same tag, prefer the one with the smallest line number,
  7828. * if the nodes also have the same line number, prefer the one with the smallest column. */
  7829. if (nds.r.distance > nd.distance) {
  7830. nds.r = nd;
  7831. } else if (nds.r.distance == nd.distance && nds.r.node) {
  7832. if (_synctex_data_tag(nds.r.node) == _synctex_data_tag(nd.node)
  7833. && (_synctex_data_line(nds.r.node) > _synctex_data_line(nd.node)
  7834. || (_synctex_data_line(nds.r.node) == _synctex_data_line(nd.node)
  7835. && _synctex_data_column(nds.r.node) > _synctex_data_column(nd.node)))) {
  7836. nds.r = nd;
  7837. }
  7838. }
  7839. } else if (nd.distance == 0) {
  7840. /* hit point is inside node. */
  7841. nds.l = nd;
  7842. } else { /* here nd.d < 0, the hit point is to the right of node */
  7843. nd.distance = -nd.distance;
  7844. if (nds.l.distance > nd.distance) {
  7845. nds.l = nd;
  7846. } else if (nds.l.distance == nd.distance && nds.l.node) {
  7847. if (_synctex_data_tag(nds.l.node) == _synctex_data_tag(nd.node)
  7848. && (_synctex_data_line(nds.l.node) > _synctex_data_line(nd.node)
  7849. || (_synctex_data_line(nds.l.node) == _synctex_data_line(nd.node)
  7850. && _synctex_data_column(nds.l.node) > _synctex_data_column(nd.node)))) {
  7851. nds.l = nd;
  7852. }
  7853. }
  7854. }
  7855. } while((nd.node = __synctex_tree_sibling(nd.node)));
  7856. if (nds.l.node) {
  7857. /* the left node is new, try to narrow the result */
  7858. if ((nd.node = _synctex_eq_deepest_container_v2(hitP,nds.l.node))) {
  7859. nds.l.node = nd.node;
  7860. }
  7861. if((nd = _synctex_eq_closest_child_v2(hitP,nds.l.node)).node) {
  7862. nds.l.node = nd.node;
  7863. }
  7864. }
  7865. if (nds.r.node) {
  7866. /* the right node is new, try to narrow the result */
  7867. if ((nd.node = _synctex_eq_deepest_container_v2(hitP,nds.r.node))) {
  7868. nds.r.node = nd.node;
  7869. }
  7870. if((nd = _synctex_eq_closest_child_v2(hitP,nds.r.node)).node) {
  7871. nds.r.node = nd.node;
  7872. }
  7873. }
  7874. }
  7875. return nds;
  7876. }
  7877. #endif
  7878. SYNCTEX_INLINE static synctex_nd_lr_s __synctex_eq_get_closest_children_in_vbox_v2(synctex_point_p hitP, synctex_node_p nodeP) {
  7879. SYNCTEX_UNUSED(nodeP)
  7880. synctex_nd_lr_s nds = {SYNCTEX_ND_0,SYNCTEX_ND_0};
  7881. synctex_nd_s nd = SYNCTEX_ND_0;
  7882. if ((nd.node = synctex_node_child(nd.node))) {
  7883. do {
  7884. nd = _synctex_point_v_ordered_distance_v2(hitP,nd.node);
  7885. /* this is what makes the difference with the h version above */
  7886. if (nd.distance > 0) {
  7887. /* node is to the top of the hit point (below because TeX is oriented from top to bottom.
  7888. * We compare node and the previously recorded one, through the recorded distance.
  7889. * If the nodes have the same tag, prefer the one with the smallest line number,
  7890. * if the nodes also have the same line number, prefer the one with the smallest column. */
  7891. if (nds.r.distance > nd.distance) {
  7892. nds.r = nd;
  7893. } else if (nds.r.distance == nd.distance && nds.r.node) {
  7894. if (_synctex_data_tag(nds.r.node) == _synctex_data_tag(nd.node)
  7895. && (_synctex_data_line(nds.r.node) > _synctex_data_line(nd.node)
  7896. || (_synctex_data_line(nds.r.node) == _synctex_data_line(nd.node)
  7897. && _synctex_data_column(nds.r.node) > _synctex_data_column(nd.node)))) {
  7898. nds.r = nd;
  7899. }
  7900. }
  7901. } else if (nd.distance == 0) {
  7902. nds.l = nd;
  7903. } else { /* here nd < 0 */
  7904. nd.distance = -nd.distance;
  7905. if (nds.l.distance > nd.distance) {
  7906. nds.l = nd;
  7907. } else if (nds.l.distance == nd.distance && nds.l.node) {
  7908. if (_synctex_data_tag(nds.l.node) == _synctex_data_tag(nd.node)
  7909. && (_synctex_data_line(nds.l.node) > _synctex_data_line(nd.node)
  7910. || (_synctex_data_line(nds.l.node) == _synctex_data_line(nd.node)
  7911. && _synctex_data_column(nds.l.node) > _synctex_data_column(nd.node)))) {
  7912. nds.l = nd;
  7913. }
  7914. }
  7915. }
  7916. } while((nd.node = synctex_node_sibling(nd.node)));
  7917. if (nds.l.node) {
  7918. if ((nd.node = _synctex_eq_deepest_container_v2(hitP,nds.l.node))) {
  7919. nds.l.node = nd.node;
  7920. }
  7921. if((nd = _synctex_eq_closest_child_v2(hitP,nds.l.node)).node) {
  7922. nds.l.node = nd.node;
  7923. }
  7924. }
  7925. if (nds.r.node) {
  7926. if ((nd.node = _synctex_eq_deepest_container_v2(hitP,nds.r.node))) {
  7927. nds.r.node = nd.node;
  7928. }
  7929. if((nd = _synctex_eq_closest_child_v2(hitP,nds.r.node)).node) {
  7930. nds.r.node = nd.node;
  7931. }
  7932. }
  7933. }
  7934. return nds;
  7935. }
  7936. /**
  7937. * Get the child closest to the hit point.
  7938. * - parameter: hit point
  7939. * - parameter: containing node
  7940. * - returns: the child and the distance to the hit point.
  7941. * SYNCTEX_ND_0 if the parameter node has no children.
  7942. * - note: recursive call.
  7943. */
  7944. static synctex_nd_s __synctex_closest_deep_child_v2(synctex_point_p hitP, synctex_node_p node) {
  7945. synctex_nd_s best = SYNCTEX_ND_0;
  7946. synctex_node_p child = NULL;
  7947. if ((child = synctex_node_child(node))) {
  7948. #if defined(SYNCTEX_DEBUG)
  7949. printf("Closest deep child on box at line %i\n",
  7950. SYNCTEX_LINEINDEX(node));
  7951. #endif
  7952. do {
  7953. #if SYNCTEX_DEBUG>500
  7954. synctex_node_display(child);
  7955. #endif
  7956. synctex_nd_s nd = SYNCTEX_ND_0;
  7957. if (_synctex_node_is_box(child)) {
  7958. nd = __synctex_closest_deep_child_v2(hitP,child);
  7959. } else {
  7960. nd = (synctex_nd_s) {child, _synctex_point_node_distance_v2(hitP,child)};
  7961. }
  7962. if (nd.distance < best.distance ||(nd.distance == best.distance
  7963. && synctex_node_type(nd.node) != synctex_node_type_kern)) {
  7964. #if defined(SYNCTEX_DEBUG)
  7965. if(nd.node) {
  7966. printf("New best %i<=%i line %i\n",nd.distance,
  7967. best.distance,SYNCTEX_LINEINDEX(nd.node));
  7968. }
  7969. #endif
  7970. best = nd;
  7971. }
  7972. } while((child = synctex_node_sibling(child)));
  7973. #if defined(SYNCTEX_DEBUG)
  7974. if(best.node) {
  7975. printf("Found new best %i line %i\n",best.distance,SYNCTEX_LINEINDEX(best.node));
  7976. }
  7977. #endif
  7978. }
  7979. return best;
  7980. }
  7981. /**
  7982. * Return the closest child.
  7983. * - parameter: a pointer to the hit point,
  7984. * - parameter: the container
  7985. * - return: SYNCTEX_ND_0 if node has no child,
  7986. * the __synctex_closest_deep_child_v2 otherwise.
  7987. */
  7988. static synctex_nd_s _synctex_eq_closest_child_v2(synctex_point_p hitP, synctex_node_p node) {
  7989. synctex_nd_s nd = SYNCTEX_ND_0;
  7990. if (_synctex_node_is_box(node)) {
  7991. nd = __synctex_closest_deep_child_v2(hitP, node);
  7992. if (_synctex_node_is_box(nd.node)) {
  7993. synctex_node_p child = NULL;
  7994. if ((child = synctex_node_child(nd.node))) {
  7995. synctex_nd_s best = {child,_synctex_point_node_distance_v2(hitP,child)};
  7996. while((child = synctex_node_sibling(child))) {
  7997. int d = _synctex_point_node_distance_v2(hitP,child);
  7998. if (d < best.distance) {
  7999. best = (synctex_nd_s){child,d};
  8000. } else if (d == best.distance && synctex_node_type(child) != synctex_node_type_kern) {
  8001. best.node = child;
  8002. }
  8003. }
  8004. return best;
  8005. }
  8006. }
  8007. return nd;
  8008. }
  8009. return SYNCTEX_ND_0;
  8010. }
  8011. SYNCTEX_INLINE static synctex_nd_lr_s _synctex_eq_get_closest_children_in_box_v2(synctex_point_p hitP, synctex_node_p node) {
  8012. synctex_nd_lr_s nds = {SYNCTEX_ND_0,SYNCTEX_ND_0};
  8013. if(_synctex_tree_has_child(node)) { /* node != NULL */
  8014. if (node->class_->type==synctex_node_type_hbox ||
  8015. node->class_->type==synctex_node_type_proxy_hbox) {
  8016. return __synctex_eq_get_closest_children_in_hbox_v2(hitP,node);
  8017. } else {
  8018. return __synctex_eq_get_closest_children_in_vbox_v2(hitP,node);
  8019. }
  8020. }
  8021. return nds;
  8022. }
  8023. #ifndef SYNCTEX_NO_UPDATER
  8024. # ifdef SYNCTEX_NOTHING
  8025. # pragma mark -
  8026. # pragma mark Updater
  8027. # endif
  8028. typedef int (*synctex_print_f)(synctex_updater_p, const char * , ...); /* print formatted to either FILE * or gzFile */
  8029. typedef void (*synctex_close_f)(synctex_updater_p); /* close FILE * or gzFile */
  8030. # define SYNCTEX_BITS_PER_BYTE 8
  8031. typedef union {
  8032. gzFile as_gzFile;
  8033. FILE * as_FILE_p;
  8034. void * as_ptr;
  8035. } syncex_file_u;
  8036. struct synctex_updater_t {
  8037. syncex_file_u file;
  8038. synctex_print_f print;
  8039. synctex_close_f close;
  8040. int length; /* the number of chars appended */
  8041. };
  8042. static int _synctex_updater_print(synctex_updater_p updater, const char * format, ...) {
  8043. int result = 0;
  8044. if (updater) {
  8045. va_list va;
  8046. va_start(va, format);
  8047. result = vfprintf(updater->file.as_FILE_p,
  8048. format,
  8049. va);
  8050. va_end(va);
  8051. }
  8052. return result;
  8053. }
  8054. #if defined(_MSC_VER)
  8055. #include <stdio.h>
  8056. #include <stdlib.h>
  8057. #include <stdarg.h>
  8058. static int vasprintf(char **ret,
  8059. const char *format,
  8060. va_list ap)
  8061. {
  8062. int len;
  8063. len = _vsnprintf(NULL, 0, format, ap);
  8064. if (len < 0) return -1;
  8065. *ret = malloc(len + 1);
  8066. if (!*ret) return -1;
  8067. _vsnprintf(*ret, len+1, format, ap);
  8068. (*ret)[len] = '\0';
  8069. return len;
  8070. }
  8071. #endif
  8072. /**
  8073. * gzvprintf is not available until OSX 10.10
  8074. */
  8075. static int _synctex_updater_print_gz(synctex_updater_p updater, const char * format, ...) {
  8076. int result = 0;
  8077. if (updater) {
  8078. char * buffer;
  8079. va_list va;
  8080. va_start(va, format);
  8081. if (vasprintf(&buffer, format, va) < 0) {
  8082. _synctex_error("Out of memory...");
  8083. } else if ((result = (int)strlen(buffer))) {
  8084. result = gzwrite(updater->file.as_gzFile, buffer, (unsigned)result);
  8085. }
  8086. va_end(va);
  8087. free(buffer);
  8088. }
  8089. return result;
  8090. }
  8091. static void _synctex_updater_close(synctex_updater_p updater) {
  8092. if (updater) {
  8093. fclose(updater->file.as_FILE_p);
  8094. }
  8095. }
  8096. static void _synctex_updater_close_gz(synctex_updater_p updater) {
  8097. if (updater) {
  8098. gzclose(updater->file.as_gzFile);
  8099. }
  8100. }
  8101. synctex_updater_p synctex_updater_new_with_output_file(const char * output, const char * build_directory) {
  8102. synctex_updater_p updater = NULL;
  8103. const char * mode = NULL;
  8104. synctex_open_s open;
  8105. /* prepare the updater, the memory is the only one dynamically allocated */
  8106. updater = (synctex_updater_p)_synctex_malloc(sizeof(synctex_updater_s));
  8107. if (NULL == updater) {
  8108. _synctex_error("! synctex_updater_new_with_file: malloc problem");
  8109. return NULL;
  8110. }
  8111. open = _synctex_open_v2(output,build_directory,0,synctex_ADD_QUOTES);
  8112. if (open.status < SYNCTEX_STATUS_OK) {
  8113. open = _synctex_open_v2(output,build_directory,0,synctex_DONT_ADD_QUOTES);
  8114. if (open.status < SYNCTEX_STATUS_OK) {
  8115. return_on_error:
  8116. _synctex_free(updater);
  8117. return updater = NULL;
  8118. }
  8119. }
  8120. /* OK, the file exists, we close it and reopen it with the correct mode.
  8121. * The receiver is now the owner of the "synctex" variable. */
  8122. gzclose(open.file);
  8123. updater->file.as_ptr = NULL;
  8124. mode = _synctex_get_io_mode_name(open.io_mode|synctex_io_append_mask);/* either "a" or "ab", depending on the file extension */
  8125. if (open.io_mode&synctex_io_gz_mask) {
  8126. if (NULL == (updater->file.as_FILE_p = fopen(open.synctex,mode))) {
  8127. no_write_error:
  8128. _synctex_error("! synctex_updater_new_with_file: Can't append to %s",open.synctex);
  8129. free(open.synctex);
  8130. goto return_on_error;
  8131. }
  8132. updater->print = &_synctex_updater_print;
  8133. updater->close = &_synctex_updater_close;
  8134. } else {
  8135. if (NULL == (updater->file.as_gzFile = gzopen(open.synctex,mode))) {
  8136. goto no_write_error;
  8137. }
  8138. updater->print = &_synctex_updater_print_gz;
  8139. updater->close = &_synctex_updater_close_gz;
  8140. }
  8141. printf("SyncTeX: updating %s...",open.synctex);
  8142. _synctex_free(open.synctex);
  8143. return updater;
  8144. }
  8145. void synctex_updater_append_magnification(synctex_updater_p updater, char * magnification){
  8146. if (NULL==updater) {
  8147. return;
  8148. }
  8149. if (magnification && strlen(magnification)) {
  8150. updater->length +=
  8151. updater->print(updater,"Magnification:%s\n",magnification);
  8152. }
  8153. }
  8154. void synctex_updater_append_x_offset(synctex_updater_p updater, char * x_offset){
  8155. if (NULL==updater) {
  8156. return;
  8157. }
  8158. if (x_offset && strlen(x_offset)) {
  8159. updater->length += updater->print(updater,"X Offset:%s\n",x_offset);
  8160. }
  8161. }
  8162. void synctex_updater_append_y_offset(synctex_updater_p updater, char * y_offset){
  8163. if (NULL==updater) {
  8164. return;
  8165. }
  8166. if (y_offset && strlen(y_offset)) {
  8167. updater->length += updater->print(updater,"Y Offset:%s\n",y_offset);
  8168. }
  8169. }
  8170. void synctex_updater_free(synctex_updater_p updater){
  8171. if (NULL==updater) {
  8172. return;
  8173. }
  8174. if (updater->length>0) {
  8175. updater->print(updater,"!%i\n",updater->length);
  8176. }
  8177. updater->close(updater);
  8178. _synctex_free(updater);
  8179. printf("... done.\n");
  8180. return;
  8181. }
  8182. #endif
  8183. #if defined(SYNCTEX_TESTING)
  8184. # ifdef SYNCTEX_NOTHING
  8185. # pragma mark -
  8186. # pragma mark Testers
  8187. # endif
  8188. /**
  8189. * The next nodes corresponds to a deep first tree traversal.
  8190. * Does not create child proxies as side effect contrary to
  8191. * the synctex_node_next method above.
  8192. * May loop infinitely many times if the tree
  8193. * is not properly built (contains loops).
  8194. */
  8195. static synctex_node_p _synctex_node_next(synctex_node_p node) {
  8196. synctex_node_p N = _synctex_tree_child(node);
  8197. if (N) {
  8198. return N;
  8199. }
  8200. return _synctex_node_sibling_or_parents(node);
  8201. }
  8202. static int _synctex_input_copy_name(synctex_node_p input, char * name) {
  8203. char * copy = _synctex_malloc(strlen(name)+1);
  8204. memcpy(copy,name,strlen(name)+1);
  8205. _synctex_data_set_name(input,copy);
  8206. return 0;
  8207. }
  8208. int synctex_test_setup_scanner_sheets_421(synctex_scanner_p scanner) {
  8209. int TC = 0;
  8210. synctex_node_p sheet = synctex_node_new(scanner,synctex_node_type_sheet);
  8211. _synctex_data_set_page(sheet,4);
  8212. SYNCTEX_TEST_BODY(TC, _synctex_data_page(sheet)==4,"");
  8213. synctex_node_free(scanner->sheet);
  8214. scanner->sheet = sheet;
  8215. sheet = synctex_node_new(scanner,synctex_node_type_sheet);
  8216. _synctex_data_set_page(sheet,2);
  8217. SYNCTEX_TEST_BODY(TC, _synctex_data_page(sheet)==2,"");
  8218. __synctex_tree_set_sibling(sheet, scanner->sheet);
  8219. scanner->sheet = sheet;
  8220. sheet = synctex_node_new(scanner,synctex_node_type_sheet);
  8221. _synctex_data_set_page(sheet,1);
  8222. SYNCTEX_TEST_BODY(TC, _synctex_data_page(sheet)==1,"");
  8223. __synctex_tree_set_sibling(sheet, scanner->sheet);
  8224. scanner->sheet = sheet;
  8225. return TC;
  8226. }
  8227. int synctex_test_input(synctex_scanner_p scanner) {
  8228. int TC = 0;
  8229. synctex_node_p input = synctex_node_new(scanner,synctex_node_type_input);
  8230. _synctex_data_set_tag(input,421);
  8231. SYNCTEX_TEST_BODY(TC, _synctex_data_tag(input)==421,"");
  8232. _synctex_data_set_tag(input,124);
  8233. SYNCTEX_TEST_BODY(TC, _synctex_data_tag(input)==124,"");
  8234. _synctex_data_set_line(input,421);
  8235. SYNCTEX_TEST_BODY(TC, _synctex_data_line(input)==421,"");
  8236. _synctex_data_set_line(input,214);
  8237. SYNCTEX_TEST_BODY(TC, _synctex_data_line(input)==214,"");
  8238. _synctex_data_set_line(input,214);
  8239. SYNCTEX_TEST_BODY(TC, _synctex_data_line(input)==214,"");
  8240. _synctex_input_copy_name(input,"214");
  8241. SYNCTEX_TEST_BODY(TC, 0==memcmp(_synctex_data_name(input),"214",4),"");
  8242. _synctex_input_copy_name(input,"421421");
  8243. SYNCTEX_TEST_BODY(TC,
  8244. 0==memcmp(_synctex_data_name(input),
  8245. "421421",
  8246. 4),
  8247. "");
  8248. synctex_node_free(input);
  8249. return TC;
  8250. }
  8251. int synctex_test_proxy(synctex_scanner_p scanner) {
  8252. int TC = 0;
  8253. synctex_node_p proxy = synctex_node_new(scanner,synctex_node_type_proxy);
  8254. synctex_node_p target = synctex_node_new(scanner,synctex_node_type_rule);
  8255. _synctex_tree_set_target(proxy,target);
  8256. _synctex_data_set_tag(target,421);
  8257. SYNCTEX_TEST_BODY(TC, _synctex_data_tag(target)==421,"");
  8258. SYNCTEX_TEST_BODY(TC, synctex_node_tag(target)==421,"");
  8259. SYNCTEX_TEST_BODY(TC, synctex_node_tag(proxy)==421,"");
  8260. synctex_node_free(proxy);
  8261. synctex_node_free(target);
  8262. return TC;
  8263. }
  8264. int synctex_test_handle(synctex_scanner_p scanner) {
  8265. int TC = 0;
  8266. synctex_node_p handle = synctex_node_new(scanner,synctex_node_type_handle);
  8267. synctex_node_p proxy = synctex_node_new(scanner, synctex_node_type_proxy);
  8268. synctex_node_p target = synctex_node_new(scanner,synctex_node_type_rule);
  8269. _synctex_tree_set_target(handle,target);
  8270. _synctex_data_set_tag(target,421);
  8271. SYNCTEX_TEST_BODY(TC, _synctex_data_tag(target)==421,"");
  8272. SYNCTEX_TEST_BODY(TC, synctex_node_tag(target)==421,"");
  8273. SYNCTEX_TEST_BODY(TC, synctex_node_tag(handle)==421,"");
  8274. _synctex_data_set_line(target,214);
  8275. SYNCTEX_TEST_BODY(TC, _synctex_data_line(target)==214,"");
  8276. SYNCTEX_TEST_BODY(TC, synctex_node_line(target)==214,"");
  8277. SYNCTEX_TEST_BODY(TC, synctex_node_line(handle)==214,"");
  8278. _synctex_data_set_column(target,142);
  8279. SYNCTEX_TEST_BODY(TC, _synctex_data_column(target)==142,"");
  8280. SYNCTEX_TEST_BODY(TC, synctex_node_column(target)==142,"");
  8281. SYNCTEX_TEST_BODY(TC, synctex_node_column(handle)==142,"");
  8282. _synctex_tree_set_target(proxy,target);
  8283. _synctex_tree_set_target(handle,proxy);
  8284. _synctex_data_set_tag(target,412);
  8285. SYNCTEX_TEST_BODY(TC, _synctex_data_tag(target)==412,"");
  8286. SYNCTEX_TEST_BODY(TC, synctex_node_tag(target)==412,"");
  8287. SYNCTEX_TEST_BODY(TC, synctex_node_tag(handle)==412,"");
  8288. _synctex_data_set_line(target,124);
  8289. SYNCTEX_TEST_BODY(TC, _synctex_data_line(target)==124,"");
  8290. SYNCTEX_TEST_BODY(TC, synctex_node_line(target)==124,"");
  8291. SYNCTEX_TEST_BODY(TC, synctex_node_line(handle)==124,"");
  8292. _synctex_data_set_column(target,241);
  8293. SYNCTEX_TEST_BODY(TC, _synctex_data_column(target)==241,"");
  8294. SYNCTEX_TEST_BODY(TC, synctex_node_column(target)==241,"");
  8295. SYNCTEX_TEST_BODY(TC, synctex_node_column(handle)==241,"");
  8296. synctex_node_free(handle);
  8297. synctex_node_free(proxy);
  8298. synctex_node_free(target);
  8299. return TC;
  8300. }
  8301. int synctex_test_setup_scanner_input(synctex_scanner_p scanner) {
  8302. int TC = 0;
  8303. synctex_node_p input = synctex_node_new(scanner,synctex_node_type_input);
  8304. _synctex_data_set_tag(input,4);
  8305. _synctex_input_copy_name(input,"21");
  8306. _synctex_data_set_line(input,421);
  8307. synctex_node_free(scanner->input);
  8308. scanner->input = input;
  8309. SYNCTEX_TEST_BODY(TC, _synctex_data_tag(input)==4,"");
  8310. SYNCTEX_TEST_BODY(TC, strcmp(_synctex_data_name(input),"21")==0,"");
  8311. SYNCTEX_TEST_BODY(TC, _synctex_data_line(input)==421,"");
  8312. return TC;
  8313. }
  8314. int synctex_test_setup_nodes(synctex_scanner_p scanner, synctex_node_r nodes) {
  8315. int TC = 0;
  8316. int n;
  8317. for (n=0;n<synctex_node_number_of_types;++n) {
  8318. nodes[n] = synctex_node_new(scanner,n);
  8319. SYNCTEX_TEST_BODY(TC, nodes[n]!=NULL,"");
  8320. }
  8321. return TC;
  8322. }
  8323. int synctex_test_teardown_nodes(synctex_scanner_p scanner, synctex_node_r nodes) {
  8324. int n;
  8325. for (n=0;n<synctex_node_number_of_types;++n) {
  8326. synctex_node_free(nodes[n]);
  8327. nodes[n]=NULL;
  8328. }
  8329. return 1;
  8330. }
  8331. int synctex_test_tree(synctex_scanner_p scanner) {
  8332. int TC = 0;
  8333. synctex_node_p nodes1[synctex_node_number_of_types];
  8334. synctex_node_p nodes2[synctex_node_number_of_types];
  8335. synctex_node_p nodes3[synctex_node_number_of_types];
  8336. int i,j;
  8337. TC += synctex_test_setup_nodes(scanner,nodes1);
  8338. TC += synctex_test_setup_nodes(scanner,nodes2);
  8339. TC += synctex_test_setup_nodes(scanner,nodes3);
  8340. /* Every node has a sibling */
  8341. for (i=0;i<synctex_node_number_of_types;++i) {
  8342. for (j=0;j<synctex_node_number_of_types;++j) {
  8343. _synctex_tree_set_sibling(nodes1[i],nodes2[i]);
  8344. SYNCTEX_TEST_BODY(TC, nodes2[i]==synctex_node_sibling(nodes1[i]),"");
  8345. }
  8346. }
  8347. synctex_test_teardown_nodes(scanner,nodes3);
  8348. synctex_test_teardown_nodes(scanner,nodes2);
  8349. synctex_test_teardown_nodes(scanner,nodes1);
  8350. return TC;
  8351. }
  8352. int synctex_test_page(synctex_scanner_p scanner) {
  8353. int TC = synctex_test_setup_scanner_sheets_421(scanner);
  8354. synctex_node_p sheet = scanner->sheet;
  8355. synctex_node_p node = synctex_node_new(scanner,synctex_node_type_rule);
  8356. _synctex_data_set_tag(node,4);
  8357. _synctex_data_set_line(node,21);
  8358. synctex_node_free(_synctex_node_set_child(sheet,node));
  8359. SYNCTEX_TEST_BODY(TC, synctex_node_page(node)==synctex_node_page(sheet),"");
  8360. return TC;
  8361. }
  8362. int synctex_test_display_query(synctex_scanner_p scanner) {
  8363. int TC = synctex_test_setup_scanner_sheets_421(scanner);
  8364. synctex_node_p sheet = scanner->sheet;
  8365. synctex_node_p node = synctex_node_new(scanner,synctex_node_type_rule);
  8366. _synctex_data_set_tag(node,4);
  8367. _synctex_data_set_line(node,21);
  8368. synctex_node_free(_synctex_node_set_child(sheet,node));
  8369. SYNCTEX_TEST_BODY(TC, node==synctex_node_child(sheet),"");
  8370. __synctex_node_make_friend_tlc(node);
  8371. SYNCTEX_TEST_BODY(TC, _synctex_scanner_friend(scanner, 25)==node,"");
  8372. sheet = __synctex_tree_sibling(sheet);
  8373. node = synctex_node_new(scanner,synctex_node_type_rule);
  8374. _synctex_data_set_tag(node,4);
  8375. _synctex_data_set_line(node,21);
  8376. synctex_node_free(_synctex_node_set_child(sheet,node));
  8377. SYNCTEX_TEST_BODY(TC, node==synctex_node_child(sheet),"");
  8378. __synctex_node_make_friend_tlc(node);
  8379. SYNCTEX_TEST_BODY(TC, _synctex_scanner_friend(scanner, 25)==node,"");
  8380. sheet = __synctex_tree_sibling(sheet);
  8381. node = synctex_node_new(scanner,synctex_node_type_rule);
  8382. _synctex_data_set_tag(node,4);
  8383. _synctex_data_set_line(node,21);
  8384. synctex_node_free(_synctex_node_set_child(sheet,node));
  8385. SYNCTEX_TEST_BODY(TC, node==synctex_node_child(sheet),"");
  8386. __synctex_node_make_friend_tlc(node);
  8387. SYNCTEX_TEST_BODY(TC, (_synctex_scanner_friend(scanner, 25)==node),"");
  8388. synctex_test_setup_scanner_input(scanner);
  8389. scanner->flags.has_parsed = synctex_YES;
  8390. #if 1
  8391. SYNCTEX_TEST_BODY(TC, (synctex_display_query(scanner,"21",21,4,-1)==3),"");
  8392. #endif
  8393. return TC;
  8394. }
  8395. typedef struct {
  8396. int s; /* status */
  8397. char n[25]; /* name */
  8398. } synctex_test_sn_s;
  8399. synctex_test_sn_s synctex_test_tmp_sn(char * content) {
  8400. synctex_test_sn_s sn = {0, "/tmp/test.XXXXXX.synctex"};
  8401. FILE *sfp;
  8402. int fd = mkstemps(sn.n,8);
  8403. if (fd < 0) {
  8404. fprintf(stderr, "%s: %s\n", sn.n, strerror(errno));
  8405. sn.s = -1;
  8406. return sn;
  8407. }
  8408. if ((sfp = fdopen(fd, "w+")) == NULL) {
  8409. unlink(sn.n);
  8410. close(fd);
  8411. fprintf(stderr, "%s: %s\n", sn.n, strerror(errno));
  8412. sn.s = -2;
  8413. return sn;
  8414. }
  8415. sn.s = fputs(content,sfp);
  8416. printf("temp:%s\n%i\n",sn.n,sn.s);
  8417. fclose(sfp);
  8418. if (sn.s==0) {
  8419. sn.s = -2;
  8420. unlink(sn.n);
  8421. }
  8422. return sn;
  8423. }
  8424. int synctex_test_sheet_1() {
  8425. int TC = 0;
  8426. char * content =
  8427. "SyncTeX Version:1 \n" /*00-19*/
  8428. "Input:1:./1.tex \n" /*20-39*/
  8429. "Output:pdf \n" /*40-59*/
  8430. "Magnification:100000000 \n" /*60-89*/
  8431. "Unit:1 \n" /*90-99*/
  8432. "X Offset:0 \n" /*00-19*/
  8433. "Y Offset:0 \n" /*20-39*/
  8434. "Content: \n" /*40-49*/
  8435. "{1 \n" /*50-59*/
  8436. "[1,10:20,350:330,330,0 \n" /*60-89*/
  8437. "] \n" /*90-99*/
  8438. "} \n" /*00-09*/
  8439. "Postamble:\n";
  8440. synctex_test_sn_s sn = synctex_test_tmp_sn(content);
  8441. if (sn.s>0) {
  8442. synctex_scanner_p scanner = synctex_scanner_new_with_output_file(sn.n, NULL, synctex_YES);
  8443. synctex_node_p node = synctex_scanner_handle(scanner);
  8444. printf("Created nodes:\n");
  8445. while (node) {
  8446. printf("%s\n",_synctex_node_abstract(node));
  8447. node = synctex_node_next(node);
  8448. }
  8449. synctex_scanner_free(scanner);
  8450. unlink(sn.n);
  8451. } else {
  8452. ++TC;
  8453. }
  8454. return TC;
  8455. }
  8456. int synctex_test_sheet_2() {
  8457. int TC = 0;
  8458. char * content =
  8459. "SyncTeX Version:1 \n" /*00-19*/
  8460. "Input:1:./1.tex \n" /*20-39*/
  8461. "Output:pdf \n" /*40-59*/
  8462. "Magnification:100000000 \n" /*60-89*/
  8463. "Unit:1 \n" /*90-99*/
  8464. "X Offset:0 \n" /*00-19*/
  8465. "Y Offset:0 \n" /*20-39*/
  8466. "Content: \n" /*40-49*/
  8467. "{1 \n" /*50-59*/
  8468. "(1,10:20,350:330,330,0 \n" /*60-89*/
  8469. ") \n" /*90-99*/
  8470. "} \n" /*00-09*/
  8471. "Postamble:\n";
  8472. synctex_test_sn_s sn = synctex_test_tmp_sn(content);
  8473. if (sn.s>0) {
  8474. synctex_scanner_p scanner = synctex_scanner_new_with_output_file(sn.n, NULL, synctex_YES);
  8475. synctex_node_p node = synctex_scanner_handle(scanner);
  8476. printf("Created nodes:\n");
  8477. while (node) {
  8478. printf("%s\n",_synctex_node_abstract(node));
  8479. node = _synctex_node_next(node);
  8480. }
  8481. TC += synctex_scanner_free(scanner);
  8482. unlink(sn.n);
  8483. } else {
  8484. ++TC;
  8485. }
  8486. return TC;
  8487. }
  8488. int synctex_test_charindex() {
  8489. int TC = 0;
  8490. char * content =
  8491. "SyncTeX Version:1 \n" /*00-19*/
  8492. "Input:1:./1.tex \n" /*20-39*/
  8493. "Output:pdf \n" /*40-59*/
  8494. "Magnification:100000000 \n" /*60-89*/
  8495. "Unit:1 \n" /*90-99*/
  8496. "X Offset:0 \n" /*00-19*/
  8497. "Y Offset:0 \n" /*20-39*/
  8498. "Content: \n" /*40-49*/
  8499. "{1 \n" /*50-59*/
  8500. "[1,10:20,350:330,330,0 \n" /*60-89*/
  8501. "(1,58:20,100:250,10,5 \n" /*90-119*/
  8502. "f1000:50,100 \n" /*20-39*/
  8503. ") \n" /*40-49*/
  8504. "] \n" /*50-59*/
  8505. "} \n" /*60-69*/
  8506. "Postamble:\n";
  8507. synctex_test_sn_s sn = synctex_test_tmp_sn(content);
  8508. if (sn.s>0) {
  8509. synctex_scanner_p scanner = synctex_scanner_new_with_output_file(sn.n, NULL, synctex_YES);
  8510. synctex_node_p node = synctex_scanner_handle(scanner);
  8511. printf("Created nodes:\n");
  8512. while (node) {
  8513. printf("%s\n",_synctex_node_abstract(node));
  8514. node = synctex_node_next(node);
  8515. }
  8516. TC += synctex_scanner_free(scanner);
  8517. unlink(sn.n);
  8518. } else {
  8519. ++TC;
  8520. }
  8521. return TC;
  8522. }
  8523. int synctex_test_form() {
  8524. int TC = 0;
  8525. char * content =
  8526. "SyncTeX Version:1 \n" /*00-19*/
  8527. "Input:1:./1.tex \n" /*20-39*/
  8528. "Output:pdf \n" /*40-59*/
  8529. "Magnification:100000000 \n" /*60-89*/
  8530. "Unit:1 \n" /*90-99*/
  8531. "X Offset:0 \n" /*00-19*/
  8532. "Y Offset:0 \n" /*20-39*/
  8533. "Content: \n" /*40-49*/
  8534. "{1 \n" /*50-59*/
  8535. "[1,10:20,350:330,330,0 \n" /*60-89*/
  8536. "(1,58:20,100:250,10,5 \n" /*90-119*/
  8537. "f1000:50,100 \n" /*20-39*/
  8538. ") \n" /*40-49*/
  8539. "] \n" /*50-59*/
  8540. "} \n" /*60-69*/
  8541. "<1000 \n" /*70-79*/
  8542. "(1,63:0,0:100,8,3 \n" /*80-99*/
  8543. ") \n" /*00-09*/
  8544. "> \n" /*10-19*/
  8545. "Postamble:\n";
  8546. synctex_test_sn_s sn = synctex_test_tmp_sn(content);
  8547. if (sn.s>0) {
  8548. synctex_scanner_p scanner = synctex_scanner_new_with_output_file(sn.n, NULL, synctex_YES);
  8549. synctex_node_p node = synctex_scanner_handle(scanner);
  8550. while (node) {
  8551. printf("%s\n",_synctex_node_abstract(node));
  8552. node = _synctex_node_next(node);
  8553. }
  8554. TC += synctex_scanner_free(scanner);
  8555. unlink(sn.n);
  8556. } else {
  8557. ++TC;
  8558. }
  8559. return TC;
  8560. }
  8561. #endif