12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719 |
- char pot_etags_version[] = "@(#) pot revision number is 17.38.1.4";
- #define TRUE 1
- #define FALSE 0
- #ifdef DEBUG
- # undef DEBUG
- # define DEBUG TRUE
- #else
- # define DEBUG FALSE
- # define NDEBUG
- #endif
- #ifdef HAVE_CONFIG_H
- # include <config.h>
-
- # undef static
- # ifndef PTR
- # define PTR void *
- # endif
- #else
- # if defined (__STDC__) && (__STDC__ || defined (__SUNPRO_C))
- # define PTR void *
- # else
- # define const
- # define PTR long *
- # endif
- #endif
- #ifndef _GNU_SOURCE
- # define _GNU_SOURCE 1
- #endif
- #ifdef WIN32_NATIVE
- # undef MSDOS
- # undef WINDOWSNT
- # define WINDOWSNT
- #endif
- #ifdef MSDOS
- # undef MSDOS
- # define MSDOS TRUE
- # include <fcntl.h>
- # include <sys/param.h>
- # include <io.h>
- # ifndef HAVE_CONFIG_H
- # define DOS_NT
- # include <sys/config.h>
- # endif
- #else
- # define MSDOS FALSE
- #endif
- #ifdef WINDOWSNT
- # include <fcntl.h>
- # include <direct.h>
- # include <io.h>
- # define MAXPATHLEN _MAX_PATH
- # undef HAVE_NTGUI
- # undef DOS_NT
- # define DOS_NT
- # ifndef HAVE_GETCWD
- # define HAVE_GETCWD
- # endif
- #else
- #endif
- #include <unistd.h>
- #ifndef HAVE_UNISTD_H
- # if defined (HAVE_GETCWD) && !defined (WINDOWSNT)
- extern char *getcwd (char *buf, size_t size);
- # endif
- #endif
- #include <stdlib.h>
- #include <string.h>
- #include <stdio.h>
- #include <ctype.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <assert.h>
- #ifdef NDEBUG
- # undef assert
- # define assert(x) ((void) 0)
- #endif
- #ifdef NO_LONG_OPTIONS
- # define NO_LONG_OPTIONS TRUE
- # define getopt_long(argc,argv,optstr,lopts,lind) getopt (argc, argv, optstr)
- extern char *optarg;
- extern int optind, opterr;
- #else
- # define NO_LONG_OPTIONS FALSE
- # include <getopt.h>
- #endif
- #ifndef HAVE_CONFIG_H
- # ifdef __CYGWIN__
- !!! NOTICE !!!
- the regex.h distributed with Cygwin is not compatible with etags, alas!
- If you want regular expression support, you should delete this notice and
- arrange to use the GNU regex.h and regex.c.
- # endif
- #endif
- #include <regex.h>
- #ifdef CTAGS
- # undef CTAGS
- # define CTAGS TRUE
- #else
- # define CTAGS FALSE
- #endif
- #define streq(s,t) (assert ((s)!=NULL || (t)!=NULL), !strcmp (s, t))
- #define strcaseeq(s,t) (assert ((s)!=NULL && (t)!=NULL), !etags_strcasecmp (s, t))
- #define strneq(s,t,n) (assert ((s)!=NULL || (t)!=NULL), !strncmp (s, t, n))
- #define strncaseeq(s,t,n) (assert ((s)!=NULL && (t)!=NULL), !etags_strncasecmp (s, t, n))
- #define CHARS 256
- #define CHAR(x) ((unsigned int)(x) & (CHARS - 1))
- #define iswhite(c) (_wht[CHAR (c)])
- #define notinname(c) (_nin[CHAR (c)])
- #define begtoken(c) (_btk[CHAR (c)])
- #define intoken(c) (_itk[CHAR (c)])
- #define endtoken(c) (_etk[CHAR (c)])
- #define ISALNUM(c) isalnum (CHAR (c))
- #define ISALPHA(c) isalpha (CHAR (c))
- #define ISDIGIT(c) isdigit (CHAR (c))
- #define ISLOWER(c) islower (CHAR (c))
- #define lowcase(c) tolower (CHAR (c))
- #if DEBUG
- # include "chkmalloc.h"
- # define xnew(n,Type) ((Type *) trace_malloc (__FILE__, __LINE__, \
- (n) * sizeof (Type)))
- # define xrnew(op,n,Type) ((op) = (Type *) trace_realloc (__FILE__, __LINE__, \
- (char *) (op), (n) * sizeof (Type)))
- #else
- # define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type)))
- # define xrnew(op,n,Type) ((op) = (Type *) xrealloc ( \
- (char *) (op), (n) * sizeof (Type)))
- #endif
- #define bool int
- typedef void Lang_function (FILE *);
- typedef struct
- {
- const char *suffix;
- const char *command;
- } compressor;
- typedef struct
- {
- const char *name;
- const char *help;
- Lang_function *function;
- const char **suffixes;
- const char **filenames;
- const char **interpreters;
- bool metasource;
- } language;
- typedef struct fdesc
- {
- struct fdesc *next;
- char *infname;
- char *infabsname;
- char *infabsdir;
- char *taggedfname;
- language *lang;
- char *prop;
- bool usecharno;
- bool written;
- } fdesc;
- typedef struct node_st
- {
- struct node_st *left, *right;
- fdesc *fdp;
- char *name;
- char *regex;
- bool valid;
- bool is_func;
- bool been_warned;
- int lno;
- long cno;
- } node;
- typedef struct
- {
- long size;
- int len;
- char *buffer;
- } linebuffer;
- typedef struct
- {
- enum {
- at_language,
- at_regexp,
- at_filename,
- at_stdin,
- at_end
- } arg_type;
- language *lang;
- char *what;
- } argument;
- typedef struct regexp
- {
- struct regexp *p_next;
- language *lang;
- char *pattern;
- char *name;
- struct re_pattern_buffer *pat;
- struct re_registers regs;
- bool error_signaled;
- bool force_explicit_name;
- bool ignore_case;
- bool multi_line;
- } regexp;
- static void Ada_funcs (FILE *);
- static void Asm_labels (FILE *);
- static void C_entries (int c_ext, FILE *);
- static void default_C_entries (FILE *);
- static void plain_C_entries (FILE *);
- static void Cjava_entries (FILE *);
- static void Cobol_paragraphs (FILE *);
- static void Cplusplus_entries (FILE *);
- static void Cstar_entries (FILE *);
- static void Erlang_functions (FILE *);
- static void Forth_words (FILE *);
- static void Fortran_functions (FILE *);
- static void HTML_labels (FILE *);
- static void Lisp_functions (FILE *);
- static void Lua_functions (FILE *);
- static void Makefile_targets (FILE *);
- static void Pascal_functions (FILE *);
- static void Perl_functions (FILE *);
- static void PHP_functions (FILE *);
- static void PS_functions (FILE *);
- static void Prolog_functions (FILE *);
- static void Python_functions (FILE *);
- static void Scheme_functions (FILE *);
- static void TeX_commands (FILE *);
- static void Texinfo_nodes (FILE *);
- static void Yacc_entries (FILE *);
- static void just_read_file (FILE *);
- static void print_language_names (void);
- static void print_version (void);
- static void print_help (argument *);
- int main (int, char **);
- static compressor *get_compressor_from_suffix (char *, char **);
- static language *get_language_from_langname (const char *);
- static language *get_language_from_interpreter (char *);
- static language *get_language_from_filename (char *, bool);
- static void readline (linebuffer *, FILE *);
- static long readline_internal (linebuffer *, FILE *);
- static bool nocase_tail (const char *);
- static void get_tag (char *, char **);
- static void analyse_regex (char *);
- static void free_regexps (void);
- static void regex_tag_multiline (void);
- static void error (const char *, const char *);
- static void suggest_asking_for_help (void) NO_RETURN;
- void fatal (const char *, const char *) NO_RETURN;
- static void pfatal (const char *) NO_RETURN;
- static void add_node (node *, node **);
- static void init (void);
- static void process_file_name (char *, language *);
- static void process_file (FILE *, char *, language *);
- static void find_entries (FILE *);
- static void free_tree (node *);
- static void free_fdesc (fdesc *);
- static void pfnote (char *, bool, char *, int, int, long);
- static void make_tag (const char *, int, bool, char *, int, int, long);
- static void invalidate_nodes (fdesc *, node **);
- static void put_entries (node *);
- static char *concat (const char *, const char *, const char *);
- static char *skip_spaces (char *);
- static char *skip_non_spaces (char *);
- static char *savenstr (const char *, int);
- static char *savestr (const char *);
- static char *etags_strchr (const char *, int);
- static char *etags_strrchr (const char *, int);
- static int etags_strcasecmp (const char *, const char *);
- static int etags_strncasecmp (const char *, const char *, int);
- static char *etags_getcwd (void);
- static char *relative_filename (char *, char *);
- static char *absolute_filename (char *, char *);
- static char *absolute_dirname (char *, char *);
- static bool filename_is_absolute (char *f);
- static void canonicalize_filename (char *);
- static void linebuffer_init (linebuffer *);
- static void linebuffer_setlen (linebuffer *, int);
- static PTR xmalloc (size_t);
- static PTR xrealloc (char *, size_t);
- static char searchar = '/';
- static char *tagfile;
- static char *progname;
- static char *cwd;
- static char *tagfiledir;
- static FILE *tagf;
- static ptrdiff_t whatlen_max;
- static fdesc *fdhead;
- static fdesc *curfdp;
- static int lineno;
- static long charno;
- static long linecharno;
- static char *dbp;
- static const int invalidcharno = -1;
- static node *nodehead;
- static node *last_node;
- static linebuffer lb;
- static linebuffer filebuf;
- static linebuffer token_name;
- static bool _wht[CHARS], _nin[CHARS], _itk[CHARS], _btk[CHARS], _etk[CHARS];
- static const char
-
- *white = " \f\t\n\r\v",
-
- *nonam = " \f\t\n\r()=,;",
-
- *endtk = " \t\n\r\"'#()[]{}=-+%*/&|^~!<>;,.:?",
-
- *begtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~@",
-
- *midtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789";
- static bool append_to_tagfile;
- static bool typedefs;
- static bool typedefs_or_cplusplus;
-
-
- static bool constantypedefs;
-
-
- static bool globals;
- static bool members;
- static bool declarations;
- static bool no_line_directive;
- static bool no_duplicates;
- static bool update;
- static bool vgrind_style;
- static bool no_warnings;
- static bool cxref_style;
- static bool cplusplus;
- static bool ignoreindent;
- static bool packages_only;
- #ifdef STDIN
- # undef STDIN
- #endif
- #define STDIN 0x1001
- static bool parsing_stdin;
- static regexp *p_head;
- static bool need_filebuf;
- static struct option longopts[] =
- {
- { "append", no_argument, NULL, 'a' },
- { "packages-only", no_argument, &packages_only, TRUE },
- { "c++", no_argument, NULL, 'C' },
- { "declarations", no_argument, &declarations, TRUE },
- { "no-line-directive", no_argument, &no_line_directive, TRUE },
- { "no-duplicates", no_argument, &no_duplicates, TRUE },
- { "help", no_argument, NULL, 'h' },
- { "help", no_argument, NULL, 'H' },
- { "ignore-indentation", no_argument, NULL, 'I' },
- { "language", required_argument, NULL, 'l' },
- { "members", no_argument, &members, TRUE },
- { "no-members", no_argument, &members, FALSE },
- { "output", required_argument, NULL, 'o' },
- { "regex", required_argument, NULL, 'r' },
- { "no-regex", no_argument, NULL, 'R' },
- { "ignore-case-regex", required_argument, NULL, 'c' },
- { "parse-stdin", required_argument, NULL, STDIN },
- { "version", no_argument, NULL, 'V' },
- #if CTAGS
- { "backward-search", no_argument, NULL, 'B' },
- { "cxref", no_argument, NULL, 'x' },
- { "defines", no_argument, NULL, 'd' },
- { "globals", no_argument, &globals, TRUE },
- { "typedefs", no_argument, NULL, 't' },
- { "typedefs-and-c++", no_argument, NULL, 'T' },
- { "update", no_argument, NULL, 'u' },
- { "vgrind", no_argument, NULL, 'v' },
- { "no-warn", no_argument, NULL, 'w' },
- #else
- { "no-defines", no_argument, NULL, 'D' },
- { "no-globals", no_argument, &globals, FALSE },
- { "include", required_argument, NULL, 'i' },
- #endif
- { NULL }
- };
- static compressor compressors[] =
- {
- { "z", "gzip -d -c"},
- { "Z", "gzip -d -c"},
- { "gz", "gzip -d -c"},
- { "GZ", "gzip -d -c"},
- { "bz2", "bzip2 -d -c" },
- { "xz", "xz -d -c" },
- { NULL }
- };
- static const char *Ada_suffixes [] =
- { "ads", "adb", "ada", NULL };
- static const char Ada_help [] =
- "In Ada code, functions, procedures, packages, tasks and types are\n\
- tags. Use the `--packages-only' option to create tags for\n\
- packages only.\n\
- Ada tag names have suffixes indicating the type of entity:\n\
- Entity type: Qualifier:\n\
- ------------ ----------\n\
- function /f\n\
- procedure /p\n\
- package spec /s\n\
- package body /b\n\
- type /t\n\
- task /k\n\
- Thus, `M-x find-tag <RET> bidule/b <RET>' will go directly to the\n\
- body of the package `bidule', while `M-x find-tag <RET> bidule <RET>'\n\
- will just search for any tag `bidule'.";
- static const char *Asm_suffixes [] =
- { "a",
- "asm",
- "def",
- "inc",
- "ins",
- "s", "sa",
- "S",
- "src",
- NULL
- };
- static const char Asm_help [] =
- "In assembler code, labels appearing at the beginning of a line,\n\
- followed by a colon, are tags.";
- static const char *default_C_suffixes [] =
- { "c", "h", NULL };
- #if CTAGS
- static const char default_C_help [] =
- "In C code, any C function is a tag. Use -t to tag typedefs.\n\
- Use -T to tag definitions of `struct', `union' and `enum'.\n\
- Use -d to tag `#define' macro definitions and `enum' constants.\n\
- Use --globals to tag global variables.\n\
- You can tag function declarations and external variables by\n\
- using `--declarations', and struct members by using `--members'.";
- #else
- static const char default_C_help [] =
- "In C code, any C function or typedef is a tag, and so are\n\
- definitions of `struct', `union' and `enum'. `#define' macro\n\
- definitions and `enum' constants are tags unless you specify\n\
- `--no-defines'. Global variables are tags unless you specify\n\
- `--no-globals' and so are struct members unless you specify\n\
- `--no-members'. Use of `--no-globals', `--no-defines' and\n\
- `--no-members' can make the tags table file much smaller.\n\
- You can tag function declarations and external variables by\n\
- using `--declarations'.";
- #endif
- static const char *Cplusplus_suffixes [] =
- { "C", "c++", "cc", "cpp", "cxx", "H", "h++", "hh", "hpp", "hxx",
- "M",
- "pdb",
- NULL };
- static const char Cplusplus_help [] =
- "In C++ code, all the tag constructs of C code are tagged. (Use\n\
- --help --lang=c --lang=c++ for full help.)\n\
- In addition to C tags, member functions are also recognized. Member\n\
- variables are recognized unless you use the `--no-members' option.\n\
- Tags for variables and functions in classes are named `CLASS::VARIABLE'\n\
- and `CLASS::FUNCTION'. `operator' definitions have tag names like\n\
- `operator+'.";
- static const char *Cjava_suffixes [] =
- { "java", NULL };
- static char Cjava_help [] =
- "In Java code, all the tags constructs of C and C++ code are\n\
- tagged. (Use --help --lang=c --lang=c++ --lang=java for full help.)";
- static const char *Cobol_suffixes [] =
- { "COB", "cob", NULL };
- static char Cobol_help [] =
- "In Cobol code, tags are paragraph names; that is, any word\n\
- starting in column 8 and followed by a period.";
- static const char *Cstar_suffixes [] =
- { "cs", "hs", NULL };
- static const char *Erlang_suffixes [] =
- { "erl", "hrl", NULL };
- static const char Erlang_help [] =
- "In Erlang code, the tags are the functions, records and macros\n\
- defined in the file.";
- const char *Forth_suffixes [] =
- { "fth", "tok", NULL };
- static const char Forth_help [] =
- "In Forth code, tags are words defined by `:',\n\
- constant, code, create, defer, value, variable, buffer:, field.";
- static const char *Fortran_suffixes [] =
- { "F", "f", "f90", "for", NULL };
- static const char Fortran_help [] =
- "In Fortran code, functions, subroutines and block data are tags.";
- static const char *HTML_suffixes [] =
- { "htm", "html", "shtml", NULL };
- static const char HTML_help [] =
- "In HTML input files, the tags are the `title' and the `h1', `h2',\n\
- `h3' headers. Also, tags are `name=' in anchors and all\n\
- occurrences of `id='.";
- static const char *Lisp_suffixes [] =
- { "cl", "clisp", "el", "l", "lisp", "LSP", "lsp", "ml", NULL };
- static const char Lisp_help [] =
- "In Lisp code, any function defined with `defun', any variable\n\
- defined with `defvar' or `defconst', and in general the first\n\
- argument of any expression that starts with `(def' in column zero\n\
- is a tag.";
- static const char *Lua_suffixes [] =
- { "lua", "LUA", NULL };
- static const char Lua_help [] =
- "In Lua scripts, all functions are tags.";
- static const char *Makefile_filenames [] =
- { "Makefile", "makefile", "GNUMakefile", "Makefile.in", "Makefile.am", NULL};
- static const char Makefile_help [] =
- "In makefiles, targets are tags; additionally, variables are tags\n\
- unless you specify `--no-globals'.";
- static const char *Objc_suffixes [] =
- { "lm",
- "m",
- NULL };
- static const char Objc_help [] =
- "In Objective C code, tags include Objective C definitions for classes,\n\
- class categories, methods and protocols. Tags for variables and\n\
- functions in classes are named `CLASS::VARIABLE' and `CLASS::FUNCTION'.\n\
- (Use --help --lang=c --lang=objc --lang=java for full help.)";
- static const char *Pascal_suffixes [] =
- { "p", "pas", NULL };
- static const char Pascal_help [] =
- "In Pascal code, the tags are the functions and procedures defined\n\
- in the file.";
- static const char *Perl_suffixes [] =
- { "pl", "pm", NULL };
- static const char *Perl_interpreters [] =
- { "perl", "@PERL@", NULL };
- static const char Perl_help [] =
- "In Perl code, the tags are the packages, subroutines and variables\n\
- defined by the `package', `sub', `my' and `local' keywords. Use\n\
- `--globals' if you want to tag global variables. Tags for\n\
- subroutines are named `PACKAGE::SUB'. The name for subroutines\n\
- defined in the default package is `main::SUB'.";
- static const char *PHP_suffixes [] =
- { "php", "php3", "php4", NULL };
- static const char PHP_help [] =
- "In PHP code, tags are functions, classes and defines. Unless you use\n\
- the `--no-members' option, vars are tags too.";
- static const char *plain_C_suffixes [] =
- { "pc",
- NULL };
- static const char *PS_suffixes [] =
- { "ps", "psw", NULL };
- static const char PS_help [] =
- "In PostScript code, the tags are the functions.";
- static const char *Prolog_suffixes [] =
- { "prolog", NULL };
- static const char Prolog_help [] =
- "In Prolog code, tags are predicates and rules at the beginning of\n\
- line.";
- static const char *Python_suffixes [] =
- { "py", NULL };
- static const char Python_help [] =
- "In Python code, `def' or `class' at the beginning of a line\n\
- generate a tag.";
- static const char *Scheme_suffixes [] =
- { "oak", "sch", "scheme", "SCM", "scm", "SM", "sm", "ss", "t", NULL };
- static const char Scheme_help [] =
- "In Scheme code, tags include anything defined with `def' or with a\n\
- construct whose name starts with `def'. They also include\n\
- variables set with `set!' at top level in the file.";
- static const char *TeX_suffixes [] =
- { "bib", "clo", "cls", "ltx", "sty", "TeX", "tex", NULL };
- static const char TeX_help [] =
- "In LaTeX text, the argument of any of the commands `\\chapter',\n\
- `\\section', `\\subsection', `\\subsubsection', `\\eqno', `\\label',\n\
- `\\ref', `\\cite', `\\bibitem', `\\part', `\\appendix', `\\entry',\n\
- `\\index', `\\def', `\\newcommand', `\\renewcommand',\n\
- `\\newenvironment' or `\\renewenvironment' is a tag.\n\
- \n\
- Other commands can be specified by setting the environment variable\n\
- `TEXTAGS' to a colon-separated list like, for example,\n\
- TEXTAGS=\"mycommand:myothercommand\".";
- static const char *Texinfo_suffixes [] =
- { "texi", "texinfo", "txi", NULL };
- static const char Texinfo_help [] =
- "for texinfo files, lines starting with @node are tagged.";
- static const char *Yacc_suffixes [] =
- { "y", "y++", "ym", "yxx", "yy", NULL };
- static const char Yacc_help [] =
- "In Bison or Yacc input files, each rule defines as a tag the\n\
- nonterminal it constructs. The portions of the file that contain\n\
- C code are parsed as C code (use --help --lang=c --lang=yacc\n\
- for full help).";
- static const char auto_help [] =
- "`auto' is not a real language, it indicates to use\n\
- a default language for files base on file name suffix and file contents.";
- static const char none_help [] =
- "`none' is not a real language, it indicates to only do\n\
- regexp processing on files.";
- static const char no_lang_help [] =
- "No detailed help available for this language.";
- static language lang_names [] =
- {
- { "ada", Ada_help, Ada_funcs, Ada_suffixes },
- { "asm", Asm_help, Asm_labels, Asm_suffixes },
- { "c", default_C_help, default_C_entries, default_C_suffixes },
- { "c++", Cplusplus_help, Cplusplus_entries, Cplusplus_suffixes },
- { "c*", no_lang_help, Cstar_entries, Cstar_suffixes },
- { "cobol", Cobol_help, Cobol_paragraphs, Cobol_suffixes },
- { "erlang", Erlang_help, Erlang_functions, Erlang_suffixes },
- { "forth", Forth_help, Forth_words, Forth_suffixes },
- { "fortran", Fortran_help, Fortran_functions, Fortran_suffixes },
- { "html", HTML_help, HTML_labels, HTML_suffixes },
- { "java", Cjava_help, Cjava_entries, Cjava_suffixes },
- { "lisp", Lisp_help, Lisp_functions, Lisp_suffixes },
- { "lua", Lua_help, Lua_functions, Lua_suffixes },
- { "makefile", Makefile_help,Makefile_targets,NULL,Makefile_filenames},
- { "objc", Objc_help, plain_C_entries, Objc_suffixes },
- { "pascal", Pascal_help, Pascal_functions, Pascal_suffixes },
- { "perl",Perl_help,Perl_functions,Perl_suffixes,NULL,Perl_interpreters},
- { "php", PHP_help, PHP_functions, PHP_suffixes },
- { "postscript",PS_help, PS_functions, PS_suffixes },
- { "proc", no_lang_help, plain_C_entries, plain_C_suffixes },
- { "prolog", Prolog_help, Prolog_functions, Prolog_suffixes },
- { "python", Python_help, Python_functions, Python_suffixes },
- { "scheme", Scheme_help, Scheme_functions, Scheme_suffixes },
- { "tex", TeX_help, TeX_commands, TeX_suffixes },
- { "texinfo", Texinfo_help, Texinfo_nodes, Texinfo_suffixes },
- { "yacc", Yacc_help,Yacc_entries,Yacc_suffixes,NULL,NULL,TRUE},
- { "auto", auto_help },
- { "none", none_help, just_read_file },
- { NULL }
- };
- static void
- print_language_names (void)
- {
- language *lang;
- const char **name, **ext;
- puts ("\nThese are the currently supported languages, along with the\n\
- default file names and dot suffixes:");
- for (lang = lang_names; lang->name != NULL; lang++)
- {
- printf (" %-*s", 10, lang->name);
- if (lang->filenames != NULL)
- for (name = lang->filenames; *name != NULL; name++)
- printf (" %s", *name);
- if (lang->suffixes != NULL)
- for (ext = lang->suffixes; *ext != NULL; ext++)
- printf (" .%s", *ext);
- puts ("");
- }
- puts ("where `auto' means use default language for files based on file\n\
- name suffix, and `none' means only do regexp processing on files.\n\
- If no language is specified and no matching suffix is found,\n\
- the first line of the file is read for a sharp-bang (#!) sequence\n\
- followed by the name of an interpreter. If no such sequence is found,\n\
- Fortran is tried first; if no tags are found, C is tried next.\n\
- When parsing any C file, a \"class\" or \"template\" keyword\n\
- switches to C++.");
- puts ("Compressed files are supported using gzip, bzip2, and xz.\n\
- \n\
- For detailed help on a given language use, for example,\n\
- etags --help --lang=ada.");
- }
- #ifndef EMACS_NAME
- # define EMACS_NAME "standalone"
- #endif
- #ifndef VERSION
- # define VERSION "17.38.1.4"
- #endif
- static void
- print_version (void)
- {
-
- char emacs_copyright[] = "Copyright (C) 2012 Free Software Foundation, Inc.";
- printf ("%s (%s %s)\n", (CTAGS) ? "ctags" : "etags", EMACS_NAME, VERSION);
- puts (emacs_copyright);
- puts ("This program is distributed under the terms in ETAGS.README");
- exit (EXIT_SUCCESS);
- }
- #ifndef PRINT_UNDOCUMENTED_OPTIONS_HELP
- # define PRINT_UNDOCUMENTED_OPTIONS_HELP FALSE
- #endif
- static void
- print_help (argument *argbuffer)
- {
- bool help_for_lang = FALSE;
- for (; argbuffer->arg_type != at_end; argbuffer++)
- if (argbuffer->arg_type == at_language)
- {
- if (help_for_lang)
- puts ("");
- puts (argbuffer->lang->help);
- help_for_lang = TRUE;
- }
- if (help_for_lang)
- exit (EXIT_SUCCESS);
- printf ("Usage: %s [options] [[regex-option ...] file-name] ...\n\
- \n\
- These are the options accepted by %s.\n", progname, progname);
- if (NO_LONG_OPTIONS)
- puts ("WARNING: long option names do not work with this executable,\n\
- as it is not linked with GNU getopt.");
- else
- puts ("You may use unambiguous abbreviations for the long option names.");
- puts (" A - as file name means read names from stdin (one per line).\n\
- Absolute names are stored in the output file as they are.\n\
- Relative ones are stored relative to the output file's directory.\n");
- puts ("-a, --append\n\
- Append tag entries to existing tags file.");
- puts ("--packages-only\n\
- For Ada files, only generate tags for packages.");
- if (CTAGS)
- puts ("-B, --backward-search\n\
- Write the search commands for the tag entries using '?', the\n\
- backward-search command instead of '/', the forward-search command.");
-
- puts ("--declarations\n\
- In C and derived languages, create tags for function declarations,");
- if (CTAGS)
- puts ("\tand create tags for extern variables if --globals is used.");
- else
- puts
- ("\tand create tags for extern variables unless --no-globals is used.");
- if (CTAGS)
- puts ("-d, --defines\n\
- Create tag entries for C #define constants and enum constants, too.");
- else
- puts ("-D, --no-defines\n\
- Don't create tag entries for C #define constants and enum constants.\n\
- This makes the tags file smaller.");
- if (!CTAGS)
- puts ("-i FILE, --include=FILE\n\
- Include a note in tag file indicating that, when searching for\n\
- a tag, one should also consult the tags file FILE after\n\
- checking the current file.");
- puts ("-l LANG, --language=LANG\n\
- Force the following files to be considered as written in the\n\
- named language up to the next --language=LANG option.");
- if (CTAGS)
- puts ("--globals\n\
- Create tag entries for global variables in some languages.");
- else
- puts ("--no-globals\n\
- Do not create tag entries for global variables in some\n\
- languages. This makes the tags file smaller.");
- if (PRINT_UNDOCUMENTED_OPTIONS_HELP)
- puts ("--no-line-directive\n\
- Ignore #line preprocessor directives in C and derived languages.");
- if (CTAGS)
- puts ("--members\n\
- Create tag entries for members of structures in some languages.");
- else
- puts ("--no-members\n\
- Do not create tag entries for members of structures\n\
- in some languages.");
- puts ("-r REGEXP, --regex=REGEXP or --regex=@regexfile\n\
- Make a tag for each line matching a regular expression pattern\n\
- in the following files. {LANGUAGE}REGEXP uses REGEXP for LANGUAGE\n\
- files only. REGEXFILE is a file containing one REGEXP per line.\n\
- REGEXP takes the form /TAGREGEXP/TAGNAME/MODS, where TAGNAME/ is\n\
- optional. The TAGREGEXP pattern is anchored (as if preceded by ^).");
- puts (" If TAGNAME/ is present, the tags created are named.\n\
- For example Tcl named tags can be created with:\n\
- --regex=\"/proc[ \\t]+\\([^ \\t]+\\)/\\1/.\".\n\
- MODS are optional one-letter modifiers: `i' means to ignore case,\n\
- `m' means to allow multi-line matches, `s' implies `m' and\n\
- causes dot to match any character, including newline.");
- puts ("-R, --no-regex\n\
- Don't create tags from regexps for the following files.");
- puts ("-I, --ignore-indentation\n\
- In C and C++ do not assume that a closing brace in the first\n\
- column is the final brace of a function or structure definition.");
- puts ("-o FILE, --output=FILE\n\
- Write the tags to FILE.");
- puts ("--parse-stdin=NAME\n\
- Read from standard input and record tags as belonging to file NAME.");
- if (CTAGS)
- {
- puts ("-t, --typedefs\n\
- Generate tag entries for C and Ada typedefs.");
- puts ("-T, --typedefs-and-c++\n\
- Generate tag entries for C typedefs, C struct/enum/union tags,\n\
- and C++ member functions.");
- }
- if (CTAGS)
- puts ("-u, --update\n\
- Update the tag entries for the given files, leaving tag\n\
- entries for other files in place. Currently, this is\n\
- implemented by deleting the existing entries for the given\n\
- files and then rewriting the new entries at the end of the\n\
- tags file. It is often faster to simply rebuild the entire\n\
- tag file than to use this.");
- if (CTAGS)
- {
- puts ("-v, --vgrind\n\
- Print on the standard output an index of items intended for\n\
- human consumption, similar to the output of vgrind. The index\n\
- is sorted, and gives the page number of each item.");
- if (PRINT_UNDOCUMENTED_OPTIONS_HELP)
- puts ("-w, --no-duplicates\n\
- Do not create duplicate tag entries, for compatibility with\n\
- traditional ctags.");
- if (PRINT_UNDOCUMENTED_OPTIONS_HELP)
- puts ("-w, --no-warn\n\
- Suppress warning messages about duplicate tag entries.");
- puts ("-x, --cxref\n\
- Like --vgrind, but in the style of cxref, rather than vgrind.\n\
- The output uses line numbers instead of page numbers, but\n\
- beyond that the differences are cosmetic; try both to see\n\
- which you like.");
- }
- puts ("-V, --version\n\
- Print the version of the program.\n\
- -h, --help\n\
- Print this help message.\n\
- Followed by one or more `--language' options prints detailed\n\
- help about tag generation for the specified languages.");
- print_language_names ();
- puts ("");
- puts ("Report bugs to bug-gnu-emacs@gnu.org");
- exit (EXIT_SUCCESS);
- }
- int
- main (int argc, char **argv)
- {
- int i;
- unsigned int nincluded_files;
- char **included_files;
- argument *argbuffer;
- int current_arg, file_count;
- linebuffer filename_lb;
- bool help_asked = FALSE;
- ptrdiff_t len;
- char *optstring;
- int opt;
- #ifdef DOS_NT
- _fmode = O_BINARY;
- #endif
- progname = argv[0];
- nincluded_files = 0;
- included_files = xnew (argc, char *);
- current_arg = 0;
- file_count = 0;
-
- argbuffer = xnew (argc, argument);
-
- typedefs = typedefs_or_cplusplus = constantypedefs = TRUE;
- globals = members = TRUE;
-
- optstring = concat (NO_LONG_OPTIONS ? "" : "-",
- "ac:Cf:Il:o:r:RSVhH",
- (CTAGS) ? "BxdtTuvw" : "Di:");
- while ((opt = getopt_long (argc, argv, optstring, longopts, NULL)) != EOF)
- switch (opt)
- {
- case 0:
-
- break;
- case 1:
-
- argbuffer[current_arg].arg_type = at_filename;
- argbuffer[current_arg].what = optarg;
- len = strlen (optarg);
- if (whatlen_max < len)
- whatlen_max = len;
- ++current_arg;
- ++file_count;
- break;
- case STDIN:
-
- argbuffer[current_arg].arg_type = at_stdin;
- argbuffer[current_arg].what = optarg;
- len = strlen (optarg);
- if (whatlen_max < len)
- whatlen_max = len;
- ++current_arg;
- ++file_count;
- if (parsing_stdin)
- fatal ("cannot parse standard input more than once", (char *)NULL);
- parsing_stdin = TRUE;
- break;
-
- case 'a': append_to_tagfile = TRUE; break;
- case 'C': cplusplus = TRUE; break;
- case 'f':
- case 'o':
- if (tagfile)
- {
- error ("-o option may only be given once.", (char *)NULL);
- suggest_asking_for_help ();
-
- }
- tagfile = optarg;
- break;
- case 'I':
- case 'S':
- ignoreindent = TRUE;
- break;
- case 'l':
- {
- language *lang = get_language_from_langname (optarg);
- if (lang != NULL)
- {
- argbuffer[current_arg].lang = lang;
- argbuffer[current_arg].arg_type = at_language;
- ++current_arg;
- }
- }
- break;
- case 'c':
-
- optarg = concat (optarg, "i", "");
-
- case 'r':
- argbuffer[current_arg].arg_type = at_regexp;
- argbuffer[current_arg].what = optarg;
- len = strlen (optarg);
- if (whatlen_max < len)
- whatlen_max = len;
- ++current_arg;
- break;
- case 'R':
- argbuffer[current_arg].arg_type = at_regexp;
- argbuffer[current_arg].what = NULL;
- ++current_arg;
- break;
- case 'V':
- print_version ();
- break;
- case 'h':
- case 'H':
- help_asked = TRUE;
- break;
-
- case 'D': constantypedefs = FALSE; break;
- case 'i': included_files[nincluded_files++] = optarg; break;
-
- case 'B': searchar = '?'; break;
- case 'd': constantypedefs = TRUE; break;
- case 't': typedefs = TRUE; break;
- case 'T': typedefs = typedefs_or_cplusplus = TRUE; break;
- case 'u': update = TRUE; break;
- case 'v': vgrind_style = TRUE;
- case 'x': cxref_style = TRUE; break;
- case 'w': no_warnings = TRUE; break;
- default:
- suggest_asking_for_help ();
-
- }
-
- for (; optind < argc; optind++)
- {
- argbuffer[current_arg].arg_type = at_filename;
- argbuffer[current_arg].what = argv[optind];
- len = strlen (argv[optind]);
- if (whatlen_max < len)
- whatlen_max = len;
- ++current_arg;
- ++file_count;
- }
- argbuffer[current_arg].arg_type = at_end;
- if (help_asked)
- print_help (argbuffer);
-
- if (nincluded_files == 0 && file_count == 0)
- {
- error ("no input files specified.", (char *)NULL);
- suggest_asking_for_help ();
-
- }
- if (tagfile == NULL)
- tagfile = savestr (CTAGS ? "tags" : "TAGS");
- cwd = etags_getcwd ();
- if (cwd[strlen (cwd) - 1] != '/')
- {
- char *oldcwd = cwd;
- cwd = concat (oldcwd, "/", "");
- free (oldcwd);
- }
-
- if (streq (tagfile, "-")
- || strneq (tagfile, "/dev/", 5))
- tagfiledir = cwd;
- else
- {
- canonicalize_filename (tagfile);
- tagfiledir = absolute_dirname (tagfile, cwd);
- }
- init ();
- linebuffer_init (&lb);
- linebuffer_init (&filename_lb);
- linebuffer_init (&filebuf);
- linebuffer_init (&token_name);
- if (!CTAGS)
- {
- if (streq (tagfile, "-"))
- {
- tagf = stdout;
- #ifdef DOS_NT
-
- if (!isatty (fileno (stdout)))
- setmode (fileno (stdout), O_BINARY);
- #endif
- }
- else
- tagf = fopen (tagfile, append_to_tagfile ? "a" : "w");
- if (tagf == NULL)
- pfatal (tagfile);
- }
-
- for (i = 0; i < current_arg; i++)
- {
- static language *lang;
- char *this_file;
- switch (argbuffer[i].arg_type)
- {
- case at_language:
- lang = argbuffer[i].lang;
- break;
- case at_regexp:
- analyse_regex (argbuffer[i].what);
- break;
- case at_filename:
- this_file = argbuffer[i].what;
-
- if (streq (this_file, "-"))
- {
- if (parsing_stdin)
- fatal ("cannot parse standard input AND read file names from it",
- (char *)NULL);
- while (readline_internal (&filename_lb, stdin) > 0)
- process_file_name (filename_lb.buffer, lang);
- }
- else
- process_file_name (this_file, lang);
- break;
- case at_stdin:
- this_file = argbuffer[i].what;
- process_file (stdin, this_file, lang);
- break;
- }
- }
- free_regexps ();
- free (lb.buffer);
- free (filebuf.buffer);
- free (token_name.buffer);
- if (!CTAGS || cxref_style)
- {
-
- put_entries (nodehead);
- free_tree (nodehead);
- nodehead = NULL;
- if (!CTAGS)
- {
- fdesc *fdp;
-
- for (fdp = fdhead; fdp != NULL; fdp = fdp->next)
- if (!fdp->written)
- fprintf (tagf, "\f\n%s,0\n", fdp->taggedfname);
- while (nincluded_files-- > 0)
- fprintf (tagf, "\f\n%s,include\n", *included_files++);
- if (fclose (tagf) == EOF)
- pfatal (tagfile);
- }
- exit (EXIT_SUCCESS);
- }
-
- if (update)
- {
- char *cmd =
- xmalloc (strlen (tagfile) + whatlen_max +
- sizeof "mv..OTAGS;fgrep -v '\t\t' OTAGS >;rm OTAGS");
- for (i = 0; i < current_arg; ++i)
- {
- switch (argbuffer[i].arg_type)
- {
- case at_filename:
- case at_stdin:
- break;
- default:
- continue;
- }
- strcpy (cmd, "mv ");
- strcat (cmd, tagfile);
- strcat (cmd, " OTAGS;fgrep -v '\t");
- strcat (cmd, argbuffer[i].what);
- strcat (cmd, "\t' OTAGS >");
- strcat (cmd, tagfile);
- strcat (cmd, ";rm OTAGS");
- if (system (cmd) != EXIT_SUCCESS)
- fatal ("failed to execute shell command", (char *)NULL);
- }
- free (cmd);
- append_to_tagfile = TRUE;
- }
- tagf = fopen (tagfile, append_to_tagfile ? "a" : "w");
- if (tagf == NULL)
- pfatal (tagfile);
- put_entries (nodehead);
- free_tree (nodehead);
- nodehead = NULL;
- if (fclose (tagf) == EOF)
- pfatal (tagfile);
- if (CTAGS)
- if (append_to_tagfile || update)
- {
- char *cmd = xmalloc (2 * strlen (tagfile) + sizeof "sort -u -o..");
-
- strcpy (cmd, "sort -u -o ");
- strcat (cmd, tagfile);
- strcat (cmd, " ");
- strcat (cmd, tagfile);
- exit (system (cmd));
- }
- return EXIT_SUCCESS;
- }
- static compressor *
- get_compressor_from_suffix (char *file, char **extptr)
- {
- compressor *compr;
- char *slash, *suffix;
-
- slash = etags_strrchr (file, '/');
- suffix = etags_strrchr (file, '.');
- if (suffix == NULL || suffix < slash)
- return NULL;
- if (extptr != NULL)
- *extptr = suffix;
- suffix += 1;
-
- do
- {
- for (compr = compressors; compr->suffix != NULL; compr++)
- if (streq (compr->suffix, suffix))
- return compr;
- if (!MSDOS)
- break;
- if (extptr != NULL)
- *extptr = ++suffix;
- } while (*suffix != '\0');
- return NULL;
- }
- static language *
- get_language_from_langname (const char *name)
- {
- language *lang;
- if (name == NULL)
- error ("empty language name", (char *)NULL);
- else
- {
- for (lang = lang_names; lang->name != NULL; lang++)
- if (streq (name, lang->name))
- return lang;
- error ("unknown language \"%s\"", name);
- }
- return NULL;
- }
- static language *
- get_language_from_interpreter (char *interpreter)
- {
- language *lang;
- const char **iname;
- if (interpreter == NULL)
- return NULL;
- for (lang = lang_names; lang->name != NULL; lang++)
- if (lang->interpreters != NULL)
- for (iname = lang->interpreters; *iname != NULL; iname++)
- if (streq (*iname, interpreter))
- return lang;
- return NULL;
- }
- static language *
- get_language_from_filename (char *file, int case_sensitive)
- {
- language *lang;
- const char **name, **ext, *suffix;
-
- for (lang = lang_names; lang->name != NULL; lang++)
- if (lang->filenames != NULL)
- for (name = lang->filenames; *name != NULL; name++)
- if ((case_sensitive)
- ? streq (*name, file)
- : strcaseeq (*name, file))
- return lang;
-
- suffix = etags_strrchr (file, '.');
- if (suffix == NULL)
- return NULL;
- suffix += 1;
- for (lang = lang_names; lang->name != NULL; lang++)
- if (lang->suffixes != NULL)
- for (ext = lang->suffixes; *ext != NULL; ext++)
- if ((case_sensitive)
- ? streq (*ext, suffix)
- : strcaseeq (*ext, suffix))
- return lang;
- return NULL;
- }
- static void
- process_file_name (char *file, language *lang)
- {
- struct stat stat_buf;
- FILE *inf;
- fdesc *fdp;
- compressor *compr;
- char *compressed_name, *uncompressed_name;
- char *ext, *real_name;
- int retval;
- canonicalize_filename (file);
- if (streq (file, tagfile) && !streq (tagfile, "-"))
- {
- error ("skipping inclusion of %s in self.", file);
- return;
- }
- if ((compr = get_compressor_from_suffix (file, &ext)) == NULL)
- {
- compressed_name = NULL;
- real_name = uncompressed_name = savestr (file);
- }
- else
- {
- real_name = compressed_name = savestr (file);
- uncompressed_name = savenstr (file, ext - file);
- }
-
- for (fdp = fdhead; fdp != NULL; fdp = fdp->next)
- {
- assert (fdp->infname != NULL);
- if (streq (uncompressed_name, fdp->infname))
- goto cleanup;
- }
- if (stat (real_name, &stat_buf) != 0)
- {
-
- real_name = NULL;
- if (compressed_name != NULL)
- {
- if (stat (uncompressed_name, &stat_buf) == 0)
- real_name = uncompressed_name;
- }
- else
- {
- for (compr = compressors; compr->suffix != NULL; compr++)
- {
- compressed_name = concat (file, ".", compr->suffix);
- if (stat (compressed_name, &stat_buf) != 0)
- {
- if (MSDOS)
- {
- char *suf = compressed_name + strlen (file);
- size_t suflen = strlen (compr->suffix) + 1;
- for ( ; suf[1]; suf++, suflen--)
- {
- memmove (suf, suf + 1, suflen);
- if (stat (compressed_name, &stat_buf) == 0)
- {
- real_name = compressed_name;
- break;
- }
- }
- if (real_name != NULL)
- break;
- }
- free (compressed_name);
- compressed_name = NULL;
- }
- else
- {
- real_name = compressed_name;
- break;
- }
- }
- }
- if (real_name == NULL)
- {
- perror (file);
- goto cleanup;
- }
- }
- if (!S_ISREG (stat_buf.st_mode))
- {
- error ("skipping %s: it is not a regular file.", real_name);
- goto cleanup;
- }
- if (real_name == compressed_name)
- {
- char *cmd = concat (compr->command, " ", real_name);
- inf = (FILE *) popen (cmd, "r");
- free (cmd);
- }
- else
- inf = fopen (real_name, "r");
- if (inf == NULL)
- {
- perror (real_name);
- goto cleanup;
- }
- process_file (inf, uncompressed_name, lang);
- if (real_name == compressed_name)
- retval = pclose (inf);
- else
- retval = fclose (inf);
- if (retval < 0)
- pfatal (file);
- cleanup:
- free (compressed_name);
- free (uncompressed_name);
- last_node = NULL;
- curfdp = NULL;
- return;
- }
- static void
- process_file (FILE *fh, char *fn, language *lang)
- {
- static const fdesc emptyfdesc;
- fdesc *fdp;
-
- fdp = xnew (1, fdesc);
- *fdp = emptyfdesc;
- fdp->next = fdhead;
- fdp->infname = savestr (fn);
- fdp->lang = lang;
- fdp->infabsname = absolute_filename (fn, cwd);
- fdp->infabsdir = absolute_dirname (fn, cwd);
- if (filename_is_absolute (fn))
- {
-
- fdp->taggedfname = absolute_filename (fn, NULL);
- }
- else
- {
-
- fdp->taggedfname = relative_filename (fn, tagfiledir);
- }
- fdp->usecharno = TRUE;
- fdp->prop = NULL;
- fdp->written = FALSE;
- fdhead = fdp;
- curfdp = fdhead;
- find_entries (fh);
-
- if (!CTAGS
- && curfdp->usecharno
- && !curfdp->lang->metasource)
- {
- node *np, *prev;
-
- prev = NULL;
- for (np = nodehead; np != NULL; prev = np, np = np->left)
- if (np->fdp == curfdp)
- break;
-
- if (np != NULL)
- {
-
- assert (np->left == NULL);
- assert (fdhead == curfdp);
- assert (last_node->fdp == curfdp);
- put_entries (np);
- free_tree (np);
- if (prev == NULL)
- nodehead = NULL;
- else
- prev->left = NULL;
- }
- }
- }
- static void
- init (void)
- {
- register const char *sp;
- register int i;
- for (i = 0; i < CHARS; i++)
- iswhite (i) = notinname (i) = begtoken (i) = intoken (i) = endtoken (i) = FALSE;
- for (sp = white; *sp != '\0'; sp++) iswhite (*sp) = TRUE;
- for (sp = nonam; *sp != '\0'; sp++) notinname (*sp) = TRUE;
- notinname ('\0') = notinname ('\n');
- for (sp = begtk; *sp != '\0'; sp++) begtoken (*sp) = TRUE;
- begtoken ('\0') = begtoken ('\n');
- for (sp = midtk; *sp != '\0'; sp++) intoken (*sp) = TRUE;
- intoken ('\0') = intoken ('\n');
- for (sp = endtk; *sp != '\0'; sp++) endtoken (*sp) = TRUE;
- endtoken ('\0') = endtoken ('\n');
- }
- static void
- find_entries (FILE *inf)
- {
- char *cp;
- language *lang = curfdp->lang;
- Lang_function *parser = NULL;
-
- if (lang != NULL && lang->function != NULL)
- {
- parser = lang->function;
- }
-
- if (parser == NULL)
- {
- lang = get_language_from_filename (curfdp->infname, TRUE);
- if (lang != NULL && lang->function != NULL)
- {
- curfdp->lang = lang;
- parser = lang->function;
- }
- }
-
- if (parser == NULL
- && readline_internal (&lb, inf) > 0
- && lb.len >= 2
- && lb.buffer[0] == '#'
- && lb.buffer[1] == '!')
- {
- char *lp;
-
- lp = etags_strrchr (lb.buffer+2, '/');
- if (lp != NULL)
- lp += 1;
- else
- lp = skip_spaces (lb.buffer + 2);
- cp = skip_non_spaces (lp);
- *cp = '\0';
- if (strlen (lp) > 0)
- {
- lang = get_language_from_interpreter (lp);
- if (lang != NULL && lang->function != NULL)
- {
- curfdp->lang = lang;
- parser = lang->function;
- }
- }
- }
-
- rewind (inf);
-
- if (parser == NULL)
- {
- lang = get_language_from_filename (curfdp->infname, FALSE);
- if (lang != NULL && lang->function != NULL)
- {
- curfdp->lang = lang;
- parser = lang->function;
- }
- }
-
- if (parser == NULL)
- {
- node *old_last_node = last_node;
- curfdp->lang = get_language_from_langname ("fortran");
- find_entries (inf);
- if (old_last_node == last_node)
-
- {
-
- rewind (inf);
- curfdp->lang = get_language_from_langname (cplusplus ? "c++" : "c");
- find_entries (inf);
- }
- return;
- }
- if (!no_line_directive
- && curfdp->lang != NULL && curfdp->lang->metasource)
-
- {
- fdesc **fdpp = &fdhead;
- while (*fdpp != NULL)
- if (*fdpp != curfdp
- && streq ((*fdpp)->taggedfname, curfdp->taggedfname))
-
- {
- fdesc *badfdp = *fdpp;
-
- invalidate_nodes (badfdp, &nodehead);
- *fdpp = badfdp->next;
- free_fdesc (badfdp);
- }
- else
- fdpp = &(*fdpp)->next;
- }
- assert (parser != NULL);
-
- linebuffer_setlen (&filebuf, 0);
-
- lineno = 0;
- charno = 0;
- linecharno = 0;
- parser (inf);
- regex_tag_multiline ();
- }
- static void
- make_tag (const char *name,
- int namelen,
- int is_func,
- char *linestart,
- int linelen,
- int lno,
- long int cno)
- {
- bool named = (name != NULL && namelen > 0);
- char *nname = NULL;
- if (!CTAGS && named)
-
- {
- int i;
- register const char *cp = name;
- for (i = 0; i < namelen; i++)
- if (notinname (*cp++))
- break;
- if (i == namelen)
- {
- cp = linestart + linelen - namelen;
- if (notinname (linestart[linelen-1]))
- cp -= 1;
- if (cp >= linestart
- && (cp == linestart
- || notinname (cp[-1]))
- && strneq (name, cp, namelen))
- named = FALSE;
- }
- }
- if (named)
- nname = savenstr (name, namelen);
- pfnote (nname, is_func, linestart, linelen, lno, cno);
- }
- static void
- pfnote (char *name, int is_func, char *linestart, int linelen, int lno, long int cno)
-
-
-
-
-
-
- {
- register node *np;
- assert (name == NULL || name[0] != '\0');
- if (CTAGS && name == NULL)
- return;
- np = xnew (1, node);
-
- if (CTAGS && !cxref_style && streq (name, "main"))
- {
- register char *fp = etags_strrchr (curfdp->taggedfname, '/');
- np->name = concat ("M", fp == NULL ? curfdp->taggedfname : fp + 1, "");
- fp = etags_strrchr (np->name, '.');
- if (fp != NULL && fp[1] != '\0' && fp[2] == '\0')
- fp[0] = '\0';
- }
- else
- np->name = name;
- np->valid = TRUE;
- np->been_warned = FALSE;
- np->fdp = curfdp;
- np->is_func = is_func;
- np->lno = lno;
- if (np->fdp->usecharno)
-
- np->cno = cno ;
- else
- np->cno = invalidcharno;
- np->left = np->right = NULL;
- if (CTAGS && !cxref_style)
- {
- if (strlen (linestart) < 50)
- np->regex = concat (linestart, "$", "");
- else
- np->regex = savenstr (linestart, 50);
- }
- else
- np->regex = savenstr (linestart, linelen);
- add_node (np, &nodehead);
- }
- static void
- free_tree (register node *np)
- {
- while (np)
- {
- register node *node_right = np->right;
- free_tree (np->left);
- free (np->name);
- free (np->regex);
- free (np);
- np = node_right;
- }
- }
- static void
- free_fdesc (register fdesc *fdp)
- {
- free (fdp->infname);
- free (fdp->infabsname);
- free (fdp->infabsdir);
- free (fdp->taggedfname);
- free (fdp->prop);
- free (fdp);
- }
- static void
- add_node (node *np, node **cur_node_p)
- {
- register int dif;
- register node *cur_node = *cur_node_p;
- if (cur_node == NULL)
- {
- *cur_node_p = np;
- last_node = np;
- return;
- }
- if (!CTAGS)
-
- {
-
- if (last_node != NULL && last_node->fdp == np->fdp)
- {
-
- assert (last_node->right == NULL);
- last_node->right = np;
- last_node = np;
- }
- else if (cur_node->fdp == np->fdp)
- {
-
- add_node (np, &cur_node->right);
- }
- else
-
- add_node (np, &cur_node->left);
- }
- else
- {
-
- dif = strcmp (np->name, cur_node->name);
-
- if (no_duplicates && !dif)
- {
- if (np->fdp == cur_node->fdp)
- {
- if (!no_warnings)
- {
- fprintf (stderr, "Duplicate entry in file %s, line %d: %s\n",
- np->fdp->infname, lineno, np->name);
- fprintf (stderr, "Second entry ignored\n");
- }
- }
- else if (!cur_node->been_warned && !no_warnings)
- {
- fprintf
- (stderr,
- "Duplicate entry in files %s and %s: %s (Warning only)\n",
- np->fdp->infname, cur_node->fdp->infname, np->name);
- cur_node->been_warned = TRUE;
- }
- return;
- }
-
- add_node (np, dif < 0 ? &cur_node->left : &cur_node->right);
- }
- }
- static void
- invalidate_nodes (fdesc *badfdp, node **npp)
- {
- node *np = *npp;
- if (np == NULL)
- return;
- if (CTAGS)
- {
- if (np->left != NULL)
- invalidate_nodes (badfdp, &np->left);
- if (np->fdp == badfdp)
- np->valid = FALSE;
- if (np->right != NULL)
- invalidate_nodes (badfdp, &np->right);
- }
- else
- {
- assert (np->fdp != NULL);
- if (np->fdp == badfdp)
- {
- *npp = np->left;
- np->left = NULL;
- free_tree (np);
- invalidate_nodes (badfdp, npp);
- }
- else
- invalidate_nodes (badfdp, &np->left);
- }
- }
- static int total_size_of_entries (node *);
- static int number_len (long);
- static int
- number_len (long int num)
- {
- int len = 1;
- while ((num /= 10) > 0)
- len += 1;
- return len;
- }
- static int
- total_size_of_entries (register node *np)
- {
- register int total = 0;
- for (; np != NULL; np = np->right)
- if (np->valid)
- {
- total += strlen (np->regex) + 1;
- if (np->name != NULL)
- total += strlen (np->name) + 1;
- total += number_len ((long) np->lno) + 1;
- if (np->cno != invalidcharno)
- total += number_len (np->cno);
- total += 1;
- }
- return total;
- }
- static void
- put_entries (register node *np)
- {
- register char *sp;
- static fdesc *fdp = NULL;
- if (np == NULL)
- return;
-
- if (CTAGS)
- put_entries (np->left);
-
- if (np->valid)
- {
- if (!CTAGS)
- {
-
- if (fdp != np->fdp)
- {
- fdp = np->fdp;
- fprintf (tagf, "\f\n%s,%d\n",
- fdp->taggedfname, total_size_of_entries (np));
- fdp->written = TRUE;
- }
- fputs (np->regex, tagf);
- fputc ('\177', tagf);
- if (np->name != NULL)
- {
- fputs (np->name, tagf);
- fputc ('\001', tagf);
- }
- fprintf (tagf, "%d,", np->lno);
- if (np->cno != invalidcharno)
- fprintf (tagf, "%ld", np->cno);
- fputs ("\n", tagf);
- }
- else
- {
-
- if (np->name == NULL)
- error ("internal error: NULL name in ctags mode.", (char *)NULL);
- if (cxref_style)
- {
- if (vgrind_style)
- fprintf (stdout, "%s %s %d\n",
- np->name, np->fdp->taggedfname, (np->lno + 63) / 64);
- else
- fprintf (stdout, "%-16s %3d %-16s %s\n",
- np->name, np->lno, np->fdp->taggedfname, np->regex);
- }
- else
- {
- fprintf (tagf, "%s\t%s\t", np->name, np->fdp->taggedfname);
- if (np->is_func)
- {
- putc (searchar, tagf);
- putc ('^', tagf);
- for (sp = np->regex; *sp; sp++)
- {
- if (*sp == '\\' || *sp == searchar)
- putc ('\\', tagf);
- putc (*sp, tagf);
- }
- putc (searchar, tagf);
- }
- else
- {
- fprintf (tagf, "%d", np->lno);
- }
- putc ('\n', tagf);
- }
- }
- }
-
- put_entries (np->right);
- if (!CTAGS)
- put_entries (np->left);
- }
- #define C_EXT 0x00fff
- #define C_PLAIN 0x00000
- #define C_PLPL 0x00001
- #define C_STAR 0x00003
- #define C_JAVA 0x00005
- #define C_AUTO 0x01000
- #define YACC 0x10000
- enum sym_type
- {
- st_none,
- st_C_objprot, st_C_objimpl, st_C_objend,
- st_C_gnumacro,
- st_C_ignore, st_C_attribute,
- st_C_javastruct,
- st_C_operator,
- st_C_class, st_C_template,
- st_C_struct, st_C_extern, st_C_enum, st_C_define, st_C_typedef
- };
- static unsigned int hash (const char *, unsigned int);
- static struct C_stab_entry * in_word_set (const char *, unsigned int);
- static enum sym_type C_symtype (char *, int, int);
- struct C_stab_entry { const char *name; int c_ext; enum sym_type type; };
- static inline unsigned int
- hash (register const char *str, register unsigned int len)
- {
- static unsigned char asso_values[] =
- {
- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35, 35, 3,
- 26, 35, 35, 35, 35, 35, 35, 35, 27, 35,
- 35, 35, 35, 24, 0, 35, 35, 35, 35, 0,
- 35, 35, 35, 35, 35, 1, 35, 16, 35, 6,
- 23, 0, 0, 35, 22, 0, 35, 35, 5, 0,
- 0, 15, 1, 35, 6, 35, 8, 19, 35, 16,
- 4, 5, 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35
- };
- register int hval = len;
- switch (hval)
- {
- default:
- hval += asso_values[(unsigned char)str[2]];
-
- case 2:
- hval += asso_values[(unsigned char)str[1]];
- break;
- }
- return hval;
- }
- static struct C_stab_entry *
- in_word_set (register const char *str, register unsigned int len)
- {
- enum
- {
- TOTAL_KEYWORDS = 33,
- MIN_WORD_LENGTH = 2,
- MAX_WORD_LENGTH = 15,
- MIN_HASH_VALUE = 2,
- MAX_HASH_VALUE = 34
- };
- static struct C_stab_entry wordlist[] =
- {
- {""}, {""},
- {"if", 0, st_C_ignore},
- {"GTY", 0, st_C_attribute},
- {"@end", 0, st_C_objend},
- {"union", 0, st_C_struct},
- {"define", 0, st_C_define},
- {"import", (C_JAVA & ~C_PLPL), st_C_ignore},
- {"template", 0, st_C_template},
- {"operator", C_PLPL, st_C_operator},
- {"@interface", 0, st_C_objprot},
- {"implements", (C_JAVA & ~C_PLPL), st_C_javastruct},
- {"friend", C_PLPL, st_C_ignore},
- {"typedef", 0, st_C_typedef},
- {"return", 0, st_C_ignore},
- {"@implementation",0, st_C_objimpl},
- {"@protocol", 0, st_C_objprot},
- {"interface", (C_JAVA & ~C_PLPL), st_C_struct},
- {"extern", 0, st_C_extern},
- {"extends", (C_JAVA & ~C_PLPL), st_C_javastruct},
- {"struct", 0, st_C_struct},
- {"domain", C_STAR, st_C_struct},
- {"switch", 0, st_C_ignore},
- {"enum", 0, st_C_enum},
- {"for", 0, st_C_ignore},
- {"namespace", C_PLPL, st_C_struct},
- {"class", 0, st_C_class},
- {"while", 0, st_C_ignore},
- {"undef", 0, st_C_define},
- {"package", (C_JAVA & ~C_PLPL), st_C_ignore},
- {"__attribute__", 0, st_C_attribute},
- {"SYSCALL", 0, st_C_gnumacro},
- {"ENTRY", 0, st_C_gnumacro},
- {"PSEUDO", 0, st_C_gnumacro},
- {"DEFUN", 0, st_C_gnumacro}
- };
- if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
- {
- register int key = hash (str, len);
- if (key <= MAX_HASH_VALUE && key >= 0)
- {
- register const char *s = wordlist[key].name;
- if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
- return &wordlist[key];
- }
- }
- return 0;
- }
- static enum sym_type
- C_symtype (char *str, int len, int c_ext)
- {
- register struct C_stab_entry *se = in_word_set (str, len);
- if (se == NULL || (se->c_ext && !(c_ext & se->c_ext)))
- return st_none;
- return se->type;
- }
- static bool inattribute;
- static enum
- {
- fvnone,
- fdefunkey,
- fdefunname,
- foperator,
- fvnameseen,
- fstartlist,
- finlist,
- flistseen,
- fignore,
- vignore
- } fvdef;
- static bool fvextern;
- static enum
- {
- tnone,
- tkeyseen,
- ttypeseen,
- tinbody,
- tend,
- tignore
- } typdef;
- static enum
- {
- snone,
- skeyseen,
- stagseen,
- scolonseen
- } structdef;
- static const char *objtag = "<uninited>";
- static enum
- {
- dnone,
- dsharpseen,
- ddefineseen,
- dignorerest
- } definedef;
- static enum
- {
- onone,
- oprotocol,
- oimplementation,
- otagseen,
- oparenseen,
- ocatseen,
- oinbody,
- omethodsign,
- omethodtag,
- omethodcolon,
- omethodparm,
- oignore
- } objdef;
- static struct tok
- {
- char *line;
- int offset;
- int length;
-
- bool valid;
- bool named;
- int lineno;
- long linepos;
- } token;
- static void pushclass_above (int, char *, int);
- static void popclass_above (int);
- static void write_classname (linebuffer *, const char *qualifier);
- static struct {
- char **cname;
- int *bracelev;
- int nl;
- int size;
- } cstack;
- #define nestlev (cstack.nl)
- #define instruct (structdef == snone && nestlev > 0 \
- && bracelev == cstack.bracelev[nestlev-1] + 1)
- static void
- pushclass_above (int bracelev, char *str, int len)
- {
- int nl;
- popclass_above (bracelev);
- nl = cstack.nl;
- if (nl >= cstack.size)
- {
- int size = cstack.size *= 2;
- xrnew (cstack.cname, size, char *);
- xrnew (cstack.bracelev, size, int);
- }
- assert (nl == 0 || cstack.bracelev[nl-1] < bracelev);
- cstack.cname[nl] = (str == NULL) ? NULL : savenstr (str, len);
- cstack.bracelev[nl] = bracelev;
- cstack.nl = nl + 1;
- }
- static void
- popclass_above (int bracelev)
- {
- int nl;
- for (nl = cstack.nl - 1;
- nl >= 0 && cstack.bracelev[nl] >= bracelev;
- nl--)
- {
- free (cstack.cname[nl]);
- cstack.nl = nl;
- }
- }
- static void
- write_classname (linebuffer *cn, const char *qualifier)
- {
- int i, len;
- int qlen = strlen (qualifier);
- if (cstack.nl == 0 || cstack.cname[0] == NULL)
- {
- len = 0;
- cn->len = 0;
- cn->buffer[0] = '\0';
- }
- else
- {
- len = strlen (cstack.cname[0]);
- linebuffer_setlen (cn, len);
- strcpy (cn->buffer, cstack.cname[0]);
- }
- for (i = 1; i < cstack.nl; i++)
- {
- char *s;
- int slen;
- s = cstack.cname[i];
- if (s == NULL)
- continue;
- slen = strlen (s);
- len += slen + qlen;
- linebuffer_setlen (cn, len);
- strncat (cn->buffer, qualifier, qlen);
- strncat (cn->buffer, s, slen);
- }
- }
- static bool consider_token (char *, int, int, int *, int, int, bool *);
- static void make_C_tag (bool);
- static bool
- consider_token (register char *str, register int len, register int c, int *c_extp, int bracelev, int parlev, int *is_func_or_var)
-
-
-
-
-
-
-
- {
-
- static enum sym_type structtype;
- static int structbracelev;
- static enum sym_type toktype;
- toktype = C_symtype (str, len, *c_extp);
-
- if (toktype == st_C_attribute)
- {
- inattribute = TRUE;
- return FALSE;
- }
-
- switch (definedef)
- {
- case dnone:
-
- if (toktype == st_C_gnumacro)
- {
- fvdef = fdefunkey;
- return FALSE;
- }
- break;
- case dsharpseen:
- if (toktype == st_C_define)
- {
- definedef = ddefineseen;
- }
- else
- {
- definedef = dignorerest;
- }
- return FALSE;
- case ddefineseen:
-
- definedef = dignorerest;
- *is_func_or_var = (c == '(');
- if (!*is_func_or_var && !constantypedefs)
- return FALSE;
- else
- return TRUE;
- case dignorerest:
- return FALSE;
- default:
- error ("internal error: definedef value.", (char *)NULL);
- }
-
- switch (typdef)
- {
- case tnone:
- if (toktype == st_C_typedef)
- {
- if (typedefs)
- typdef = tkeyseen;
- fvextern = FALSE;
- fvdef = fvnone;
- return FALSE;
- }
- break;
- case tkeyseen:
- switch (toktype)
- {
- case st_none:
- case st_C_class:
- case st_C_struct:
- case st_C_enum:
- typdef = ttypeseen;
- }
- break;
- case ttypeseen:
- if (structdef == snone && fvdef == fvnone)
- {
- fvdef = fvnameseen;
- return TRUE;
- }
- break;
- case tend:
- switch (toktype)
- {
- case st_C_class:
- case st_C_struct:
- case st_C_enum:
- return FALSE;
- }
- return TRUE;
- }
- switch (toktype)
- {
- case st_C_javastruct:
- if (structdef == stagseen)
- structdef = scolonseen;
- return FALSE;
- case st_C_template:
- case st_C_class:
- if ((*c_extp & C_AUTO)
- && bracelev == 0
- && definedef == dnone && structdef == snone
- && typdef == tnone && fvdef == fvnone)
- *c_extp = (*c_extp | C_PLPL) & ~C_AUTO;
- if (toktype == st_C_template)
- break;
-
- case st_C_struct:
- case st_C_enum:
- if (parlev == 0
- && fvdef != vignore
- && (typdef == tkeyseen
- || (typedefs_or_cplusplus && structdef == snone)))
- {
- structdef = skeyseen;
- structtype = toktype;
- structbracelev = bracelev;
- if (fvdef == fvnameseen)
- fvdef = fvnone;
- }
- return FALSE;
- }
- if (structdef == skeyseen)
- {
- structdef = stagseen;
- return TRUE;
- }
- if (typdef != tnone)
- definedef = dnone;
-
- switch (objdef)
- {
- case onone:
- switch (toktype)
- {
- case st_C_objprot:
- objdef = oprotocol;
- return FALSE;
- case st_C_objimpl:
- objdef = oimplementation;
- return FALSE;
- }
- break;
- case oimplementation:
-
- objtag = savenstr (str, len);
- objdef = oinbody;
- return FALSE;
- case oprotocol:
-
- objtag = savenstr (str, len);
- objdef = otagseen;
- *is_func_or_var = TRUE;
- return TRUE;
- case oparenseen:
- objdef = ocatseen;
- *is_func_or_var = TRUE;
- return TRUE;
- case oinbody:
- break;
- case omethodsign:
- if (parlev == 0)
- {
- fvdef = fvnone;
- objdef = omethodtag;
- linebuffer_setlen (&token_name, len);
- strncpy (token_name.buffer, str, len);
- token_name.buffer[len] = '\0';
- return TRUE;
- }
- return FALSE;
- case omethodcolon:
- if (parlev == 0)
- objdef = omethodparm;
- return FALSE;
- case omethodparm:
- if (parlev == 0)
- {
- fvdef = fvnone;
- objdef = omethodtag;
- linebuffer_setlen (&token_name, token_name.len + len);
- strncat (token_name.buffer, str, len);
- return TRUE;
- }
- return FALSE;
- case oignore:
- if (toktype == st_C_objend)
- {
-
- objdef = onone;
- }
- return FALSE;
- }
-
- switch (toktype)
- {
- case st_C_extern:
- fvextern = TRUE;
- switch (fvdef)
- {
- case finlist:
- case flistseen:
- case fignore:
- case vignore:
- break;
- default:
- fvdef = fvnone;
- }
- return FALSE;
- case st_C_ignore:
- fvextern = FALSE;
- fvdef = vignore;
- return FALSE;
- case st_C_operator:
- fvdef = foperator;
- *is_func_or_var = TRUE;
- return TRUE;
- case st_none:
- if (constantypedefs
- && structdef == snone
- && structtype == st_C_enum && bracelev > structbracelev)
- return TRUE;
- switch (fvdef)
- {
- case fdefunkey:
- if (bracelev > 0)
- break;
- fvdef = fdefunname;
- *is_func_or_var = TRUE;
- return TRUE;
- case fvnone:
- switch (typdef)
- {
- case ttypeseen:
- return FALSE;
- case tnone:
- if ((strneq (str, "asm", 3) && endtoken (str[3]))
- || (strneq (str, "__asm__", 7) && endtoken (str[7])))
- {
- fvdef = vignore;
- return FALSE;
- }
- break;
- }
-
- case fvnameseen:
- if (len >= 10 && strneq (str+len-10, "::operator", 10))
- {
- if (*c_extp & C_AUTO)
- *c_extp = (*c_extp | C_PLPL) & ~C_AUTO;
- fvdef = foperator;
- *is_func_or_var = TRUE;
- return TRUE;
- }
- if (bracelev > 0 && !instruct)
- break;
- fvdef = fvnameseen;
- *is_func_or_var = TRUE;
- return TRUE;
- }
- break;
- }
- return FALSE;
- }
- static struct
- {
- long linepos;
- linebuffer lb;
- } lbs[2];
- #define current_lb_is_new (newndx == curndx)
- #define switch_line_buffers() (curndx = 1 - curndx)
- #define curlb (lbs[curndx].lb)
- #define newlb (lbs[newndx].lb)
- #define curlinepos (lbs[curndx].linepos)
- #define newlinepos (lbs[newndx].linepos)
- #define plainc ((c_ext & C_EXT) == C_PLAIN)
- #define cplpl (c_ext & C_PLPL)
- #define cjava ((c_ext & C_JAVA) == C_JAVA)
- #define CNL_SAVE_DEFINEDEF() \
- do { \
- curlinepos = charno; \
- readline (&curlb, inf); \
- lp = curlb.buffer; \
- quotednl = FALSE; \
- newndx = curndx; \
- } while (0)
- #define CNL() \
- do { \
- CNL_SAVE_DEFINEDEF(); \
- if (savetoken.valid) \
- { \
- token = savetoken; \
- savetoken.valid = FALSE; \
- } \
- definedef = dnone; \
- } while (0)
- static void
- make_C_tag (int isfun)
- {
-
- if (token.valid)
- make_tag (token_name.buffer, token_name.len, isfun, token.line,
- token.offset+token.length+1, token.lineno, token.linepos);
- else if (DEBUG)
- {
- make_tag (concat ("INVALID TOKEN:-->", token_name.buffer, ""),
- token_name.len + 17, isfun, token.line,
- token.offset+token.length+1, token.lineno, token.linepos);
- error ("INVALID TOKEN", NULL);
- }
- token.valid = FALSE;
- }
- static void
- C_entries (int c_ext, FILE *inf)
-
-
- {
- register char c;
- register char *lp;
- int curndx, newndx;
- register int tokoff;
- register int toklen;
- const char *qualifier;
- int qlen;
- int bracelev;
- int bracketlev;
- int parlev;
- int attrparlev;
- int templatelev;
- int typdefbracelev;
- bool incomm, inquote, inchar, quotednl, midtoken;
- bool yacc_rules;
- struct tok savetoken = {0};
- linebuffer_init (&lbs[0].lb);
- linebuffer_init (&lbs[1].lb);
- if (cstack.size == 0)
- {
- cstack.size = (DEBUG) ? 1 : 4;
- cstack.nl = 0;
- cstack.cname = xnew (cstack.size, char *);
- cstack.bracelev = xnew (cstack.size, int);
- }
- tokoff = toklen = typdefbracelev = 0;
- curndx = newndx = 0;
- lp = curlb.buffer;
- *lp = 0;
- fvdef = fvnone; fvextern = FALSE; typdef = tnone;
- structdef = snone; definedef = dnone; objdef = onone;
- yacc_rules = FALSE;
- midtoken = inquote = inchar = incomm = quotednl = FALSE;
- token.valid = savetoken.valid = FALSE;
- bracelev = bracketlev = parlev = attrparlev = templatelev = 0;
- if (cjava)
- { qualifier = "."; qlen = 1; }
- else
- { qualifier = "::"; qlen = 2; }
- while (!feof (inf))
- {
- c = *lp++;
- if (c == '\\')
- {
-
- if (*lp == '\0')
- {
- quotednl = TRUE;
- continue;
- }
- lp++;
- c = ' ';
- }
- else if (incomm)
- {
- switch (c)
- {
- case '*':
- if (*lp == '/')
- {
- c = *lp++;
- incomm = FALSE;
- }
- break;
- case '\0':
-
- CNL_SAVE_DEFINEDEF ();
- break;
- }
- continue;
- }
- else if (inquote)
- {
- switch (c)
- {
- case '"':
- inquote = FALSE;
- break;
- case '\0':
-
- CNL_SAVE_DEFINEDEF ();
- break;
- }
- continue;
- }
- else if (inchar)
- {
- switch (c)
- {
- case '\0':
-
- CNL ();
-
- case '\'':
- inchar = FALSE;
- break;
- }
- continue;
- }
- else switch (c)
- {
- case '"':
- inquote = TRUE;
- if (bracketlev > 0)
- continue;
- if (inattribute)
- break;
- switch (fvdef)
- {
- case fdefunkey:
- case fstartlist:
- case finlist:
- case fignore:
- case vignore:
- break;
- default:
- fvextern = FALSE;
- fvdef = fvnone;
- }
- continue;
- case '\'':
- inchar = TRUE;
- if (bracketlev > 0)
- continue;
- if (inattribute)
- break;
- if (fvdef != finlist && fvdef != fignore && fvdef != vignore)
- {
- fvextern = FALSE;
- fvdef = fvnone;
- }
- continue;
- case '/':
- if (*lp == '*')
- {
- incomm = TRUE;
- lp++;
- c = ' ';
- if (bracketlev > 0)
- continue;
- }
- else if ( *lp == '/')
- {
- c = '\0';
- }
- break;
- case '%':
- if ((c_ext & YACC) && *lp == '%')
- {
-
- lp++;
- definedef = dnone; fvdef = fvnone; fvextern = FALSE;
- typdef = tnone; structdef = snone;
- midtoken = inquote = inchar = incomm = quotednl = FALSE;
- bracelev = 0;
- yacc_rules = !yacc_rules;
- continue;
- }
- else
- break;
- case '#':
- if (definedef == dnone)
- {
- char *cp;
- bool cpptoken = TRUE;
-
- for (cp = newlb.buffer; cp < lp-1; cp++)
- if (!iswhite (*cp))
- {
- if (*cp == '*' && cp[1] == '/')
- {
- cp++;
- cpptoken = TRUE;
- }
- else
- cpptoken = FALSE;
- }
- if (cpptoken)
- definedef = dsharpseen;
- }
- continue;
- case '[':
- bracketlev++;
- continue;
- default:
- if (bracketlev > 0)
- {
- if (c == ']')
- --bracketlev;
- else if (c == '\0')
- CNL_SAVE_DEFINEDEF ();
- continue;
- }
- break;
- }
-
- if (typdef != tignore
- && definedef != dignorerest
- && fvdef != finlist
- && templatelev == 0
- && (definedef != dnone
- || structdef != scolonseen)
- && !inattribute)
- {
- if (midtoken)
- {
- if (endtoken (c))
- {
- if (c == ':' && *lp == ':' && begtoken (lp[1]))
-
- {
- if (c_ext & C_AUTO)
- c_ext = (c_ext | C_PLPL) & ~C_AUTO;
- lp += 2;
- toklen += 2;
- c = lp[-1];
- goto still_in_token;
- }
- else
- {
- bool funorvar = FALSE;
- if (yacc_rules
- || consider_token (newlb.buffer + tokoff, toklen, c,
- &c_ext, bracelev, parlev,
- &funorvar))
- {
- if (fvdef == foperator)
- {
- char *oldlp = lp;
- lp = skip_spaces (lp-1);
- if (*lp != '\0')
- lp += 1;
- while (*lp != '\0'
- && !iswhite (*lp) && *lp != '(')
- lp += 1;
- c = *lp++;
- toklen += lp - oldlp;
- }
- token.named = FALSE;
- if (!plainc
- && nestlev > 0 && definedef == dnone)
-
- {
- write_classname (&token_name, qualifier);
- linebuffer_setlen (&token_name,
- token_name.len+qlen+toklen);
- strcat (token_name.buffer, qualifier);
- strncat (token_name.buffer,
- newlb.buffer + tokoff, toklen);
- token.named = TRUE;
- }
- else if (objdef == ocatseen)
-
- {
- int len = strlen (objtag) + 2 + toklen;
- linebuffer_setlen (&token_name, len);
- strcpy (token_name.buffer, objtag);
- strcat (token_name.buffer, "(");
- strncat (token_name.buffer,
- newlb.buffer + tokoff, toklen);
- strcat (token_name.buffer, ")");
- token.named = TRUE;
- }
- else if (objdef == omethodtag
- || objdef == omethodparm)
-
- {
- token.named = TRUE;
- }
- else if (fvdef == fdefunname)
-
- {
- bool defun = (newlb.buffer[tokoff] == 'F');
- int off = tokoff;
- int len = toklen;
-
- if (defun)
- {
- off += 1;
- len -= 1;
- }
- linebuffer_setlen (&token_name, len);
- strncpy (token_name.buffer,
- newlb.buffer + off, len);
- token_name.buffer[len] = '\0';
- if (defun)
- while (--len >= 0)
- if (token_name.buffer[len] == '_')
- token_name.buffer[len] = '-';
- token.named = defun;
- }
- else
- {
- linebuffer_setlen (&token_name, toklen);
- strncpy (token_name.buffer,
- newlb.buffer + tokoff, toklen);
- token_name.buffer[toklen] = '\0';
-
- token.named = (structdef == stagseen
- || typdef == ttypeseen
- || typdef == tend
- || (funorvar
- && definedef == dignorerest)
- || (funorvar
- && definedef == dnone
- && structdef == snone
- && bracelev > 0));
- }
- token.lineno = lineno;
- token.offset = tokoff;
- token.length = toklen;
- token.line = newlb.buffer;
- token.linepos = newlinepos;
- token.valid = TRUE;
- if (definedef == dnone
- && (fvdef == fvnameseen
- || fvdef == foperator
- || structdef == stagseen
- || typdef == tend
- || typdef == ttypeseen
- || objdef != onone))
- {
- if (current_lb_is_new)
- switch_line_buffers ();
- }
- else if (definedef != dnone
- || fvdef == fdefunname
- || instruct)
- make_C_tag (funorvar);
- }
- else
- {
- if (inattribute && fvdef == fignore)
- {
-
- fvdef = fvnone;
- }
- }
- midtoken = FALSE;
- }
- }
- else if (intoken (c))
- still_in_token:
- {
- toklen++;
- continue;
- }
- }
- else if (begtoken (c))
- {
- switch (definedef)
- {
- case dnone:
- switch (fvdef)
- {
- case fstartlist:
-
- fvdef = finlist;
- continue;
- case flistseen:
- if (plainc || declarations)
- {
- make_C_tag (TRUE);
- fvdef = fignore;
- }
- break;
- }
- if (structdef == stagseen && !cjava)
- {
- popclass_above (bracelev);
- structdef = snone;
- }
- break;
- case dsharpseen:
- savetoken = token;
- break;
- }
- if (!yacc_rules || lp == newlb.buffer + 1)
- {
- tokoff = lp - 1 - newlb.buffer;
- toklen = 1;
- midtoken = TRUE;
- }
- continue;
- }
- }
-
- switch (c)
- {
- case ':':
- if (inattribute)
- break;
- if (yacc_rules && token.offset == 0 && token.valid)
- {
- make_C_tag (FALSE);
- break;
- }
- if (definedef != dnone)
- break;
- switch (objdef)
- {
- case otagseen:
- objdef = oignore;
- make_C_tag (TRUE);
- break;
- case omethodtag:
- case omethodparm:
- objdef = omethodcolon;
- linebuffer_setlen (&token_name, token_name.len + 1);
- strcat (token_name.buffer, ":");
- break;
- }
- if (structdef == stagseen)
- {
- structdef = scolonseen;
- break;
- }
-
- if (cplpl && fvdef == flistseen)
- {
- make_C_tag (TRUE);
- fvdef = fignore;
- break;
- }
- break;
- case ';':
- if (definedef != dnone || inattribute)
- break;
- switch (typdef)
- {
- case tend:
- case ttypeseen:
- make_C_tag (FALSE);
- typdef = tnone;
- fvdef = fvnone;
- break;
- case tnone:
- case tinbody:
- case tignore:
- switch (fvdef)
- {
- case fignore:
- if (typdef == tignore || cplpl)
- fvdef = fvnone;
- break;
- case fvnameseen:
- if ((globals && bracelev == 0 && (!fvextern || declarations))
- || (members && instruct))
- make_C_tag (FALSE);
- fvextern = FALSE;
- fvdef = fvnone;
- token.valid = FALSE;
- break;
- case flistseen:
- if ((declarations
- && (cplpl || !instruct)
- && (typdef == tnone || (typdef != tignore && instruct)))
- || (members
- && plainc && instruct))
- make_C_tag (TRUE);
-
- default:
- fvextern = FALSE;
- fvdef = fvnone;
- if (declarations
- && cplpl && structdef == stagseen)
- make_C_tag (FALSE);
- else
- token.valid = FALSE;
- }
-
- default:
- if (!instruct)
- typdef = tnone;
- }
- if (structdef == stagseen)
- structdef = snone;
- break;
- case ',':
- if (definedef != dnone || inattribute)
- break;
- switch (objdef)
- {
- case omethodtag:
- case omethodparm:
- make_C_tag (TRUE);
- objdef = oinbody;
- break;
- }
- switch (fvdef)
- {
- case fdefunkey:
- case foperator:
- case fstartlist:
- case finlist:
- case fignore:
- case vignore:
- break;
- case fdefunname:
- fvdef = fignore;
- break;
- case fvnameseen:
- if (parlev == 0
- && ((globals
- && bracelev == 0
- && templatelev == 0
- && (!fvextern || declarations))
- || (members && instruct)))
- make_C_tag (FALSE);
- break;
- case flistseen:
- if ((declarations && typdef == tnone && !instruct)
- || (members && typdef != tignore && instruct))
- {
- make_C_tag (TRUE);
- fvdef = fvnameseen;
- }
- else if (!declarations)
- fvdef = fvnone;
- token.valid = FALSE;
- break;
- default:
- fvdef = fvnone;
- }
- if (structdef == stagseen)
- structdef = snone;
- break;
- case ']':
- if (definedef != dnone || inattribute)
- break;
- if (structdef == stagseen)
- structdef = snone;
- switch (typdef)
- {
- case ttypeseen:
- case tend:
- typdef = tignore;
- make_C_tag (FALSE);
- break;
- case tnone:
- case tinbody:
- switch (fvdef)
- {
- case foperator:
- case finlist:
- case fignore:
- case vignore:
- break;
- case fvnameseen:
- if ((members && bracelev == 1)
- || (globals && bracelev == 0
- && (!fvextern || declarations)))
- make_C_tag (FALSE);
-
- default:
- fvdef = fvnone;
- }
- break;
- }
- break;
- case '(':
- if (inattribute)
- {
- attrparlev++;
- break;
- }
- if (definedef != dnone)
- break;
- if (objdef == otagseen && parlev == 0)
- objdef = oparenseen;
- switch (fvdef)
- {
- case fvnameseen:
- if (typdef == ttypeseen
- && *lp != '*'
- && !instruct)
- {
-
- make_C_tag (FALSE);
- typdef = tignore;
- fvdef = fignore;
- break;
- }
-
- case foperator:
- fvdef = fstartlist;
- break;
- case flistseen:
- fvdef = finlist;
- break;
- }
- parlev++;
- break;
- case ')':
- if (inattribute)
- {
- if (--attrparlev == 0)
- inattribute = FALSE;
- break;
- }
- if (definedef != dnone)
- break;
- if (objdef == ocatseen && parlev == 1)
- {
- make_C_tag (TRUE);
- objdef = oignore;
- }
- if (--parlev == 0)
- {
- switch (fvdef)
- {
- case fstartlist:
- case finlist:
- fvdef = flistseen;
- break;
- }
- if (!instruct
- && (typdef == tend
- || typdef == ttypeseen))
- {
- typdef = tignore;
- make_C_tag (FALSE);
- }
- }
- else if (parlev < 0)
- parlev = 0;
- break;
- case '{':
- if (definedef != dnone)
- break;
- if (typdef == ttypeseen)
- {
-
- typdef = tinbody;
- typdefbracelev = bracelev;
- }
- switch (fvdef)
- {
- case flistseen:
- make_C_tag (TRUE);
-
- case fignore:
- fvdef = fvnone;
- break;
- case fvnone:
- switch (objdef)
- {
- case otagseen:
- make_C_tag (TRUE);
- objdef = oignore;
- break;
- case omethodtag:
- case omethodparm:
- make_C_tag (TRUE);
- objdef = oinbody;
- break;
- default:
-
- if (bracelev == 0 && structdef == snone && nestlev == 0
- && typdef == tnone)
- bracelev = -1;
- }
- break;
- }
- switch (structdef)
- {
- case skeyseen:
- pushclass_above (bracelev, NULL, 0);
- structdef = snone;
- break;
- case stagseen:
- case scolonseen:
- pushclass_above (bracelev,token.line+token.offset, token.length);
- structdef = snone;
- make_C_tag (FALSE);
- break;
- }
- bracelev += 1;
- break;
- case '*':
- if (definedef != dnone)
- break;
- if (fvdef == fstartlist)
- {
- fvdef = fvnone;
- token.valid = FALSE;
- }
- break;
- case '}':
- if (definedef != dnone)
- break;
- bracelev -= 1;
- if (!ignoreindent && lp == newlb.buffer + 1)
- {
- if (bracelev != 0)
- token.valid = FALSE;
- bracelev = 0;
- parlev = 0;
- }
- else if (bracelev < 0)
- {
- token.valid = FALSE;
- bracelev = 0;
- }
- if (bracelev == 0 && fvdef == vignore)
- fvdef = fvnone;
- popclass_above (bracelev);
- structdef = snone;
-
- if (typdef == tinbody && bracelev <= typdefbracelev)
- {
- assert (bracelev == typdefbracelev);
- typdef = tend;
- }
- break;
- case '=':
- if (definedef != dnone)
- break;
- switch (fvdef)
- {
- case foperator:
- case finlist:
- case fignore:
- case vignore:
- break;
- case fvnameseen:
- if ((members && bracelev == 1)
- || (globals && bracelev == 0 && (!fvextern || declarations)))
- make_C_tag (FALSE);
-
- default:
- fvdef = vignore;
- }
- break;
- case '<':
- if (cplpl
- && (structdef == stagseen || fvdef == fvnameseen))
- {
- templatelev++;
- break;
- }
- goto resetfvdef;
- case '>':
- if (templatelev > 0)
- {
- templatelev--;
- break;
- }
- goto resetfvdef;
- case '+':
- case '-':
- if (objdef == oinbody && bracelev == 0)
- {
- objdef = omethodsign;
- break;
- }
-
- resetfvdef:
- case '#': case '~': case '&': case '%': case '/':
- case '|': case '^': case '!': case '.': case '?':
- if (definedef != dnone)
- break;
-
- switch (fvdef)
- {
- case foperator:
- case finlist:
- case fignore:
- case vignore:
- break;
- default:
- fvdef = fvnone;
- }
- break;
- case '\0':
- if (objdef == otagseen)
- {
- make_C_tag (TRUE);
- objdef = oignore;
- }
-
- if (quotednl)
- CNL_SAVE_DEFINEDEF ();
- else
- CNL ();
- break;
- }
- }
- free (lbs[0].lb.buffer);
- free (lbs[1].lb.buffer);
- }
- static void
- default_C_entries (FILE *inf)
- {
- C_entries (cplusplus ? C_PLPL : C_AUTO, inf);
- }
- static void
- plain_C_entries (FILE *inf)
- {
- C_entries (0, inf);
- }
- static void
- Cplusplus_entries (FILE *inf)
- {
- C_entries (C_PLPL, inf);
- }
- static void
- Cjava_entries (FILE *inf)
- {
- C_entries (C_JAVA, inf);
- }
- static void
- Cstar_entries (FILE *inf)
- {
- C_entries (C_STAR, inf);
- }
- static void
- Yacc_entries (FILE *inf)
- {
- C_entries (YACC, inf);
- }
- #define LOOP_ON_INPUT_LINES(file_pointer, line_buffer, char_pointer) \
- for (; \
- !feof (file_pointer) \
- && \
- (readline (&line_buffer, file_pointer), \
- char_pointer = line_buffer.buffer, \
- TRUE); \
- )
- #define LOOKING_AT(cp, kw) \
- ((assert ("" kw), TRUE) \
- && strneq ((cp), kw, sizeof (kw)-1) \
- && notinname ((cp)[sizeof (kw)-1]) \
- && ((cp) = skip_spaces ((cp)+sizeof (kw)-1)))
- #define LOOKING_AT_NOCASE(cp, kw) \
- ((assert ("" kw), TRUE) \
- && strncaseeq ((cp), kw, sizeof (kw)-1) \
- && ((cp) += sizeof (kw)-1))
- static void
- just_read_file (FILE *inf)
- {
- while (!feof (inf))
- readline (&lb, inf);
- }
- static void F_takeprec (void);
- static void F_getit (FILE *);
- static void
- F_takeprec (void)
- {
- dbp = skip_spaces (dbp);
- if (*dbp != '*')
- return;
- dbp++;
- dbp = skip_spaces (dbp);
- if (strneq (dbp, "(*)", 3))
- {
- dbp += 3;
- return;
- }
- if (!ISDIGIT (*dbp))
- {
- --dbp;
- return;
- }
- do
- dbp++;
- while (ISDIGIT (*dbp));
- }
- static void
- F_getit (FILE *inf)
- {
- register char *cp;
- dbp = skip_spaces (dbp);
- if (*dbp == '\0')
- {
- readline (&lb, inf);
- dbp = lb.buffer;
- if (dbp[5] != '&')
- return;
- dbp += 6;
- dbp = skip_spaces (dbp);
- }
- if (!ISALPHA (*dbp) && *dbp != '_' && *dbp != '$')
- return;
- for (cp = dbp + 1; *cp != '\0' && intoken (*cp); cp++)
- continue;
- make_tag (dbp, cp-dbp, TRUE,
- lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
- }
- static void
- Fortran_functions (FILE *inf)
- {
- LOOP_ON_INPUT_LINES (inf, lb, dbp)
- {
- if (*dbp == '%')
- dbp++;
- dbp = skip_spaces (dbp);
- if (*dbp == '\0')
- continue;
- if (LOOKING_AT_NOCASE (dbp, "recursive"))
- dbp = skip_spaces (dbp);
- if (LOOKING_AT_NOCASE (dbp, "pure"))
- dbp = skip_spaces (dbp);
- if (LOOKING_AT_NOCASE (dbp, "elemental"))
- dbp = skip_spaces (dbp);
- switch (lowcase (*dbp))
- {
- case 'i':
- if (nocase_tail ("integer"))
- F_takeprec ();
- break;
- case 'r':
- if (nocase_tail ("real"))
- F_takeprec ();
- break;
- case 'l':
- if (nocase_tail ("logical"))
- F_takeprec ();
- break;
- case 'c':
- if (nocase_tail ("complex") || nocase_tail ("character"))
- F_takeprec ();
- break;
- case 'd':
- if (nocase_tail ("double"))
- {
- dbp = skip_spaces (dbp);
- if (*dbp == '\0')
- continue;
- if (nocase_tail ("precision"))
- break;
- continue;
- }
- break;
- }
- dbp = skip_spaces (dbp);
- if (*dbp == '\0')
- continue;
- switch (lowcase (*dbp))
- {
- case 'f':
- if (nocase_tail ("function"))
- F_getit (inf);
- continue;
- case 's':
- if (nocase_tail ("subroutine"))
- F_getit (inf);
- continue;
- case 'e':
- if (nocase_tail ("entry"))
- F_getit (inf);
- continue;
- case 'b':
- if (nocase_tail ("blockdata") || nocase_tail ("block data"))
- {
- dbp = skip_spaces (dbp);
- if (*dbp == '\0')
- make_tag ("blockdata", 9, TRUE,
- lb.buffer, dbp - lb.buffer, lineno, linecharno);
- else
- F_getit (inf);
- }
- continue;
- }
- }
- }
- static void
- Ada_getit (FILE *inf, const char *name_qualifier)
- {
- register char *cp;
- char *name;
- char c;
- while (!feof (inf))
- {
- dbp = skip_spaces (dbp);
- if (*dbp == '\0'
- || (dbp[0] == '-' && dbp[1] == '-'))
- {
- readline (&lb, inf);
- dbp = lb.buffer;
- }
- switch (lowcase (*dbp))
- {
- case 'b':
- if (nocase_tail ("body"))
- {
-
- name_qualifier = "/b";
- continue;
- }
- break;
- case 't':
-
- if (nocase_tail ("type"))
- continue;
- break;
- }
- if (*dbp == '"')
- {
- dbp += 1;
- for (cp = dbp; *cp != '\0' && *cp != '"'; cp++)
- continue;
- }
- else
- {
- dbp = skip_spaces (dbp);
- for (cp = dbp;
- (*cp != '\0'
- && (ISALPHA (*cp) || ISDIGIT (*cp) || *cp == '_' || *cp == '.'));
- cp++)
- continue;
- if (cp == dbp)
- return;
- }
- c = *cp;
- *cp = '\0';
- name = concat (dbp, name_qualifier, "");
- *cp = c;
- make_tag (name, strlen (name), TRUE,
- lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
- free (name);
- if (c == '"')
- dbp = cp + 1;
- return;
- }
- }
- static void
- Ada_funcs (FILE *inf)
- {
- bool inquote = FALSE;
- bool skip_till_semicolumn = FALSE;
- LOOP_ON_INPUT_LINES (inf, lb, dbp)
- {
- while (*dbp != '\0')
- {
-
- if (inquote || (*dbp == '"'))
- {
- dbp = etags_strchr (dbp + !inquote, '"');
- if (dbp != NULL)
- {
- inquote = FALSE;
- dbp += 1;
- continue;
- }
- else
- {
- inquote = TRUE;
- break;
- }
- }
-
- if (dbp[0] == '-' && dbp[1] == '-')
- break;
-
- if (*dbp == '\'')
- {
- dbp++ ;
- if (*dbp != '\0')
- dbp++;
- continue;
- }
- if (skip_till_semicolumn)
- {
- if (*dbp == ';')
- skip_till_semicolumn = FALSE;
- dbp++;
- continue;
- }
-
- if (!begtoken (*dbp))
- {
- dbp++;
- continue;
- }
-
- switch (lowcase (*dbp))
- {
- case 'f':
- if (!packages_only && nocase_tail ("function"))
- Ada_getit (inf, "/f");
- else
- break;
- continue;
- case 'p':
- if (!packages_only && nocase_tail ("procedure"))
- Ada_getit (inf, "/p");
- else if (nocase_tail ("package"))
- Ada_getit (inf, "/s");
- else if (nocase_tail ("protected"))
- Ada_getit (inf, "/t");
- else
- break;
- continue;
- case 'u':
- if (typedefs && !packages_only && nocase_tail ("use"))
- {
-
- skip_till_semicolumn = TRUE;
- continue;
- }
- case 't':
- if (!packages_only && nocase_tail ("task"))
- Ada_getit (inf, "/k");
- else if (typedefs && !packages_only && nocase_tail ("type"))
- {
- Ada_getit (inf, "/t");
- while (*dbp != '\0')
- dbp += 1;
- }
- else
- break;
- continue;
- }
-
- while (!endtoken (*dbp))
- dbp++;
- }
- }
- }
- static void
- Asm_labels (FILE *inf)
- {
- register char *cp;
- LOOP_ON_INPUT_LINES (inf, lb, cp)
- {
-
- if (ISALPHA (*cp) || *cp == '_' || *cp == '.' || *cp == '$')
- {
-
- cp++;
- while (ISALNUM (*cp) || *cp == '_' || *cp == '.' || *cp == '$')
- cp++;
- if (*cp == ':' || iswhite (*cp))
-
- make_tag (lb.buffer, cp - lb.buffer, TRUE,
- lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
- }
- }
- }
- static void
- Perl_functions (FILE *inf)
- {
- char *package = savestr ("main");
- register char *cp;
- LOOP_ON_INPUT_LINES (inf, lb, cp)
- {
- cp = skip_spaces (cp);
- if (LOOKING_AT (cp, "package"))
- {
- free (package);
- get_tag (cp, &package);
- }
- else if (LOOKING_AT (cp, "sub"))
- {
- char *pos;
- char *sp = cp;
- while (!notinname (*cp))
- cp++;
- if (cp == sp)
- continue;
- if ((pos = etags_strchr (sp, ':')) != NULL
- && pos < cp && pos[1] == ':')
-
- make_tag (sp, cp - sp, TRUE,
- lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
- else
-
- {
- char savechar, *name;
- savechar = *cp;
- *cp = '\0';
- name = concat (package, "::", sp);
- *cp = savechar;
- make_tag (name, strlen (name), TRUE,
- lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
- free (name);
- }
- }
- else if (globals)
- {
-
- bool qual = LOOKING_AT (cp, "my") || LOOKING_AT (cp, "local");
-
- char *varstart = cp;
- if (qual
- && (*cp == '$' || *cp == '@' || *cp == '%'))
- {
- varstart += 1;
- do
- cp++;
- while (ISALNUM (*cp) || *cp == '_');
- }
- else if (qual)
- {
-
- while (*cp != '\0' && *cp != ';' && *cp != '=' && *cp != ')')
- cp++;
- }
- else
- continue;
- make_tag (varstart, cp - varstart, FALSE,
- lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
- }
- }
- free (package);
- }
- static void
- Python_functions (FILE *inf)
- {
- register char *cp;
- LOOP_ON_INPUT_LINES (inf, lb, cp)
- {
- cp = skip_spaces (cp);
- if (LOOKING_AT (cp, "def") || LOOKING_AT (cp, "class"))
- {
- char *name = cp;
- while (!notinname (*cp) && *cp != ':')
- cp++;
- make_tag (name, cp - name, TRUE,
- lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
- }
- }
- }
- static void
- PHP_functions (FILE *inf)
- {
- register char *cp, *name;
- bool search_identifier = FALSE;
- LOOP_ON_INPUT_LINES (inf, lb, cp)
- {
- cp = skip_spaces (cp);
- name = cp;
- if (search_identifier
- && *cp != '\0')
- {
- while (!notinname (*cp))
- cp++;
- make_tag (name, cp - name, TRUE,
- lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
- search_identifier = FALSE;
- }
- else if (LOOKING_AT (cp, "function"))
- {
- if (*cp == '&')
- cp = skip_spaces (cp+1);
- if (*cp != '\0')
- {
- name = cp;
- while (!notinname (*cp))
- cp++;
- make_tag (name, cp - name, TRUE,
- lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
- }
- else
- search_identifier = TRUE;
- }
- else if (LOOKING_AT (cp, "class"))
- {
- if (*cp != '\0')
- {
- name = cp;
- while (*cp != '\0' && !iswhite (*cp))
- cp++;
- make_tag (name, cp - name, FALSE,
- lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
- }
- else
- search_identifier = TRUE;
- }
- else if (strneq (cp, "define", 6)
- && (cp = skip_spaces (cp+6))
- && *cp++ == '('
- && (*cp == '"' || *cp == '\''))
- {
- char quote = *cp++;
- name = cp;
- while (*cp != quote && *cp != '\0')
- cp++;
- make_tag (name, cp - name, FALSE,
- lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
- }
- else if (members
- && LOOKING_AT (cp, "var")
- && *cp == '$')
- {
- name = cp;
- while (!notinname (*cp))
- cp++;
- make_tag (name, cp - name, FALSE,
- lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
- }
- }
- }
- static void
- Cobol_paragraphs (FILE *inf)
- {
- register char *bp, *ep;
- LOOP_ON_INPUT_LINES (inf, lb, bp)
- {
- if (lb.len < 9)
- continue;
- bp += 8;
-
- if (bp[-1] != ' ' || !ISALNUM (bp[0]))
- continue;
- for (ep = bp; ISALNUM (*ep) || *ep == '-'; ep++)
- continue;
- if (*ep++ == '.')
- make_tag (bp, ep - bp, TRUE,
- lb.buffer, ep - lb.buffer + 1, lineno, linecharno);
- }
- }
- static void
- Makefile_targets (FILE *inf)
- {
- register char *bp;
- LOOP_ON_INPUT_LINES (inf, lb, bp)
- {
- if (*bp == '\t' || *bp == '#')
- continue;
- while (*bp != '\0' && *bp != '=' && *bp != ':')
- bp++;
- if (*bp == ':' || (globals && *bp == '='))
- {
-
- char * namestart = skip_spaces (lb.buffer);
- while (--bp > namestart)
- if (!notinname (*bp))
- break;
- make_tag (namestart, bp - namestart + 1, TRUE,
- lb.buffer, bp - lb.buffer + 2, lineno, linecharno);
- }
- }
- }
- static void
- Pascal_functions (FILE *inf)
- {
- linebuffer tline;
- long save_lcno;
- int save_lineno, namelen, taglen;
- char c, *name;
- bool
- incomment,
- inquote,
- get_tagname,
- found_tag,
- inparms,
- verify_tag;
- save_lcno = save_lineno = namelen = taglen = 0;
- name = NULL;
- dbp = lb.buffer;
- *dbp = '\0';
- linebuffer_init (&tline);
- incomment = inquote = FALSE;
- found_tag = FALSE;
- get_tagname = FALSE;
- inparms = FALSE;
- verify_tag = FALSE;
- while (!feof (inf))
- {
- c = *dbp++;
- if (c == '\0')
- {
- readline (&lb, inf);
- dbp = lb.buffer;
- if (*dbp == '\0')
- continue;
- if (!((found_tag && verify_tag)
- || get_tagname))
- c = *dbp++;
- }
- if (incomment)
- {
- if (c == '}')
- incomment = FALSE;
- else if (c == '*' && *dbp == ')')
- {
- dbp++;
- incomment = FALSE;
- }
- continue;
- }
- else if (inquote)
- {
- if (c == '\'')
- inquote = FALSE;
- continue;
- }
- else
- switch (c)
- {
- case '\'':
- inquote = TRUE;
- continue;
- case '{':
- incomment = TRUE;
- continue;
- case '(':
- if (*dbp == '*')
- {
- incomment = TRUE;
- dbp++;
- }
- else if (found_tag)
- inparms = TRUE;
- continue;
- case ')':
- if (inparms)
- inparms = FALSE;
- continue;
- case ';':
- if (found_tag && !inparms)
- {
- verify_tag = TRUE;
- break;
- }
- continue;
- }
- if (found_tag && verify_tag && (*dbp != ' '))
- {
-
- if (*dbp == '\0')
- continue;
- if (lowcase (*dbp == 'e'))
- {
- if (nocase_tail ("extern"))
- {
- found_tag = FALSE;
- verify_tag = FALSE;
- }
- }
- else if (lowcase (*dbp) == 'f')
- {
- if (nocase_tail ("forward"))
- {
- found_tag = FALSE;
- verify_tag = FALSE;
- }
- }
- if (found_tag && verify_tag)
- {
- found_tag = FALSE;
- verify_tag = FALSE;
- make_tag (name, namelen, TRUE,
- tline.buffer, taglen, save_lineno, save_lcno);
- continue;
- }
- }
- if (get_tagname)
- {
- char *cp;
- if (*dbp == '\0')
- continue;
-
- for (cp = dbp + 1; *cp != '\0' && !endtoken (*cp); cp++)
- continue;
-
- linebuffer_setlen (&tline, lb.len);
- strcpy (tline.buffer, lb.buffer);
- save_lineno = lineno;
- save_lcno = linecharno;
- name = tline.buffer + (dbp - lb.buffer);
- namelen = cp - dbp;
- taglen = cp - lb.buffer + 1;
- dbp = cp;
- get_tagname = FALSE;
- found_tag = TRUE;
- continue;
-
- }
- else if (!incomment && !inquote && !found_tag)
- {
-
- switch (lowcase (c))
- {
- case 'p':
- if (nocase_tail ("rocedure"))
- get_tagname = TRUE;
- continue;
- case 'f':
- if (nocase_tail ("unction"))
- get_tagname = TRUE;
- continue;
- }
- }
- }
- free (tline.buffer);
- }
- static void L_getit (void);
- static void
- L_getit (void)
- {
- if (*dbp == '\'')
- dbp++;
- else if (*dbp == '(')
- {
- dbp++;
-
- if (!LOOKING_AT (dbp, "quote") && !LOOKING_AT (dbp, "QUOTE"))
-
- dbp = skip_spaces (dbp);
- }
- get_tag (dbp, NULL);
- }
- static void
- Lisp_functions (FILE *inf)
- {
- LOOP_ON_INPUT_LINES (inf, lb, dbp)
- {
- if (dbp[0] != '(')
- continue;
- if (strneq (dbp+1, "def", 3) || strneq (dbp+1, "DEF", 3))
- {
- dbp = skip_non_spaces (dbp);
- dbp = skip_spaces (dbp);
- L_getit ();
- }
- else
- {
-
- do
- dbp++;
- while (!notinname (*dbp) && *dbp != ':');
- if (*dbp == ':')
- {
- do
- dbp++;
- while (*dbp == ':');
- if (strneq (dbp, "def", 3) || strneq (dbp, "DEF", 3))
- {
- dbp = skip_non_spaces (dbp);
- dbp = skip_spaces (dbp);
- L_getit ();
- }
- }
- }
- }
- }
- static void
- Lua_functions (FILE *inf)
- {
- register char *bp;
- LOOP_ON_INPUT_LINES (inf, lb, bp)
- {
- if (bp[0] != 'f' && bp[0] != 'l')
- continue;
- (void)LOOKING_AT (bp, "local");
- if (LOOKING_AT (bp, "function"))
- get_tag (bp, NULL);
- }
- }
- static void
- PS_functions (FILE *inf)
- {
- register char *bp, *ep;
- LOOP_ON_INPUT_LINES (inf, lb, bp)
- {
- if (bp[0] == '/')
- {
- for (ep = bp+1;
- *ep != '\0' && *ep != ' ' && *ep != '{';
- ep++)
- continue;
- make_tag (bp, ep - bp, TRUE,
- lb.buffer, ep - lb.buffer + 1, lineno, linecharno);
- }
- else if (LOOKING_AT (bp, "defineps"))
- get_tag (bp, NULL);
- }
- }
- static void
- Forth_words (FILE *inf)
- {
- register char *bp;
- LOOP_ON_INPUT_LINES (inf, lb, bp)
- while ((bp = skip_spaces (bp))[0] != '\0')
- if (bp[0] == '\\' && iswhite (bp[1]))
- break;
- else if (bp[0] == '(' && iswhite (bp[1]))
- do
- bp++;
- while (*bp != ')' && *bp != '\0');
- else if ((bp[0] == ':' && iswhite (bp[1]) && bp++)
- || LOOKING_AT_NOCASE (bp, "constant")
- || LOOKING_AT_NOCASE (bp, "code")
- || LOOKING_AT_NOCASE (bp, "create")
- || LOOKING_AT_NOCASE (bp, "defer")
- || LOOKING_AT_NOCASE (bp, "value")
- || LOOKING_AT_NOCASE (bp, "variable")
- || LOOKING_AT_NOCASE (bp, "buffer:")
- || LOOKING_AT_NOCASE (bp, "field"))
- get_tag (skip_spaces (bp), NULL);
- else
- bp = skip_non_spaces (bp);
- }
- static void
- Scheme_functions (FILE *inf)
- {
- register char *bp;
- LOOP_ON_INPUT_LINES (inf, lb, bp)
- {
- if (strneq (bp, "(def", 4) || strneq (bp, "(DEF", 4))
- {
- bp = skip_non_spaces (bp+4);
-
- while (*bp && notinname (*bp))
- bp++;
- get_tag (bp, NULL);
- }
- if (LOOKING_AT (bp, "(SET!") || LOOKING_AT (bp, "(set!"))
- get_tag (bp, NULL);
- }
- }
- static linebuffer *TEX_toktab = NULL;
- static const char *TEX_defenv = "\
- :chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem\
- :part:appendix:entry:index:def\
- :newcommand:renewcommand:newenvironment:renewenvironment";
- static void TEX_mode (FILE *);
- static void TEX_decode_env (const char *, const char *);
- static char TEX_esc = '\\';
- static char TEX_opgrp = '{';
- static char TEX_clgrp = '}';
- static void
- TeX_commands (FILE *inf)
- {
- char *cp;
- linebuffer *key;
-
- TEX_mode (inf);
-
- if (TEX_toktab == NULL)
- TEX_decode_env ("TEXTAGS", TEX_defenv);
- LOOP_ON_INPUT_LINES (inf, lb, cp)
- {
-
- for (;;)
- {
-
- while (*cp++ != TEX_esc)
- if (cp[-1] == '\0' || cp[-1] == '%')
- goto tex_next_line;
- for (key = TEX_toktab; key->buffer != NULL; key++)
- if (strneq (cp, key->buffer, key->len))
- {
- register char *p;
- int namelen, linelen;
- bool opgrp = FALSE;
- cp = skip_spaces (cp + key->len);
- if (*cp == TEX_opgrp)
- {
- opgrp = TRUE;
- cp++;
- }
- for (p = cp;
- (!iswhite (*p) && *p != '#' &&
- *p != TEX_opgrp && *p != TEX_clgrp);
- p++)
- continue;
- namelen = p - cp;
- linelen = lb.len;
- if (!opgrp || *p == TEX_clgrp)
- {
- while (*p != '\0' && *p != TEX_opgrp && *p != TEX_clgrp)
- p++;
- linelen = p - lb.buffer + 1;
- }
- make_tag (cp, namelen, TRUE,
- lb.buffer, linelen, lineno, linecharno);
- goto tex_next_line;
- }
- }
- tex_next_line:
- ;
- }
- }
- #define TEX_LESC '\\'
- #define TEX_SESC '!'
- static void
- TEX_mode (FILE *inf)
- {
- int c;
- while ((c = getc (inf)) != EOF)
- {
-
- if (c == '%')
- while (c != '\n' && c != EOF)
- c = getc (inf);
- else if (c == TEX_LESC || c == TEX_SESC )
- break;
- }
- if (c == TEX_LESC)
- {
- TEX_esc = TEX_LESC;
- TEX_opgrp = '{';
- TEX_clgrp = '}';
- }
- else
- {
- TEX_esc = TEX_SESC;
- TEX_opgrp = '<';
- TEX_clgrp = '>';
- }
-
- rewind (inf);
- }
- static void
- TEX_decode_env (const char *evarname, const char *defenv)
- {
- register const char *env, *p;
- int i, len;
-
- env = getenv (evarname);
- if (!env)
- env = defenv;
- else
- env = concat (env, defenv, "");
-
- for (len = 1, p = env; p;)
- if ((p = etags_strchr (p, ':')) && *++p != '\0')
- len++;
- TEX_toktab = xnew (len, linebuffer);
-
-
- for (i = 0; *env != '\0';)
- {
- p = etags_strchr (env, ':');
- if (!p)
- p = env + strlen (env);
- if (p - env > 0)
- {
- TEX_toktab[i].buffer = savenstr (env, p - env);
- TEX_toktab[i].len = p - env;
- i++;
- }
- if (*p)
- env = p + 1;
- else
- {
- TEX_toktab[i].buffer = NULL;
- TEX_toktab[i].len = 0;
- break;
- }
- }
- }
- static void
- Texinfo_nodes (FILE *inf)
- {
- char *cp, *start;
- LOOP_ON_INPUT_LINES (inf, lb, cp)
- if (LOOKING_AT (cp, "@node"))
- {
- start = cp;
- while (*cp != '\0' && *cp != ',')
- cp++;
- make_tag (start, cp - start, TRUE,
- lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
- }
- }
- static void
- HTML_labels (FILE *inf)
- {
- bool getnext = FALSE;
- bool skiptag = FALSE;
- bool intag = FALSE;
- bool inanchor = FALSE;
- char *end;
- linebuffer_setlen (&token_name, 0);
- LOOP_ON_INPUT_LINES (inf, lb, dbp)
- for (;;)
- {
- if (skiptag)
- {
- while (*dbp != '\0' && *dbp != '>')
- dbp++;
- if (*dbp == '>')
- {
- dbp += 1;
- skiptag = FALSE;
- continue;
- }
- break;
- }
- else if (intag)
- {
- while (*dbp != '\0' && *dbp != '>'
- && lowcase (*dbp) != 'n' && lowcase (*dbp) != 'i')
- dbp++;
- if (*dbp == '\0')
- break;
- if (*dbp == '>')
- {
- dbp += 1;
- intag = FALSE;
- continue;
- }
- if ((inanchor && LOOKING_AT_NOCASE (dbp, "name="))
- || LOOKING_AT_NOCASE (dbp, "id="))
- {
- bool quoted = (dbp[0] == '"');
- if (quoted)
- for (end = ++dbp; *end != '\0' && *end != '"'; end++)
- continue;
- else
- for (end = dbp; *end != '\0' && intoken (*end); end++)
- continue;
- linebuffer_setlen (&token_name, end - dbp);
- strncpy (token_name.buffer, dbp, end - dbp);
- token_name.buffer[end - dbp] = '\0';
- dbp = end;
- intag = FALSE;
- skiptag = TRUE;
- getnext = TRUE;
- continue;
- }
- dbp += 1;
- }
- else if (getnext)
- {
- dbp = skip_spaces (dbp);
- if (*dbp == '\0')
- break;
- if (*dbp == '<')
- {
- intag = TRUE;
- inanchor = (lowcase (dbp[1]) == 'a' && !intoken (dbp[2]));
- continue;
- }
- for (end = dbp + 1; *end != '\0' && *end != '<'; end++)
- continue;
- make_tag (token_name.buffer, token_name.len, TRUE,
- dbp, end - dbp, lineno, linecharno);
- linebuffer_setlen (&token_name, 0);
- getnext = FALSE;
- break;
- }
- else
- {
- while (*dbp != '\0' && *dbp != '<')
- dbp++;
- if (*dbp == '\0')
- break;
- intag = TRUE;
- if (lowcase (dbp[1]) == 'a' && !intoken (dbp[2]))
- {
- inanchor = TRUE;
- continue;
- }
- else if (LOOKING_AT_NOCASE (dbp, "<title>")
- || LOOKING_AT_NOCASE (dbp, "<h1>")
- || LOOKING_AT_NOCASE (dbp, "<h2>")
- || LOOKING_AT_NOCASE (dbp, "<h3>"))
- {
- intag = FALSE;
- getnext = TRUE;
- continue;
- }
- dbp += 1;
- }
- }
- }
- static size_t prolog_pr (char *, char *);
- static void prolog_skip_comment (linebuffer *, FILE *);
- static size_t prolog_atom (char *, size_t);
- static void
- Prolog_functions (FILE *inf)
- {
- char *cp, *last;
- size_t len;
- size_t allocated;
- allocated = 0;
- len = 0;
- last = NULL;
- LOOP_ON_INPUT_LINES (inf, lb, cp)
- {
- if (cp[0] == '\0')
- continue;
- else if (iswhite (cp[0]))
- continue;
- else if (cp[0] == '/' && cp[1] == '*')
- prolog_skip_comment (&lb, inf);
- else if ((len = prolog_pr (cp, last)) > 0)
- {
-
- if (last == NULL)
- last = xnew (len + 1, char);
- else if (len + 1 > allocated)
- xrnew (last, len + 1, char);
- allocated = len + 1;
- strncpy (last, cp, len);
- last[len] = '\0';
- }
- }
- free (last);
- }
- static void
- prolog_skip_comment (linebuffer *plb, FILE *inf)
- {
- char *cp;
- do
- {
- for (cp = plb->buffer; *cp != '\0'; cp++)
- if (cp[0] == '*' && cp[1] == '/')
- return;
- readline (plb, inf);
- }
- while (!feof (inf));
- }
- static size_t
- prolog_pr (char *s, char *last)
-
- {
- size_t pos;
- size_t len;
- pos = prolog_atom (s, 0);
- if (! pos)
- return 0;
- len = pos;
- pos = skip_spaces (s + pos) - s;
- if ((s[pos] == '.'
- || (s[pos] == '(' && (pos += 1))
- || (s[pos] == ':' && s[pos + 1] == '-' && (pos += 2)))
- && (last == NULL
- || len != strlen (last)
- || !strneq (s, last, len)))
- {
- make_tag (s, len, TRUE, s, pos, lineno, linecharno);
- return len;
- }
- else
- return 0;
- }
- static size_t
- prolog_atom (char *s, size_t pos)
- {
- size_t origpos;
- origpos = pos;
- if (ISLOWER (s[pos]) || (s[pos] == '_'))
- {
-
- pos++;
- while (ISALNUM (s[pos]) || (s[pos] == '_'))
- {
- pos++;
- }
- return pos - origpos;
- }
- else if (s[pos] == '\'')
- {
- pos++;
- for (;;)
- {
- if (s[pos] == '\'')
- {
- pos++;
- if (s[pos] != '\'')
- break;
- pos++;
- }
- else if (s[pos] == '\0')
-
- return 0;
- else if (s[pos] == '\\')
- {
- if (s[pos+1] == '\0')
- return 0;
- pos += 2;
- }
- else
- pos++;
- }
- return pos - origpos;
- }
- else
- return 0;
- }
- static int erlang_func (char *, char *);
- static void erlang_attribute (char *);
- static int erlang_atom (char *);
- static void
- Erlang_functions (FILE *inf)
- {
- char *cp, *last;
- int len;
- int allocated;
- allocated = 0;
- len = 0;
- last = NULL;
- LOOP_ON_INPUT_LINES (inf, lb, cp)
- {
- if (cp[0] == '\0')
- continue;
- else if (iswhite (cp[0]))
- continue;
- else if (cp[0] == '%')
- continue;
- else if (cp[0] == '"')
- continue;
- else if (cp[0] == '-')
- {
- erlang_attribute (cp);
- if (last != NULL)
- {
- free (last);
- last = NULL;
- }
- }
- else if ((len = erlang_func (cp, last)) > 0)
- {
-
- if (last == NULL)
- last = xnew (len + 1, char);
- else if (len + 1 > allocated)
- xrnew (last, len + 1, char);
- allocated = len + 1;
- strncpy (last, cp, len);
- last[len] = '\0';
- }
- }
- free (last);
- }
- static int
- erlang_func (char *s, char *last)
-
- {
- int pos;
- int len;
- pos = erlang_atom (s);
- if (pos < 1)
- return 0;
- len = pos;
- pos = skip_spaces (s + pos) - s;
-
- if (s[pos++] == '('
- && (last == NULL
- || len != (int)strlen (last)
- || !strneq (s, last, len)))
- {
- make_tag (s, len, TRUE, s, pos, lineno, linecharno);
- return len;
- }
- return 0;
- }
- static void
- erlang_attribute (char *s)
- {
- char *cp = s;
- if ((LOOKING_AT (cp, "-define") || LOOKING_AT (cp, "-record"))
- && *cp++ == '(')
- {
- int len = erlang_atom (skip_spaces (cp));
- if (len > 0)
- make_tag (cp, len, TRUE, s, cp + len - s, lineno, linecharno);
- }
- return;
- }
- static int
- erlang_atom (char *s)
- {
- int pos = 0;
- if (ISALPHA (s[pos]) || s[pos] == '_')
- {
-
- do
- pos++;
- while (ISALNUM (s[pos]) || s[pos] == '_');
- }
- else if (s[pos] == '\'')
- {
- for (pos++; s[pos] != '\''; pos++)
- if (s[pos] == '\0'
- || (s[pos] == '\\' && s[++pos] == '\0'))
- return 0;
- pos++;
- }
- return pos;
- }
- static char *scan_separators (char *);
- static void add_regex (char *, language *);
- static char *substitute (char *, char *, struct re_registers *);
- static char *
- scan_separators (char *name)
- {
- char sep = name[0];
- char *copyto = name;
- bool quoted = FALSE;
- for (++name; *name != '\0'; ++name)
- {
- if (quoted)
- {
- switch (*name)
- {
- case 'a': *copyto++ = '\007'; break;
- case 'b': *copyto++ = '\b'; break;
- case 'd': *copyto++ = 0177; break;
- case 'e': *copyto++ = 033; break;
- case 'f': *copyto++ = '\f'; break;
- case 'n': *copyto++ = '\n'; break;
- case 'r': *copyto++ = '\r'; break;
- case 't': *copyto++ = '\t'; break;
- case 'v': *copyto++ = '\v'; break;
- default:
- if (*name == sep)
- *copyto++ = sep;
- else
- {
-
- *copyto++ = '\\';
- *copyto++ = *name;
- }
- break;
- }
- quoted = FALSE;
- }
- else if (*name == '\\')
- quoted = TRUE;
- else if (*name == sep)
- break;
- else
- *copyto++ = *name;
- }
- if (*name != sep)
- name = NULL;
-
- *copyto = '\0';
- return name;
- }
- static void
- analyse_regex (char *regex_arg)
- {
- if (regex_arg == NULL)
- {
- free_regexps ();
- return;
- }
-
- switch (regex_arg[0])
- {
-
- case '\0':
- case ' ':
- case '\t':
- break;
-
- case '@':
- {
- FILE *regexfp;
- linebuffer regexbuf;
- char *regexfile = regex_arg + 1;
-
- regexfp = fopen (regexfile, "r");
- if (regexfp == NULL)
- {
- pfatal (regexfile);
- return;
- }
- linebuffer_init (®exbuf);
- while (readline_internal (®exbuf, regexfp) > 0)
- analyse_regex (regexbuf.buffer);
- free (regexbuf.buffer);
- fclose (regexfp);
- }
- break;
-
- case '{':
- {
- language *lang;
- char *lang_name = regex_arg + 1;
- char *cp;
- for (cp = lang_name; *cp != '}'; cp++)
- if (*cp == '\0')
- {
- error ("unterminated language name in regex: %s", regex_arg);
- return;
- }
- *cp++ = '\0';
- lang = get_language_from_langname (lang_name);
- if (lang == NULL)
- return;
- add_regex (cp, lang);
- }
- break;
-
- default:
- add_regex (regex_arg, NULL);
- break;
- }
- }
- static void
- add_regex (char *regexp_pattern, language *lang)
- {
- static struct re_pattern_buffer zeropattern;
- char sep, *pat, *name, *modifiers;
- char empty[] = "";
- const char *err;
- struct re_pattern_buffer *patbuf;
- regexp *rp;
- bool
- force_explicit_name = TRUE,
- ignore_case = FALSE,
- multi_line = FALSE,
- single_line = FALSE;
- if (strlen (regexp_pattern) < 3)
- {
- error ("null regexp", (char *)NULL);
- return;
- }
- sep = regexp_pattern[0];
- name = scan_separators (regexp_pattern);
- if (name == NULL)
- {
- error ("%s: unterminated regexp", regexp_pattern);
- return;
- }
- if (name[1] == sep)
- {
- error ("null name for regexp \"%s\"", regexp_pattern);
- return;
- }
- modifiers = scan_separators (name);
- if (modifiers == NULL)
- {
- modifiers = name;
- name = empty;
- }
- else
- modifiers += 1;
-
- for (; modifiers[0] != '\0'; modifiers++)
- switch (modifiers[0])
- {
- case 'N':
- if (modifiers == name)
- error ("forcing explicit tag name but no name, ignoring", NULL);
- force_explicit_name = TRUE;
- break;
- case 'i':
- ignore_case = TRUE;
- break;
- case 's':
- single_line = TRUE;
-
- case 'm':
- multi_line = TRUE;
- need_filebuf = TRUE;
- break;
- default:
- {
- char wrongmod [2];
- wrongmod[0] = modifiers[0];
- wrongmod[1] = '\0';
- error ("invalid regexp modifier `%s', ignoring", wrongmod);
- }
- break;
- }
- patbuf = xnew (1, struct re_pattern_buffer);
- *patbuf = zeropattern;
- if (ignore_case)
- {
- static char lc_trans[CHARS];
- int i;
- for (i = 0; i < CHARS; i++)
- lc_trans[i] = lowcase (i);
- patbuf->translate = lc_trans;
- }
- if (multi_line)
- pat = concat ("^", regexp_pattern, "");
- else
- pat = regexp_pattern;
- if (single_line)
- re_set_syntax (RE_SYNTAX_EMACS | RE_DOT_NEWLINE);
- else
- re_set_syntax (RE_SYNTAX_EMACS);
- err = re_compile_pattern (pat, strlen (pat), patbuf);
- if (multi_line)
- free (pat);
- if (err != NULL)
- {
- error ("%s while compiling pattern", err);
- return;
- }
- rp = p_head;
- p_head = xnew (1, regexp);
- p_head->pattern = savestr (regexp_pattern);
- p_head->p_next = rp;
- p_head->lang = lang;
- p_head->pat = patbuf;
- p_head->name = savestr (name);
- p_head->error_signaled = FALSE;
- p_head->force_explicit_name = force_explicit_name;
- p_head->ignore_case = ignore_case;
- p_head->multi_line = multi_line;
- }
- static char *
- substitute (char *in, char *out, struct re_registers *regs)
- {
- char *result, *t;
- int size, dig, diglen;
- result = NULL;
- size = strlen (out);
-
- if (out[size - 1] == '\\')
- fatal ("pattern error in \"%s\"", out);
- for (t = etags_strchr (out, '\\');
- t != NULL;
- t = etags_strchr (t + 2, '\\'))
- if (ISDIGIT (t[1]))
- {
- dig = t[1] - '0';
- diglen = regs->end[dig] - regs->start[dig];
- size += diglen - 2;
- }
- else
- size -= 1;
-
- assert (size >= 0);
- result = xnew (size + 1, char);
- for (t = result; *out != '\0'; out++)
- if (*out == '\\' && ISDIGIT (*++out))
- {
- dig = *out - '0';
- diglen = regs->end[dig] - regs->start[dig];
- strncpy (t, in + regs->start[dig], diglen);
- t += diglen;
- }
- else
- *t++ = *out;
- *t = '\0';
- assert (t <= result + size);
- assert (t - result == (int)strlen (result));
- return result;
- }
- static void
- free_regexps (void)
- {
- regexp *rp;
- while (p_head != NULL)
- {
- rp = p_head->p_next;
- free (p_head->pattern);
- free (p_head->name);
- free (p_head);
- p_head = rp;
- }
- return;
- }
- static void
- regex_tag_multiline (void)
- {
- char *buffer = filebuf.buffer;
- regexp *rp;
- char *name;
- for (rp = p_head; rp != NULL; rp = rp->p_next)
- {
- int match = 0;
- if (!rp->multi_line)
- continue;
-
- lineno = 1;
- charno = 0;
- linecharno = 0;
-
- if (rp->lang != NULL && rp->lang != curfdp->lang)
- continue;
- while (match >= 0 && match < filebuf.len)
- {
- match = re_search (rp->pat, buffer, filebuf.len, charno,
- filebuf.len - match, &rp->regs);
- switch (match)
- {
- case -2:
-
- if (!rp->error_signaled)
- {
- error ("regexp stack overflow while matching \"%s\"",
- rp->pattern);
- rp->error_signaled = TRUE;
- }
- break;
- case -1:
-
- break;
- default:
- if (match == rp->regs.end[0])
- {
- if (!rp->error_signaled)
- {
- error ("regexp matches the empty string: \"%s\"",
- rp->pattern);
- rp->error_signaled = TRUE;
- }
- match = -3;
- break;
- }
-
- while (charno < rp->regs.end[0])
- if (buffer[charno++] == '\n')
- lineno++, linecharno = charno;
- name = rp->name;
- if (name[0] == '\0')
- name = NULL;
- else
- name = substitute (buffer, rp->name, &rp->regs);
- if (rp->force_explicit_name)
-
- pfnote (name, TRUE, buffer + linecharno,
- charno - linecharno + 1, lineno, linecharno);
- else
- make_tag (name, strlen (name), TRUE, buffer + linecharno,
- charno - linecharno + 1, lineno, linecharno);
- break;
- }
- }
- }
- }
- static bool
- nocase_tail (const char *cp)
- {
- register int len = 0;
- while (*cp != '\0' && lowcase (*cp) == lowcase (dbp[len]))
- cp++, len++;
- if (*cp == '\0' && !intoken (dbp[len]))
- {
- dbp += len;
- return TRUE;
- }
- return FALSE;
- }
- static void
- get_tag (register char *bp, char **namepp)
- {
- register char *cp = bp;
- if (*bp != '\0')
- {
-
- for (cp = bp + 1; !notinname (*cp); cp++)
- continue;
- make_tag (bp, cp - bp, TRUE,
- lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
- }
- if (namepp != NULL)
- *namepp = savenstr (bp, cp - bp);
- }
- static long
- readline_internal (linebuffer *lbp, register FILE *stream)
- {
- char *buffer = lbp->buffer;
- register char *p = lbp->buffer;
- register char *pend;
- int chars_deleted;
- pend = p + lbp->size;
- for (;;)
- {
- register int c = getc (stream);
- if (p == pend)
- {
-
- lbp->size *= 2;
- xrnew (buffer, lbp->size, char);
- p += buffer - lbp->buffer;
- pend = buffer + lbp->size;
- lbp->buffer = buffer;
- }
- if (c == EOF)
- {
- *p = '\0';
- chars_deleted = 0;
- break;
- }
- if (c == '\n')
- {
- if (p > buffer && p[-1] == '\r')
- {
- p -= 1;
- #ifdef DOS_NT
-
- chars_deleted = 1;
- #else
- chars_deleted = 2;
- #endif
- }
- else
- {
- chars_deleted = 1;
- }
- *p = '\0';
- break;
- }
- *p++ = c;
- }
- lbp->len = p - buffer;
- if (need_filebuf
- && chars_deleted > 0)
- {
- while (filebuf.size <= filebuf.len + lbp->len + 1)
- {
-
- filebuf.size *= 2;
- xrnew (filebuf.buffer, filebuf.size, char);
- }
- strncpy (filebuf.buffer + filebuf.len, lbp->buffer, lbp->len);
- filebuf.len += lbp->len;
- filebuf.buffer[filebuf.len++] = '\n';
- filebuf.buffer[filebuf.len] = '\0';
- }
- return lbp->len + chars_deleted;
- }
- static void
- readline (linebuffer *lbp, FILE *stream)
- {
- long result;
- linecharno = charno;
- result = readline_internal (lbp, stream);
- lineno += 1;
- charno += result;
-
- if (!no_line_directive)
- {
- static bool discard_until_line_directive;
-
- if (result > 12 && strneq (lbp->buffer, "#line ", 6))
- {
- unsigned int lno;
- int start = 0;
- if (sscanf (lbp->buffer, "#line %u \"%n", &lno, &start) >= 1
- && start > 0)
- {
- char *endp = lbp->buffer + start;
- while ((endp = etags_strchr (endp, '"')) != NULL
- && endp[-1] == '\\')
- endp++;
- if (endp != NULL)
-
- {
- char *taggedabsname;
- char *taggedfname;
- char *name;
- discard_until_line_directive = FALSE;
- name = lbp->buffer + start;
- *endp = '\0';
- canonicalize_filename (name);
- taggedabsname = absolute_filename (name, tagfiledir);
- if (filename_is_absolute (name)
- || filename_is_absolute (curfdp->infname))
- taggedfname = savestr (taggedabsname);
- else
- taggedfname = relative_filename (taggedabsname,tagfiledir);
- if (streq (curfdp->taggedfname, taggedfname))
-
- free (taggedfname);
- else
-
- {
- fdesc *fdp;
-
- for (fdp = fdhead; fdp != NULL; fdp = fdp->next)
- if (streq (fdp->infname, curfdp->infname)
- && streq (fdp->taggedfname, taggedfname))
-
- {
- curfdp = fdp;
- free (taggedfname);
- break;
- }
-
- if (fdp == NULL)
- for (fdp = fdhead; fdp != NULL; fdp = fdp->next)
- if (streq (fdp->infabsname, taggedabsname))
- {
- discard_until_line_directive = TRUE;
- free (taggedfname);
- break;
- }
-
- if (fdp == NULL)
- {
- fdp = fdhead;
- fdhead = xnew (1, fdesc);
- *fdhead = *curfdp;
- fdhead->next = fdp;
- fdhead->infname = savestr (curfdp->infname);
- fdhead->infabsname = savestr (curfdp->infabsname);
- fdhead->infabsdir = savestr (curfdp->infabsdir);
- fdhead->taggedfname = taggedfname;
- fdhead->usecharno = FALSE;
- fdhead->prop = NULL;
- fdhead->written = FALSE;
- curfdp = fdhead;
- }
- }
- free (taggedabsname);
- lineno = lno - 1;
- readline (lbp, stream);
- return;
- }
- }
- }
-
- if (discard_until_line_directive)
- {
- if (result > 0)
- {
-
- readline (lbp, stream);
- return;
- }
-
- discard_until_line_directive = FALSE;
- return;
- }
- }
- {
- int match;
- regexp *rp;
- char *name;
-
- if (lbp->len > 0)
- for (rp = p_head; rp != NULL; rp = rp->p_next)
- {
-
- if ((rp->lang != NULL && rp->lang != fdhead->lang)
- || rp->multi_line)
- continue;
- match = re_match (rp->pat, lbp->buffer, lbp->len, 0, &rp->regs);
- switch (match)
- {
- case -2:
-
- if (!rp->error_signaled)
- {
- error ("regexp stack overflow while matching \"%s\"",
- rp->pattern);
- rp->error_signaled = TRUE;
- }
- break;
- case -1:
-
- break;
- case 0:
-
- if (!rp->error_signaled)
- {
- error ("regexp matches the empty string: \"%s\"", rp->pattern);
- rp->error_signaled = TRUE;
- }
- break;
- default:
-
- name = rp->name;
- if (name[0] == '\0')
- name = NULL;
- else
- name = substitute (lbp->buffer, rp->name, &rp->regs);
- if (rp->force_explicit_name)
-
- pfnote (name, TRUE, lbp->buffer, match, lineno, linecharno);
- else
- make_tag (name, strlen (name), TRUE,
- lbp->buffer, match, lineno, linecharno);
- break;
- }
- }
- }
- }
- static char *
- savestr (const char *cp)
- {
- return savenstr (cp, strlen (cp));
- }
- static char *
- savenstr (const char *cp, int len)
- {
- register char *dp;
- dp = xnew (len + 1, char);
- strncpy (dp, cp, len);
- dp[len] = '\0';
- return dp;
- }
- static char *
- etags_strrchr (register const char *sp, register int c)
- {
- register const char *r;
- r = NULL;
- do
- {
- if (*sp == c)
- r = sp;
- } while (*sp++);
- return (char *)r;
- }
- static char *
- etags_strchr (register const char *sp, register int c)
- {
- do
- {
- if (*sp == c)
- return (char *)sp;
- } while (*sp++);
- return NULL;
- }
- static int
- etags_strcasecmp (register const char *s1, register const char *s2)
- {
- while (*s1 != '\0'
- && (ISALPHA (*s1) && ISALPHA (*s2)
- ? lowcase (*s1) == lowcase (*s2)
- : *s1 == *s2))
- s1++, s2++;
- return (ISALPHA (*s1) && ISALPHA (*s2)
- ? lowcase (*s1) - lowcase (*s2)
- : *s1 - *s2);
- }
- static int
- etags_strncasecmp (register const char *s1, register const char *s2, register int n)
- {
- while (*s1 != '\0' && n-- > 0
- && (ISALPHA (*s1) && ISALPHA (*s2)
- ? lowcase (*s1) == lowcase (*s2)
- : *s1 == *s2))
- s1++, s2++;
- if (n < 0)
- return 0;
- else
- return (ISALPHA (*s1) && ISALPHA (*s2)
- ? lowcase (*s1) - lowcase (*s2)
- : *s1 - *s2);
- }
- static char *
- skip_spaces (char *cp)
- {
- while (iswhite (*cp))
- cp++;
- return cp;
- }
- static char *
- skip_non_spaces (char *cp)
- {
- while (*cp != '\0' && !iswhite (*cp))
- cp++;
- return cp;
- }
- void
- fatal (const char *s1, const char *s2)
- {
- error (s1, s2);
- exit (EXIT_FAILURE);
- }
- static void
- pfatal (const char *s1)
- {
- perror (s1);
- exit (EXIT_FAILURE);
- }
- static void
- suggest_asking_for_help (void)
- {
- fprintf (stderr, "\tTry `%s %s' for a complete list of options.\n",
- progname, NO_LONG_OPTIONS ? "-h" : "--help");
- exit (EXIT_FAILURE);
- }
- static void
- error (const char *s1, const char *s2)
- {
- fprintf (stderr, "%s: ", progname);
- fprintf (stderr, s1, s2);
- fprintf (stderr, "\n");
- }
- static char *
- concat (const char *s1, const char *s2, const char *s3)
- {
- int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
- char *result = xnew (len1 + len2 + len3 + 1, char);
- strcpy (result, s1);
- strcpy (result + len1, s2);
- strcpy (result + len1 + len2, s3);
- result[len1 + len2 + len3] = '\0';
- return result;
- }
- static char *
- etags_getcwd (void)
- {
- #ifdef HAVE_GETCWD
- int bufsize = 200;
- char *path = xnew (bufsize, char);
- while (getcwd (path, bufsize) == NULL)
- {
- if (errno != ERANGE)
- pfatal ("getcwd");
- bufsize *= 2;
- free (path);
- path = xnew (bufsize, char);
- }
- canonicalize_filename (path);
- return path;
- #else
- #if MSDOS
- char *p, path[MAXPATHLEN + 1];
- getwd (path);
- for (p = path; *p != '\0'; p++)
- if (*p == '\\')
- *p = '/';
- else
- *p = lowcase (*p);
- return strdup (path);
- #else
- linebuffer path;
- FILE *pipe;
- linebuffer_init (&path);
- pipe = (FILE *) popen ("pwd 2>/dev/null", "r");
- if (pipe == NULL || readline_internal (&path, pipe) == 0)
- pfatal ("pwd");
- pclose (pipe);
- return path.buffer;
- #endif
- #endif
- }
- static char *
- relative_filename (char *file, char *dir)
- {
- char *fp, *dp, *afn, *res;
- int i;
-
- afn = absolute_filename (file, cwd);
- fp = afn;
- dp = dir;
- while (*fp++ == *dp++)
- continue;
- fp--, dp--;
- #ifdef DOS_NT
- if (fp == afn && afn[0] != '/')
- return afn;
- #endif
- do
- fp--, dp--;
- while (*fp != '/');
-
- i = 0;
- while ((dp = etags_strchr (dp + 1, '/')) != NULL)
- i += 1;
- res = xnew (3*i + strlen (fp + 1) + 1, char);
- res[0] = '\0';
- while (i-- > 0)
- strcat (res, "../");
-
- strcat (res, fp + 1);
- free (afn);
- return res;
- }
- static char *
- absolute_filename (char *file, char *dir)
- {
- char *slashp, *cp, *res;
- if (filename_is_absolute (file))
- res = savestr (file);
- #ifdef DOS_NT
-
- else if (file[1] == ':')
- fatal ("%s: relative file names with drive letters not supported", file);
- #endif
- else
- res = concat (dir, file, "");
-
- slashp = etags_strchr (res, '/');
- while (slashp != NULL && slashp[0] != '\0')
- {
- if (slashp[1] == '.')
- {
- if (slashp[2] == '.'
- && (slashp[3] == '/' || slashp[3] == '\0'))
- {
- cp = slashp;
- do
- cp--;
- while (cp >= res && !filename_is_absolute (cp));
- if (cp < res)
- cp = slashp;
- #ifdef DOS_NT
-
- else if (cp[0] != '/')
- cp = slashp;
- #endif
- memmove (cp, slashp + 3, strlen (slashp + 2));
- slashp = cp;
- continue;
- }
- else if (slashp[2] == '/' || slashp[2] == '\0')
- {
- memmove (slashp, slashp + 2, strlen (slashp + 1));
- continue;
- }
- }
- slashp = etags_strchr (slashp + 1, '/');
- }
- if (res[0] == '\0')
- {
- free (res);
- return savestr ("/");
- }
- else
- return res;
- }
- static char *
- absolute_dirname (char *file, char *dir)
- {
- char *slashp, *res;
- char save;
- slashp = etags_strrchr (file, '/');
- if (slashp == NULL)
- return savestr (dir);
- save = slashp[1];
- slashp[1] = '\0';
- res = absolute_filename (file, dir);
- slashp[1] = save;
- return res;
- }
- static bool
- filename_is_absolute (char *fn)
- {
- return (fn[0] == '/'
- #ifdef DOS_NT
- || (ISALPHA (fn[0]) && fn[1] == ':' && fn[2] == '/')
- #endif
- );
- }
- static void
- canonicalize_filename (register char *fn)
- {
- register char* cp;
- char sep = '/';
- #ifdef DOS_NT
-
- # define ISUPPER(c) isupper (CHAR (c))
- if (fn[0] != '\0' && fn[1] == ':' && ISUPPER (fn[0]))
- fn[0] = lowcase (fn[0]);
- sep = '\\';
- #endif
-
- for (cp = fn; *cp != '\0'; cp++, fn++)
- if (*cp == sep)
- {
- *fn = '/';
- while (cp[1] == sep)
- cp++;
- }
- else
- *fn = *cp;
- *fn = '\0';
- }
- static void
- linebuffer_init (linebuffer *lbp)
- {
- lbp->size = (DEBUG) ? 3 : 200;
- lbp->buffer = xnew (lbp->size, char);
- lbp->buffer[0] = '\0';
- lbp->len = 0;
- }
- static void
- linebuffer_setlen (linebuffer *lbp, int toksize)
- {
- while (lbp->size <= toksize)
- {
- lbp->size *= 2;
- xrnew (lbp->buffer, lbp->size, char);
- }
- lbp->len = toksize;
- }
- static PTR
- xmalloc (size_t size)
- {
- PTR result = (PTR) malloc (size);
- if (result == NULL)
- fatal ("virtual memory exhausted", (char *)NULL);
- return result;
- }
- static PTR
- xrealloc (char *ptr, size_t size)
- {
- PTR result = (PTR) realloc (ptr, size);
- if (result == NULL)
- fatal ("virtual memory exhausted", (char *)NULL);
- return result;
- }
|