relaxng.c 350 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809
  1. /*
  2. * relaxng.c : implementation of the Relax-NG handling and validity checking
  3. *
  4. * See Copyright for the status of this software.
  5. *
  6. * Daniel Veillard <veillard@redhat.com>
  7. */
  8. /**
  9. * TODO:
  10. * - add support for DTD compatibility spec
  11. * http://www.oasis-open.org/committees/relax-ng/compatibility-20011203.html
  12. * - report better mem allocations pbms at runtime and abort immediately.
  13. */
  14. #define IN_LIBXML
  15. #include "libxml.h"
  16. #ifdef LIBXML_SCHEMAS_ENABLED
  17. #include <string.h>
  18. #include <stdio.h>
  19. #include <stddef.h>
  20. #include <libxml/xmlmemory.h>
  21. #include <libxml/parser.h>
  22. #include <libxml/parserInternals.h>
  23. #include <libxml/hash.h>
  24. #include <libxml/uri.h>
  25. #include <libxml/relaxng.h>
  26. #include <libxml/xmlschemastypes.h>
  27. #include <libxml/xmlautomata.h>
  28. #include <libxml/xmlregexp.h>
  29. #include <libxml/xmlschemastypes.h>
  30. #include "private/error.h"
  31. #include "private/regexp.h"
  32. #include "private/string.h"
  33. /*
  34. * The Relax-NG namespace
  35. */
  36. static const xmlChar *xmlRelaxNGNs = (const xmlChar *)
  37. "http://relaxng.org/ns/structure/1.0";
  38. #define IS_RELAXNG(node, typ) \
  39. ((node != NULL) && (node->ns != NULL) && \
  40. (node->type == XML_ELEMENT_NODE) && \
  41. (xmlStrEqual(node->name, (const xmlChar *) typ)) && \
  42. (xmlStrEqual(node->ns->href, xmlRelaxNGNs)))
  43. #define MAX_ERROR 5
  44. #define TODO \
  45. xmlGenericError(xmlGenericErrorContext, \
  46. "Unimplemented block at %s:%d\n", \
  47. __FILE__, __LINE__);
  48. typedef struct _xmlRelaxNGSchema xmlRelaxNGSchema;
  49. typedef xmlRelaxNGSchema *xmlRelaxNGSchemaPtr;
  50. typedef struct _xmlRelaxNGDefine xmlRelaxNGDefine;
  51. typedef xmlRelaxNGDefine *xmlRelaxNGDefinePtr;
  52. typedef struct _xmlRelaxNGDocument xmlRelaxNGDocument;
  53. typedef xmlRelaxNGDocument *xmlRelaxNGDocumentPtr;
  54. typedef struct _xmlRelaxNGInclude xmlRelaxNGInclude;
  55. typedef xmlRelaxNGInclude *xmlRelaxNGIncludePtr;
  56. typedef enum {
  57. XML_RELAXNG_COMBINE_UNDEFINED = 0, /* undefined */
  58. XML_RELAXNG_COMBINE_CHOICE, /* choice */
  59. XML_RELAXNG_COMBINE_INTERLEAVE /* interleave */
  60. } xmlRelaxNGCombine;
  61. typedef enum {
  62. XML_RELAXNG_CONTENT_ERROR = -1,
  63. XML_RELAXNG_CONTENT_EMPTY = 0,
  64. XML_RELAXNG_CONTENT_SIMPLE,
  65. XML_RELAXNG_CONTENT_COMPLEX
  66. } xmlRelaxNGContentType;
  67. typedef struct _xmlRelaxNGGrammar xmlRelaxNGGrammar;
  68. typedef xmlRelaxNGGrammar *xmlRelaxNGGrammarPtr;
  69. struct _xmlRelaxNGGrammar {
  70. xmlRelaxNGGrammarPtr parent; /* the parent grammar if any */
  71. xmlRelaxNGGrammarPtr children; /* the children grammar if any */
  72. xmlRelaxNGGrammarPtr next; /* the next grammar if any */
  73. xmlRelaxNGDefinePtr start; /* <start> content */
  74. xmlRelaxNGCombine combine; /* the default combine value */
  75. xmlRelaxNGDefinePtr startList; /* list of <start> definitions */
  76. xmlHashTablePtr defs; /* define* */
  77. xmlHashTablePtr refs; /* references */
  78. };
  79. typedef enum {
  80. XML_RELAXNG_NOOP = -1, /* a no operation from simplification */
  81. XML_RELAXNG_EMPTY = 0, /* an empty pattern */
  82. XML_RELAXNG_NOT_ALLOWED, /* not allowed top */
  83. XML_RELAXNG_EXCEPT, /* except present in nameclass defs */
  84. XML_RELAXNG_TEXT, /* textual content */
  85. XML_RELAXNG_ELEMENT, /* an element */
  86. XML_RELAXNG_DATATYPE, /* external data type definition */
  87. XML_RELAXNG_PARAM, /* external data type parameter */
  88. XML_RELAXNG_VALUE, /* value from an external data type definition */
  89. XML_RELAXNG_LIST, /* a list of patterns */
  90. XML_RELAXNG_ATTRIBUTE, /* an attribute following a pattern */
  91. XML_RELAXNG_DEF, /* a definition */
  92. XML_RELAXNG_REF, /* reference to a definition */
  93. XML_RELAXNG_EXTERNALREF, /* reference to an external def */
  94. XML_RELAXNG_PARENTREF, /* reference to a def in the parent grammar */
  95. XML_RELAXNG_OPTIONAL, /* optional patterns */
  96. XML_RELAXNG_ZEROORMORE, /* zero or more non empty patterns */
  97. XML_RELAXNG_ONEORMORE, /* one or more non empty patterns */
  98. XML_RELAXNG_CHOICE, /* a choice between non empty patterns */
  99. XML_RELAXNG_GROUP, /* a pair/group of non empty patterns */
  100. XML_RELAXNG_INTERLEAVE, /* interleaving choice of non-empty patterns */
  101. XML_RELAXNG_START /* Used to keep track of starts on grammars */
  102. } xmlRelaxNGType;
  103. #define IS_NULLABLE (1 << 0)
  104. #define IS_NOT_NULLABLE (1 << 1)
  105. #define IS_INDETERMINIST (1 << 2)
  106. #define IS_MIXED (1 << 3)
  107. #define IS_TRIABLE (1 << 4)
  108. #define IS_PROCESSED (1 << 5)
  109. #define IS_COMPILABLE (1 << 6)
  110. #define IS_NOT_COMPILABLE (1 << 7)
  111. #define IS_EXTERNAL_REF (1 << 8)
  112. struct _xmlRelaxNGDefine {
  113. xmlRelaxNGType type; /* the type of definition */
  114. xmlNodePtr node; /* the node in the source */
  115. xmlChar *name; /* the element local name if present */
  116. xmlChar *ns; /* the namespace local name if present */
  117. xmlChar *value; /* value when available */
  118. void *data; /* data lib or specific pointer */
  119. xmlRelaxNGDefinePtr content; /* the expected content */
  120. xmlRelaxNGDefinePtr parent; /* the parent definition, if any */
  121. xmlRelaxNGDefinePtr next; /* list within grouping sequences */
  122. xmlRelaxNGDefinePtr attrs; /* list of attributes for elements */
  123. xmlRelaxNGDefinePtr nameClass; /* the nameClass definition if any */
  124. xmlRelaxNGDefinePtr nextHash; /* next define in defs/refs hash tables */
  125. short depth; /* used for the cycle detection */
  126. short dflags; /* define related flags */
  127. xmlRegexpPtr contModel; /* a compiled content model if available */
  128. };
  129. /**
  130. * _xmlRelaxNG:
  131. *
  132. * A RelaxNGs definition
  133. */
  134. struct _xmlRelaxNG {
  135. void *_private; /* unused by the library for users or bindings */
  136. xmlRelaxNGGrammarPtr topgrammar;
  137. xmlDocPtr doc;
  138. int idref; /* requires idref checking */
  139. xmlHashTablePtr defs; /* define */
  140. xmlHashTablePtr refs; /* references */
  141. xmlRelaxNGDocumentPtr documents; /* all the documents loaded */
  142. xmlRelaxNGIncludePtr includes; /* all the includes loaded */
  143. int defNr; /* number of defines used */
  144. xmlRelaxNGDefinePtr *defTab; /* pointer to the allocated definitions */
  145. };
  146. #define XML_RELAXNG_IN_ATTRIBUTE (1 << 0)
  147. #define XML_RELAXNG_IN_ONEORMORE (1 << 1)
  148. #define XML_RELAXNG_IN_LIST (1 << 2)
  149. #define XML_RELAXNG_IN_DATAEXCEPT (1 << 3)
  150. #define XML_RELAXNG_IN_START (1 << 4)
  151. #define XML_RELAXNG_IN_OOMGROUP (1 << 5)
  152. #define XML_RELAXNG_IN_OOMINTERLEAVE (1 << 6)
  153. #define XML_RELAXNG_IN_EXTERNALREF (1 << 7)
  154. #define XML_RELAXNG_IN_ANYEXCEPT (1 << 8)
  155. #define XML_RELAXNG_IN_NSEXCEPT (1 << 9)
  156. struct _xmlRelaxNGParserCtxt {
  157. void *userData; /* user specific data block */
  158. xmlRelaxNGValidityErrorFunc error; /* the callback in case of errors */
  159. xmlRelaxNGValidityWarningFunc warning; /* the callback in case of warning */
  160. xmlStructuredErrorFunc serror;
  161. xmlRelaxNGValidErr err;
  162. xmlRelaxNGPtr schema; /* The schema in use */
  163. xmlRelaxNGGrammarPtr grammar; /* the current grammar */
  164. xmlRelaxNGGrammarPtr parentgrammar; /* the parent grammar */
  165. int flags; /* parser flags */
  166. int nbErrors; /* number of errors at parse time */
  167. int nbWarnings; /* number of warnings at parse time */
  168. const xmlChar *define; /* the current define scope */
  169. xmlRelaxNGDefinePtr def; /* the current define */
  170. int nbInterleaves;
  171. xmlHashTablePtr interleaves; /* keep track of all the interleaves */
  172. xmlRelaxNGDocumentPtr documents; /* all the documents loaded */
  173. xmlRelaxNGIncludePtr includes; /* all the includes loaded */
  174. xmlChar *URL;
  175. xmlDocPtr document;
  176. int defNr; /* number of defines used */
  177. int defMax; /* number of defines allocated */
  178. xmlRelaxNGDefinePtr *defTab; /* pointer to the allocated definitions */
  179. const char *buffer;
  180. int size;
  181. /* the document stack */
  182. xmlRelaxNGDocumentPtr doc; /* Current parsed external ref */
  183. int docNr; /* Depth of the parsing stack */
  184. int docMax; /* Max depth of the parsing stack */
  185. xmlRelaxNGDocumentPtr *docTab; /* array of docs */
  186. /* the include stack */
  187. xmlRelaxNGIncludePtr inc; /* Current parsed include */
  188. int incNr; /* Depth of the include parsing stack */
  189. int incMax; /* Max depth of the parsing stack */
  190. xmlRelaxNGIncludePtr *incTab; /* array of incs */
  191. int idref; /* requires idref checking */
  192. /* used to compile content models */
  193. xmlAutomataPtr am; /* the automata */
  194. xmlAutomataStatePtr state; /* used to build the automata */
  195. int crng; /* compact syntax and other flags */
  196. int freedoc; /* need to free the document */
  197. };
  198. #define FLAGS_IGNORABLE 1
  199. #define FLAGS_NEGATIVE 2
  200. #define FLAGS_MIXED_CONTENT 4
  201. #define FLAGS_NOERROR 8
  202. /**
  203. * xmlRelaxNGInterleaveGroup:
  204. *
  205. * A RelaxNGs partition set associated to lists of definitions
  206. */
  207. typedef struct _xmlRelaxNGInterleaveGroup xmlRelaxNGInterleaveGroup;
  208. typedef xmlRelaxNGInterleaveGroup *xmlRelaxNGInterleaveGroupPtr;
  209. struct _xmlRelaxNGInterleaveGroup {
  210. xmlRelaxNGDefinePtr rule; /* the rule to satisfy */
  211. xmlRelaxNGDefinePtr *defs; /* the array of element definitions */
  212. xmlRelaxNGDefinePtr *attrs; /* the array of attributes definitions */
  213. };
  214. #define IS_DETERMINIST 1
  215. #define IS_NEEDCHECK 2
  216. /**
  217. * xmlRelaxNGPartitions:
  218. *
  219. * A RelaxNGs partition associated to an interleave group
  220. */
  221. typedef struct _xmlRelaxNGPartition xmlRelaxNGPartition;
  222. typedef xmlRelaxNGPartition *xmlRelaxNGPartitionPtr;
  223. struct _xmlRelaxNGPartition {
  224. int nbgroups; /* number of groups in the partitions */
  225. xmlHashTablePtr triage; /* hash table used to direct nodes to the
  226. * right group when possible */
  227. int flags; /* determinist ? */
  228. xmlRelaxNGInterleaveGroupPtr *groups;
  229. };
  230. /**
  231. * xmlRelaxNGValidState:
  232. *
  233. * A RelaxNGs validation state
  234. */
  235. #define MAX_ATTR 20
  236. typedef struct _xmlRelaxNGValidState xmlRelaxNGValidState;
  237. typedef xmlRelaxNGValidState *xmlRelaxNGValidStatePtr;
  238. struct _xmlRelaxNGValidState {
  239. xmlNodePtr node; /* the current node */
  240. xmlNodePtr seq; /* the sequence of children left to validate */
  241. int nbAttrs; /* the number of attributes */
  242. int maxAttrs; /* the size of attrs */
  243. int nbAttrLeft; /* the number of attributes left to validate */
  244. xmlChar *value; /* the value when operating on string */
  245. xmlChar *endvalue; /* the end value when operating on string */
  246. xmlAttrPtr *attrs; /* the array of attributes */
  247. };
  248. /**
  249. * xmlRelaxNGStates:
  250. *
  251. * A RelaxNGs container for validation state
  252. */
  253. typedef struct _xmlRelaxNGStates xmlRelaxNGStates;
  254. typedef xmlRelaxNGStates *xmlRelaxNGStatesPtr;
  255. struct _xmlRelaxNGStates {
  256. int nbState; /* the number of states */
  257. int maxState; /* the size of the array */
  258. xmlRelaxNGValidStatePtr *tabState;
  259. };
  260. #define ERROR_IS_DUP 1
  261. /**
  262. * xmlRelaxNGValidError:
  263. *
  264. * A RelaxNGs validation error
  265. */
  266. typedef struct _xmlRelaxNGValidError xmlRelaxNGValidError;
  267. typedef xmlRelaxNGValidError *xmlRelaxNGValidErrorPtr;
  268. struct _xmlRelaxNGValidError {
  269. xmlRelaxNGValidErr err; /* the error number */
  270. int flags; /* flags */
  271. xmlNodePtr node; /* the current node */
  272. xmlNodePtr seq; /* the current child */
  273. const xmlChar *arg1; /* first arg */
  274. const xmlChar *arg2; /* second arg */
  275. };
  276. /**
  277. * xmlRelaxNGValidCtxt:
  278. *
  279. * A RelaxNGs validation context
  280. */
  281. struct _xmlRelaxNGValidCtxt {
  282. void *userData; /* user specific data block */
  283. xmlRelaxNGValidityErrorFunc error; /* the callback in case of errors */
  284. xmlRelaxNGValidityWarningFunc warning; /* the callback in case of warning */
  285. xmlStructuredErrorFunc serror;
  286. int nbErrors; /* number of errors in validation */
  287. xmlRelaxNGPtr schema; /* The schema in use */
  288. xmlDocPtr doc; /* the document being validated */
  289. int flags; /* validation flags */
  290. int depth; /* validation depth */
  291. int idref; /* requires idref checking */
  292. int errNo; /* the first error found */
  293. /*
  294. * Errors accumulated in branches may have to be stacked to be
  295. * provided back when it's sure they affect validation.
  296. */
  297. xmlRelaxNGValidErrorPtr err; /* Last error */
  298. int errNr; /* Depth of the error stack */
  299. int errMax; /* Max depth of the error stack */
  300. xmlRelaxNGValidErrorPtr errTab; /* stack of errors */
  301. xmlRelaxNGValidStatePtr state; /* the current validation state */
  302. xmlRelaxNGStatesPtr states; /* the accumulated state list */
  303. xmlRelaxNGStatesPtr freeState; /* the pool of free valid states */
  304. int freeStatesNr;
  305. int freeStatesMax;
  306. xmlRelaxNGStatesPtr *freeStates; /* the pool of free state groups */
  307. /*
  308. * This is used for "progressive" validation
  309. */
  310. xmlRegExecCtxtPtr elem; /* the current element regexp */
  311. int elemNr; /* the number of element validated */
  312. int elemMax; /* the max depth of elements */
  313. xmlRegExecCtxtPtr *elemTab; /* the stack of regexp runtime */
  314. int pstate; /* progressive state */
  315. xmlNodePtr pnode; /* the current node */
  316. xmlRelaxNGDefinePtr pdef; /* the non-streamable definition */
  317. int perr; /* signal error in content model
  318. * outside the regexp */
  319. };
  320. /**
  321. * xmlRelaxNGInclude:
  322. *
  323. * Structure associated to a RelaxNGs document element
  324. */
  325. struct _xmlRelaxNGInclude {
  326. xmlRelaxNGIncludePtr next; /* keep a chain of includes */
  327. xmlChar *href; /* the normalized href value */
  328. xmlDocPtr doc; /* the associated XML document */
  329. xmlRelaxNGDefinePtr content; /* the definitions */
  330. xmlRelaxNGPtr schema; /* the schema */
  331. };
  332. /**
  333. * xmlRelaxNGDocument:
  334. *
  335. * Structure associated to a RelaxNGs document element
  336. */
  337. struct _xmlRelaxNGDocument {
  338. xmlRelaxNGDocumentPtr next; /* keep a chain of documents */
  339. xmlChar *href; /* the normalized href value */
  340. xmlDocPtr doc; /* the associated XML document */
  341. xmlRelaxNGDefinePtr content; /* the definitions */
  342. xmlRelaxNGPtr schema; /* the schema */
  343. int externalRef; /* 1 if an external ref */
  344. };
  345. /************************************************************************
  346. * *
  347. * Some factorized error routines *
  348. * *
  349. ************************************************************************/
  350. /**
  351. * xmlRngPErrMemory:
  352. * @ctxt: an Relax-NG parser context
  353. * @extra: extra information
  354. *
  355. * Handle a redefinition of attribute error
  356. */
  357. static void
  358. xmlRngPErrMemory(xmlRelaxNGParserCtxtPtr ctxt, const char *extra)
  359. {
  360. xmlStructuredErrorFunc schannel = NULL;
  361. xmlGenericErrorFunc channel = NULL;
  362. void *data = NULL;
  363. if (ctxt != NULL) {
  364. if (ctxt->serror != NULL)
  365. schannel = ctxt->serror;
  366. else
  367. channel = ctxt->error;
  368. data = ctxt->userData;
  369. ctxt->nbErrors++;
  370. }
  371. if (extra)
  372. __xmlRaiseError(schannel, channel, data,
  373. NULL, NULL, XML_FROM_RELAXNGP,
  374. XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
  375. NULL, NULL, 0, 0,
  376. "Memory allocation failed : %s\n", extra);
  377. else
  378. __xmlRaiseError(schannel, channel, data,
  379. NULL, NULL, XML_FROM_RELAXNGP,
  380. XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL,
  381. NULL, NULL, 0, 0, "Memory allocation failed\n");
  382. }
  383. /**
  384. * xmlRngVErrMemory:
  385. * @ctxt: a Relax-NG validation context
  386. * @extra: extra information
  387. *
  388. * Handle a redefinition of attribute error
  389. */
  390. static void
  391. xmlRngVErrMemory(xmlRelaxNGValidCtxtPtr ctxt, const char *extra)
  392. {
  393. xmlStructuredErrorFunc schannel = NULL;
  394. xmlGenericErrorFunc channel = NULL;
  395. void *data = NULL;
  396. if (ctxt != NULL) {
  397. if (ctxt->serror != NULL)
  398. schannel = ctxt->serror;
  399. else
  400. channel = ctxt->error;
  401. data = ctxt->userData;
  402. ctxt->nbErrors++;
  403. }
  404. if (extra)
  405. __xmlRaiseError(schannel, channel, data,
  406. NULL, NULL, XML_FROM_RELAXNGV,
  407. XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
  408. NULL, NULL, 0, 0,
  409. "Memory allocation failed : %s\n", extra);
  410. else
  411. __xmlRaiseError(schannel, channel, data,
  412. NULL, NULL, XML_FROM_RELAXNGV,
  413. XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL,
  414. NULL, NULL, 0, 0, "Memory allocation failed\n");
  415. }
  416. /**
  417. * xmlRngPErr:
  418. * @ctxt: a Relax-NG parser context
  419. * @node: the node raising the error
  420. * @error: the error code
  421. * @msg: message
  422. * @str1: extra info
  423. * @str2: extra info
  424. *
  425. * Handle a Relax NG Parsing error
  426. */
  427. static void LIBXML_ATTR_FORMAT(4,0)
  428. xmlRngPErr(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node, int error,
  429. const char *msg, const xmlChar * str1, const xmlChar * str2)
  430. {
  431. xmlStructuredErrorFunc schannel = NULL;
  432. xmlGenericErrorFunc channel = NULL;
  433. void *data = NULL;
  434. if (ctxt != NULL) {
  435. if (ctxt->serror != NULL)
  436. schannel = ctxt->serror;
  437. else
  438. channel = ctxt->error;
  439. data = ctxt->userData;
  440. ctxt->nbErrors++;
  441. }
  442. __xmlRaiseError(schannel, channel, data,
  443. NULL, node, XML_FROM_RELAXNGP,
  444. error, XML_ERR_ERROR, NULL, 0,
  445. (const char *) str1, (const char *) str2, NULL, 0, 0,
  446. msg, str1, str2);
  447. }
  448. /**
  449. * xmlRngVErr:
  450. * @ctxt: a Relax-NG validation context
  451. * @node: the node raising the error
  452. * @error: the error code
  453. * @msg: message
  454. * @str1: extra info
  455. * @str2: extra info
  456. *
  457. * Handle a Relax NG Validation error
  458. */
  459. static void LIBXML_ATTR_FORMAT(4,0)
  460. xmlRngVErr(xmlRelaxNGValidCtxtPtr ctxt, xmlNodePtr node, int error,
  461. const char *msg, const xmlChar * str1, const xmlChar * str2)
  462. {
  463. xmlStructuredErrorFunc schannel = NULL;
  464. xmlGenericErrorFunc channel = NULL;
  465. void *data = NULL;
  466. if (ctxt != NULL) {
  467. if (ctxt->serror != NULL)
  468. schannel = ctxt->serror;
  469. else
  470. channel = ctxt->error;
  471. data = ctxt->userData;
  472. ctxt->nbErrors++;
  473. }
  474. __xmlRaiseError(schannel, channel, data,
  475. NULL, node, XML_FROM_RELAXNGV,
  476. error, XML_ERR_ERROR, NULL, 0,
  477. (const char *) str1, (const char *) str2, NULL, 0, 0,
  478. msg, str1, str2);
  479. }
  480. /************************************************************************
  481. * *
  482. * Preliminary type checking interfaces *
  483. * *
  484. ************************************************************************/
  485. /**
  486. * xmlRelaxNGTypeHave:
  487. * @data: data needed for the library
  488. * @type: the type name
  489. * @value: the value to check
  490. *
  491. * Function provided by a type library to check if a type is exported
  492. *
  493. * Returns 1 if yes, 0 if no and -1 in case of error.
  494. */
  495. typedef int (*xmlRelaxNGTypeHave) (void *data, const xmlChar * type);
  496. /**
  497. * xmlRelaxNGTypeCheck:
  498. * @data: data needed for the library
  499. * @type: the type name
  500. * @value: the value to check
  501. * @result: place to store the result if needed
  502. *
  503. * Function provided by a type library to check if a value match a type
  504. *
  505. * Returns 1 if yes, 0 if no and -1 in case of error.
  506. */
  507. typedef int (*xmlRelaxNGTypeCheck) (void *data, const xmlChar * type,
  508. const xmlChar * value, void **result,
  509. xmlNodePtr node);
  510. /**
  511. * xmlRelaxNGFacetCheck:
  512. * @data: data needed for the library
  513. * @type: the type name
  514. * @facet: the facet name
  515. * @val: the facet value
  516. * @strval: the string value
  517. * @value: the value to check
  518. *
  519. * Function provided by a type library to check a value facet
  520. *
  521. * Returns 1 if yes, 0 if no and -1 in case of error.
  522. */
  523. typedef int (*xmlRelaxNGFacetCheck) (void *data, const xmlChar * type,
  524. const xmlChar * facet,
  525. const xmlChar * val,
  526. const xmlChar * strval, void *value);
  527. /**
  528. * xmlRelaxNGTypeFree:
  529. * @data: data needed for the library
  530. * @result: the value to free
  531. *
  532. * Function provided by a type library to free a returned result
  533. */
  534. typedef void (*xmlRelaxNGTypeFree) (void *data, void *result);
  535. /**
  536. * xmlRelaxNGTypeCompare:
  537. * @data: data needed for the library
  538. * @type: the type name
  539. * @value1: the first value
  540. * @value2: the second value
  541. *
  542. * Function provided by a type library to compare two values accordingly
  543. * to a type.
  544. *
  545. * Returns 1 if yes, 0 if no and -1 in case of error.
  546. */
  547. typedef int (*xmlRelaxNGTypeCompare) (void *data, const xmlChar * type,
  548. const xmlChar * value1,
  549. xmlNodePtr ctxt1,
  550. void *comp1,
  551. const xmlChar * value2,
  552. xmlNodePtr ctxt2);
  553. typedef struct _xmlRelaxNGTypeLibrary xmlRelaxNGTypeLibrary;
  554. typedef xmlRelaxNGTypeLibrary *xmlRelaxNGTypeLibraryPtr;
  555. struct _xmlRelaxNGTypeLibrary {
  556. const xmlChar *namespace; /* the datatypeLibrary value */
  557. void *data; /* data needed for the library */
  558. xmlRelaxNGTypeHave have; /* the export function */
  559. xmlRelaxNGTypeCheck check; /* the checking function */
  560. xmlRelaxNGTypeCompare comp; /* the compare function */
  561. xmlRelaxNGFacetCheck facet; /* the facet check function */
  562. xmlRelaxNGTypeFree freef; /* the freeing function */
  563. };
  564. /************************************************************************
  565. * *
  566. * Allocation functions *
  567. * *
  568. ************************************************************************/
  569. static void xmlRelaxNGFreeGrammar(xmlRelaxNGGrammarPtr grammar);
  570. static void xmlRelaxNGFreeDefine(xmlRelaxNGDefinePtr define);
  571. static void xmlRelaxNGNormExtSpace(xmlChar * value);
  572. static void xmlRelaxNGFreeInnerSchema(xmlRelaxNGPtr schema);
  573. static int xmlRelaxNGEqualValidState(xmlRelaxNGValidCtxtPtr ctxt
  574. ATTRIBUTE_UNUSED,
  575. xmlRelaxNGValidStatePtr state1,
  576. xmlRelaxNGValidStatePtr state2);
  577. static void xmlRelaxNGFreeValidState(xmlRelaxNGValidCtxtPtr ctxt,
  578. xmlRelaxNGValidStatePtr state);
  579. /**
  580. * xmlRelaxNGFreeDocument:
  581. * @docu: a document structure
  582. *
  583. * Deallocate a RelaxNG document structure.
  584. */
  585. static void
  586. xmlRelaxNGFreeDocument(xmlRelaxNGDocumentPtr docu)
  587. {
  588. if (docu == NULL)
  589. return;
  590. if (docu->href != NULL)
  591. xmlFree(docu->href);
  592. if (docu->doc != NULL)
  593. xmlFreeDoc(docu->doc);
  594. if (docu->schema != NULL)
  595. xmlRelaxNGFreeInnerSchema(docu->schema);
  596. xmlFree(docu);
  597. }
  598. /**
  599. * xmlRelaxNGFreeDocumentList:
  600. * @docu: a list of document structure
  601. *
  602. * Deallocate a RelaxNG document structures.
  603. */
  604. static void
  605. xmlRelaxNGFreeDocumentList(xmlRelaxNGDocumentPtr docu)
  606. {
  607. xmlRelaxNGDocumentPtr next;
  608. while (docu != NULL) {
  609. next = docu->next;
  610. xmlRelaxNGFreeDocument(docu);
  611. docu = next;
  612. }
  613. }
  614. /**
  615. * xmlRelaxNGFreeInclude:
  616. * @incl: a include structure
  617. *
  618. * Deallocate a RelaxNG include structure.
  619. */
  620. static void
  621. xmlRelaxNGFreeInclude(xmlRelaxNGIncludePtr incl)
  622. {
  623. if (incl == NULL)
  624. return;
  625. if (incl->href != NULL)
  626. xmlFree(incl->href);
  627. if (incl->doc != NULL)
  628. xmlFreeDoc(incl->doc);
  629. if (incl->schema != NULL)
  630. xmlRelaxNGFree(incl->schema);
  631. xmlFree(incl);
  632. }
  633. /**
  634. * xmlRelaxNGFreeIncludeList:
  635. * @incl: a include structure list
  636. *
  637. * Deallocate a RelaxNG include structure.
  638. */
  639. static void
  640. xmlRelaxNGFreeIncludeList(xmlRelaxNGIncludePtr incl)
  641. {
  642. xmlRelaxNGIncludePtr next;
  643. while (incl != NULL) {
  644. next = incl->next;
  645. xmlRelaxNGFreeInclude(incl);
  646. incl = next;
  647. }
  648. }
  649. /**
  650. * xmlRelaxNGNewRelaxNG:
  651. * @ctxt: a Relax-NG validation context (optional)
  652. *
  653. * Allocate a new RelaxNG structure.
  654. *
  655. * Returns the newly allocated structure or NULL in case or error
  656. */
  657. static xmlRelaxNGPtr
  658. xmlRelaxNGNewRelaxNG(xmlRelaxNGParserCtxtPtr ctxt)
  659. {
  660. xmlRelaxNGPtr ret;
  661. ret = (xmlRelaxNGPtr) xmlMalloc(sizeof(xmlRelaxNG));
  662. if (ret == NULL) {
  663. xmlRngPErrMemory(ctxt, NULL);
  664. return (NULL);
  665. }
  666. memset(ret, 0, sizeof(xmlRelaxNG));
  667. return (ret);
  668. }
  669. /**
  670. * xmlRelaxNGFreeInnerSchema:
  671. * @schema: a schema structure
  672. *
  673. * Deallocate a RelaxNG schema structure.
  674. */
  675. static void
  676. xmlRelaxNGFreeInnerSchema(xmlRelaxNGPtr schema)
  677. {
  678. if (schema == NULL)
  679. return;
  680. if (schema->doc != NULL)
  681. xmlFreeDoc(schema->doc);
  682. if (schema->defTab != NULL) {
  683. int i;
  684. for (i = 0; i < schema->defNr; i++)
  685. xmlRelaxNGFreeDefine(schema->defTab[i]);
  686. xmlFree(schema->defTab);
  687. }
  688. xmlFree(schema);
  689. }
  690. /**
  691. * xmlRelaxNGFree:
  692. * @schema: a schema structure
  693. *
  694. * Deallocate a RelaxNG structure.
  695. */
  696. void
  697. xmlRelaxNGFree(xmlRelaxNGPtr schema)
  698. {
  699. if (schema == NULL)
  700. return;
  701. if (schema->topgrammar != NULL)
  702. xmlRelaxNGFreeGrammar(schema->topgrammar);
  703. if (schema->doc != NULL)
  704. xmlFreeDoc(schema->doc);
  705. if (schema->documents != NULL)
  706. xmlRelaxNGFreeDocumentList(schema->documents);
  707. if (schema->includes != NULL)
  708. xmlRelaxNGFreeIncludeList(schema->includes);
  709. if (schema->defTab != NULL) {
  710. int i;
  711. for (i = 0; i < schema->defNr; i++)
  712. xmlRelaxNGFreeDefine(schema->defTab[i]);
  713. xmlFree(schema->defTab);
  714. }
  715. xmlFree(schema);
  716. }
  717. /**
  718. * xmlRelaxNGNewGrammar:
  719. * @ctxt: a Relax-NG validation context (optional)
  720. *
  721. * Allocate a new RelaxNG grammar.
  722. *
  723. * Returns the newly allocated structure or NULL in case or error
  724. */
  725. static xmlRelaxNGGrammarPtr
  726. xmlRelaxNGNewGrammar(xmlRelaxNGParserCtxtPtr ctxt)
  727. {
  728. xmlRelaxNGGrammarPtr ret;
  729. ret = (xmlRelaxNGGrammarPtr) xmlMalloc(sizeof(xmlRelaxNGGrammar));
  730. if (ret == NULL) {
  731. xmlRngPErrMemory(ctxt, NULL);
  732. return (NULL);
  733. }
  734. memset(ret, 0, sizeof(xmlRelaxNGGrammar));
  735. return (ret);
  736. }
  737. /**
  738. * xmlRelaxNGFreeGrammar:
  739. * @grammar: a grammar structure
  740. *
  741. * Deallocate a RelaxNG grammar structure.
  742. */
  743. static void
  744. xmlRelaxNGFreeGrammar(xmlRelaxNGGrammarPtr grammar)
  745. {
  746. if (grammar == NULL)
  747. return;
  748. if (grammar->children != NULL) {
  749. xmlRelaxNGFreeGrammar(grammar->children);
  750. }
  751. if (grammar->next != NULL) {
  752. xmlRelaxNGFreeGrammar(grammar->next);
  753. }
  754. if (grammar->refs != NULL) {
  755. xmlHashFree(grammar->refs, NULL);
  756. }
  757. if (grammar->defs != NULL) {
  758. xmlHashFree(grammar->defs, NULL);
  759. }
  760. xmlFree(grammar);
  761. }
  762. /**
  763. * xmlRelaxNGNewDefine:
  764. * @ctxt: a Relax-NG validation context
  765. * @node: the node in the input document.
  766. *
  767. * Allocate a new RelaxNG define.
  768. *
  769. * Returns the newly allocated structure or NULL in case or error
  770. */
  771. static xmlRelaxNGDefinePtr
  772. xmlRelaxNGNewDefine(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
  773. {
  774. xmlRelaxNGDefinePtr ret;
  775. if (ctxt->defMax == 0) {
  776. ctxt->defMax = 16;
  777. ctxt->defNr = 0;
  778. ctxt->defTab = (xmlRelaxNGDefinePtr *)
  779. xmlMalloc(ctxt->defMax * sizeof(xmlRelaxNGDefinePtr));
  780. if (ctxt->defTab == NULL) {
  781. xmlRngPErrMemory(ctxt, "allocating define\n");
  782. return (NULL);
  783. }
  784. } else if (ctxt->defMax <= ctxt->defNr) {
  785. xmlRelaxNGDefinePtr *tmp;
  786. ctxt->defMax *= 2;
  787. tmp = (xmlRelaxNGDefinePtr *) xmlRealloc(ctxt->defTab,
  788. ctxt->defMax *
  789. sizeof
  790. (xmlRelaxNGDefinePtr));
  791. if (tmp == NULL) {
  792. xmlRngPErrMemory(ctxt, "allocating define\n");
  793. return (NULL);
  794. }
  795. ctxt->defTab = tmp;
  796. }
  797. ret = (xmlRelaxNGDefinePtr) xmlMalloc(sizeof(xmlRelaxNGDefine));
  798. if (ret == NULL) {
  799. xmlRngPErrMemory(ctxt, "allocating define\n");
  800. return (NULL);
  801. }
  802. memset(ret, 0, sizeof(xmlRelaxNGDefine));
  803. ctxt->defTab[ctxt->defNr++] = ret;
  804. ret->node = node;
  805. ret->depth = -1;
  806. return (ret);
  807. }
  808. /**
  809. * xmlRelaxNGFreePartition:
  810. * @partitions: a partition set structure
  811. *
  812. * Deallocate RelaxNG partition set structures.
  813. */
  814. static void
  815. xmlRelaxNGFreePartition(xmlRelaxNGPartitionPtr partitions)
  816. {
  817. xmlRelaxNGInterleaveGroupPtr group;
  818. int j;
  819. if (partitions != NULL) {
  820. if (partitions->groups != NULL) {
  821. for (j = 0; j < partitions->nbgroups; j++) {
  822. group = partitions->groups[j];
  823. if (group != NULL) {
  824. if (group->defs != NULL)
  825. xmlFree(group->defs);
  826. if (group->attrs != NULL)
  827. xmlFree(group->attrs);
  828. xmlFree(group);
  829. }
  830. }
  831. xmlFree(partitions->groups);
  832. }
  833. if (partitions->triage != NULL) {
  834. xmlHashFree(partitions->triage, NULL);
  835. }
  836. xmlFree(partitions);
  837. }
  838. }
  839. /**
  840. * xmlRelaxNGFreeDefine:
  841. * @define: a define structure
  842. *
  843. * Deallocate a RelaxNG define structure.
  844. */
  845. static void
  846. xmlRelaxNGFreeDefine(xmlRelaxNGDefinePtr define)
  847. {
  848. if (define == NULL)
  849. return;
  850. if ((define->type == XML_RELAXNG_VALUE) && (define->attrs != NULL)) {
  851. xmlRelaxNGTypeLibraryPtr lib;
  852. lib = (xmlRelaxNGTypeLibraryPtr) define->data;
  853. if ((lib != NULL) && (lib->freef != NULL))
  854. lib->freef(lib->data, (void *) define->attrs);
  855. }
  856. if ((define->data != NULL) && (define->type == XML_RELAXNG_INTERLEAVE))
  857. xmlRelaxNGFreePartition((xmlRelaxNGPartitionPtr) define->data);
  858. if ((define->data != NULL) && (define->type == XML_RELAXNG_CHOICE))
  859. xmlHashFree((xmlHashTablePtr) define->data, NULL);
  860. if (define->name != NULL)
  861. xmlFree(define->name);
  862. if (define->ns != NULL)
  863. xmlFree(define->ns);
  864. if (define->value != NULL)
  865. xmlFree(define->value);
  866. if (define->contModel != NULL)
  867. xmlRegFreeRegexp(define->contModel);
  868. xmlFree(define);
  869. }
  870. /**
  871. * xmlRelaxNGNewStates:
  872. * @ctxt: a Relax-NG validation context
  873. * @size: the default size for the container
  874. *
  875. * Allocate a new RelaxNG validation state container
  876. *
  877. * Returns the newly allocated structure or NULL in case or error
  878. */
  879. static xmlRelaxNGStatesPtr
  880. xmlRelaxNGNewStates(xmlRelaxNGValidCtxtPtr ctxt, int size)
  881. {
  882. xmlRelaxNGStatesPtr ret;
  883. if ((ctxt != NULL) &&
  884. (ctxt->freeStates != NULL) && (ctxt->freeStatesNr > 0)) {
  885. ctxt->freeStatesNr--;
  886. ret = ctxt->freeStates[ctxt->freeStatesNr];
  887. ret->nbState = 0;
  888. return (ret);
  889. }
  890. if (size < 16)
  891. size = 16;
  892. ret = (xmlRelaxNGStatesPtr) xmlMalloc(sizeof(xmlRelaxNGStates) +
  893. (size -
  894. 1) *
  895. sizeof(xmlRelaxNGValidStatePtr));
  896. if (ret == NULL) {
  897. xmlRngVErrMemory(ctxt, "allocating states\n");
  898. return (NULL);
  899. }
  900. ret->nbState = 0;
  901. ret->maxState = size;
  902. ret->tabState = (xmlRelaxNGValidStatePtr *) xmlMalloc((size) *
  903. sizeof
  904. (xmlRelaxNGValidStatePtr));
  905. if (ret->tabState == NULL) {
  906. xmlRngVErrMemory(ctxt, "allocating states\n");
  907. xmlFree(ret);
  908. return (NULL);
  909. }
  910. return (ret);
  911. }
  912. /**
  913. * xmlRelaxNGAddStateUniq:
  914. * @ctxt: a Relax-NG validation context
  915. * @states: the states container
  916. * @state: the validation state
  917. *
  918. * Add a RelaxNG validation state to the container without checking
  919. * for unicity.
  920. *
  921. * Return 1 in case of success and 0 if this is a duplicate and -1 on error
  922. */
  923. static int
  924. xmlRelaxNGAddStatesUniq(xmlRelaxNGValidCtxtPtr ctxt,
  925. xmlRelaxNGStatesPtr states,
  926. xmlRelaxNGValidStatePtr state)
  927. {
  928. if (state == NULL) {
  929. return (-1);
  930. }
  931. if (states->nbState >= states->maxState) {
  932. xmlRelaxNGValidStatePtr *tmp;
  933. int size;
  934. size = states->maxState * 2;
  935. tmp = (xmlRelaxNGValidStatePtr *) xmlRealloc(states->tabState,
  936. (size) *
  937. sizeof
  938. (xmlRelaxNGValidStatePtr));
  939. if (tmp == NULL) {
  940. xmlRngVErrMemory(ctxt, "adding states\n");
  941. return (-1);
  942. }
  943. states->tabState = tmp;
  944. states->maxState = size;
  945. }
  946. states->tabState[states->nbState++] = state;
  947. return (1);
  948. }
  949. /**
  950. * xmlRelaxNGAddState:
  951. * @ctxt: a Relax-NG validation context
  952. * @states: the states container
  953. * @state: the validation state
  954. *
  955. * Add a RelaxNG validation state to the container
  956. *
  957. * Return 1 in case of success and 0 if this is a duplicate and -1 on error
  958. */
  959. static int
  960. xmlRelaxNGAddStates(xmlRelaxNGValidCtxtPtr ctxt,
  961. xmlRelaxNGStatesPtr states,
  962. xmlRelaxNGValidStatePtr state)
  963. {
  964. int i;
  965. if (state == NULL || states == NULL) {
  966. return (-1);
  967. }
  968. if (states->nbState >= states->maxState) {
  969. xmlRelaxNGValidStatePtr *tmp;
  970. int size;
  971. size = states->maxState * 2;
  972. tmp = (xmlRelaxNGValidStatePtr *) xmlRealloc(states->tabState,
  973. (size) *
  974. sizeof
  975. (xmlRelaxNGValidStatePtr));
  976. if (tmp == NULL) {
  977. xmlRngVErrMemory(ctxt, "adding states\n");
  978. return (-1);
  979. }
  980. states->tabState = tmp;
  981. states->maxState = size;
  982. }
  983. for (i = 0; i < states->nbState; i++) {
  984. if (xmlRelaxNGEqualValidState(ctxt, state, states->tabState[i])) {
  985. xmlRelaxNGFreeValidState(ctxt, state);
  986. return (0);
  987. }
  988. }
  989. states->tabState[states->nbState++] = state;
  990. return (1);
  991. }
  992. /**
  993. * xmlRelaxNGFreeStates:
  994. * @ctxt: a Relax-NG validation context
  995. * @states: the container
  996. *
  997. * Free a RelaxNG validation state container
  998. */
  999. static void
  1000. xmlRelaxNGFreeStates(xmlRelaxNGValidCtxtPtr ctxt,
  1001. xmlRelaxNGStatesPtr states)
  1002. {
  1003. if (states == NULL)
  1004. return;
  1005. if ((ctxt != NULL) && (ctxt->freeStates == NULL)) {
  1006. ctxt->freeStatesMax = 40;
  1007. ctxt->freeStatesNr = 0;
  1008. ctxt->freeStates = (xmlRelaxNGStatesPtr *)
  1009. xmlMalloc(ctxt->freeStatesMax * sizeof(xmlRelaxNGStatesPtr));
  1010. if (ctxt->freeStates == NULL) {
  1011. xmlRngVErrMemory(ctxt, "storing states\n");
  1012. }
  1013. } else if ((ctxt != NULL)
  1014. && (ctxt->freeStatesNr >= ctxt->freeStatesMax)) {
  1015. xmlRelaxNGStatesPtr *tmp;
  1016. tmp = (xmlRelaxNGStatesPtr *) xmlRealloc(ctxt->freeStates,
  1017. 2 * ctxt->freeStatesMax *
  1018. sizeof
  1019. (xmlRelaxNGStatesPtr));
  1020. if (tmp == NULL) {
  1021. xmlRngVErrMemory(ctxt, "storing states\n");
  1022. xmlFree(states->tabState);
  1023. xmlFree(states);
  1024. return;
  1025. }
  1026. ctxt->freeStates = tmp;
  1027. ctxt->freeStatesMax *= 2;
  1028. }
  1029. if ((ctxt == NULL) || (ctxt->freeStates == NULL)) {
  1030. xmlFree(states->tabState);
  1031. xmlFree(states);
  1032. } else {
  1033. ctxt->freeStates[ctxt->freeStatesNr++] = states;
  1034. }
  1035. }
  1036. /**
  1037. * xmlRelaxNGNewValidState:
  1038. * @ctxt: a Relax-NG validation context
  1039. * @node: the current node or NULL for the document
  1040. *
  1041. * Allocate a new RelaxNG validation state
  1042. *
  1043. * Returns the newly allocated structure or NULL in case or error
  1044. */
  1045. static xmlRelaxNGValidStatePtr
  1046. xmlRelaxNGNewValidState(xmlRelaxNGValidCtxtPtr ctxt, xmlNodePtr node)
  1047. {
  1048. xmlRelaxNGValidStatePtr ret;
  1049. xmlAttrPtr attr;
  1050. xmlAttrPtr attrs[MAX_ATTR];
  1051. int nbAttrs = 0;
  1052. xmlNodePtr root = NULL;
  1053. if (node == NULL) {
  1054. root = xmlDocGetRootElement(ctxt->doc);
  1055. if (root == NULL)
  1056. return (NULL);
  1057. } else {
  1058. attr = node->properties;
  1059. while (attr != NULL) {
  1060. if (nbAttrs < MAX_ATTR)
  1061. attrs[nbAttrs++] = attr;
  1062. else
  1063. nbAttrs++;
  1064. attr = attr->next;
  1065. }
  1066. }
  1067. if ((ctxt->freeState != NULL) && (ctxt->freeState->nbState > 0)) {
  1068. ctxt->freeState->nbState--;
  1069. ret = ctxt->freeState->tabState[ctxt->freeState->nbState];
  1070. } else {
  1071. ret =
  1072. (xmlRelaxNGValidStatePtr)
  1073. xmlMalloc(sizeof(xmlRelaxNGValidState));
  1074. if (ret == NULL) {
  1075. xmlRngVErrMemory(ctxt, "allocating states\n");
  1076. return (NULL);
  1077. }
  1078. memset(ret, 0, sizeof(xmlRelaxNGValidState));
  1079. }
  1080. ret->value = NULL;
  1081. ret->endvalue = NULL;
  1082. if (node == NULL) {
  1083. ret->node = (xmlNodePtr) ctxt->doc;
  1084. ret->seq = root;
  1085. } else {
  1086. ret->node = node;
  1087. ret->seq = node->children;
  1088. }
  1089. ret->nbAttrs = 0;
  1090. if (nbAttrs > 0) {
  1091. if (ret->attrs == NULL) {
  1092. if (nbAttrs < 4)
  1093. ret->maxAttrs = 4;
  1094. else
  1095. ret->maxAttrs = nbAttrs;
  1096. ret->attrs = (xmlAttrPtr *) xmlMalloc(ret->maxAttrs *
  1097. sizeof(xmlAttrPtr));
  1098. if (ret->attrs == NULL) {
  1099. xmlRngVErrMemory(ctxt, "allocating states\n");
  1100. return (ret);
  1101. }
  1102. } else if (ret->maxAttrs < nbAttrs) {
  1103. xmlAttrPtr *tmp;
  1104. tmp = (xmlAttrPtr *) xmlRealloc(ret->attrs, nbAttrs *
  1105. sizeof(xmlAttrPtr));
  1106. if (tmp == NULL) {
  1107. xmlRngVErrMemory(ctxt, "allocating states\n");
  1108. return (ret);
  1109. }
  1110. ret->attrs = tmp;
  1111. ret->maxAttrs = nbAttrs;
  1112. }
  1113. ret->nbAttrs = nbAttrs;
  1114. if (nbAttrs < MAX_ATTR) {
  1115. memcpy(ret->attrs, attrs, sizeof(xmlAttrPtr) * nbAttrs);
  1116. } else {
  1117. attr = node->properties;
  1118. nbAttrs = 0;
  1119. while (attr != NULL) {
  1120. ret->attrs[nbAttrs++] = attr;
  1121. attr = attr->next;
  1122. }
  1123. }
  1124. }
  1125. ret->nbAttrLeft = ret->nbAttrs;
  1126. return (ret);
  1127. }
  1128. /**
  1129. * xmlRelaxNGCopyValidState:
  1130. * @ctxt: a Relax-NG validation context
  1131. * @state: a validation state
  1132. *
  1133. * Copy the validation state
  1134. *
  1135. * Returns the newly allocated structure or NULL in case or error
  1136. */
  1137. static xmlRelaxNGValidStatePtr
  1138. xmlRelaxNGCopyValidState(xmlRelaxNGValidCtxtPtr ctxt,
  1139. xmlRelaxNGValidStatePtr state)
  1140. {
  1141. xmlRelaxNGValidStatePtr ret;
  1142. unsigned int maxAttrs;
  1143. xmlAttrPtr *attrs;
  1144. if (state == NULL)
  1145. return (NULL);
  1146. if ((ctxt->freeState != NULL) && (ctxt->freeState->nbState > 0)) {
  1147. ctxt->freeState->nbState--;
  1148. ret = ctxt->freeState->tabState[ctxt->freeState->nbState];
  1149. } else {
  1150. ret =
  1151. (xmlRelaxNGValidStatePtr)
  1152. xmlMalloc(sizeof(xmlRelaxNGValidState));
  1153. if (ret == NULL) {
  1154. xmlRngVErrMemory(ctxt, "allocating states\n");
  1155. return (NULL);
  1156. }
  1157. memset(ret, 0, sizeof(xmlRelaxNGValidState));
  1158. }
  1159. attrs = ret->attrs;
  1160. maxAttrs = ret->maxAttrs;
  1161. memcpy(ret, state, sizeof(xmlRelaxNGValidState));
  1162. ret->attrs = attrs;
  1163. ret->maxAttrs = maxAttrs;
  1164. if (state->nbAttrs > 0) {
  1165. if (ret->attrs == NULL) {
  1166. ret->maxAttrs = state->maxAttrs;
  1167. ret->attrs = (xmlAttrPtr *) xmlMalloc(ret->maxAttrs *
  1168. sizeof(xmlAttrPtr));
  1169. if (ret->attrs == NULL) {
  1170. xmlRngVErrMemory(ctxt, "allocating states\n");
  1171. ret->nbAttrs = 0;
  1172. return (ret);
  1173. }
  1174. } else if (ret->maxAttrs < state->nbAttrs) {
  1175. xmlAttrPtr *tmp;
  1176. tmp = (xmlAttrPtr *) xmlRealloc(ret->attrs, state->maxAttrs *
  1177. sizeof(xmlAttrPtr));
  1178. if (tmp == NULL) {
  1179. xmlRngVErrMemory(ctxt, "allocating states\n");
  1180. ret->nbAttrs = 0;
  1181. return (ret);
  1182. }
  1183. ret->maxAttrs = state->maxAttrs;
  1184. ret->attrs = tmp;
  1185. }
  1186. memcpy(ret->attrs, state->attrs,
  1187. state->nbAttrs * sizeof(xmlAttrPtr));
  1188. }
  1189. return (ret);
  1190. }
  1191. /**
  1192. * xmlRelaxNGEqualValidState:
  1193. * @ctxt: a Relax-NG validation context
  1194. * @state1: a validation state
  1195. * @state2: a validation state
  1196. *
  1197. * Compare the validation states for equality
  1198. *
  1199. * Returns 1 if equal, 0 otherwise
  1200. */
  1201. static int
  1202. xmlRelaxNGEqualValidState(xmlRelaxNGValidCtxtPtr ctxt ATTRIBUTE_UNUSED,
  1203. xmlRelaxNGValidStatePtr state1,
  1204. xmlRelaxNGValidStatePtr state2)
  1205. {
  1206. int i;
  1207. if ((state1 == NULL) || (state2 == NULL))
  1208. return (0);
  1209. if (state1 == state2)
  1210. return (1);
  1211. if (state1->node != state2->node)
  1212. return (0);
  1213. if (state1->seq != state2->seq)
  1214. return (0);
  1215. if (state1->nbAttrLeft != state2->nbAttrLeft)
  1216. return (0);
  1217. if (state1->nbAttrs != state2->nbAttrs)
  1218. return (0);
  1219. if (state1->endvalue != state2->endvalue)
  1220. return (0);
  1221. if ((state1->value != state2->value) &&
  1222. (!xmlStrEqual(state1->value, state2->value)))
  1223. return (0);
  1224. for (i = 0; i < state1->nbAttrs; i++) {
  1225. if (state1->attrs[i] != state2->attrs[i])
  1226. return (0);
  1227. }
  1228. return (1);
  1229. }
  1230. /**
  1231. * xmlRelaxNGFreeValidState:
  1232. * @state: a validation state structure
  1233. *
  1234. * Deallocate a RelaxNG validation state structure.
  1235. */
  1236. static void
  1237. xmlRelaxNGFreeValidState(xmlRelaxNGValidCtxtPtr ctxt,
  1238. xmlRelaxNGValidStatePtr state)
  1239. {
  1240. if (state == NULL)
  1241. return;
  1242. if ((ctxt != NULL) && (ctxt->freeState == NULL)) {
  1243. ctxt->freeState = xmlRelaxNGNewStates(ctxt, 40);
  1244. }
  1245. if ((ctxt == NULL) || (ctxt->freeState == NULL)) {
  1246. if (state->attrs != NULL)
  1247. xmlFree(state->attrs);
  1248. xmlFree(state);
  1249. } else {
  1250. xmlRelaxNGAddStatesUniq(ctxt, ctxt->freeState, state);
  1251. }
  1252. }
  1253. /************************************************************************
  1254. * *
  1255. * Semi internal functions *
  1256. * *
  1257. ************************************************************************/
  1258. /**
  1259. * xmlRelaxParserSetFlag:
  1260. * @ctxt: a RelaxNG parser context
  1261. * @flags: a set of flags values
  1262. *
  1263. * Semi private function used to pass information to a parser context
  1264. * which are a combination of xmlRelaxNGParserFlag .
  1265. *
  1266. * Returns 0 if success and -1 in case of error
  1267. */
  1268. int
  1269. xmlRelaxParserSetFlag(xmlRelaxNGParserCtxtPtr ctxt, int flags)
  1270. {
  1271. if (ctxt == NULL) return(-1);
  1272. if (flags & XML_RELAXNGP_FREE_DOC) {
  1273. ctxt->crng |= XML_RELAXNGP_FREE_DOC;
  1274. flags -= XML_RELAXNGP_FREE_DOC;
  1275. }
  1276. if (flags & XML_RELAXNGP_CRNG) {
  1277. ctxt->crng |= XML_RELAXNGP_CRNG;
  1278. flags -= XML_RELAXNGP_CRNG;
  1279. }
  1280. if (flags != 0) return(-1);
  1281. return(0);
  1282. }
  1283. /************************************************************************
  1284. * *
  1285. * Document functions *
  1286. * *
  1287. ************************************************************************/
  1288. static xmlDocPtr xmlRelaxNGCleanupDoc(xmlRelaxNGParserCtxtPtr ctxt,
  1289. xmlDocPtr doc);
  1290. /**
  1291. * xmlRelaxNGIncludePush:
  1292. * @ctxt: the parser context
  1293. * @value: the element doc
  1294. *
  1295. * Pushes a new include on top of the include stack
  1296. *
  1297. * Returns 0 in case of error, the index in the stack otherwise
  1298. */
  1299. static int
  1300. xmlRelaxNGIncludePush(xmlRelaxNGParserCtxtPtr ctxt,
  1301. xmlRelaxNGIncludePtr value)
  1302. {
  1303. if (ctxt->incTab == NULL) {
  1304. ctxt->incMax = 4;
  1305. ctxt->incNr = 0;
  1306. ctxt->incTab =
  1307. (xmlRelaxNGIncludePtr *) xmlMalloc(ctxt->incMax *
  1308. sizeof(ctxt->incTab[0]));
  1309. if (ctxt->incTab == NULL) {
  1310. xmlRngPErrMemory(ctxt, "allocating include\n");
  1311. return (0);
  1312. }
  1313. }
  1314. if (ctxt->incNr >= ctxt->incMax) {
  1315. ctxt->incMax *= 2;
  1316. ctxt->incTab =
  1317. (xmlRelaxNGIncludePtr *) xmlRealloc(ctxt->incTab,
  1318. ctxt->incMax *
  1319. sizeof(ctxt->incTab[0]));
  1320. if (ctxt->incTab == NULL) {
  1321. xmlRngPErrMemory(ctxt, "allocating include\n");
  1322. return (0);
  1323. }
  1324. }
  1325. ctxt->incTab[ctxt->incNr] = value;
  1326. ctxt->inc = value;
  1327. return (ctxt->incNr++);
  1328. }
  1329. /**
  1330. * xmlRelaxNGIncludePop:
  1331. * @ctxt: the parser context
  1332. *
  1333. * Pops the top include from the include stack
  1334. *
  1335. * Returns the include just removed
  1336. */
  1337. static xmlRelaxNGIncludePtr
  1338. xmlRelaxNGIncludePop(xmlRelaxNGParserCtxtPtr ctxt)
  1339. {
  1340. xmlRelaxNGIncludePtr ret;
  1341. if (ctxt->incNr <= 0)
  1342. return (NULL);
  1343. ctxt->incNr--;
  1344. if (ctxt->incNr > 0)
  1345. ctxt->inc = ctxt->incTab[ctxt->incNr - 1];
  1346. else
  1347. ctxt->inc = NULL;
  1348. ret = ctxt->incTab[ctxt->incNr];
  1349. ctxt->incTab[ctxt->incNr] = NULL;
  1350. return (ret);
  1351. }
  1352. /**
  1353. * xmlRelaxNGRemoveRedefine:
  1354. * @ctxt: the parser context
  1355. * @URL: the normalized URL
  1356. * @target: the included target
  1357. * @name: the define name to eliminate
  1358. *
  1359. * Applies the elimination algorithm of 4.7
  1360. *
  1361. * Returns 0 in case of error, 1 in case of success.
  1362. */
  1363. static int
  1364. xmlRelaxNGRemoveRedefine(xmlRelaxNGParserCtxtPtr ctxt,
  1365. const xmlChar * URL ATTRIBUTE_UNUSED,
  1366. xmlNodePtr target, const xmlChar * name)
  1367. {
  1368. int found = 0;
  1369. xmlNodePtr tmp, tmp2;
  1370. xmlChar *name2;
  1371. tmp = target;
  1372. while (tmp != NULL) {
  1373. tmp2 = tmp->next;
  1374. if ((name == NULL) && (IS_RELAXNG(tmp, "start"))) {
  1375. found = 1;
  1376. xmlUnlinkNode(tmp);
  1377. xmlFreeNode(tmp);
  1378. } else if ((name != NULL) && (IS_RELAXNG(tmp, "define"))) {
  1379. name2 = xmlGetProp(tmp, BAD_CAST "name");
  1380. xmlRelaxNGNormExtSpace(name2);
  1381. if (name2 != NULL) {
  1382. if (xmlStrEqual(name, name2)) {
  1383. found = 1;
  1384. xmlUnlinkNode(tmp);
  1385. xmlFreeNode(tmp);
  1386. }
  1387. xmlFree(name2);
  1388. }
  1389. } else if (IS_RELAXNG(tmp, "include")) {
  1390. xmlChar *href = NULL;
  1391. xmlRelaxNGDocumentPtr inc = tmp->psvi;
  1392. if ((inc != NULL) && (inc->doc != NULL) &&
  1393. (inc->doc->children != NULL)) {
  1394. if (xmlStrEqual
  1395. (inc->doc->children->name, BAD_CAST "grammar")) {
  1396. if (xmlRelaxNGRemoveRedefine(ctxt, href,
  1397. xmlDocGetRootElement(inc->doc)->children,
  1398. name) == 1) {
  1399. found = 1;
  1400. }
  1401. }
  1402. }
  1403. if (xmlRelaxNGRemoveRedefine(ctxt, URL, tmp->children, name) == 1) {
  1404. found = 1;
  1405. }
  1406. }
  1407. tmp = tmp2;
  1408. }
  1409. return (found);
  1410. }
  1411. /**
  1412. * xmlRelaxNGLoadInclude:
  1413. * @ctxt: the parser context
  1414. * @URL: the normalized URL
  1415. * @node: the include node.
  1416. * @ns: the namespace passed from the context.
  1417. *
  1418. * First lookup if the document is already loaded into the parser context,
  1419. * check against recursion. If not found the resource is loaded and
  1420. * the content is preprocessed before being returned back to the caller.
  1421. *
  1422. * Returns the xmlRelaxNGIncludePtr or NULL in case of error
  1423. */
  1424. static xmlRelaxNGIncludePtr
  1425. xmlRelaxNGLoadInclude(xmlRelaxNGParserCtxtPtr ctxt, const xmlChar * URL,
  1426. xmlNodePtr node, const xmlChar * ns)
  1427. {
  1428. xmlRelaxNGIncludePtr ret = NULL;
  1429. xmlDocPtr doc;
  1430. int i;
  1431. xmlNodePtr root, cur;
  1432. /*
  1433. * check against recursion in the stack
  1434. */
  1435. for (i = 0; i < ctxt->incNr; i++) {
  1436. if (xmlStrEqual(ctxt->incTab[i]->href, URL)) {
  1437. xmlRngPErr(ctxt, NULL, XML_RNGP_INCLUDE_RECURSE,
  1438. "Detected an Include recursion for %s\n", URL,
  1439. NULL);
  1440. return (NULL);
  1441. }
  1442. }
  1443. /*
  1444. * load the document
  1445. */
  1446. doc = xmlReadFile((const char *) URL,NULL,0);
  1447. if (doc == NULL) {
  1448. xmlRngPErr(ctxt, node, XML_RNGP_PARSE_ERROR,
  1449. "xmlRelaxNG: could not load %s\n", URL, NULL);
  1450. return (NULL);
  1451. }
  1452. /*
  1453. * Allocate the document structures and register it first.
  1454. */
  1455. ret = (xmlRelaxNGIncludePtr) xmlMalloc(sizeof(xmlRelaxNGInclude));
  1456. if (ret == NULL) {
  1457. xmlRngPErrMemory(ctxt, "allocating include\n");
  1458. xmlFreeDoc(doc);
  1459. return (NULL);
  1460. }
  1461. memset(ret, 0, sizeof(xmlRelaxNGInclude));
  1462. ret->doc = doc;
  1463. ret->href = xmlStrdup(URL);
  1464. ret->next = ctxt->includes;
  1465. ctxt->includes = ret;
  1466. /*
  1467. * transmit the ns if needed
  1468. */
  1469. if (ns != NULL) {
  1470. root = xmlDocGetRootElement(doc);
  1471. if (root != NULL) {
  1472. if (xmlHasProp(root, BAD_CAST "ns") == NULL) {
  1473. xmlSetProp(root, BAD_CAST "ns", ns);
  1474. }
  1475. }
  1476. }
  1477. /*
  1478. * push it on the stack
  1479. */
  1480. xmlRelaxNGIncludePush(ctxt, ret);
  1481. /*
  1482. * Some preprocessing of the document content, this include recursing
  1483. * in the include stack.
  1484. */
  1485. doc = xmlRelaxNGCleanupDoc(ctxt, doc);
  1486. if (doc == NULL) {
  1487. ctxt->inc = NULL;
  1488. return (NULL);
  1489. }
  1490. /*
  1491. * Pop up the include from the stack
  1492. */
  1493. xmlRelaxNGIncludePop(ctxt);
  1494. /*
  1495. * Check that the top element is a grammar
  1496. */
  1497. root = xmlDocGetRootElement(doc);
  1498. if (root == NULL) {
  1499. xmlRngPErr(ctxt, node, XML_RNGP_EMPTY,
  1500. "xmlRelaxNG: included document is empty %s\n", URL,
  1501. NULL);
  1502. return (NULL);
  1503. }
  1504. if (!IS_RELAXNG(root, "grammar")) {
  1505. xmlRngPErr(ctxt, node, XML_RNGP_GRAMMAR_MISSING,
  1506. "xmlRelaxNG: included document %s root is not a grammar\n",
  1507. URL, NULL);
  1508. return (NULL);
  1509. }
  1510. /*
  1511. * Elimination of redefined rules in the include.
  1512. */
  1513. cur = node->children;
  1514. while (cur != NULL) {
  1515. if (IS_RELAXNG(cur, "start")) {
  1516. int found = 0;
  1517. found =
  1518. xmlRelaxNGRemoveRedefine(ctxt, URL, root->children, NULL);
  1519. if (!found) {
  1520. xmlRngPErr(ctxt, node, XML_RNGP_START_MISSING,
  1521. "xmlRelaxNG: include %s has a start but not the included grammar\n",
  1522. URL, NULL);
  1523. }
  1524. } else if (IS_RELAXNG(cur, "define")) {
  1525. xmlChar *name;
  1526. name = xmlGetProp(cur, BAD_CAST "name");
  1527. if (name == NULL) {
  1528. xmlRngPErr(ctxt, node, XML_RNGP_NAME_MISSING,
  1529. "xmlRelaxNG: include %s has define without name\n",
  1530. URL, NULL);
  1531. } else {
  1532. int found;
  1533. xmlRelaxNGNormExtSpace(name);
  1534. found = xmlRelaxNGRemoveRedefine(ctxt, URL,
  1535. root->children, name);
  1536. if (!found) {
  1537. xmlRngPErr(ctxt, node, XML_RNGP_DEFINE_MISSING,
  1538. "xmlRelaxNG: include %s has a define %s but not the included grammar\n",
  1539. URL, name);
  1540. }
  1541. xmlFree(name);
  1542. }
  1543. }
  1544. if (IS_RELAXNG(cur, "div") && cur->children != NULL) {
  1545. cur = cur->children;
  1546. } else {
  1547. if (cur->next != NULL) {
  1548. cur = cur->next;
  1549. } else {
  1550. while (cur->parent != node && cur->parent->next == NULL) {
  1551. cur = cur->parent;
  1552. }
  1553. cur = cur->parent != node ? cur->parent->next : NULL;
  1554. }
  1555. }
  1556. }
  1557. return (ret);
  1558. }
  1559. /**
  1560. * xmlRelaxNGValidErrorPush:
  1561. * @ctxt: the validation context
  1562. * @err: the error code
  1563. * @arg1: the first string argument
  1564. * @arg2: the second string argument
  1565. * @dup: arg need to be duplicated
  1566. *
  1567. * Pushes a new error on top of the error stack
  1568. *
  1569. * Returns 0 in case of error, the index in the stack otherwise
  1570. */
  1571. static int
  1572. xmlRelaxNGValidErrorPush(xmlRelaxNGValidCtxtPtr ctxt,
  1573. xmlRelaxNGValidErr err, const xmlChar * arg1,
  1574. const xmlChar * arg2, int dup)
  1575. {
  1576. xmlRelaxNGValidErrorPtr cur;
  1577. if (ctxt->errTab == NULL) {
  1578. ctxt->errMax = 8;
  1579. ctxt->errNr = 0;
  1580. ctxt->errTab =
  1581. (xmlRelaxNGValidErrorPtr) xmlMalloc(ctxt->errMax *
  1582. sizeof
  1583. (xmlRelaxNGValidError));
  1584. if (ctxt->errTab == NULL) {
  1585. xmlRngVErrMemory(ctxt, "pushing error\n");
  1586. return (0);
  1587. }
  1588. ctxt->err = NULL;
  1589. }
  1590. if (ctxt->errNr >= ctxt->errMax) {
  1591. ctxt->errMax *= 2;
  1592. ctxt->errTab =
  1593. (xmlRelaxNGValidErrorPtr) xmlRealloc(ctxt->errTab,
  1594. ctxt->errMax *
  1595. sizeof
  1596. (xmlRelaxNGValidError));
  1597. if (ctxt->errTab == NULL) {
  1598. xmlRngVErrMemory(ctxt, "pushing error\n");
  1599. return (0);
  1600. }
  1601. ctxt->err = &ctxt->errTab[ctxt->errNr - 1];
  1602. }
  1603. if ((ctxt->err != NULL) && (ctxt->state != NULL) &&
  1604. (ctxt->err->node == ctxt->state->node) && (ctxt->err->err == err))
  1605. return (ctxt->errNr);
  1606. cur = &ctxt->errTab[ctxt->errNr];
  1607. cur->err = err;
  1608. if (dup) {
  1609. cur->arg1 = xmlStrdup(arg1);
  1610. cur->arg2 = xmlStrdup(arg2);
  1611. cur->flags = ERROR_IS_DUP;
  1612. } else {
  1613. cur->arg1 = arg1;
  1614. cur->arg2 = arg2;
  1615. cur->flags = 0;
  1616. }
  1617. if (ctxt->state != NULL) {
  1618. cur->node = ctxt->state->node;
  1619. cur->seq = ctxt->state->seq;
  1620. } else {
  1621. cur->node = NULL;
  1622. cur->seq = NULL;
  1623. }
  1624. ctxt->err = cur;
  1625. return (ctxt->errNr++);
  1626. }
  1627. /**
  1628. * xmlRelaxNGValidErrorPop:
  1629. * @ctxt: the validation context
  1630. *
  1631. * Pops the top error from the error stack
  1632. */
  1633. static void
  1634. xmlRelaxNGValidErrorPop(xmlRelaxNGValidCtxtPtr ctxt)
  1635. {
  1636. xmlRelaxNGValidErrorPtr cur;
  1637. if (ctxt->errNr <= 0) {
  1638. ctxt->err = NULL;
  1639. return;
  1640. }
  1641. ctxt->errNr--;
  1642. if (ctxt->errNr > 0)
  1643. ctxt->err = &ctxt->errTab[ctxt->errNr - 1];
  1644. else
  1645. ctxt->err = NULL;
  1646. cur = &ctxt->errTab[ctxt->errNr];
  1647. if (cur->flags & ERROR_IS_DUP) {
  1648. if (cur->arg1 != NULL)
  1649. xmlFree((xmlChar *) cur->arg1);
  1650. cur->arg1 = NULL;
  1651. if (cur->arg2 != NULL)
  1652. xmlFree((xmlChar *) cur->arg2);
  1653. cur->arg2 = NULL;
  1654. cur->flags = 0;
  1655. }
  1656. }
  1657. /**
  1658. * xmlRelaxNGDocumentPush:
  1659. * @ctxt: the parser context
  1660. * @value: the element doc
  1661. *
  1662. * Pushes a new doc on top of the doc stack
  1663. *
  1664. * Returns 0 in case of error, the index in the stack otherwise
  1665. */
  1666. static int
  1667. xmlRelaxNGDocumentPush(xmlRelaxNGParserCtxtPtr ctxt,
  1668. xmlRelaxNGDocumentPtr value)
  1669. {
  1670. if (ctxt->docTab == NULL) {
  1671. ctxt->docMax = 4;
  1672. ctxt->docNr = 0;
  1673. ctxt->docTab =
  1674. (xmlRelaxNGDocumentPtr *) xmlMalloc(ctxt->docMax *
  1675. sizeof(ctxt->docTab[0]));
  1676. if (ctxt->docTab == NULL) {
  1677. xmlRngPErrMemory(ctxt, "adding document\n");
  1678. return (0);
  1679. }
  1680. }
  1681. if (ctxt->docNr >= ctxt->docMax) {
  1682. ctxt->docMax *= 2;
  1683. ctxt->docTab =
  1684. (xmlRelaxNGDocumentPtr *) xmlRealloc(ctxt->docTab,
  1685. ctxt->docMax *
  1686. sizeof(ctxt->docTab[0]));
  1687. if (ctxt->docTab == NULL) {
  1688. xmlRngPErrMemory(ctxt, "adding document\n");
  1689. return (0);
  1690. }
  1691. }
  1692. ctxt->docTab[ctxt->docNr] = value;
  1693. ctxt->doc = value;
  1694. return (ctxt->docNr++);
  1695. }
  1696. /**
  1697. * xmlRelaxNGDocumentPop:
  1698. * @ctxt: the parser context
  1699. *
  1700. * Pops the top doc from the doc stack
  1701. *
  1702. * Returns the doc just removed
  1703. */
  1704. static xmlRelaxNGDocumentPtr
  1705. xmlRelaxNGDocumentPop(xmlRelaxNGParserCtxtPtr ctxt)
  1706. {
  1707. xmlRelaxNGDocumentPtr ret;
  1708. if (ctxt->docNr <= 0)
  1709. return (NULL);
  1710. ctxt->docNr--;
  1711. if (ctxt->docNr > 0)
  1712. ctxt->doc = ctxt->docTab[ctxt->docNr - 1];
  1713. else
  1714. ctxt->doc = NULL;
  1715. ret = ctxt->docTab[ctxt->docNr];
  1716. ctxt->docTab[ctxt->docNr] = NULL;
  1717. return (ret);
  1718. }
  1719. /**
  1720. * xmlRelaxNGLoadExternalRef:
  1721. * @ctxt: the parser context
  1722. * @URL: the normalized URL
  1723. * @ns: the inherited ns if any
  1724. *
  1725. * First lookup if the document is already loaded into the parser context,
  1726. * check against recursion. If not found the resource is loaded and
  1727. * the content is preprocessed before being returned back to the caller.
  1728. *
  1729. * Returns the xmlRelaxNGDocumentPtr or NULL in case of error
  1730. */
  1731. static xmlRelaxNGDocumentPtr
  1732. xmlRelaxNGLoadExternalRef(xmlRelaxNGParserCtxtPtr ctxt,
  1733. const xmlChar * URL, const xmlChar * ns)
  1734. {
  1735. xmlRelaxNGDocumentPtr ret = NULL;
  1736. xmlDocPtr doc;
  1737. xmlNodePtr root;
  1738. int i;
  1739. /*
  1740. * check against recursion in the stack
  1741. */
  1742. for (i = 0; i < ctxt->docNr; i++) {
  1743. if (xmlStrEqual(ctxt->docTab[i]->href, URL)) {
  1744. xmlRngPErr(ctxt, NULL, XML_RNGP_EXTERNALREF_RECURSE,
  1745. "Detected an externalRef recursion for %s\n", URL,
  1746. NULL);
  1747. return (NULL);
  1748. }
  1749. }
  1750. /*
  1751. * load the document
  1752. */
  1753. doc = xmlReadFile((const char *) URL,NULL,0);
  1754. if (doc == NULL) {
  1755. xmlRngPErr(ctxt, NULL, XML_RNGP_PARSE_ERROR,
  1756. "xmlRelaxNG: could not load %s\n", URL, NULL);
  1757. return (NULL);
  1758. }
  1759. /*
  1760. * Allocate the document structures and register it first.
  1761. */
  1762. ret = (xmlRelaxNGDocumentPtr) xmlMalloc(sizeof(xmlRelaxNGDocument));
  1763. if (ret == NULL) {
  1764. xmlRngPErr(ctxt, (xmlNodePtr) doc, XML_ERR_NO_MEMORY,
  1765. "xmlRelaxNG: allocate memory for doc %s\n", URL, NULL);
  1766. xmlFreeDoc(doc);
  1767. return (NULL);
  1768. }
  1769. memset(ret, 0, sizeof(xmlRelaxNGDocument));
  1770. ret->doc = doc;
  1771. ret->href = xmlStrdup(URL);
  1772. ret->next = ctxt->documents;
  1773. ret->externalRef = 1;
  1774. ctxt->documents = ret;
  1775. /*
  1776. * transmit the ns if needed
  1777. */
  1778. if (ns != NULL) {
  1779. root = xmlDocGetRootElement(doc);
  1780. if (root != NULL) {
  1781. if (xmlHasProp(root, BAD_CAST "ns") == NULL) {
  1782. xmlSetProp(root, BAD_CAST "ns", ns);
  1783. }
  1784. }
  1785. }
  1786. /*
  1787. * push it on the stack and register it in the hash table
  1788. */
  1789. xmlRelaxNGDocumentPush(ctxt, ret);
  1790. /*
  1791. * Some preprocessing of the document content
  1792. */
  1793. doc = xmlRelaxNGCleanupDoc(ctxt, doc);
  1794. if (doc == NULL) {
  1795. ctxt->doc = NULL;
  1796. return (NULL);
  1797. }
  1798. xmlRelaxNGDocumentPop(ctxt);
  1799. return (ret);
  1800. }
  1801. /************************************************************************
  1802. * *
  1803. * Error functions *
  1804. * *
  1805. ************************************************************************/
  1806. #define VALID_ERR(a) xmlRelaxNGAddValidError(ctxt, a, NULL, NULL, 0);
  1807. #define VALID_ERR2(a, b) xmlRelaxNGAddValidError(ctxt, a, b, NULL, 0);
  1808. #define VALID_ERR3(a, b, c) xmlRelaxNGAddValidError(ctxt, a, b, c, 0);
  1809. #define VALID_ERR2P(a, b) xmlRelaxNGAddValidError(ctxt, a, b, NULL, 1);
  1810. #define VALID_ERR3P(a, b, c) xmlRelaxNGAddValidError(ctxt, a, b, c, 1);
  1811. static const char *
  1812. xmlRelaxNGDefName(xmlRelaxNGDefinePtr def)
  1813. {
  1814. if (def == NULL)
  1815. return ("none");
  1816. switch (def->type) {
  1817. case XML_RELAXNG_EMPTY:
  1818. return ("empty");
  1819. case XML_RELAXNG_NOT_ALLOWED:
  1820. return ("notAllowed");
  1821. case XML_RELAXNG_EXCEPT:
  1822. return ("except");
  1823. case XML_RELAXNG_TEXT:
  1824. return ("text");
  1825. case XML_RELAXNG_ELEMENT:
  1826. return ("element");
  1827. case XML_RELAXNG_DATATYPE:
  1828. return ("datatype");
  1829. case XML_RELAXNG_VALUE:
  1830. return ("value");
  1831. case XML_RELAXNG_LIST:
  1832. return ("list");
  1833. case XML_RELAXNG_ATTRIBUTE:
  1834. return ("attribute");
  1835. case XML_RELAXNG_DEF:
  1836. return ("def");
  1837. case XML_RELAXNG_REF:
  1838. return ("ref");
  1839. case XML_RELAXNG_EXTERNALREF:
  1840. return ("externalRef");
  1841. case XML_RELAXNG_PARENTREF:
  1842. return ("parentRef");
  1843. case XML_RELAXNG_OPTIONAL:
  1844. return ("optional");
  1845. case XML_RELAXNG_ZEROORMORE:
  1846. return ("zeroOrMore");
  1847. case XML_RELAXNG_ONEORMORE:
  1848. return ("oneOrMore");
  1849. case XML_RELAXNG_CHOICE:
  1850. return ("choice");
  1851. case XML_RELAXNG_GROUP:
  1852. return ("group");
  1853. case XML_RELAXNG_INTERLEAVE:
  1854. return ("interleave");
  1855. case XML_RELAXNG_START:
  1856. return ("start");
  1857. case XML_RELAXNG_NOOP:
  1858. return ("noop");
  1859. case XML_RELAXNG_PARAM:
  1860. return ("param");
  1861. }
  1862. return ("unknown");
  1863. }
  1864. /**
  1865. * xmlRelaxNGGetErrorString:
  1866. * @err: the error code
  1867. * @arg1: the first string argument
  1868. * @arg2: the second string argument
  1869. *
  1870. * computes a formatted error string for the given error code and args
  1871. *
  1872. * Returns the error string, it must be deallocated by the caller
  1873. */
  1874. static xmlChar *
  1875. xmlRelaxNGGetErrorString(xmlRelaxNGValidErr err, const xmlChar * arg1,
  1876. const xmlChar * arg2)
  1877. {
  1878. char msg[1000];
  1879. xmlChar *result;
  1880. if (arg1 == NULL)
  1881. arg1 = BAD_CAST "";
  1882. if (arg2 == NULL)
  1883. arg2 = BAD_CAST "";
  1884. msg[0] = 0;
  1885. switch (err) {
  1886. case XML_RELAXNG_OK:
  1887. return (NULL);
  1888. case XML_RELAXNG_ERR_MEMORY:
  1889. return (xmlCharStrdup("out of memory\n"));
  1890. case XML_RELAXNG_ERR_TYPE:
  1891. snprintf(msg, 1000, "failed to validate type %s\n", arg1);
  1892. break;
  1893. case XML_RELAXNG_ERR_TYPEVAL:
  1894. snprintf(msg, 1000, "Type %s doesn't allow value '%s'\n", arg1,
  1895. arg2);
  1896. break;
  1897. case XML_RELAXNG_ERR_DUPID:
  1898. snprintf(msg, 1000, "ID %s redefined\n", arg1);
  1899. break;
  1900. case XML_RELAXNG_ERR_TYPECMP:
  1901. snprintf(msg, 1000, "failed to compare type %s\n", arg1);
  1902. break;
  1903. case XML_RELAXNG_ERR_NOSTATE:
  1904. return (xmlCharStrdup("Internal error: no state\n"));
  1905. case XML_RELAXNG_ERR_NODEFINE:
  1906. return (xmlCharStrdup("Internal error: no define\n"));
  1907. case XML_RELAXNG_ERR_INTERNAL:
  1908. snprintf(msg, 1000, "Internal error: %s\n", arg1);
  1909. break;
  1910. case XML_RELAXNG_ERR_LISTEXTRA:
  1911. snprintf(msg, 1000, "Extra data in list: %s\n", arg1);
  1912. break;
  1913. case XML_RELAXNG_ERR_INTERNODATA:
  1914. return (xmlCharStrdup
  1915. ("Internal: interleave block has no data\n"));
  1916. case XML_RELAXNG_ERR_INTERSEQ:
  1917. return (xmlCharStrdup("Invalid sequence in interleave\n"));
  1918. case XML_RELAXNG_ERR_INTEREXTRA:
  1919. snprintf(msg, 1000, "Extra element %s in interleave\n", arg1);
  1920. break;
  1921. case XML_RELAXNG_ERR_ELEMNAME:
  1922. snprintf(msg, 1000, "Expecting element %s, got %s\n", arg1,
  1923. arg2);
  1924. break;
  1925. case XML_RELAXNG_ERR_ELEMNONS:
  1926. snprintf(msg, 1000, "Expecting a namespace for element %s\n",
  1927. arg1);
  1928. break;
  1929. case XML_RELAXNG_ERR_ELEMWRONGNS:
  1930. snprintf(msg, 1000,
  1931. "Element %s has wrong namespace: expecting %s\n", arg1,
  1932. arg2);
  1933. break;
  1934. case XML_RELAXNG_ERR_ELEMWRONG:
  1935. snprintf(msg, 1000, "Did not expect element %s there\n", arg1);
  1936. break;
  1937. case XML_RELAXNG_ERR_TEXTWRONG:
  1938. snprintf(msg, 1000,
  1939. "Did not expect text in element %s content\n", arg1);
  1940. break;
  1941. case XML_RELAXNG_ERR_ELEMEXTRANS:
  1942. snprintf(msg, 1000, "Expecting no namespace for element %s\n",
  1943. arg1);
  1944. break;
  1945. case XML_RELAXNG_ERR_ELEMNOTEMPTY:
  1946. snprintf(msg, 1000, "Expecting element %s to be empty\n", arg1);
  1947. break;
  1948. case XML_RELAXNG_ERR_NOELEM:
  1949. snprintf(msg, 1000, "Expecting an element %s, got nothing\n",
  1950. arg1);
  1951. break;
  1952. case XML_RELAXNG_ERR_NOTELEM:
  1953. return (xmlCharStrdup("Expecting an element got text\n"));
  1954. case XML_RELAXNG_ERR_ATTRVALID:
  1955. snprintf(msg, 1000, "Element %s failed to validate attributes\n",
  1956. arg1);
  1957. break;
  1958. case XML_RELAXNG_ERR_CONTENTVALID:
  1959. snprintf(msg, 1000, "Element %s failed to validate content\n",
  1960. arg1);
  1961. break;
  1962. case XML_RELAXNG_ERR_EXTRACONTENT:
  1963. snprintf(msg, 1000, "Element %s has extra content: %s\n",
  1964. arg1, arg2);
  1965. break;
  1966. case XML_RELAXNG_ERR_INVALIDATTR:
  1967. snprintf(msg, 1000, "Invalid attribute %s for element %s\n",
  1968. arg1, arg2);
  1969. break;
  1970. case XML_RELAXNG_ERR_LACKDATA:
  1971. snprintf(msg, 1000, "Datatype element %s contains no data\n",
  1972. arg1);
  1973. break;
  1974. case XML_RELAXNG_ERR_DATAELEM:
  1975. snprintf(msg, 1000, "Datatype element %s has child elements\n",
  1976. arg1);
  1977. break;
  1978. case XML_RELAXNG_ERR_VALELEM:
  1979. snprintf(msg, 1000, "Value element %s has child elements\n",
  1980. arg1);
  1981. break;
  1982. case XML_RELAXNG_ERR_LISTELEM:
  1983. snprintf(msg, 1000, "List element %s has child elements\n",
  1984. arg1);
  1985. break;
  1986. case XML_RELAXNG_ERR_DATATYPE:
  1987. snprintf(msg, 1000, "Error validating datatype %s\n", arg1);
  1988. break;
  1989. case XML_RELAXNG_ERR_VALUE:
  1990. snprintf(msg, 1000, "Error validating value %s\n", arg1);
  1991. break;
  1992. case XML_RELAXNG_ERR_LIST:
  1993. return (xmlCharStrdup("Error validating list\n"));
  1994. case XML_RELAXNG_ERR_NOGRAMMAR:
  1995. return (xmlCharStrdup("No top grammar defined\n"));
  1996. case XML_RELAXNG_ERR_EXTRADATA:
  1997. return (xmlCharStrdup("Extra data in the document\n"));
  1998. default:
  1999. return (xmlCharStrdup("Unknown error !\n"));
  2000. }
  2001. if (msg[0] == 0) {
  2002. snprintf(msg, 1000, "Unknown error code %d\n", err);
  2003. }
  2004. msg[1000 - 1] = 0;
  2005. result = xmlCharStrdup(msg);
  2006. return (xmlEscapeFormatString(&result));
  2007. }
  2008. /**
  2009. * xmlRelaxNGShowValidError:
  2010. * @ctxt: the validation context
  2011. * @err: the error number
  2012. * @node: the node
  2013. * @child: the node child generating the problem.
  2014. * @arg1: the first argument
  2015. * @arg2: the second argument
  2016. *
  2017. * Show a validation error.
  2018. */
  2019. static void
  2020. xmlRelaxNGShowValidError(xmlRelaxNGValidCtxtPtr ctxt,
  2021. xmlRelaxNGValidErr err, xmlNodePtr node,
  2022. xmlNodePtr child, const xmlChar * arg1,
  2023. const xmlChar * arg2)
  2024. {
  2025. xmlChar *msg;
  2026. if (ctxt->flags & FLAGS_NOERROR)
  2027. return;
  2028. msg = xmlRelaxNGGetErrorString(err, arg1, arg2);
  2029. if (msg == NULL)
  2030. return;
  2031. if (ctxt->errNo == XML_RELAXNG_OK)
  2032. ctxt->errNo = err;
  2033. xmlRngVErr(ctxt, (child == NULL ? node : child), err,
  2034. (const char *) msg, arg1, arg2);
  2035. xmlFree(msg);
  2036. }
  2037. /**
  2038. * xmlRelaxNGPopErrors:
  2039. * @ctxt: the validation context
  2040. * @level: the error level in the stack
  2041. *
  2042. * pop and discard all errors until the given level is reached
  2043. */
  2044. static void
  2045. xmlRelaxNGPopErrors(xmlRelaxNGValidCtxtPtr ctxt, int level)
  2046. {
  2047. int i;
  2048. xmlRelaxNGValidErrorPtr err;
  2049. for (i = level; i < ctxt->errNr; i++) {
  2050. err = &ctxt->errTab[i];
  2051. if (err->flags & ERROR_IS_DUP) {
  2052. if (err->arg1 != NULL)
  2053. xmlFree((xmlChar *) err->arg1);
  2054. err->arg1 = NULL;
  2055. if (err->arg2 != NULL)
  2056. xmlFree((xmlChar *) err->arg2);
  2057. err->arg2 = NULL;
  2058. err->flags = 0;
  2059. }
  2060. }
  2061. ctxt->errNr = level;
  2062. if (ctxt->errNr <= 0)
  2063. ctxt->err = NULL;
  2064. }
  2065. /**
  2066. * xmlRelaxNGDumpValidError:
  2067. * @ctxt: the validation context
  2068. *
  2069. * Show all validation error over a given index.
  2070. */
  2071. static void
  2072. xmlRelaxNGDumpValidError(xmlRelaxNGValidCtxtPtr ctxt)
  2073. {
  2074. int i, j, k;
  2075. xmlRelaxNGValidErrorPtr err, dup;
  2076. for (i = 0, k = 0; i < ctxt->errNr; i++) {
  2077. err = &ctxt->errTab[i];
  2078. if (k < MAX_ERROR) {
  2079. for (j = 0; j < i; j++) {
  2080. dup = &ctxt->errTab[j];
  2081. if ((err->err == dup->err) && (err->node == dup->node) &&
  2082. (xmlStrEqual(err->arg1, dup->arg1)) &&
  2083. (xmlStrEqual(err->arg2, dup->arg2))) {
  2084. goto skip;
  2085. }
  2086. }
  2087. xmlRelaxNGShowValidError(ctxt, err->err, err->node, err->seq,
  2088. err->arg1, err->arg2);
  2089. k++;
  2090. }
  2091. skip:
  2092. if (err->flags & ERROR_IS_DUP) {
  2093. if (err->arg1 != NULL)
  2094. xmlFree((xmlChar *) err->arg1);
  2095. err->arg1 = NULL;
  2096. if (err->arg2 != NULL)
  2097. xmlFree((xmlChar *) err->arg2);
  2098. err->arg2 = NULL;
  2099. err->flags = 0;
  2100. }
  2101. }
  2102. ctxt->errNr = 0;
  2103. }
  2104. /**
  2105. * xmlRelaxNGAddValidError:
  2106. * @ctxt: the validation context
  2107. * @err: the error number
  2108. * @arg1: the first argument
  2109. * @arg2: the second argument
  2110. * @dup: need to dup the args
  2111. *
  2112. * Register a validation error, either generating it if it's sure
  2113. * or stacking it for later handling if unsure.
  2114. */
  2115. static void
  2116. xmlRelaxNGAddValidError(xmlRelaxNGValidCtxtPtr ctxt,
  2117. xmlRelaxNGValidErr err, const xmlChar * arg1,
  2118. const xmlChar * arg2, int dup)
  2119. {
  2120. if (ctxt == NULL)
  2121. return;
  2122. if (ctxt->flags & FLAGS_NOERROR)
  2123. return;
  2124. /*
  2125. * generate the error directly
  2126. */
  2127. if (((ctxt->flags & FLAGS_IGNORABLE) == 0) ||
  2128. (ctxt->flags & FLAGS_NEGATIVE)) {
  2129. xmlNodePtr node, seq;
  2130. /*
  2131. * Flush first any stacked error which might be the
  2132. * real cause of the problem.
  2133. */
  2134. if (ctxt->errNr != 0)
  2135. xmlRelaxNGDumpValidError(ctxt);
  2136. if (ctxt->state != NULL) {
  2137. node = ctxt->state->node;
  2138. seq = ctxt->state->seq;
  2139. } else {
  2140. node = seq = NULL;
  2141. }
  2142. if ((node == NULL) && (seq == NULL)) {
  2143. node = ctxt->pnode;
  2144. }
  2145. xmlRelaxNGShowValidError(ctxt, err, node, seq, arg1, arg2);
  2146. }
  2147. /*
  2148. * Stack the error for later processing if needed
  2149. */
  2150. else {
  2151. xmlRelaxNGValidErrorPush(ctxt, err, arg1, arg2, dup);
  2152. }
  2153. }
  2154. /************************************************************************
  2155. * *
  2156. * Type library hooks *
  2157. * *
  2158. ************************************************************************/
  2159. static xmlChar *xmlRelaxNGNormalize(xmlRelaxNGValidCtxtPtr ctxt,
  2160. const xmlChar * str);
  2161. /**
  2162. * xmlRelaxNGSchemaTypeHave:
  2163. * @data: data needed for the library
  2164. * @type: the type name
  2165. *
  2166. * Check if the given type is provided by
  2167. * the W3C XMLSchema Datatype library.
  2168. *
  2169. * Returns 1 if yes, 0 if no and -1 in case of error.
  2170. */
  2171. static int
  2172. xmlRelaxNGSchemaTypeHave(void *data ATTRIBUTE_UNUSED, const xmlChar * type)
  2173. {
  2174. xmlSchemaTypePtr typ;
  2175. if (type == NULL)
  2176. return (-1);
  2177. typ = xmlSchemaGetPredefinedType(type,
  2178. BAD_CAST
  2179. "http://www.w3.org/2001/XMLSchema");
  2180. if (typ == NULL)
  2181. return (0);
  2182. return (1);
  2183. }
  2184. /**
  2185. * xmlRelaxNGSchemaTypeCheck:
  2186. * @data: data needed for the library
  2187. * @type: the type name
  2188. * @value: the value to check
  2189. * @node: the node
  2190. *
  2191. * Check if the given type and value are validated by
  2192. * the W3C XMLSchema Datatype library.
  2193. *
  2194. * Returns 1 if yes, 0 if no and -1 in case of error.
  2195. */
  2196. static int
  2197. xmlRelaxNGSchemaTypeCheck(void *data ATTRIBUTE_UNUSED,
  2198. const xmlChar * type,
  2199. const xmlChar * value,
  2200. void **result, xmlNodePtr node)
  2201. {
  2202. xmlSchemaTypePtr typ;
  2203. int ret;
  2204. if ((type == NULL) || (value == NULL))
  2205. return (-1);
  2206. typ = xmlSchemaGetPredefinedType(type,
  2207. BAD_CAST
  2208. "http://www.w3.org/2001/XMLSchema");
  2209. if (typ == NULL)
  2210. return (-1);
  2211. ret = xmlSchemaValPredefTypeNode(typ, value,
  2212. (xmlSchemaValPtr *) result, node);
  2213. if (ret == 2) /* special ID error code */
  2214. return (2);
  2215. if (ret == 0)
  2216. return (1);
  2217. if (ret > 0)
  2218. return (0);
  2219. return (-1);
  2220. }
  2221. /**
  2222. * xmlRelaxNGSchemaFacetCheck:
  2223. * @data: data needed for the library
  2224. * @type: the type name
  2225. * @facet: the facet name
  2226. * @val: the facet value
  2227. * @strval: the string value
  2228. * @value: the value to check
  2229. *
  2230. * Function provided by a type library to check a value facet
  2231. *
  2232. * Returns 1 if yes, 0 if no and -1 in case of error.
  2233. */
  2234. static int
  2235. xmlRelaxNGSchemaFacetCheck(void *data ATTRIBUTE_UNUSED,
  2236. const xmlChar * type, const xmlChar * facetname,
  2237. const xmlChar * val, const xmlChar * strval,
  2238. void *value)
  2239. {
  2240. xmlSchemaFacetPtr facet;
  2241. xmlSchemaTypePtr typ;
  2242. int ret;
  2243. if ((type == NULL) || (strval == NULL))
  2244. return (-1);
  2245. typ = xmlSchemaGetPredefinedType(type,
  2246. BAD_CAST
  2247. "http://www.w3.org/2001/XMLSchema");
  2248. if (typ == NULL)
  2249. return (-1);
  2250. facet = xmlSchemaNewFacet();
  2251. if (facet == NULL)
  2252. return (-1);
  2253. if (xmlStrEqual(facetname, BAD_CAST "minInclusive")) {
  2254. facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
  2255. } else if (xmlStrEqual(facetname, BAD_CAST "minExclusive")) {
  2256. facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
  2257. } else if (xmlStrEqual(facetname, BAD_CAST "maxInclusive")) {
  2258. facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
  2259. } else if (xmlStrEqual(facetname, BAD_CAST "maxExclusive")) {
  2260. facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
  2261. } else if (xmlStrEqual(facetname, BAD_CAST "totalDigits")) {
  2262. facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
  2263. } else if (xmlStrEqual(facetname, BAD_CAST "fractionDigits")) {
  2264. facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
  2265. } else if (xmlStrEqual(facetname, BAD_CAST "pattern")) {
  2266. facet->type = XML_SCHEMA_FACET_PATTERN;
  2267. } else if (xmlStrEqual(facetname, BAD_CAST "enumeration")) {
  2268. facet->type = XML_SCHEMA_FACET_ENUMERATION;
  2269. } else if (xmlStrEqual(facetname, BAD_CAST "whiteSpace")) {
  2270. facet->type = XML_SCHEMA_FACET_WHITESPACE;
  2271. } else if (xmlStrEqual(facetname, BAD_CAST "length")) {
  2272. facet->type = XML_SCHEMA_FACET_LENGTH;
  2273. } else if (xmlStrEqual(facetname, BAD_CAST "maxLength")) {
  2274. facet->type = XML_SCHEMA_FACET_MAXLENGTH;
  2275. } else if (xmlStrEqual(facetname, BAD_CAST "minLength")) {
  2276. facet->type = XML_SCHEMA_FACET_MINLENGTH;
  2277. } else {
  2278. xmlSchemaFreeFacet(facet);
  2279. return (-1);
  2280. }
  2281. facet->value = val;
  2282. ret = xmlSchemaCheckFacet(facet, typ, NULL, type);
  2283. if (ret != 0) {
  2284. xmlSchemaFreeFacet(facet);
  2285. return (-1);
  2286. }
  2287. ret = xmlSchemaValidateFacet(typ, facet, strval, value);
  2288. xmlSchemaFreeFacet(facet);
  2289. if (ret != 0)
  2290. return (-1);
  2291. return (0);
  2292. }
  2293. /**
  2294. * xmlRelaxNGSchemaFreeValue:
  2295. * @data: data needed for the library
  2296. * @value: the value to free
  2297. *
  2298. * Function provided by a type library to free a Schemas value
  2299. *
  2300. * Returns 1 if yes, 0 if no and -1 in case of error.
  2301. */
  2302. static void
  2303. xmlRelaxNGSchemaFreeValue(void *data ATTRIBUTE_UNUSED, void *value)
  2304. {
  2305. xmlSchemaFreeValue(value);
  2306. }
  2307. /**
  2308. * xmlRelaxNGSchemaTypeCompare:
  2309. * @data: data needed for the library
  2310. * @type: the type name
  2311. * @value1: the first value
  2312. * @value2: the second value
  2313. *
  2314. * Compare two values for equality accordingly a type from the W3C XMLSchema
  2315. * Datatype library.
  2316. *
  2317. * Returns 1 if equal, 0 if no and -1 in case of error.
  2318. */
  2319. static int
  2320. xmlRelaxNGSchemaTypeCompare(void *data ATTRIBUTE_UNUSED,
  2321. const xmlChar * type,
  2322. const xmlChar * value1,
  2323. xmlNodePtr ctxt1,
  2324. void *comp1,
  2325. const xmlChar * value2, xmlNodePtr ctxt2)
  2326. {
  2327. int ret;
  2328. xmlSchemaTypePtr typ;
  2329. xmlSchemaValPtr res1 = NULL, res2 = NULL;
  2330. if ((type == NULL) || (value1 == NULL) || (value2 == NULL))
  2331. return (-1);
  2332. typ = xmlSchemaGetPredefinedType(type,
  2333. BAD_CAST
  2334. "http://www.w3.org/2001/XMLSchema");
  2335. if (typ == NULL)
  2336. return (-1);
  2337. if (comp1 == NULL) {
  2338. ret = xmlSchemaValPredefTypeNode(typ, value1, &res1, ctxt1);
  2339. if (ret != 0)
  2340. return (-1);
  2341. if (res1 == NULL)
  2342. return (-1);
  2343. } else {
  2344. res1 = (xmlSchemaValPtr) comp1;
  2345. }
  2346. ret = xmlSchemaValPredefTypeNode(typ, value2, &res2, ctxt2);
  2347. if (ret != 0) {
  2348. if (res1 != (xmlSchemaValPtr) comp1)
  2349. xmlSchemaFreeValue(res1);
  2350. return (-1);
  2351. }
  2352. ret = xmlSchemaCompareValues(res1, res2);
  2353. if (res1 != (xmlSchemaValPtr) comp1)
  2354. xmlSchemaFreeValue(res1);
  2355. xmlSchemaFreeValue(res2);
  2356. if (ret == -2)
  2357. return (-1);
  2358. if (ret == 0)
  2359. return (1);
  2360. return (0);
  2361. }
  2362. /**
  2363. * xmlRelaxNGDefaultTypeHave:
  2364. * @data: data needed for the library
  2365. * @type: the type name
  2366. *
  2367. * Check if the given type is provided by
  2368. * the default datatype library.
  2369. *
  2370. * Returns 1 if yes, 0 if no and -1 in case of error.
  2371. */
  2372. static int
  2373. xmlRelaxNGDefaultTypeHave(void *data ATTRIBUTE_UNUSED,
  2374. const xmlChar * type)
  2375. {
  2376. if (type == NULL)
  2377. return (-1);
  2378. if (xmlStrEqual(type, BAD_CAST "string"))
  2379. return (1);
  2380. if (xmlStrEqual(type, BAD_CAST "token"))
  2381. return (1);
  2382. return (0);
  2383. }
  2384. /**
  2385. * xmlRelaxNGDefaultTypeCheck:
  2386. * @data: data needed for the library
  2387. * @type: the type name
  2388. * @value: the value to check
  2389. * @node: the node
  2390. *
  2391. * Check if the given type and value are validated by
  2392. * the default datatype library.
  2393. *
  2394. * Returns 1 if yes, 0 if no and -1 in case of error.
  2395. */
  2396. static int
  2397. xmlRelaxNGDefaultTypeCheck(void *data ATTRIBUTE_UNUSED,
  2398. const xmlChar * type ATTRIBUTE_UNUSED,
  2399. const xmlChar * value ATTRIBUTE_UNUSED,
  2400. void **result ATTRIBUTE_UNUSED,
  2401. xmlNodePtr node ATTRIBUTE_UNUSED)
  2402. {
  2403. if (value == NULL)
  2404. return (-1);
  2405. if (xmlStrEqual(type, BAD_CAST "string"))
  2406. return (1);
  2407. if (xmlStrEqual(type, BAD_CAST "token")) {
  2408. return (1);
  2409. }
  2410. return (0);
  2411. }
  2412. /**
  2413. * xmlRelaxNGDefaultTypeCompare:
  2414. * @data: data needed for the library
  2415. * @type: the type name
  2416. * @value1: the first value
  2417. * @value2: the second value
  2418. *
  2419. * Compare two values accordingly a type from the default
  2420. * datatype library.
  2421. *
  2422. * Returns 1 if yes, 0 if no and -1 in case of error.
  2423. */
  2424. static int
  2425. xmlRelaxNGDefaultTypeCompare(void *data ATTRIBUTE_UNUSED,
  2426. const xmlChar * type,
  2427. const xmlChar * value1,
  2428. xmlNodePtr ctxt1 ATTRIBUTE_UNUSED,
  2429. void *comp1 ATTRIBUTE_UNUSED,
  2430. const xmlChar * value2,
  2431. xmlNodePtr ctxt2 ATTRIBUTE_UNUSED)
  2432. {
  2433. int ret = -1;
  2434. if (xmlStrEqual(type, BAD_CAST "string")) {
  2435. ret = xmlStrEqual(value1, value2);
  2436. } else if (xmlStrEqual(type, BAD_CAST "token")) {
  2437. if (!xmlStrEqual(value1, value2)) {
  2438. xmlChar *nval, *nvalue;
  2439. /*
  2440. * TODO: trivial optimizations are possible by
  2441. * computing at compile-time
  2442. */
  2443. nval = xmlRelaxNGNormalize(NULL, value1);
  2444. nvalue = xmlRelaxNGNormalize(NULL, value2);
  2445. if ((nval == NULL) || (nvalue == NULL))
  2446. ret = -1;
  2447. else if (xmlStrEqual(nval, nvalue))
  2448. ret = 1;
  2449. else
  2450. ret = 0;
  2451. if (nval != NULL)
  2452. xmlFree(nval);
  2453. if (nvalue != NULL)
  2454. xmlFree(nvalue);
  2455. } else
  2456. ret = 1;
  2457. }
  2458. return (ret);
  2459. }
  2460. static int xmlRelaxNGTypeInitialized = 0;
  2461. static xmlHashTablePtr xmlRelaxNGRegisteredTypes = NULL;
  2462. /**
  2463. * xmlRelaxNGFreeTypeLibrary:
  2464. * @lib: the type library structure
  2465. * @namespace: the URI bound to the library
  2466. *
  2467. * Free the structure associated to the type library
  2468. */
  2469. static void
  2470. xmlRelaxNGFreeTypeLibrary(void *payload,
  2471. const xmlChar * namespace ATTRIBUTE_UNUSED)
  2472. {
  2473. xmlRelaxNGTypeLibraryPtr lib = (xmlRelaxNGTypeLibraryPtr) payload;
  2474. if (lib == NULL)
  2475. return;
  2476. if (lib->namespace != NULL)
  2477. xmlFree((xmlChar *) lib->namespace);
  2478. xmlFree(lib);
  2479. }
  2480. /**
  2481. * xmlRelaxNGRegisterTypeLibrary:
  2482. * @namespace: the URI bound to the library
  2483. * @data: data associated to the library
  2484. * @have: the provide function
  2485. * @check: the checking function
  2486. * @comp: the comparison function
  2487. *
  2488. * Register a new type library
  2489. *
  2490. * Returns 0 in case of success and -1 in case of error.
  2491. */
  2492. static int
  2493. xmlRelaxNGRegisterTypeLibrary(const xmlChar * namespace, void *data,
  2494. xmlRelaxNGTypeHave have,
  2495. xmlRelaxNGTypeCheck check,
  2496. xmlRelaxNGTypeCompare comp,
  2497. xmlRelaxNGFacetCheck facet,
  2498. xmlRelaxNGTypeFree freef)
  2499. {
  2500. xmlRelaxNGTypeLibraryPtr lib;
  2501. int ret;
  2502. if ((xmlRelaxNGRegisteredTypes == NULL) || (namespace == NULL) ||
  2503. (check == NULL) || (comp == NULL))
  2504. return (-1);
  2505. if (xmlHashLookup(xmlRelaxNGRegisteredTypes, namespace) != NULL) {
  2506. xmlGenericError(xmlGenericErrorContext,
  2507. "Relax-NG types library '%s' already registered\n",
  2508. namespace);
  2509. return (-1);
  2510. }
  2511. lib =
  2512. (xmlRelaxNGTypeLibraryPtr)
  2513. xmlMalloc(sizeof(xmlRelaxNGTypeLibrary));
  2514. if (lib == NULL) {
  2515. xmlRngVErrMemory(NULL, "adding types library\n");
  2516. return (-1);
  2517. }
  2518. memset(lib, 0, sizeof(xmlRelaxNGTypeLibrary));
  2519. lib->namespace = xmlStrdup(namespace);
  2520. lib->data = data;
  2521. lib->have = have;
  2522. lib->comp = comp;
  2523. lib->check = check;
  2524. lib->facet = facet;
  2525. lib->freef = freef;
  2526. ret = xmlHashAddEntry(xmlRelaxNGRegisteredTypes, namespace, lib);
  2527. if (ret < 0) {
  2528. xmlGenericError(xmlGenericErrorContext,
  2529. "Relax-NG types library failed to register '%s'\n",
  2530. namespace);
  2531. xmlRelaxNGFreeTypeLibrary(lib, namespace);
  2532. return (-1);
  2533. }
  2534. return (0);
  2535. }
  2536. /**
  2537. * xmlRelaxNGInitTypes:
  2538. *
  2539. * Initialize the default type libraries.
  2540. *
  2541. * Returns 0 in case of success and -1 in case of error.
  2542. */
  2543. int
  2544. xmlRelaxNGInitTypes(void)
  2545. {
  2546. if (xmlRelaxNGTypeInitialized != 0)
  2547. return (0);
  2548. xmlRelaxNGRegisteredTypes = xmlHashCreate(10);
  2549. if (xmlRelaxNGRegisteredTypes == NULL) {
  2550. xmlGenericError(xmlGenericErrorContext,
  2551. "Failed to allocate sh table for Relax-NG types\n");
  2552. return (-1);
  2553. }
  2554. xmlRelaxNGRegisterTypeLibrary(BAD_CAST
  2555. "http://www.w3.org/2001/XMLSchema-datatypes",
  2556. NULL, xmlRelaxNGSchemaTypeHave,
  2557. xmlRelaxNGSchemaTypeCheck,
  2558. xmlRelaxNGSchemaTypeCompare,
  2559. xmlRelaxNGSchemaFacetCheck,
  2560. xmlRelaxNGSchemaFreeValue);
  2561. xmlRelaxNGRegisterTypeLibrary(xmlRelaxNGNs, NULL,
  2562. xmlRelaxNGDefaultTypeHave,
  2563. xmlRelaxNGDefaultTypeCheck,
  2564. xmlRelaxNGDefaultTypeCompare, NULL,
  2565. NULL);
  2566. xmlRelaxNGTypeInitialized = 1;
  2567. return (0);
  2568. }
  2569. /**
  2570. * xmlRelaxNGCleanupTypes:
  2571. *
  2572. * DEPRECATED: This function will be made private. Call xmlCleanupParser
  2573. * to free global state but see the warnings there. xmlCleanupParser
  2574. * should be only called once at program exit. In most cases, you don't
  2575. * have call cleanup functions at all.
  2576. *
  2577. * Cleanup the default Schemas type library associated to RelaxNG
  2578. */
  2579. void
  2580. xmlRelaxNGCleanupTypes(void)
  2581. {
  2582. xmlSchemaCleanupTypes();
  2583. if (xmlRelaxNGTypeInitialized == 0)
  2584. return;
  2585. xmlHashFree(xmlRelaxNGRegisteredTypes, xmlRelaxNGFreeTypeLibrary);
  2586. xmlRelaxNGTypeInitialized = 0;
  2587. }
  2588. /************************************************************************
  2589. * *
  2590. * Compiling element content into regexp *
  2591. * *
  2592. * Sometime the element content can be compiled into a pure regexp, *
  2593. * This allows a faster execution and streamability at that level *
  2594. * *
  2595. ************************************************************************/
  2596. static int xmlRelaxNGTryCompile(xmlRelaxNGParserCtxtPtr ctxt,
  2597. xmlRelaxNGDefinePtr def);
  2598. /**
  2599. * xmlRelaxNGIsCompilable:
  2600. * @define: the definition to check
  2601. *
  2602. * Check if a definition is nullable.
  2603. *
  2604. * Returns 1 if yes, 0 if no and -1 in case of error
  2605. */
  2606. static int
  2607. xmlRelaxNGIsCompilable(xmlRelaxNGDefinePtr def)
  2608. {
  2609. int ret = -1;
  2610. if (def == NULL) {
  2611. return (-1);
  2612. }
  2613. if ((def->type != XML_RELAXNG_ELEMENT) &&
  2614. (def->dflags & IS_COMPILABLE))
  2615. return (1);
  2616. if ((def->type != XML_RELAXNG_ELEMENT) &&
  2617. (def->dflags & IS_NOT_COMPILABLE))
  2618. return (0);
  2619. switch (def->type) {
  2620. case XML_RELAXNG_NOOP:
  2621. ret = xmlRelaxNGIsCompilable(def->content);
  2622. break;
  2623. case XML_RELAXNG_TEXT:
  2624. case XML_RELAXNG_EMPTY:
  2625. ret = 1;
  2626. break;
  2627. case XML_RELAXNG_ELEMENT:
  2628. /*
  2629. * Check if the element content is compilable
  2630. */
  2631. if (((def->dflags & IS_NOT_COMPILABLE) == 0) &&
  2632. ((def->dflags & IS_COMPILABLE) == 0)) {
  2633. xmlRelaxNGDefinePtr list;
  2634. list = def->content;
  2635. while (list != NULL) {
  2636. ret = xmlRelaxNGIsCompilable(list);
  2637. if (ret != 1)
  2638. break;
  2639. list = list->next;
  2640. }
  2641. /*
  2642. * Because the routine is recursive, we must guard against
  2643. * discovering both COMPILABLE and NOT_COMPILABLE
  2644. */
  2645. if (ret == 0) {
  2646. def->dflags &= ~IS_COMPILABLE;
  2647. def->dflags |= IS_NOT_COMPILABLE;
  2648. }
  2649. if ((ret == 1) && !(def->dflags &= IS_NOT_COMPILABLE))
  2650. def->dflags |= IS_COMPILABLE;
  2651. }
  2652. /*
  2653. * All elements return a compilable status unless they
  2654. * are generic like anyName
  2655. */
  2656. if ((def->nameClass != NULL) || (def->name == NULL))
  2657. ret = 0;
  2658. else
  2659. ret = 1;
  2660. return (ret);
  2661. case XML_RELAXNG_REF:
  2662. case XML_RELAXNG_EXTERNALREF:
  2663. case XML_RELAXNG_PARENTREF:
  2664. if (def->depth == -20) {
  2665. return (1);
  2666. } else {
  2667. xmlRelaxNGDefinePtr list;
  2668. def->depth = -20;
  2669. list = def->content;
  2670. while (list != NULL) {
  2671. ret = xmlRelaxNGIsCompilable(list);
  2672. if (ret != 1)
  2673. break;
  2674. list = list->next;
  2675. }
  2676. }
  2677. break;
  2678. case XML_RELAXNG_START:
  2679. case XML_RELAXNG_OPTIONAL:
  2680. case XML_RELAXNG_ZEROORMORE:
  2681. case XML_RELAXNG_ONEORMORE:
  2682. case XML_RELAXNG_CHOICE:
  2683. case XML_RELAXNG_GROUP:
  2684. case XML_RELAXNG_DEF:{
  2685. xmlRelaxNGDefinePtr list;
  2686. list = def->content;
  2687. while (list != NULL) {
  2688. ret = xmlRelaxNGIsCompilable(list);
  2689. if (ret != 1)
  2690. break;
  2691. list = list->next;
  2692. }
  2693. break;
  2694. }
  2695. case XML_RELAXNG_EXCEPT:
  2696. case XML_RELAXNG_ATTRIBUTE:
  2697. case XML_RELAXNG_INTERLEAVE:
  2698. case XML_RELAXNG_DATATYPE:
  2699. case XML_RELAXNG_LIST:
  2700. case XML_RELAXNG_PARAM:
  2701. case XML_RELAXNG_VALUE:
  2702. case XML_RELAXNG_NOT_ALLOWED:
  2703. ret = 0;
  2704. break;
  2705. }
  2706. if (ret == 0)
  2707. def->dflags |= IS_NOT_COMPILABLE;
  2708. if (ret == 1)
  2709. def->dflags |= IS_COMPILABLE;
  2710. return (ret);
  2711. }
  2712. /**
  2713. * xmlRelaxNGCompile:
  2714. * ctxt: the RelaxNG parser context
  2715. * @define: the definition tree to compile
  2716. *
  2717. * Compile the set of definitions, it works recursively, till the
  2718. * element boundaries, where it tries to compile the content if possible
  2719. *
  2720. * Returns 0 if success and -1 in case of error
  2721. */
  2722. static int
  2723. xmlRelaxNGCompile(xmlRelaxNGParserCtxtPtr ctxt, xmlRelaxNGDefinePtr def)
  2724. {
  2725. int ret = 0;
  2726. xmlRelaxNGDefinePtr list;
  2727. if ((ctxt == NULL) || (def == NULL))
  2728. return (-1);
  2729. switch (def->type) {
  2730. case XML_RELAXNG_START:
  2731. if ((xmlRelaxNGIsCompilable(def) == 1) && (def->depth != -25)) {
  2732. xmlAutomataPtr oldam = ctxt->am;
  2733. xmlAutomataStatePtr oldstate = ctxt->state;
  2734. def->depth = -25;
  2735. list = def->content;
  2736. ctxt->am = xmlNewAutomata();
  2737. if (ctxt->am == NULL)
  2738. return (-1);
  2739. /*
  2740. * assume identical strings but not same pointer are different
  2741. * atoms, needed for non-determinism detection
  2742. * That way if 2 elements with the same name are in a choice
  2743. * branch the automata is found non-deterministic and
  2744. * we fallback to the normal validation which does the right
  2745. * thing of exploring both choices.
  2746. */
  2747. xmlAutomataSetFlags(ctxt->am, 1);
  2748. ctxt->state = xmlAutomataGetInitState(ctxt->am);
  2749. while (list != NULL) {
  2750. xmlRelaxNGCompile(ctxt, list);
  2751. list = list->next;
  2752. }
  2753. xmlAutomataSetFinalState(ctxt->am, ctxt->state);
  2754. if (xmlAutomataIsDeterminist(ctxt->am))
  2755. def->contModel = xmlAutomataCompile(ctxt->am);
  2756. xmlFreeAutomata(ctxt->am);
  2757. ctxt->state = oldstate;
  2758. ctxt->am = oldam;
  2759. }
  2760. break;
  2761. case XML_RELAXNG_ELEMENT:
  2762. if ((ctxt->am != NULL) && (def->name != NULL)) {
  2763. ctxt->state = xmlAutomataNewTransition2(ctxt->am,
  2764. ctxt->state, NULL,
  2765. def->name, def->ns,
  2766. def);
  2767. }
  2768. if ((def->dflags & IS_COMPILABLE) && (def->depth != -25)) {
  2769. xmlAutomataPtr oldam = ctxt->am;
  2770. xmlAutomataStatePtr oldstate = ctxt->state;
  2771. def->depth = -25;
  2772. list = def->content;
  2773. ctxt->am = xmlNewAutomata();
  2774. if (ctxt->am == NULL)
  2775. return (-1);
  2776. xmlAutomataSetFlags(ctxt->am, 1);
  2777. ctxt->state = xmlAutomataGetInitState(ctxt->am);
  2778. while (list != NULL) {
  2779. xmlRelaxNGCompile(ctxt, list);
  2780. list = list->next;
  2781. }
  2782. xmlAutomataSetFinalState(ctxt->am, ctxt->state);
  2783. def->contModel = xmlAutomataCompile(ctxt->am);
  2784. if (!xmlRegexpIsDeterminist(def->contModel)) {
  2785. /*
  2786. * we can only use the automata if it is determinist
  2787. */
  2788. xmlRegFreeRegexp(def->contModel);
  2789. def->contModel = NULL;
  2790. }
  2791. xmlFreeAutomata(ctxt->am);
  2792. ctxt->state = oldstate;
  2793. ctxt->am = oldam;
  2794. } else {
  2795. xmlAutomataPtr oldam = ctxt->am;
  2796. /*
  2797. * we can't build the content model for this element content
  2798. * but it still might be possible to build it for some of its
  2799. * children, recurse.
  2800. */
  2801. ret = xmlRelaxNGTryCompile(ctxt, def);
  2802. ctxt->am = oldam;
  2803. }
  2804. break;
  2805. case XML_RELAXNG_NOOP:
  2806. ret = xmlRelaxNGCompile(ctxt, def->content);
  2807. break;
  2808. case XML_RELAXNG_OPTIONAL:{
  2809. xmlAutomataStatePtr oldstate = ctxt->state;
  2810. list = def->content;
  2811. while (list != NULL) {
  2812. xmlRelaxNGCompile(ctxt, list);
  2813. list = list->next;
  2814. }
  2815. xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
  2816. break;
  2817. }
  2818. case XML_RELAXNG_ZEROORMORE:{
  2819. xmlAutomataStatePtr oldstate;
  2820. ctxt->state =
  2821. xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
  2822. oldstate = ctxt->state;
  2823. list = def->content;
  2824. while (list != NULL) {
  2825. xmlRelaxNGCompile(ctxt, list);
  2826. list = list->next;
  2827. }
  2828. xmlAutomataNewEpsilon(ctxt->am, ctxt->state, oldstate);
  2829. ctxt->state =
  2830. xmlAutomataNewEpsilon(ctxt->am, oldstate, NULL);
  2831. break;
  2832. }
  2833. case XML_RELAXNG_ONEORMORE:{
  2834. xmlAutomataStatePtr oldstate;
  2835. list = def->content;
  2836. while (list != NULL) {
  2837. xmlRelaxNGCompile(ctxt, list);
  2838. list = list->next;
  2839. }
  2840. oldstate = ctxt->state;
  2841. list = def->content;
  2842. while (list != NULL) {
  2843. xmlRelaxNGCompile(ctxt, list);
  2844. list = list->next;
  2845. }
  2846. xmlAutomataNewEpsilon(ctxt->am, ctxt->state, oldstate);
  2847. ctxt->state =
  2848. xmlAutomataNewEpsilon(ctxt->am, oldstate, NULL);
  2849. break;
  2850. }
  2851. case XML_RELAXNG_CHOICE:{
  2852. xmlAutomataStatePtr target = NULL;
  2853. xmlAutomataStatePtr oldstate = ctxt->state;
  2854. list = def->content;
  2855. while (list != NULL) {
  2856. ctxt->state = oldstate;
  2857. ret = xmlRelaxNGCompile(ctxt, list);
  2858. if (ret != 0)
  2859. break;
  2860. if (target == NULL)
  2861. target = ctxt->state;
  2862. else {
  2863. xmlAutomataNewEpsilon(ctxt->am, ctxt->state,
  2864. target);
  2865. }
  2866. list = list->next;
  2867. }
  2868. ctxt->state = target;
  2869. break;
  2870. }
  2871. case XML_RELAXNG_REF:
  2872. case XML_RELAXNG_EXTERNALREF:
  2873. case XML_RELAXNG_PARENTREF:
  2874. case XML_RELAXNG_GROUP:
  2875. case XML_RELAXNG_DEF:
  2876. list = def->content;
  2877. while (list != NULL) {
  2878. ret = xmlRelaxNGCompile(ctxt, list);
  2879. if (ret != 0)
  2880. break;
  2881. list = list->next;
  2882. }
  2883. break;
  2884. case XML_RELAXNG_TEXT:{
  2885. xmlAutomataStatePtr oldstate;
  2886. ctxt->state =
  2887. xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
  2888. oldstate = ctxt->state;
  2889. xmlRelaxNGCompile(ctxt, def->content);
  2890. xmlAutomataNewTransition(ctxt->am, ctxt->state,
  2891. ctxt->state, BAD_CAST "#text",
  2892. NULL);
  2893. ctxt->state =
  2894. xmlAutomataNewEpsilon(ctxt->am, oldstate, NULL);
  2895. break;
  2896. }
  2897. case XML_RELAXNG_EMPTY:
  2898. ctxt->state =
  2899. xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
  2900. break;
  2901. case XML_RELAXNG_EXCEPT:
  2902. case XML_RELAXNG_ATTRIBUTE:
  2903. case XML_RELAXNG_INTERLEAVE:
  2904. case XML_RELAXNG_NOT_ALLOWED:
  2905. case XML_RELAXNG_DATATYPE:
  2906. case XML_RELAXNG_LIST:
  2907. case XML_RELAXNG_PARAM:
  2908. case XML_RELAXNG_VALUE:
  2909. /* This should not happen and generate an internal error */
  2910. fprintf(stderr, "RNG internal error trying to compile %s\n",
  2911. xmlRelaxNGDefName(def));
  2912. break;
  2913. }
  2914. return (ret);
  2915. }
  2916. /**
  2917. * xmlRelaxNGTryCompile:
  2918. * ctxt: the RelaxNG parser context
  2919. * @define: the definition tree to compile
  2920. *
  2921. * Try to compile the set of definitions, it works recursively,
  2922. * possibly ignoring parts which cannot be compiled.
  2923. *
  2924. * Returns 0 if success and -1 in case of error
  2925. */
  2926. static int
  2927. xmlRelaxNGTryCompile(xmlRelaxNGParserCtxtPtr ctxt, xmlRelaxNGDefinePtr def)
  2928. {
  2929. int ret = 0;
  2930. xmlRelaxNGDefinePtr list;
  2931. if ((ctxt == NULL) || (def == NULL))
  2932. return (-1);
  2933. if ((def->type == XML_RELAXNG_START) ||
  2934. (def->type == XML_RELAXNG_ELEMENT)) {
  2935. ret = xmlRelaxNGIsCompilable(def);
  2936. if ((def->dflags & IS_COMPILABLE) && (def->depth != -25)) {
  2937. ctxt->am = NULL;
  2938. ret = xmlRelaxNGCompile(ctxt, def);
  2939. return (ret);
  2940. }
  2941. }
  2942. switch (def->type) {
  2943. case XML_RELAXNG_NOOP:
  2944. ret = xmlRelaxNGTryCompile(ctxt, def->content);
  2945. break;
  2946. case XML_RELAXNG_TEXT:
  2947. case XML_RELAXNG_DATATYPE:
  2948. case XML_RELAXNG_LIST:
  2949. case XML_RELAXNG_PARAM:
  2950. case XML_RELAXNG_VALUE:
  2951. case XML_RELAXNG_EMPTY:
  2952. case XML_RELAXNG_ELEMENT:
  2953. ret = 0;
  2954. break;
  2955. case XML_RELAXNG_OPTIONAL:
  2956. case XML_RELAXNG_ZEROORMORE:
  2957. case XML_RELAXNG_ONEORMORE:
  2958. case XML_RELAXNG_CHOICE:
  2959. case XML_RELAXNG_GROUP:
  2960. case XML_RELAXNG_DEF:
  2961. case XML_RELAXNG_START:
  2962. case XML_RELAXNG_REF:
  2963. case XML_RELAXNG_EXTERNALREF:
  2964. case XML_RELAXNG_PARENTREF:
  2965. list = def->content;
  2966. while (list != NULL) {
  2967. ret = xmlRelaxNGTryCompile(ctxt, list);
  2968. if (ret != 0)
  2969. break;
  2970. list = list->next;
  2971. }
  2972. break;
  2973. case XML_RELAXNG_EXCEPT:
  2974. case XML_RELAXNG_ATTRIBUTE:
  2975. case XML_RELAXNG_INTERLEAVE:
  2976. case XML_RELAXNG_NOT_ALLOWED:
  2977. ret = 0;
  2978. break;
  2979. }
  2980. return (ret);
  2981. }
  2982. /************************************************************************
  2983. * *
  2984. * Parsing functions *
  2985. * *
  2986. ************************************************************************/
  2987. static xmlRelaxNGDefinePtr xmlRelaxNGParseAttribute(xmlRelaxNGParserCtxtPtr
  2988. ctxt, xmlNodePtr node);
  2989. static xmlRelaxNGDefinePtr xmlRelaxNGParseElement(xmlRelaxNGParserCtxtPtr
  2990. ctxt, xmlNodePtr node);
  2991. static xmlRelaxNGDefinePtr xmlRelaxNGParsePatterns(xmlRelaxNGParserCtxtPtr
  2992. ctxt, xmlNodePtr nodes,
  2993. int group);
  2994. static xmlRelaxNGDefinePtr xmlRelaxNGParsePattern(xmlRelaxNGParserCtxtPtr
  2995. ctxt, xmlNodePtr node);
  2996. static xmlRelaxNGPtr xmlRelaxNGParseDocument(xmlRelaxNGParserCtxtPtr ctxt,
  2997. xmlNodePtr node);
  2998. static int xmlRelaxNGParseGrammarContent(xmlRelaxNGParserCtxtPtr ctxt,
  2999. xmlNodePtr nodes);
  3000. static xmlRelaxNGDefinePtr xmlRelaxNGParseNameClass(xmlRelaxNGParserCtxtPtr
  3001. ctxt, xmlNodePtr node,
  3002. xmlRelaxNGDefinePtr
  3003. def);
  3004. static xmlRelaxNGGrammarPtr xmlRelaxNGParseGrammar(xmlRelaxNGParserCtxtPtr
  3005. ctxt, xmlNodePtr nodes);
  3006. static int xmlRelaxNGElementMatch(xmlRelaxNGValidCtxtPtr ctxt,
  3007. xmlRelaxNGDefinePtr define,
  3008. xmlNodePtr elem);
  3009. #define IS_BLANK_NODE(n) (xmlRelaxNGIsBlank((n)->content))
  3010. /**
  3011. * xmlRelaxNGIsNullable:
  3012. * @define: the definition to verify
  3013. *
  3014. * Check if a definition is nullable.
  3015. *
  3016. * Returns 1 if yes, 0 if no and -1 in case of error
  3017. */
  3018. static int
  3019. xmlRelaxNGIsNullable(xmlRelaxNGDefinePtr define)
  3020. {
  3021. int ret;
  3022. if (define == NULL)
  3023. return (-1);
  3024. if (define->dflags & IS_NULLABLE)
  3025. return (1);
  3026. if (define->dflags & IS_NOT_NULLABLE)
  3027. return (0);
  3028. switch (define->type) {
  3029. case XML_RELAXNG_EMPTY:
  3030. case XML_RELAXNG_TEXT:
  3031. ret = 1;
  3032. break;
  3033. case XML_RELAXNG_NOOP:
  3034. case XML_RELAXNG_DEF:
  3035. case XML_RELAXNG_REF:
  3036. case XML_RELAXNG_EXTERNALREF:
  3037. case XML_RELAXNG_PARENTREF:
  3038. case XML_RELAXNG_ONEORMORE:
  3039. ret = xmlRelaxNGIsNullable(define->content);
  3040. break;
  3041. case XML_RELAXNG_EXCEPT:
  3042. case XML_RELAXNG_NOT_ALLOWED:
  3043. case XML_RELAXNG_ELEMENT:
  3044. case XML_RELAXNG_DATATYPE:
  3045. case XML_RELAXNG_PARAM:
  3046. case XML_RELAXNG_VALUE:
  3047. case XML_RELAXNG_LIST:
  3048. case XML_RELAXNG_ATTRIBUTE:
  3049. ret = 0;
  3050. break;
  3051. case XML_RELAXNG_CHOICE:{
  3052. xmlRelaxNGDefinePtr list = define->content;
  3053. while (list != NULL) {
  3054. ret = xmlRelaxNGIsNullable(list);
  3055. if (ret != 0)
  3056. goto done;
  3057. list = list->next;
  3058. }
  3059. ret = 0;
  3060. break;
  3061. }
  3062. case XML_RELAXNG_START:
  3063. case XML_RELAXNG_INTERLEAVE:
  3064. case XML_RELAXNG_GROUP:{
  3065. xmlRelaxNGDefinePtr list = define->content;
  3066. while (list != NULL) {
  3067. ret = xmlRelaxNGIsNullable(list);
  3068. if (ret != 1)
  3069. goto done;
  3070. list = list->next;
  3071. }
  3072. return (1);
  3073. }
  3074. default:
  3075. return (-1);
  3076. }
  3077. done:
  3078. if (ret == 0)
  3079. define->dflags |= IS_NOT_NULLABLE;
  3080. if (ret == 1)
  3081. define->dflags |= IS_NULLABLE;
  3082. return (ret);
  3083. }
  3084. /**
  3085. * xmlRelaxNGIsBlank:
  3086. * @str: a string
  3087. *
  3088. * Check if a string is ignorable c.f. 4.2. Whitespace
  3089. *
  3090. * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
  3091. */
  3092. static int
  3093. xmlRelaxNGIsBlank(xmlChar * str)
  3094. {
  3095. if (str == NULL)
  3096. return (1);
  3097. while (*str != 0) {
  3098. if (!(IS_BLANK_CH(*str)))
  3099. return (0);
  3100. str++;
  3101. }
  3102. return (1);
  3103. }
  3104. /**
  3105. * xmlRelaxNGGetDataTypeLibrary:
  3106. * @ctxt: a Relax-NG parser context
  3107. * @node: the current data or value element
  3108. *
  3109. * Applies algorithm from 4.3. datatypeLibrary attribute
  3110. *
  3111. * Returns the datatypeLibrary value or NULL if not found
  3112. */
  3113. static xmlChar *
  3114. xmlRelaxNGGetDataTypeLibrary(xmlRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
  3115. xmlNodePtr node)
  3116. {
  3117. xmlChar *ret, *escape;
  3118. if (node == NULL)
  3119. return(NULL);
  3120. if ((IS_RELAXNG(node, "data")) || (IS_RELAXNG(node, "value"))) {
  3121. ret = xmlGetProp(node, BAD_CAST "datatypeLibrary");
  3122. if (ret != NULL) {
  3123. if (ret[0] == 0) {
  3124. xmlFree(ret);
  3125. return (NULL);
  3126. }
  3127. escape = xmlURIEscapeStr(ret, BAD_CAST ":/#?");
  3128. if (escape == NULL) {
  3129. return (ret);
  3130. }
  3131. xmlFree(ret);
  3132. return (escape);
  3133. }
  3134. }
  3135. node = node->parent;
  3136. while ((node != NULL) && (node->type == XML_ELEMENT_NODE)) {
  3137. ret = xmlGetProp(node, BAD_CAST "datatypeLibrary");
  3138. if (ret != NULL) {
  3139. if (ret[0] == 0) {
  3140. xmlFree(ret);
  3141. return (NULL);
  3142. }
  3143. escape = xmlURIEscapeStr(ret, BAD_CAST ":/#?");
  3144. if (escape == NULL) {
  3145. return (ret);
  3146. }
  3147. xmlFree(ret);
  3148. return (escape);
  3149. }
  3150. node = node->parent;
  3151. }
  3152. return (NULL);
  3153. }
  3154. /**
  3155. * xmlRelaxNGParseValue:
  3156. * @ctxt: a Relax-NG parser context
  3157. * @node: the data node.
  3158. *
  3159. * parse the content of a RelaxNG value node.
  3160. *
  3161. * Returns the definition pointer or NULL in case of error
  3162. */
  3163. static xmlRelaxNGDefinePtr
  3164. xmlRelaxNGParseValue(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
  3165. {
  3166. xmlRelaxNGDefinePtr def = NULL;
  3167. xmlRelaxNGTypeLibraryPtr lib = NULL;
  3168. xmlChar *type;
  3169. xmlChar *library;
  3170. int success = 0;
  3171. def = xmlRelaxNGNewDefine(ctxt, node);
  3172. if (def == NULL)
  3173. return (NULL);
  3174. def->type = XML_RELAXNG_VALUE;
  3175. type = xmlGetProp(node, BAD_CAST "type");
  3176. if (type != NULL) {
  3177. xmlRelaxNGNormExtSpace(type);
  3178. if (xmlValidateNCName(type, 0)) {
  3179. xmlRngPErr(ctxt, node, XML_RNGP_TYPE_VALUE,
  3180. "value type '%s' is not an NCName\n", type, NULL);
  3181. }
  3182. library = xmlRelaxNGGetDataTypeLibrary(ctxt, node);
  3183. if (library == NULL)
  3184. library =
  3185. xmlStrdup(BAD_CAST "http://relaxng.org/ns/structure/1.0");
  3186. def->name = type;
  3187. def->ns = library;
  3188. lib = (xmlRelaxNGTypeLibraryPtr)
  3189. xmlHashLookup(xmlRelaxNGRegisteredTypes, library);
  3190. if (lib == NULL) {
  3191. xmlRngPErr(ctxt, node, XML_RNGP_UNKNOWN_TYPE_LIB,
  3192. "Use of unregistered type library '%s'\n", library,
  3193. NULL);
  3194. def->data = NULL;
  3195. } else {
  3196. def->data = lib;
  3197. if (lib->have == NULL) {
  3198. xmlRngPErr(ctxt, node, XML_RNGP_ERROR_TYPE_LIB,
  3199. "Internal error with type library '%s': no 'have'\n",
  3200. library, NULL);
  3201. } else {
  3202. success = lib->have(lib->data, def->name);
  3203. if (success != 1) {
  3204. xmlRngPErr(ctxt, node, XML_RNGP_TYPE_NOT_FOUND,
  3205. "Error type '%s' is not exported by type library '%s'\n",
  3206. def->name, library);
  3207. }
  3208. }
  3209. }
  3210. }
  3211. if (node->children == NULL) {
  3212. def->value = xmlStrdup(BAD_CAST "");
  3213. } else if (((node->children->type != XML_TEXT_NODE) &&
  3214. (node->children->type != XML_CDATA_SECTION_NODE)) ||
  3215. (node->children->next != NULL)) {
  3216. xmlRngPErr(ctxt, node, XML_RNGP_TEXT_EXPECTED,
  3217. "Expecting a single text value for <value>content\n",
  3218. NULL, NULL);
  3219. } else if (def != NULL) {
  3220. def->value = xmlNodeGetContent(node);
  3221. if (def->value == NULL) {
  3222. xmlRngPErr(ctxt, node, XML_RNGP_VALUE_NO_CONTENT,
  3223. "Element <value> has no content\n", NULL, NULL);
  3224. } else if ((lib != NULL) && (lib->check != NULL) && (success == 1)) {
  3225. void *val = NULL;
  3226. success =
  3227. lib->check(lib->data, def->name, def->value, &val, node);
  3228. if (success != 1) {
  3229. xmlRngPErr(ctxt, node, XML_RNGP_INVALID_VALUE,
  3230. "Value '%s' is not acceptable for type '%s'\n",
  3231. def->value, def->name);
  3232. } else {
  3233. if (val != NULL)
  3234. def->attrs = val;
  3235. }
  3236. }
  3237. }
  3238. return (def);
  3239. }
  3240. /**
  3241. * xmlRelaxNGParseData:
  3242. * @ctxt: a Relax-NG parser context
  3243. * @node: the data node.
  3244. *
  3245. * parse the content of a RelaxNG data node.
  3246. *
  3247. * Returns the definition pointer or NULL in case of error
  3248. */
  3249. static xmlRelaxNGDefinePtr
  3250. xmlRelaxNGParseData(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
  3251. {
  3252. xmlRelaxNGDefinePtr def = NULL, except;
  3253. xmlRelaxNGDefinePtr param, lastparam = NULL;
  3254. xmlRelaxNGTypeLibraryPtr lib;
  3255. xmlChar *type;
  3256. xmlChar *library;
  3257. xmlNodePtr content;
  3258. int tmp;
  3259. type = xmlGetProp(node, BAD_CAST "type");
  3260. if (type == NULL) {
  3261. xmlRngPErr(ctxt, node, XML_RNGP_TYPE_MISSING, "data has no type\n", NULL,
  3262. NULL);
  3263. return (NULL);
  3264. }
  3265. xmlRelaxNGNormExtSpace(type);
  3266. if (xmlValidateNCName(type, 0)) {
  3267. xmlRngPErr(ctxt, node, XML_RNGP_TYPE_VALUE,
  3268. "data type '%s' is not an NCName\n", type, NULL);
  3269. }
  3270. library = xmlRelaxNGGetDataTypeLibrary(ctxt, node);
  3271. if (library == NULL)
  3272. library =
  3273. xmlStrdup(BAD_CAST "http://relaxng.org/ns/structure/1.0");
  3274. def = xmlRelaxNGNewDefine(ctxt, node);
  3275. if (def == NULL) {
  3276. xmlFree(library);
  3277. xmlFree(type);
  3278. return (NULL);
  3279. }
  3280. def->type = XML_RELAXNG_DATATYPE;
  3281. def->name = type;
  3282. def->ns = library;
  3283. lib = (xmlRelaxNGTypeLibraryPtr)
  3284. xmlHashLookup(xmlRelaxNGRegisteredTypes, library);
  3285. if (lib == NULL) {
  3286. xmlRngPErr(ctxt, node, XML_RNGP_UNKNOWN_TYPE_LIB,
  3287. "Use of unregistered type library '%s'\n", library,
  3288. NULL);
  3289. def->data = NULL;
  3290. } else {
  3291. def->data = lib;
  3292. if (lib->have == NULL) {
  3293. xmlRngPErr(ctxt, node, XML_RNGP_ERROR_TYPE_LIB,
  3294. "Internal error with type library '%s': no 'have'\n",
  3295. library, NULL);
  3296. } else {
  3297. tmp = lib->have(lib->data, def->name);
  3298. if (tmp != 1) {
  3299. xmlRngPErr(ctxt, node, XML_RNGP_TYPE_NOT_FOUND,
  3300. "Error type '%s' is not exported by type library '%s'\n",
  3301. def->name, library);
  3302. } else
  3303. if ((xmlStrEqual
  3304. (library,
  3305. BAD_CAST
  3306. "http://www.w3.org/2001/XMLSchema-datatypes"))
  3307. && ((xmlStrEqual(def->name, BAD_CAST "IDREF"))
  3308. || (xmlStrEqual(def->name, BAD_CAST "IDREFS")))) {
  3309. ctxt->idref = 1;
  3310. }
  3311. }
  3312. }
  3313. content = node->children;
  3314. /*
  3315. * Handle optional params
  3316. */
  3317. while (content != NULL) {
  3318. if (!xmlStrEqual(content->name, BAD_CAST "param"))
  3319. break;
  3320. if (xmlStrEqual(library,
  3321. BAD_CAST "http://relaxng.org/ns/structure/1.0")) {
  3322. xmlRngPErr(ctxt, node, XML_RNGP_PARAM_FORBIDDEN,
  3323. "Type library '%s' does not allow type parameters\n",
  3324. library, NULL);
  3325. content = content->next;
  3326. while ((content != NULL) &&
  3327. (xmlStrEqual(content->name, BAD_CAST "param")))
  3328. content = content->next;
  3329. } else {
  3330. param = xmlRelaxNGNewDefine(ctxt, node);
  3331. if (param != NULL) {
  3332. param->type = XML_RELAXNG_PARAM;
  3333. param->name = xmlGetProp(content, BAD_CAST "name");
  3334. if (param->name == NULL) {
  3335. xmlRngPErr(ctxt, node, XML_RNGP_PARAM_NAME_MISSING,
  3336. "param has no name\n", NULL, NULL);
  3337. }
  3338. param->value = xmlNodeGetContent(content);
  3339. if (lastparam == NULL) {
  3340. def->attrs = lastparam = param;
  3341. } else {
  3342. lastparam->next = param;
  3343. lastparam = param;
  3344. }
  3345. if (lib != NULL) {
  3346. }
  3347. }
  3348. content = content->next;
  3349. }
  3350. }
  3351. /*
  3352. * Handle optional except
  3353. */
  3354. if ((content != NULL)
  3355. && (xmlStrEqual(content->name, BAD_CAST "except"))) {
  3356. xmlNodePtr child;
  3357. xmlRelaxNGDefinePtr tmp2, last = NULL;
  3358. except = xmlRelaxNGNewDefine(ctxt, node);
  3359. if (except == NULL) {
  3360. return (def);
  3361. }
  3362. except->type = XML_RELAXNG_EXCEPT;
  3363. child = content->children;
  3364. def->content = except;
  3365. if (child == NULL) {
  3366. xmlRngPErr(ctxt, content, XML_RNGP_EXCEPT_NO_CONTENT,
  3367. "except has no content\n", NULL, NULL);
  3368. }
  3369. while (child != NULL) {
  3370. tmp2 = xmlRelaxNGParsePattern(ctxt, child);
  3371. if (tmp2 != NULL) {
  3372. if (last == NULL) {
  3373. except->content = last = tmp2;
  3374. } else {
  3375. last->next = tmp2;
  3376. last = tmp2;
  3377. }
  3378. }
  3379. child = child->next;
  3380. }
  3381. content = content->next;
  3382. }
  3383. /*
  3384. * Check there is no unhandled data
  3385. */
  3386. if (content != NULL) {
  3387. xmlRngPErr(ctxt, content, XML_RNGP_DATA_CONTENT,
  3388. "Element data has unexpected content %s\n",
  3389. content->name, NULL);
  3390. }
  3391. return (def);
  3392. }
  3393. static const xmlChar *invalidName = BAD_CAST "\1";
  3394. /**
  3395. * xmlRelaxNGCompareNameClasses:
  3396. * @defs1: the first element/attribute defs
  3397. * @defs2: the second element/attribute defs
  3398. * @name: the restriction on the name
  3399. * @ns: the restriction on the namespace
  3400. *
  3401. * Compare the 2 lists of element definitions. The comparison is
  3402. * that if both lists do not accept the same QNames, it returns 1
  3403. * If the 2 lists can accept the same QName the comparison returns 0
  3404. *
  3405. * Returns 1 distinct, 0 if equal
  3406. */
  3407. static int
  3408. xmlRelaxNGCompareNameClasses(xmlRelaxNGDefinePtr def1,
  3409. xmlRelaxNGDefinePtr def2)
  3410. {
  3411. int ret = 1;
  3412. xmlNode node;
  3413. xmlNs ns;
  3414. xmlRelaxNGValidCtxt ctxt;
  3415. memset(&ctxt, 0, sizeof(xmlRelaxNGValidCtxt));
  3416. ctxt.flags = FLAGS_IGNORABLE | FLAGS_NOERROR;
  3417. if ((def1->type == XML_RELAXNG_ELEMENT) ||
  3418. (def1->type == XML_RELAXNG_ATTRIBUTE)) {
  3419. if (def2->type == XML_RELAXNG_TEXT)
  3420. return (1);
  3421. if (def1->name != NULL) {
  3422. node.name = def1->name;
  3423. } else {
  3424. node.name = invalidName;
  3425. }
  3426. if (def1->ns != NULL) {
  3427. if (def1->ns[0] == 0) {
  3428. node.ns = NULL;
  3429. } else {
  3430. node.ns = &ns;
  3431. ns.href = def1->ns;
  3432. }
  3433. } else {
  3434. node.ns = NULL;
  3435. }
  3436. if (xmlRelaxNGElementMatch(&ctxt, def2, &node)) {
  3437. if (def1->nameClass != NULL) {
  3438. ret = xmlRelaxNGCompareNameClasses(def1->nameClass, def2);
  3439. } else {
  3440. ret = 0;
  3441. }
  3442. } else {
  3443. ret = 1;
  3444. }
  3445. } else if (def1->type == XML_RELAXNG_TEXT) {
  3446. if (def2->type == XML_RELAXNG_TEXT)
  3447. return (0);
  3448. return (1);
  3449. } else if (def1->type == XML_RELAXNG_EXCEPT) {
  3450. ret = xmlRelaxNGCompareNameClasses(def1->content, def2);
  3451. if (ret == 0)
  3452. ret = 1;
  3453. else if (ret == 1)
  3454. ret = 0;
  3455. } else {
  3456. TODO ret = 0;
  3457. }
  3458. if (ret == 0)
  3459. return (ret);
  3460. if ((def2->type == XML_RELAXNG_ELEMENT) ||
  3461. (def2->type == XML_RELAXNG_ATTRIBUTE)) {
  3462. if (def2->name != NULL) {
  3463. node.name = def2->name;
  3464. } else {
  3465. node.name = invalidName;
  3466. }
  3467. node.ns = &ns;
  3468. if (def2->ns != NULL) {
  3469. if (def2->ns[0] == 0) {
  3470. node.ns = NULL;
  3471. } else {
  3472. ns.href = def2->ns;
  3473. }
  3474. } else {
  3475. ns.href = invalidName;
  3476. }
  3477. if (xmlRelaxNGElementMatch(&ctxt, def1, &node)) {
  3478. if (def2->nameClass != NULL) {
  3479. ret = xmlRelaxNGCompareNameClasses(def2->nameClass, def1);
  3480. } else {
  3481. ret = 0;
  3482. }
  3483. } else {
  3484. ret = 1;
  3485. }
  3486. } else {
  3487. TODO ret = 0;
  3488. }
  3489. return (ret);
  3490. }
  3491. /**
  3492. * xmlRelaxNGCompareElemDefLists:
  3493. * @ctxt: a Relax-NG parser context
  3494. * @defs1: the first list of element/attribute defs
  3495. * @defs2: the second list of element/attribute defs
  3496. *
  3497. * Compare the 2 lists of element or attribute definitions. The comparison
  3498. * is that if both lists do not accept the same QNames, it returns 1
  3499. * If the 2 lists can accept the same QName the comparison returns 0
  3500. *
  3501. * Returns 1 distinct, 0 if equal
  3502. */
  3503. static int
  3504. xmlRelaxNGCompareElemDefLists(xmlRelaxNGParserCtxtPtr ctxt
  3505. ATTRIBUTE_UNUSED, xmlRelaxNGDefinePtr * def1,
  3506. xmlRelaxNGDefinePtr * def2)
  3507. {
  3508. xmlRelaxNGDefinePtr *basedef2 = def2;
  3509. if ((def1 == NULL) || (def2 == NULL))
  3510. return (1);
  3511. if ((*def1 == NULL) || (*def2 == NULL))
  3512. return (1);
  3513. while (*def1 != NULL) {
  3514. while ((*def2) != NULL) {
  3515. if (xmlRelaxNGCompareNameClasses(*def1, *def2) == 0)
  3516. return (0);
  3517. def2++;
  3518. }
  3519. def2 = basedef2;
  3520. def1++;
  3521. }
  3522. return (1);
  3523. }
  3524. /**
  3525. * xmlRelaxNGGenerateAttributes:
  3526. * @ctxt: a Relax-NG parser context
  3527. * @def: the definition definition
  3528. *
  3529. * Check if the definition can only generate attributes
  3530. *
  3531. * Returns 1 if yes, 0 if no and -1 in case of error.
  3532. */
  3533. static int
  3534. xmlRelaxNGGenerateAttributes(xmlRelaxNGParserCtxtPtr ctxt,
  3535. xmlRelaxNGDefinePtr def)
  3536. {
  3537. xmlRelaxNGDefinePtr parent, cur, tmp;
  3538. /*
  3539. * Don't run that check in case of error. Infinite recursion
  3540. * becomes possible.
  3541. */
  3542. if (ctxt->nbErrors != 0)
  3543. return (-1);
  3544. parent = NULL;
  3545. cur = def;
  3546. while (cur != NULL) {
  3547. if ((cur->type == XML_RELAXNG_ELEMENT) ||
  3548. (cur->type == XML_RELAXNG_TEXT) ||
  3549. (cur->type == XML_RELAXNG_DATATYPE) ||
  3550. (cur->type == XML_RELAXNG_PARAM) ||
  3551. (cur->type == XML_RELAXNG_LIST) ||
  3552. (cur->type == XML_RELAXNG_VALUE) ||
  3553. (cur->type == XML_RELAXNG_EMPTY))
  3554. return (0);
  3555. if ((cur->type == XML_RELAXNG_CHOICE) ||
  3556. (cur->type == XML_RELAXNG_INTERLEAVE) ||
  3557. (cur->type == XML_RELAXNG_GROUP) ||
  3558. (cur->type == XML_RELAXNG_ONEORMORE) ||
  3559. (cur->type == XML_RELAXNG_ZEROORMORE) ||
  3560. (cur->type == XML_RELAXNG_OPTIONAL) ||
  3561. (cur->type == XML_RELAXNG_PARENTREF) ||
  3562. (cur->type == XML_RELAXNG_EXTERNALREF) ||
  3563. (cur->type == XML_RELAXNG_REF) ||
  3564. (cur->type == XML_RELAXNG_DEF)) {
  3565. if (cur->content != NULL) {
  3566. parent = cur;
  3567. cur = cur->content;
  3568. tmp = cur;
  3569. while (tmp != NULL) {
  3570. tmp->parent = parent;
  3571. tmp = tmp->next;
  3572. }
  3573. continue;
  3574. }
  3575. }
  3576. if (cur == def)
  3577. break;
  3578. if (cur->next != NULL) {
  3579. cur = cur->next;
  3580. continue;
  3581. }
  3582. do {
  3583. cur = cur->parent;
  3584. if (cur == NULL)
  3585. break;
  3586. if (cur == def)
  3587. return (1);
  3588. if (cur->next != NULL) {
  3589. cur = cur->next;
  3590. break;
  3591. }
  3592. } while (cur != NULL);
  3593. }
  3594. return (1);
  3595. }
  3596. /**
  3597. * xmlRelaxNGGetElements:
  3598. * @ctxt: a Relax-NG parser context
  3599. * @def: the definition definition
  3600. * @eora: gather elements (0), attributes (1) or elements and text (2)
  3601. *
  3602. * Compute the list of top elements a definition can generate
  3603. *
  3604. * Returns a list of elements or NULL if none was found.
  3605. */
  3606. static xmlRelaxNGDefinePtr *
  3607. xmlRelaxNGGetElements(xmlRelaxNGParserCtxtPtr ctxt,
  3608. xmlRelaxNGDefinePtr def, int eora)
  3609. {
  3610. xmlRelaxNGDefinePtr *ret = NULL, parent, cur, tmp;
  3611. int len = 0;
  3612. int max = 0;
  3613. /*
  3614. * Don't run that check in case of error. Infinite recursion
  3615. * becomes possible.
  3616. */
  3617. if (ctxt->nbErrors != 0)
  3618. return (NULL);
  3619. parent = NULL;
  3620. cur = def;
  3621. while (cur != NULL) {
  3622. if (((eora == 0) && ((cur->type == XML_RELAXNG_ELEMENT) ||
  3623. (cur->type == XML_RELAXNG_TEXT))) ||
  3624. ((eora == 1) && (cur->type == XML_RELAXNG_ATTRIBUTE)) ||
  3625. ((eora == 2) && ((cur->type == XML_RELAXNG_DATATYPE) ||
  3626. (cur->type == XML_RELAXNG_ELEMENT) ||
  3627. (cur->type == XML_RELAXNG_LIST) ||
  3628. (cur->type == XML_RELAXNG_TEXT) ||
  3629. (cur->type == XML_RELAXNG_VALUE)))) {
  3630. if (ret == NULL) {
  3631. max = 10;
  3632. ret = (xmlRelaxNGDefinePtr *)
  3633. xmlMalloc((max + 1) * sizeof(xmlRelaxNGDefinePtr));
  3634. if (ret == NULL) {
  3635. xmlRngPErrMemory(ctxt, "getting element list\n");
  3636. return (NULL);
  3637. }
  3638. } else if (max <= len) {
  3639. xmlRelaxNGDefinePtr *temp;
  3640. max *= 2;
  3641. temp = xmlRealloc(ret,
  3642. (max + 1) * sizeof(xmlRelaxNGDefinePtr));
  3643. if (temp == NULL) {
  3644. xmlRngPErrMemory(ctxt, "getting element list\n");
  3645. xmlFree(ret);
  3646. return (NULL);
  3647. }
  3648. ret = temp;
  3649. }
  3650. ret[len++] = cur;
  3651. ret[len] = NULL;
  3652. } else if ((cur->type == XML_RELAXNG_CHOICE) ||
  3653. (cur->type == XML_RELAXNG_INTERLEAVE) ||
  3654. (cur->type == XML_RELAXNG_GROUP) ||
  3655. (cur->type == XML_RELAXNG_ONEORMORE) ||
  3656. (cur->type == XML_RELAXNG_ZEROORMORE) ||
  3657. (cur->type == XML_RELAXNG_OPTIONAL) ||
  3658. (cur->type == XML_RELAXNG_PARENTREF) ||
  3659. (cur->type == XML_RELAXNG_REF) ||
  3660. (cur->type == XML_RELAXNG_DEF) ||
  3661. (cur->type == XML_RELAXNG_EXTERNALREF)) {
  3662. /*
  3663. * Don't go within elements or attributes or string values.
  3664. * Just gather the element top list
  3665. */
  3666. if (cur->content != NULL) {
  3667. parent = cur;
  3668. cur = cur->content;
  3669. tmp = cur;
  3670. while (tmp != NULL) {
  3671. tmp->parent = parent;
  3672. tmp = tmp->next;
  3673. }
  3674. continue;
  3675. }
  3676. }
  3677. if (cur == def)
  3678. break;
  3679. if (cur->next != NULL) {
  3680. cur = cur->next;
  3681. continue;
  3682. }
  3683. do {
  3684. cur = cur->parent;
  3685. if (cur == NULL)
  3686. break;
  3687. if (cur == def)
  3688. return (ret);
  3689. if (cur->next != NULL) {
  3690. cur = cur->next;
  3691. break;
  3692. }
  3693. } while (cur != NULL);
  3694. }
  3695. return (ret);
  3696. }
  3697. /**
  3698. * xmlRelaxNGCheckChoiceDeterminism:
  3699. * @ctxt: a Relax-NG parser context
  3700. * @def: the choice definition
  3701. *
  3702. * Also used to find indeterministic pattern in choice
  3703. */
  3704. static void
  3705. xmlRelaxNGCheckChoiceDeterminism(xmlRelaxNGParserCtxtPtr ctxt,
  3706. xmlRelaxNGDefinePtr def)
  3707. {
  3708. xmlRelaxNGDefinePtr **list;
  3709. xmlRelaxNGDefinePtr cur;
  3710. int nbchild = 0, i, j, ret;
  3711. int is_nullable = 0;
  3712. int is_indeterminist = 0;
  3713. xmlHashTablePtr triage = NULL;
  3714. int is_triable = 1;
  3715. if ((def == NULL) || (def->type != XML_RELAXNG_CHOICE))
  3716. return;
  3717. if (def->dflags & IS_PROCESSED)
  3718. return;
  3719. /*
  3720. * Don't run that check in case of error. Infinite recursion
  3721. * becomes possible.
  3722. */
  3723. if (ctxt->nbErrors != 0)
  3724. return;
  3725. is_nullable = xmlRelaxNGIsNullable(def);
  3726. cur = def->content;
  3727. while (cur != NULL) {
  3728. nbchild++;
  3729. cur = cur->next;
  3730. }
  3731. list = (xmlRelaxNGDefinePtr **) xmlMalloc(nbchild *
  3732. sizeof(xmlRelaxNGDefinePtr
  3733. *));
  3734. if (list == NULL) {
  3735. xmlRngPErrMemory(ctxt, "building choice\n");
  3736. return;
  3737. }
  3738. i = 0;
  3739. /*
  3740. * a bit strong but safe
  3741. */
  3742. if (is_nullable == 0) {
  3743. triage = xmlHashCreate(10);
  3744. } else {
  3745. is_triable = 0;
  3746. }
  3747. cur = def->content;
  3748. while (cur != NULL) {
  3749. list[i] = xmlRelaxNGGetElements(ctxt, cur, 0);
  3750. if ((list[i] == NULL) || (list[i][0] == NULL)) {
  3751. is_triable = 0;
  3752. } else if (is_triable == 1) {
  3753. xmlRelaxNGDefinePtr *tmp;
  3754. int res;
  3755. tmp = list[i];
  3756. while ((*tmp != NULL) && (is_triable == 1)) {
  3757. if ((*tmp)->type == XML_RELAXNG_TEXT) {
  3758. res = xmlHashAddEntry2(triage,
  3759. BAD_CAST "#text", NULL,
  3760. (void *) cur);
  3761. if (res != 0)
  3762. is_triable = -1;
  3763. } else if (((*tmp)->type == XML_RELAXNG_ELEMENT) &&
  3764. ((*tmp)->name != NULL)) {
  3765. if (((*tmp)->ns == NULL) || ((*tmp)->ns[0] == 0))
  3766. res = xmlHashAddEntry2(triage,
  3767. (*tmp)->name, NULL,
  3768. (void *) cur);
  3769. else
  3770. res = xmlHashAddEntry2(triage,
  3771. (*tmp)->name, (*tmp)->ns,
  3772. (void *) cur);
  3773. if (res != 0)
  3774. is_triable = -1;
  3775. } else if ((*tmp)->type == XML_RELAXNG_ELEMENT) {
  3776. if (((*tmp)->ns == NULL) || ((*tmp)->ns[0] == 0))
  3777. res = xmlHashAddEntry2(triage,
  3778. BAD_CAST "#any", NULL,
  3779. (void *) cur);
  3780. else
  3781. res = xmlHashAddEntry2(triage,
  3782. BAD_CAST "#any", (*tmp)->ns,
  3783. (void *) cur);
  3784. if (res != 0)
  3785. is_triable = -1;
  3786. } else {
  3787. is_triable = -1;
  3788. }
  3789. tmp++;
  3790. }
  3791. }
  3792. i++;
  3793. cur = cur->next;
  3794. }
  3795. for (i = 0; i < nbchild; i++) {
  3796. if (list[i] == NULL)
  3797. continue;
  3798. for (j = 0; j < i; j++) {
  3799. if (list[j] == NULL)
  3800. continue;
  3801. ret = xmlRelaxNGCompareElemDefLists(ctxt, list[i], list[j]);
  3802. if (ret == 0) {
  3803. is_indeterminist = 1;
  3804. }
  3805. }
  3806. }
  3807. for (i = 0; i < nbchild; i++) {
  3808. if (list[i] != NULL)
  3809. xmlFree(list[i]);
  3810. }
  3811. xmlFree(list);
  3812. if (is_indeterminist) {
  3813. def->dflags |= IS_INDETERMINIST;
  3814. }
  3815. if (is_triable == 1) {
  3816. def->dflags |= IS_TRIABLE;
  3817. def->data = triage;
  3818. } else if (triage != NULL) {
  3819. xmlHashFree(triage, NULL);
  3820. }
  3821. def->dflags |= IS_PROCESSED;
  3822. }
  3823. /**
  3824. * xmlRelaxNGCheckGroupAttrs:
  3825. * @ctxt: a Relax-NG parser context
  3826. * @def: the group definition
  3827. *
  3828. * Detects violations of rule 7.3
  3829. */
  3830. static void
  3831. xmlRelaxNGCheckGroupAttrs(xmlRelaxNGParserCtxtPtr ctxt,
  3832. xmlRelaxNGDefinePtr def)
  3833. {
  3834. xmlRelaxNGDefinePtr **list;
  3835. xmlRelaxNGDefinePtr cur;
  3836. int nbchild = 0, i, j, ret;
  3837. if ((def == NULL) ||
  3838. ((def->type != XML_RELAXNG_GROUP) &&
  3839. (def->type != XML_RELAXNG_ELEMENT)))
  3840. return;
  3841. if (def->dflags & IS_PROCESSED)
  3842. return;
  3843. /*
  3844. * Don't run that check in case of error. Infinite recursion
  3845. * becomes possible.
  3846. */
  3847. if (ctxt->nbErrors != 0)
  3848. return;
  3849. cur = def->attrs;
  3850. while (cur != NULL) {
  3851. nbchild++;
  3852. cur = cur->next;
  3853. }
  3854. cur = def->content;
  3855. while (cur != NULL) {
  3856. nbchild++;
  3857. cur = cur->next;
  3858. }
  3859. list = (xmlRelaxNGDefinePtr **) xmlMalloc(nbchild *
  3860. sizeof(xmlRelaxNGDefinePtr
  3861. *));
  3862. if (list == NULL) {
  3863. xmlRngPErrMemory(ctxt, "building group\n");
  3864. return;
  3865. }
  3866. i = 0;
  3867. cur = def->attrs;
  3868. while (cur != NULL) {
  3869. list[i] = xmlRelaxNGGetElements(ctxt, cur, 1);
  3870. i++;
  3871. cur = cur->next;
  3872. }
  3873. cur = def->content;
  3874. while (cur != NULL) {
  3875. list[i] = xmlRelaxNGGetElements(ctxt, cur, 1);
  3876. i++;
  3877. cur = cur->next;
  3878. }
  3879. for (i = 0; i < nbchild; i++) {
  3880. if (list[i] == NULL)
  3881. continue;
  3882. for (j = 0; j < i; j++) {
  3883. if (list[j] == NULL)
  3884. continue;
  3885. ret = xmlRelaxNGCompareElemDefLists(ctxt, list[i], list[j]);
  3886. if (ret == 0) {
  3887. xmlRngPErr(ctxt, def->node, XML_RNGP_GROUP_ATTR_CONFLICT,
  3888. "Attributes conflicts in group\n", NULL, NULL);
  3889. }
  3890. }
  3891. }
  3892. for (i = 0; i < nbchild; i++) {
  3893. if (list[i] != NULL)
  3894. xmlFree(list[i]);
  3895. }
  3896. xmlFree(list);
  3897. def->dflags |= IS_PROCESSED;
  3898. }
  3899. /**
  3900. * xmlRelaxNGComputeInterleaves:
  3901. * @def: the interleave definition
  3902. * @ctxt: a Relax-NG parser context
  3903. * @name: the definition name
  3904. *
  3905. * A lot of work for preprocessing interleave definitions
  3906. * is potentially needed to get a decent execution speed at runtime
  3907. * - trying to get a total order on the element nodes generated
  3908. * by the interleaves, order the list of interleave definitions
  3909. * following that order.
  3910. * - if <text/> is used to handle mixed content, it is better to
  3911. * flag this in the define and simplify the runtime checking
  3912. * algorithm
  3913. */
  3914. static void
  3915. xmlRelaxNGComputeInterleaves(void *payload, void *data,
  3916. const xmlChar * name ATTRIBUTE_UNUSED)
  3917. {
  3918. xmlRelaxNGDefinePtr def = (xmlRelaxNGDefinePtr) payload;
  3919. xmlRelaxNGParserCtxtPtr ctxt = (xmlRelaxNGParserCtxtPtr) data;
  3920. xmlRelaxNGDefinePtr cur, *tmp;
  3921. xmlRelaxNGPartitionPtr partitions = NULL;
  3922. xmlRelaxNGInterleaveGroupPtr *groups = NULL;
  3923. xmlRelaxNGInterleaveGroupPtr group;
  3924. int i, j, ret, res;
  3925. int nbgroups = 0;
  3926. int nbchild = 0;
  3927. int is_mixed = 0;
  3928. int is_determinist = 1;
  3929. /*
  3930. * Don't run that check in case of error. Infinite recursion
  3931. * becomes possible.
  3932. */
  3933. if (ctxt->nbErrors != 0)
  3934. return;
  3935. cur = def->content;
  3936. while (cur != NULL) {
  3937. nbchild++;
  3938. cur = cur->next;
  3939. }
  3940. groups = (xmlRelaxNGInterleaveGroupPtr *)
  3941. xmlMalloc(nbchild * sizeof(xmlRelaxNGInterleaveGroupPtr));
  3942. if (groups == NULL)
  3943. goto error;
  3944. cur = def->content;
  3945. while (cur != NULL) {
  3946. groups[nbgroups] = (xmlRelaxNGInterleaveGroupPtr)
  3947. xmlMalloc(sizeof(xmlRelaxNGInterleaveGroup));
  3948. if (groups[nbgroups] == NULL)
  3949. goto error;
  3950. if (cur->type == XML_RELAXNG_TEXT)
  3951. is_mixed++;
  3952. groups[nbgroups]->rule = cur;
  3953. groups[nbgroups]->defs = xmlRelaxNGGetElements(ctxt, cur, 2);
  3954. groups[nbgroups]->attrs = xmlRelaxNGGetElements(ctxt, cur, 1);
  3955. nbgroups++;
  3956. cur = cur->next;
  3957. }
  3958. /*
  3959. * Let's check that all rules makes a partitions according to 7.4
  3960. */
  3961. partitions = (xmlRelaxNGPartitionPtr)
  3962. xmlMalloc(sizeof(xmlRelaxNGPartition));
  3963. if (partitions == NULL)
  3964. goto error;
  3965. memset(partitions, 0, sizeof(xmlRelaxNGPartition));
  3966. partitions->nbgroups = nbgroups;
  3967. partitions->triage = xmlHashCreate(nbgroups);
  3968. for (i = 0; i < nbgroups; i++) {
  3969. group = groups[i];
  3970. for (j = i + 1; j < nbgroups; j++) {
  3971. if (groups[j] == NULL)
  3972. continue;
  3973. ret = xmlRelaxNGCompareElemDefLists(ctxt, group->defs,
  3974. groups[j]->defs);
  3975. if (ret == 0) {
  3976. xmlRngPErr(ctxt, def->node, XML_RNGP_ELEM_TEXT_CONFLICT,
  3977. "Element or text conflicts in interleave\n",
  3978. NULL, NULL);
  3979. }
  3980. ret = xmlRelaxNGCompareElemDefLists(ctxt, group->attrs,
  3981. groups[j]->attrs);
  3982. if (ret == 0) {
  3983. xmlRngPErr(ctxt, def->node, XML_RNGP_ATTR_CONFLICT,
  3984. "Attributes conflicts in interleave\n", NULL,
  3985. NULL);
  3986. }
  3987. }
  3988. tmp = group->defs;
  3989. if ((tmp != NULL) && (*tmp != NULL)) {
  3990. while (*tmp != NULL) {
  3991. if ((*tmp)->type == XML_RELAXNG_TEXT) {
  3992. res = xmlHashAddEntry2(partitions->triage,
  3993. BAD_CAST "#text", NULL,
  3994. (void *) (ptrdiff_t) (i + 1));
  3995. if (res != 0)
  3996. is_determinist = -1;
  3997. } else if (((*tmp)->type == XML_RELAXNG_ELEMENT) &&
  3998. ((*tmp)->name != NULL)) {
  3999. if (((*tmp)->ns == NULL) || ((*tmp)->ns[0] == 0))
  4000. res = xmlHashAddEntry2(partitions->triage,
  4001. (*tmp)->name, NULL,
  4002. (void *) (ptrdiff_t) (i + 1));
  4003. else
  4004. res = xmlHashAddEntry2(partitions->triage,
  4005. (*tmp)->name, (*tmp)->ns,
  4006. (void *) (ptrdiff_t) (i + 1));
  4007. if (res != 0)
  4008. is_determinist = -1;
  4009. } else if ((*tmp)->type == XML_RELAXNG_ELEMENT) {
  4010. if (((*tmp)->ns == NULL) || ((*tmp)->ns[0] == 0))
  4011. res = xmlHashAddEntry2(partitions->triage,
  4012. BAD_CAST "#any", NULL,
  4013. (void *) (ptrdiff_t) (i + 1));
  4014. else
  4015. res = xmlHashAddEntry2(partitions->triage,
  4016. BAD_CAST "#any", (*tmp)->ns,
  4017. (void *) (ptrdiff_t) (i + 1));
  4018. if ((*tmp)->nameClass != NULL)
  4019. is_determinist = 2;
  4020. if (res != 0)
  4021. is_determinist = -1;
  4022. } else {
  4023. is_determinist = -1;
  4024. }
  4025. tmp++;
  4026. }
  4027. } else {
  4028. is_determinist = 0;
  4029. }
  4030. }
  4031. partitions->groups = groups;
  4032. /*
  4033. * and save the partition list back in the def
  4034. */
  4035. def->data = partitions;
  4036. if (is_mixed != 0)
  4037. def->dflags |= IS_MIXED;
  4038. if (is_determinist == 1)
  4039. partitions->flags = IS_DETERMINIST;
  4040. if (is_determinist == 2)
  4041. partitions->flags = IS_DETERMINIST | IS_NEEDCHECK;
  4042. return;
  4043. error:
  4044. xmlRngPErrMemory(ctxt, "in interleave computation\n");
  4045. if (groups != NULL) {
  4046. for (i = 0; i < nbgroups; i++)
  4047. if (groups[i] != NULL) {
  4048. if (groups[i]->defs != NULL)
  4049. xmlFree(groups[i]->defs);
  4050. xmlFree(groups[i]);
  4051. }
  4052. xmlFree(groups);
  4053. }
  4054. xmlRelaxNGFreePartition(partitions);
  4055. }
  4056. /**
  4057. * xmlRelaxNGParseInterleave:
  4058. * @ctxt: a Relax-NG parser context
  4059. * @node: the data node.
  4060. *
  4061. * parse the content of a RelaxNG interleave node.
  4062. *
  4063. * Returns the definition pointer or NULL in case of error
  4064. */
  4065. static xmlRelaxNGDefinePtr
  4066. xmlRelaxNGParseInterleave(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
  4067. {
  4068. xmlRelaxNGDefinePtr def = NULL;
  4069. xmlRelaxNGDefinePtr last = NULL, cur;
  4070. xmlNodePtr child;
  4071. def = xmlRelaxNGNewDefine(ctxt, node);
  4072. if (def == NULL) {
  4073. return (NULL);
  4074. }
  4075. def->type = XML_RELAXNG_INTERLEAVE;
  4076. if (ctxt->interleaves == NULL)
  4077. ctxt->interleaves = xmlHashCreate(10);
  4078. if (ctxt->interleaves == NULL) {
  4079. xmlRngPErrMemory(ctxt, "create interleaves\n");
  4080. } else {
  4081. char name[32];
  4082. snprintf(name, 32, "interleave%d", ctxt->nbInterleaves++);
  4083. if (xmlHashAddEntry(ctxt->interleaves, BAD_CAST name, def) < 0) {
  4084. xmlRngPErr(ctxt, node, XML_RNGP_INTERLEAVE_ADD,
  4085. "Failed to add %s to hash table\n",
  4086. (const xmlChar *) name, NULL);
  4087. }
  4088. }
  4089. child = node->children;
  4090. if (child == NULL) {
  4091. xmlRngPErr(ctxt, node, XML_RNGP_INTERLEAVE_NO_CONTENT,
  4092. "Element interleave is empty\n", NULL, NULL);
  4093. }
  4094. while (child != NULL) {
  4095. if (IS_RELAXNG(child, "element")) {
  4096. cur = xmlRelaxNGParseElement(ctxt, child);
  4097. } else {
  4098. cur = xmlRelaxNGParsePattern(ctxt, child);
  4099. }
  4100. if (cur != NULL) {
  4101. cur->parent = def;
  4102. if (last == NULL) {
  4103. def->content = last = cur;
  4104. } else {
  4105. last->next = cur;
  4106. last = cur;
  4107. }
  4108. }
  4109. child = child->next;
  4110. }
  4111. return (def);
  4112. }
  4113. /**
  4114. * xmlRelaxNGParseInclude:
  4115. * @ctxt: a Relax-NG parser context
  4116. * @node: the include node
  4117. *
  4118. * Integrate the content of an include node in the current grammar
  4119. *
  4120. * Returns 0 in case of success or -1 in case of error
  4121. */
  4122. static int
  4123. xmlRelaxNGParseInclude(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
  4124. {
  4125. xmlRelaxNGIncludePtr incl;
  4126. xmlNodePtr root;
  4127. int ret = 0, tmp;
  4128. incl = node->psvi;
  4129. if (incl == NULL) {
  4130. xmlRngPErr(ctxt, node, XML_RNGP_INCLUDE_EMPTY,
  4131. "Include node has no data\n", NULL, NULL);
  4132. return (-1);
  4133. }
  4134. root = xmlDocGetRootElement(incl->doc);
  4135. if (root == NULL) {
  4136. xmlRngPErr(ctxt, node, XML_RNGP_EMPTY, "Include document is empty\n",
  4137. NULL, NULL);
  4138. return (-1);
  4139. }
  4140. if (!xmlStrEqual(root->name, BAD_CAST "grammar")) {
  4141. xmlRngPErr(ctxt, node, XML_RNGP_GRAMMAR_MISSING,
  4142. "Include document root is not a grammar\n", NULL, NULL);
  4143. return (-1);
  4144. }
  4145. /*
  4146. * Merge the definition from both the include and the internal list
  4147. */
  4148. if (root->children != NULL) {
  4149. tmp = xmlRelaxNGParseGrammarContent(ctxt, root->children);
  4150. if (tmp != 0)
  4151. ret = -1;
  4152. }
  4153. if (node->children != NULL) {
  4154. tmp = xmlRelaxNGParseGrammarContent(ctxt, node->children);
  4155. if (tmp != 0)
  4156. ret = -1;
  4157. }
  4158. return (ret);
  4159. }
  4160. /**
  4161. * xmlRelaxNGParseDefine:
  4162. * @ctxt: a Relax-NG parser context
  4163. * @node: the define node
  4164. *
  4165. * parse the content of a RelaxNG define element node.
  4166. *
  4167. * Returns 0 in case of success or -1 in case of error
  4168. */
  4169. static int
  4170. xmlRelaxNGParseDefine(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
  4171. {
  4172. xmlChar *name;
  4173. int ret = 0, tmp;
  4174. xmlRelaxNGDefinePtr def;
  4175. const xmlChar *olddefine;
  4176. name = xmlGetProp(node, BAD_CAST "name");
  4177. if (name == NULL) {
  4178. xmlRngPErr(ctxt, node, XML_RNGP_DEFINE_NAME_MISSING,
  4179. "define has no name\n", NULL, NULL);
  4180. } else {
  4181. xmlRelaxNGNormExtSpace(name);
  4182. if (xmlValidateNCName(name, 0)) {
  4183. xmlRngPErr(ctxt, node, XML_RNGP_INVALID_DEFINE_NAME,
  4184. "define name '%s' is not an NCName\n", name, NULL);
  4185. }
  4186. def = xmlRelaxNGNewDefine(ctxt, node);
  4187. if (def == NULL) {
  4188. xmlFree(name);
  4189. return (-1);
  4190. }
  4191. def->type = XML_RELAXNG_DEF;
  4192. def->name = name;
  4193. if (node->children == NULL) {
  4194. xmlRngPErr(ctxt, node, XML_RNGP_DEFINE_EMPTY,
  4195. "define has no children\n", NULL, NULL);
  4196. } else {
  4197. olddefine = ctxt->define;
  4198. ctxt->define = name;
  4199. def->content =
  4200. xmlRelaxNGParsePatterns(ctxt, node->children, 0);
  4201. ctxt->define = olddefine;
  4202. }
  4203. if (ctxt->grammar->defs == NULL)
  4204. ctxt->grammar->defs = xmlHashCreate(10);
  4205. if (ctxt->grammar->defs == NULL) {
  4206. xmlRngPErr(ctxt, node, XML_RNGP_DEFINE_CREATE_FAILED,
  4207. "Could not create definition hash\n", NULL, NULL);
  4208. ret = -1;
  4209. } else {
  4210. tmp = xmlHashAddEntry(ctxt->grammar->defs, name, def);
  4211. if (tmp < 0) {
  4212. xmlRelaxNGDefinePtr prev;
  4213. prev = xmlHashLookup(ctxt->grammar->defs, name);
  4214. if (prev == NULL) {
  4215. xmlRngPErr(ctxt, node, XML_RNGP_DEFINE_CREATE_FAILED,
  4216. "Internal error on define aggregation of %s\n",
  4217. name, NULL);
  4218. ret = -1;
  4219. } else {
  4220. while (prev->nextHash != NULL)
  4221. prev = prev->nextHash;
  4222. prev->nextHash = def;
  4223. }
  4224. }
  4225. }
  4226. }
  4227. return (ret);
  4228. }
  4229. /**
  4230. * xmlRelaxNGParseImportRef:
  4231. * @payload: the parser context
  4232. * @data: the current grammar
  4233. * @name: the reference name
  4234. *
  4235. * Import import one references into the current grammar
  4236. */
  4237. static void
  4238. xmlRelaxNGParseImportRef(void *payload, void *data, const xmlChar *name) {
  4239. xmlRelaxNGParserCtxtPtr ctxt = (xmlRelaxNGParserCtxtPtr) data;
  4240. xmlRelaxNGDefinePtr def = (xmlRelaxNGDefinePtr) payload;
  4241. int tmp;
  4242. def->dflags |= IS_EXTERNAL_REF;
  4243. tmp = xmlHashAddEntry(ctxt->grammar->refs, name, def);
  4244. if (tmp < 0) {
  4245. xmlRelaxNGDefinePtr prev;
  4246. prev = (xmlRelaxNGDefinePtr)
  4247. xmlHashLookup(ctxt->grammar->refs, def->name);
  4248. if (prev == NULL) {
  4249. if (def->name != NULL) {
  4250. xmlRngPErr(ctxt, NULL, XML_RNGP_REF_CREATE_FAILED,
  4251. "Error refs definitions '%s'\n",
  4252. def->name, NULL);
  4253. } else {
  4254. xmlRngPErr(ctxt, NULL, XML_RNGP_REF_CREATE_FAILED,
  4255. "Error refs definitions\n",
  4256. NULL, NULL);
  4257. }
  4258. } else {
  4259. def->nextHash = prev->nextHash;
  4260. prev->nextHash = def;
  4261. }
  4262. }
  4263. }
  4264. /**
  4265. * xmlRelaxNGParseImportRefs:
  4266. * @ctxt: the parser context
  4267. * @grammar: the sub grammar
  4268. *
  4269. * Import references from the subgrammar into the current grammar
  4270. *
  4271. * Returns 0 in case of success, -1 in case of failure
  4272. */
  4273. static int
  4274. xmlRelaxNGParseImportRefs(xmlRelaxNGParserCtxtPtr ctxt,
  4275. xmlRelaxNGGrammarPtr grammar) {
  4276. if ((ctxt == NULL) || (grammar == NULL) || (ctxt->grammar == NULL))
  4277. return(-1);
  4278. if (grammar->refs == NULL)
  4279. return(0);
  4280. if (ctxt->grammar->refs == NULL)
  4281. ctxt->grammar->refs = xmlHashCreate(10);
  4282. if (ctxt->grammar->refs == NULL) {
  4283. xmlRngPErr(ctxt, NULL, XML_RNGP_REF_CREATE_FAILED,
  4284. "Could not create references hash\n", NULL, NULL);
  4285. return(-1);
  4286. }
  4287. xmlHashScan(grammar->refs, xmlRelaxNGParseImportRef, ctxt);
  4288. return(0);
  4289. }
  4290. /**
  4291. * xmlRelaxNGProcessExternalRef:
  4292. * @ctxt: the parser context
  4293. * @node: the externalRef node
  4294. *
  4295. * Process and compile an externalRef node
  4296. *
  4297. * Returns the xmlRelaxNGDefinePtr or NULL in case of error
  4298. */
  4299. static xmlRelaxNGDefinePtr
  4300. xmlRelaxNGProcessExternalRef(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
  4301. {
  4302. xmlRelaxNGDocumentPtr docu;
  4303. xmlNodePtr root, tmp;
  4304. xmlChar *ns;
  4305. int newNs = 0, oldflags;
  4306. xmlRelaxNGDefinePtr def;
  4307. docu = node->psvi;
  4308. if (docu != NULL) {
  4309. def = xmlRelaxNGNewDefine(ctxt, node);
  4310. if (def == NULL)
  4311. return (NULL);
  4312. def->type = XML_RELAXNG_EXTERNALREF;
  4313. if (docu->content == NULL) {
  4314. /*
  4315. * Then do the parsing for good
  4316. */
  4317. root = xmlDocGetRootElement(docu->doc);
  4318. if (root == NULL) {
  4319. xmlRngPErr(ctxt, node, XML_RNGP_EXTERNALREF_EMTPY,
  4320. "xmlRelaxNGParse: %s is empty\n", ctxt->URL,
  4321. NULL);
  4322. return (NULL);
  4323. }
  4324. /*
  4325. * ns transmission rules
  4326. */
  4327. ns = xmlGetProp(root, BAD_CAST "ns");
  4328. if (ns == NULL) {
  4329. tmp = node;
  4330. while ((tmp != NULL) && (tmp->type == XML_ELEMENT_NODE)) {
  4331. ns = xmlGetProp(tmp, BAD_CAST "ns");
  4332. if (ns != NULL) {
  4333. break;
  4334. }
  4335. tmp = tmp->parent;
  4336. }
  4337. if (ns != NULL) {
  4338. xmlSetProp(root, BAD_CAST "ns", ns);
  4339. newNs = 1;
  4340. xmlFree(ns);
  4341. }
  4342. } else {
  4343. xmlFree(ns);
  4344. }
  4345. /*
  4346. * Parsing to get a precompiled schemas.
  4347. */
  4348. oldflags = ctxt->flags;
  4349. ctxt->flags |= XML_RELAXNG_IN_EXTERNALREF;
  4350. docu->schema = xmlRelaxNGParseDocument(ctxt, root);
  4351. ctxt->flags = oldflags;
  4352. if ((docu->schema != NULL) &&
  4353. (docu->schema->topgrammar != NULL)) {
  4354. docu->content = docu->schema->topgrammar->start;
  4355. if (docu->schema->topgrammar->refs)
  4356. xmlRelaxNGParseImportRefs(ctxt, docu->schema->topgrammar);
  4357. }
  4358. /*
  4359. * the externalRef may be reused in a different ns context
  4360. */
  4361. if (newNs == 1) {
  4362. xmlUnsetProp(root, BAD_CAST "ns");
  4363. }
  4364. }
  4365. def->content = docu->content;
  4366. } else {
  4367. def = NULL;
  4368. }
  4369. return (def);
  4370. }
  4371. /**
  4372. * xmlRelaxNGParsePattern:
  4373. * @ctxt: a Relax-NG parser context
  4374. * @node: the pattern node.
  4375. *
  4376. * parse the content of a RelaxNG pattern node.
  4377. *
  4378. * Returns the definition pointer or NULL in case of error or if no
  4379. * pattern is generated.
  4380. */
  4381. static xmlRelaxNGDefinePtr
  4382. xmlRelaxNGParsePattern(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
  4383. {
  4384. xmlRelaxNGDefinePtr def = NULL;
  4385. if (node == NULL) {
  4386. return (NULL);
  4387. }
  4388. if (IS_RELAXNG(node, "element")) {
  4389. def = xmlRelaxNGParseElement(ctxt, node);
  4390. } else if (IS_RELAXNG(node, "attribute")) {
  4391. def = xmlRelaxNGParseAttribute(ctxt, node);
  4392. } else if (IS_RELAXNG(node, "empty")) {
  4393. def = xmlRelaxNGNewDefine(ctxt, node);
  4394. if (def == NULL)
  4395. return (NULL);
  4396. def->type = XML_RELAXNG_EMPTY;
  4397. if (node->children != NULL) {
  4398. xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_NOT_EMPTY,
  4399. "empty: had a child node\n", NULL, NULL);
  4400. }
  4401. } else if (IS_RELAXNG(node, "text")) {
  4402. def = xmlRelaxNGNewDefine(ctxt, node);
  4403. if (def == NULL)
  4404. return (NULL);
  4405. def->type = XML_RELAXNG_TEXT;
  4406. if (node->children != NULL) {
  4407. xmlRngPErr(ctxt, node, XML_RNGP_TEXT_HAS_CHILD,
  4408. "text: had a child node\n", NULL, NULL);
  4409. }
  4410. } else if (IS_RELAXNG(node, "zeroOrMore")) {
  4411. def = xmlRelaxNGNewDefine(ctxt, node);
  4412. if (def == NULL)
  4413. return (NULL);
  4414. def->type = XML_RELAXNG_ZEROORMORE;
  4415. if (node->children == NULL) {
  4416. xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
  4417. "Element %s is empty\n", node->name, NULL);
  4418. } else {
  4419. def->content =
  4420. xmlRelaxNGParsePatterns(ctxt, node->children, 1);
  4421. }
  4422. } else if (IS_RELAXNG(node, "oneOrMore")) {
  4423. def = xmlRelaxNGNewDefine(ctxt, node);
  4424. if (def == NULL)
  4425. return (NULL);
  4426. def->type = XML_RELAXNG_ONEORMORE;
  4427. if (node->children == NULL) {
  4428. xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
  4429. "Element %s is empty\n", node->name, NULL);
  4430. } else {
  4431. def->content =
  4432. xmlRelaxNGParsePatterns(ctxt, node->children, 1);
  4433. }
  4434. } else if (IS_RELAXNG(node, "optional")) {
  4435. def = xmlRelaxNGNewDefine(ctxt, node);
  4436. if (def == NULL)
  4437. return (NULL);
  4438. def->type = XML_RELAXNG_OPTIONAL;
  4439. if (node->children == NULL) {
  4440. xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
  4441. "Element %s is empty\n", node->name, NULL);
  4442. } else {
  4443. def->content =
  4444. xmlRelaxNGParsePatterns(ctxt, node->children, 1);
  4445. }
  4446. } else if (IS_RELAXNG(node, "choice")) {
  4447. def = xmlRelaxNGNewDefine(ctxt, node);
  4448. if (def == NULL)
  4449. return (NULL);
  4450. def->type = XML_RELAXNG_CHOICE;
  4451. if (node->children == NULL) {
  4452. xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
  4453. "Element %s is empty\n", node->name, NULL);
  4454. } else {
  4455. def->content =
  4456. xmlRelaxNGParsePatterns(ctxt, node->children, 0);
  4457. }
  4458. } else if (IS_RELAXNG(node, "group")) {
  4459. def = xmlRelaxNGNewDefine(ctxt, node);
  4460. if (def == NULL)
  4461. return (NULL);
  4462. def->type = XML_RELAXNG_GROUP;
  4463. if (node->children == NULL) {
  4464. xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
  4465. "Element %s is empty\n", node->name, NULL);
  4466. } else {
  4467. def->content =
  4468. xmlRelaxNGParsePatterns(ctxt, node->children, 0);
  4469. }
  4470. } else if (IS_RELAXNG(node, "ref")) {
  4471. def = xmlRelaxNGNewDefine(ctxt, node);
  4472. if (def == NULL)
  4473. return (NULL);
  4474. def->type = XML_RELAXNG_REF;
  4475. def->name = xmlGetProp(node, BAD_CAST "name");
  4476. if (def->name == NULL) {
  4477. xmlRngPErr(ctxt, node, XML_RNGP_REF_NO_NAME, "ref has no name\n",
  4478. NULL, NULL);
  4479. } else {
  4480. xmlRelaxNGNormExtSpace(def->name);
  4481. if (xmlValidateNCName(def->name, 0)) {
  4482. xmlRngPErr(ctxt, node, XML_RNGP_REF_NAME_INVALID,
  4483. "ref name '%s' is not an NCName\n", def->name,
  4484. NULL);
  4485. }
  4486. }
  4487. if (node->children != NULL) {
  4488. xmlRngPErr(ctxt, node, XML_RNGP_REF_NOT_EMPTY, "ref is not empty\n",
  4489. NULL, NULL);
  4490. }
  4491. if (ctxt->grammar->refs == NULL)
  4492. ctxt->grammar->refs = xmlHashCreate(10);
  4493. if (ctxt->grammar->refs == NULL) {
  4494. xmlRngPErr(ctxt, node, XML_RNGP_REF_CREATE_FAILED,
  4495. "Could not create references hash\n", NULL, NULL);
  4496. def = NULL;
  4497. } else {
  4498. int tmp;
  4499. tmp = xmlHashAddEntry(ctxt->grammar->refs, def->name, def);
  4500. if (tmp < 0) {
  4501. xmlRelaxNGDefinePtr prev;
  4502. prev = (xmlRelaxNGDefinePtr)
  4503. xmlHashLookup(ctxt->grammar->refs, def->name);
  4504. if (prev == NULL) {
  4505. if (def->name != NULL) {
  4506. xmlRngPErr(ctxt, node, XML_RNGP_REF_CREATE_FAILED,
  4507. "Error refs definitions '%s'\n",
  4508. def->name, NULL);
  4509. } else {
  4510. xmlRngPErr(ctxt, node, XML_RNGP_REF_CREATE_FAILED,
  4511. "Error refs definitions\n",
  4512. NULL, NULL);
  4513. }
  4514. def = NULL;
  4515. } else {
  4516. def->nextHash = prev->nextHash;
  4517. prev->nextHash = def;
  4518. }
  4519. }
  4520. }
  4521. } else if (IS_RELAXNG(node, "data")) {
  4522. def = xmlRelaxNGParseData(ctxt, node);
  4523. } else if (IS_RELAXNG(node, "value")) {
  4524. def = xmlRelaxNGParseValue(ctxt, node);
  4525. } else if (IS_RELAXNG(node, "list")) {
  4526. def = xmlRelaxNGNewDefine(ctxt, node);
  4527. if (def == NULL)
  4528. return (NULL);
  4529. def->type = XML_RELAXNG_LIST;
  4530. if (node->children == NULL) {
  4531. xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT,
  4532. "Element %s is empty\n", node->name, NULL);
  4533. } else {
  4534. def->content =
  4535. xmlRelaxNGParsePatterns(ctxt, node->children, 0);
  4536. }
  4537. } else if (IS_RELAXNG(node, "interleave")) {
  4538. def = xmlRelaxNGParseInterleave(ctxt, node);
  4539. } else if (IS_RELAXNG(node, "externalRef")) {
  4540. def = xmlRelaxNGProcessExternalRef(ctxt, node);
  4541. } else if (IS_RELAXNG(node, "notAllowed")) {
  4542. def = xmlRelaxNGNewDefine(ctxt, node);
  4543. if (def == NULL)
  4544. return (NULL);
  4545. def->type = XML_RELAXNG_NOT_ALLOWED;
  4546. if (node->children != NULL) {
  4547. xmlRngPErr(ctxt, node, XML_RNGP_NOTALLOWED_NOT_EMPTY,
  4548. "xmlRelaxNGParse: notAllowed element is not empty\n",
  4549. NULL, NULL);
  4550. }
  4551. } else if (IS_RELAXNG(node, "grammar")) {
  4552. xmlRelaxNGGrammarPtr grammar, old;
  4553. xmlRelaxNGGrammarPtr oldparent;
  4554. oldparent = ctxt->parentgrammar;
  4555. old = ctxt->grammar;
  4556. ctxt->parentgrammar = old;
  4557. grammar = xmlRelaxNGParseGrammar(ctxt, node->children);
  4558. if (old != NULL) {
  4559. ctxt->grammar = old;
  4560. ctxt->parentgrammar = oldparent;
  4561. #if 0
  4562. if (grammar != NULL) {
  4563. grammar->next = old->next;
  4564. old->next = grammar;
  4565. }
  4566. #endif
  4567. }
  4568. if (grammar != NULL)
  4569. def = grammar->start;
  4570. else
  4571. def = NULL;
  4572. } else if (IS_RELAXNG(node, "parentRef")) {
  4573. if (ctxt->parentgrammar == NULL) {
  4574. xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_NO_PARENT,
  4575. "Use of parentRef without a parent grammar\n", NULL,
  4576. NULL);
  4577. return (NULL);
  4578. }
  4579. def = xmlRelaxNGNewDefine(ctxt, node);
  4580. if (def == NULL)
  4581. return (NULL);
  4582. def->type = XML_RELAXNG_PARENTREF;
  4583. def->name = xmlGetProp(node, BAD_CAST "name");
  4584. if (def->name == NULL) {
  4585. xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_NO_NAME,
  4586. "parentRef has no name\n", NULL, NULL);
  4587. } else {
  4588. xmlRelaxNGNormExtSpace(def->name);
  4589. if (xmlValidateNCName(def->name, 0)) {
  4590. xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_NAME_INVALID,
  4591. "parentRef name '%s' is not an NCName\n",
  4592. def->name, NULL);
  4593. }
  4594. }
  4595. if (node->children != NULL) {
  4596. xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_NOT_EMPTY,
  4597. "parentRef is not empty\n", NULL, NULL);
  4598. }
  4599. if (ctxt->parentgrammar->refs == NULL)
  4600. ctxt->parentgrammar->refs = xmlHashCreate(10);
  4601. if (ctxt->parentgrammar->refs == NULL) {
  4602. xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_CREATE_FAILED,
  4603. "Could not create references hash\n", NULL, NULL);
  4604. def = NULL;
  4605. } else if (def->name != NULL) {
  4606. int tmp;
  4607. tmp =
  4608. xmlHashAddEntry(ctxt->parentgrammar->refs, def->name, def);
  4609. if (tmp < 0) {
  4610. xmlRelaxNGDefinePtr prev;
  4611. prev = (xmlRelaxNGDefinePtr)
  4612. xmlHashLookup(ctxt->parentgrammar->refs, def->name);
  4613. if (prev == NULL) {
  4614. xmlRngPErr(ctxt, node, XML_RNGP_PARENTREF_CREATE_FAILED,
  4615. "Internal error parentRef definitions '%s'\n",
  4616. def->name, NULL);
  4617. def = NULL;
  4618. } else {
  4619. def->nextHash = prev->nextHash;
  4620. prev->nextHash = def;
  4621. }
  4622. }
  4623. }
  4624. } else if (IS_RELAXNG(node, "mixed")) {
  4625. if (node->children == NULL) {
  4626. xmlRngPErr(ctxt, node, XML_RNGP_EMPTY_CONSTRUCT, "Mixed is empty\n",
  4627. NULL, NULL);
  4628. def = NULL;
  4629. } else {
  4630. def = xmlRelaxNGParseInterleave(ctxt, node);
  4631. if (def != NULL) {
  4632. xmlRelaxNGDefinePtr tmp;
  4633. if ((def->content != NULL) && (def->content->next != NULL)) {
  4634. tmp = xmlRelaxNGNewDefine(ctxt, node);
  4635. if (tmp != NULL) {
  4636. tmp->type = XML_RELAXNG_GROUP;
  4637. tmp->content = def->content;
  4638. def->content = tmp;
  4639. }
  4640. }
  4641. tmp = xmlRelaxNGNewDefine(ctxt, node);
  4642. if (tmp == NULL)
  4643. return (def);
  4644. tmp->type = XML_RELAXNG_TEXT;
  4645. tmp->next = def->content;
  4646. def->content = tmp;
  4647. }
  4648. }
  4649. } else {
  4650. xmlRngPErr(ctxt, node, XML_RNGP_UNKNOWN_CONSTRUCT,
  4651. "Unexpected node %s is not a pattern\n", node->name,
  4652. NULL);
  4653. def = NULL;
  4654. }
  4655. return (def);
  4656. }
  4657. /**
  4658. * xmlRelaxNGParseAttribute:
  4659. * @ctxt: a Relax-NG parser context
  4660. * @node: the element node
  4661. *
  4662. * parse the content of a RelaxNG attribute node.
  4663. *
  4664. * Returns the definition pointer or NULL in case of error.
  4665. */
  4666. static xmlRelaxNGDefinePtr
  4667. xmlRelaxNGParseAttribute(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
  4668. {
  4669. xmlRelaxNGDefinePtr ret, cur;
  4670. xmlNodePtr child;
  4671. int old_flags;
  4672. ret = xmlRelaxNGNewDefine(ctxt, node);
  4673. if (ret == NULL)
  4674. return (NULL);
  4675. ret->type = XML_RELAXNG_ATTRIBUTE;
  4676. ret->parent = ctxt->def;
  4677. child = node->children;
  4678. if (child == NULL) {
  4679. xmlRngPErr(ctxt, node, XML_RNGP_ATTRIBUTE_EMPTY,
  4680. "xmlRelaxNGParseattribute: attribute has no children\n",
  4681. NULL, NULL);
  4682. return (ret);
  4683. }
  4684. old_flags = ctxt->flags;
  4685. ctxt->flags |= XML_RELAXNG_IN_ATTRIBUTE;
  4686. cur = xmlRelaxNGParseNameClass(ctxt, child, ret);
  4687. if (cur != NULL)
  4688. child = child->next;
  4689. if (child != NULL) {
  4690. cur = xmlRelaxNGParsePattern(ctxt, child);
  4691. if (cur != NULL) {
  4692. switch (cur->type) {
  4693. case XML_RELAXNG_EMPTY:
  4694. case XML_RELAXNG_NOT_ALLOWED:
  4695. case XML_RELAXNG_TEXT:
  4696. case XML_RELAXNG_ELEMENT:
  4697. case XML_RELAXNG_DATATYPE:
  4698. case XML_RELAXNG_VALUE:
  4699. case XML_RELAXNG_LIST:
  4700. case XML_RELAXNG_REF:
  4701. case XML_RELAXNG_PARENTREF:
  4702. case XML_RELAXNG_EXTERNALREF:
  4703. case XML_RELAXNG_DEF:
  4704. case XML_RELAXNG_ONEORMORE:
  4705. case XML_RELAXNG_ZEROORMORE:
  4706. case XML_RELAXNG_OPTIONAL:
  4707. case XML_RELAXNG_CHOICE:
  4708. case XML_RELAXNG_GROUP:
  4709. case XML_RELAXNG_INTERLEAVE:
  4710. case XML_RELAXNG_ATTRIBUTE:
  4711. ret->content = cur;
  4712. cur->parent = ret;
  4713. break;
  4714. case XML_RELAXNG_START:
  4715. case XML_RELAXNG_PARAM:
  4716. case XML_RELAXNG_EXCEPT:
  4717. xmlRngPErr(ctxt, node, XML_RNGP_ATTRIBUTE_CONTENT,
  4718. "attribute has invalid content\n", NULL,
  4719. NULL);
  4720. break;
  4721. case XML_RELAXNG_NOOP:
  4722. xmlRngPErr(ctxt, node, XML_RNGP_ATTRIBUTE_NOOP,
  4723. "RNG Internal error, noop found in attribute\n",
  4724. NULL, NULL);
  4725. break;
  4726. }
  4727. }
  4728. child = child->next;
  4729. }
  4730. if (child != NULL) {
  4731. xmlRngPErr(ctxt, node, XML_RNGP_ATTRIBUTE_CHILDREN,
  4732. "attribute has multiple children\n", NULL, NULL);
  4733. }
  4734. ctxt->flags = old_flags;
  4735. return (ret);
  4736. }
  4737. /**
  4738. * xmlRelaxNGParseExceptNameClass:
  4739. * @ctxt: a Relax-NG parser context
  4740. * @node: the except node
  4741. * @attr: 1 if within an attribute, 0 if within an element
  4742. *
  4743. * parse the content of a RelaxNG nameClass node.
  4744. *
  4745. * Returns the definition pointer or NULL in case of error.
  4746. */
  4747. static xmlRelaxNGDefinePtr
  4748. xmlRelaxNGParseExceptNameClass(xmlRelaxNGParserCtxtPtr ctxt,
  4749. xmlNodePtr node, int attr)
  4750. {
  4751. xmlRelaxNGDefinePtr ret, cur, last = NULL;
  4752. xmlNodePtr child;
  4753. if (!IS_RELAXNG(node, "except")) {
  4754. xmlRngPErr(ctxt, node, XML_RNGP_EXCEPT_MISSING,
  4755. "Expecting an except node\n", NULL, NULL);
  4756. return (NULL);
  4757. }
  4758. if (node->next != NULL) {
  4759. xmlRngPErr(ctxt, node, XML_RNGP_EXCEPT_MULTIPLE,
  4760. "exceptNameClass allows only a single except node\n",
  4761. NULL, NULL);
  4762. }
  4763. if (node->children == NULL) {
  4764. xmlRngPErr(ctxt, node, XML_RNGP_EXCEPT_EMPTY, "except has no content\n",
  4765. NULL, NULL);
  4766. return (NULL);
  4767. }
  4768. ret = xmlRelaxNGNewDefine(ctxt, node);
  4769. if (ret == NULL)
  4770. return (NULL);
  4771. ret->type = XML_RELAXNG_EXCEPT;
  4772. child = node->children;
  4773. while (child != NULL) {
  4774. cur = xmlRelaxNGNewDefine(ctxt, child);
  4775. if (cur == NULL)
  4776. break;
  4777. if (attr)
  4778. cur->type = XML_RELAXNG_ATTRIBUTE;
  4779. else
  4780. cur->type = XML_RELAXNG_ELEMENT;
  4781. if (xmlRelaxNGParseNameClass(ctxt, child, cur) != NULL) {
  4782. if (last == NULL) {
  4783. ret->content = cur;
  4784. } else {
  4785. last->next = cur;
  4786. }
  4787. last = cur;
  4788. }
  4789. child = child->next;
  4790. }
  4791. return (ret);
  4792. }
  4793. /**
  4794. * xmlRelaxNGParseNameClass:
  4795. * @ctxt: a Relax-NG parser context
  4796. * @node: the nameClass node
  4797. * @def: the current definition
  4798. *
  4799. * parse the content of a RelaxNG nameClass node.
  4800. *
  4801. * Returns the definition pointer or NULL in case of error.
  4802. */
  4803. static xmlRelaxNGDefinePtr
  4804. xmlRelaxNGParseNameClass(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node,
  4805. xmlRelaxNGDefinePtr def)
  4806. {
  4807. xmlRelaxNGDefinePtr ret, tmp;
  4808. xmlChar *val;
  4809. ret = def;
  4810. if ((IS_RELAXNG(node, "name")) || (IS_RELAXNG(node, "anyName")) ||
  4811. (IS_RELAXNG(node, "nsName"))) {
  4812. if ((def->type != XML_RELAXNG_ELEMENT) &&
  4813. (def->type != XML_RELAXNG_ATTRIBUTE)) {
  4814. ret = xmlRelaxNGNewDefine(ctxt, node);
  4815. if (ret == NULL)
  4816. return (NULL);
  4817. ret->parent = def;
  4818. if (ctxt->flags & XML_RELAXNG_IN_ATTRIBUTE)
  4819. ret->type = XML_RELAXNG_ATTRIBUTE;
  4820. else
  4821. ret->type = XML_RELAXNG_ELEMENT;
  4822. }
  4823. }
  4824. if (IS_RELAXNG(node, "name")) {
  4825. val = xmlNodeGetContent(node);
  4826. xmlRelaxNGNormExtSpace(val);
  4827. if (xmlValidateNCName(val, 0)) {
  4828. if (node->parent != NULL)
  4829. xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_NAME,
  4830. "Element %s name '%s' is not an NCName\n",
  4831. node->parent->name, val);
  4832. else
  4833. xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_NAME,
  4834. "name '%s' is not an NCName\n",
  4835. val, NULL);
  4836. }
  4837. ret->name = val;
  4838. val = xmlGetProp(node, BAD_CAST "ns");
  4839. ret->ns = val;
  4840. if ((ctxt->flags & XML_RELAXNG_IN_ATTRIBUTE) &&
  4841. (val != NULL) &&
  4842. (xmlStrEqual(val, BAD_CAST "http://www.w3.org/2000/xmlns"))) {
  4843. xmlRngPErr(ctxt, node, XML_RNGP_XML_NS,
  4844. "Attribute with namespace '%s' is not allowed\n",
  4845. val, NULL);
  4846. }
  4847. if ((ctxt->flags & XML_RELAXNG_IN_ATTRIBUTE) &&
  4848. (val != NULL) &&
  4849. (val[0] == 0) && (xmlStrEqual(ret->name, BAD_CAST "xmlns"))) {
  4850. xmlRngPErr(ctxt, node, XML_RNGP_XMLNS_NAME,
  4851. "Attribute with QName 'xmlns' is not allowed\n",
  4852. val, NULL);
  4853. }
  4854. } else if (IS_RELAXNG(node, "anyName")) {
  4855. ret->name = NULL;
  4856. ret->ns = NULL;
  4857. if (node->children != NULL) {
  4858. ret->nameClass =
  4859. xmlRelaxNGParseExceptNameClass(ctxt, node->children,
  4860. (def->type ==
  4861. XML_RELAXNG_ATTRIBUTE));
  4862. }
  4863. } else if (IS_RELAXNG(node, "nsName")) {
  4864. ret->name = NULL;
  4865. ret->ns = xmlGetProp(node, BAD_CAST "ns");
  4866. if (ret->ns == NULL) {
  4867. xmlRngPErr(ctxt, node, XML_RNGP_NSNAME_NO_NS,
  4868. "nsName has no ns attribute\n", NULL, NULL);
  4869. }
  4870. if ((ctxt->flags & XML_RELAXNG_IN_ATTRIBUTE) &&
  4871. (ret->ns != NULL) &&
  4872. (xmlStrEqual
  4873. (ret->ns, BAD_CAST "http://www.w3.org/2000/xmlns"))) {
  4874. xmlRngPErr(ctxt, node, XML_RNGP_XML_NS,
  4875. "Attribute with namespace '%s' is not allowed\n",
  4876. ret->ns, NULL);
  4877. }
  4878. if (node->children != NULL) {
  4879. ret->nameClass =
  4880. xmlRelaxNGParseExceptNameClass(ctxt, node->children,
  4881. (def->type ==
  4882. XML_RELAXNG_ATTRIBUTE));
  4883. }
  4884. } else if (IS_RELAXNG(node, "choice")) {
  4885. xmlNodePtr child;
  4886. xmlRelaxNGDefinePtr last = NULL;
  4887. if (def->type == XML_RELAXNG_CHOICE) {
  4888. ret = def;
  4889. } else {
  4890. ret = xmlRelaxNGNewDefine(ctxt, node);
  4891. if (ret == NULL)
  4892. return (NULL);
  4893. ret->parent = def;
  4894. ret->type = XML_RELAXNG_CHOICE;
  4895. }
  4896. if (node->children == NULL) {
  4897. xmlRngPErr(ctxt, node, XML_RNGP_CHOICE_EMPTY,
  4898. "Element choice is empty\n", NULL, NULL);
  4899. } else {
  4900. child = node->children;
  4901. while (child != NULL) {
  4902. tmp = xmlRelaxNGParseNameClass(ctxt, child, ret);
  4903. if (tmp != NULL) {
  4904. if (last == NULL) {
  4905. last = tmp;
  4906. } else {
  4907. last->next = tmp;
  4908. last = tmp;
  4909. }
  4910. }
  4911. child = child->next;
  4912. }
  4913. }
  4914. } else {
  4915. xmlRngPErr(ctxt, node, XML_RNGP_CHOICE_CONTENT,
  4916. "expecting name, anyName, nsName or choice : got %s\n",
  4917. (node == NULL ? (const xmlChar *) "nothing" : node->name),
  4918. NULL);
  4919. return (NULL);
  4920. }
  4921. if (ret != def) {
  4922. if (def->nameClass == NULL) {
  4923. def->nameClass = ret;
  4924. } else {
  4925. tmp = def->nameClass;
  4926. while (tmp->next != NULL) {
  4927. tmp = tmp->next;
  4928. }
  4929. tmp->next = ret;
  4930. }
  4931. }
  4932. return (ret);
  4933. }
  4934. /**
  4935. * xmlRelaxNGParseElement:
  4936. * @ctxt: a Relax-NG parser context
  4937. * @node: the element node
  4938. *
  4939. * parse the content of a RelaxNG element node.
  4940. *
  4941. * Returns the definition pointer or NULL in case of error.
  4942. */
  4943. static xmlRelaxNGDefinePtr
  4944. xmlRelaxNGParseElement(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
  4945. {
  4946. xmlRelaxNGDefinePtr ret, cur, last;
  4947. xmlNodePtr child;
  4948. const xmlChar *olddefine;
  4949. ret = xmlRelaxNGNewDefine(ctxt, node);
  4950. if (ret == NULL)
  4951. return (NULL);
  4952. ret->type = XML_RELAXNG_ELEMENT;
  4953. ret->parent = ctxt->def;
  4954. child = node->children;
  4955. if (child == NULL) {
  4956. xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_EMPTY,
  4957. "xmlRelaxNGParseElement: element has no children\n",
  4958. NULL, NULL);
  4959. return (ret);
  4960. }
  4961. cur = xmlRelaxNGParseNameClass(ctxt, child, ret);
  4962. if (cur != NULL)
  4963. child = child->next;
  4964. if (child == NULL) {
  4965. xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_NO_CONTENT,
  4966. "xmlRelaxNGParseElement: element has no content\n",
  4967. NULL, NULL);
  4968. return (ret);
  4969. }
  4970. olddefine = ctxt->define;
  4971. ctxt->define = NULL;
  4972. last = NULL;
  4973. while (child != NULL) {
  4974. cur = xmlRelaxNGParsePattern(ctxt, child);
  4975. if (cur != NULL) {
  4976. cur->parent = ret;
  4977. switch (cur->type) {
  4978. case XML_RELAXNG_EMPTY:
  4979. case XML_RELAXNG_NOT_ALLOWED:
  4980. case XML_RELAXNG_TEXT:
  4981. case XML_RELAXNG_ELEMENT:
  4982. case XML_RELAXNG_DATATYPE:
  4983. case XML_RELAXNG_VALUE:
  4984. case XML_RELAXNG_LIST:
  4985. case XML_RELAXNG_REF:
  4986. case XML_RELAXNG_PARENTREF:
  4987. case XML_RELAXNG_EXTERNALREF:
  4988. case XML_RELAXNG_DEF:
  4989. case XML_RELAXNG_ZEROORMORE:
  4990. case XML_RELAXNG_ONEORMORE:
  4991. case XML_RELAXNG_OPTIONAL:
  4992. case XML_RELAXNG_CHOICE:
  4993. case XML_RELAXNG_GROUP:
  4994. case XML_RELAXNG_INTERLEAVE:
  4995. if (last == NULL) {
  4996. ret->content = last = cur;
  4997. } else {
  4998. if ((last->type == XML_RELAXNG_ELEMENT) &&
  4999. (ret->content == last)) {
  5000. ret->content = xmlRelaxNGNewDefine(ctxt, node);
  5001. if (ret->content != NULL) {
  5002. ret->content->type = XML_RELAXNG_GROUP;
  5003. ret->content->content = last;
  5004. } else {
  5005. ret->content = last;
  5006. }
  5007. }
  5008. last->next = cur;
  5009. last = cur;
  5010. }
  5011. break;
  5012. case XML_RELAXNG_ATTRIBUTE:
  5013. cur->next = ret->attrs;
  5014. ret->attrs = cur;
  5015. break;
  5016. case XML_RELAXNG_START:
  5017. xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_CONTENT,
  5018. "RNG Internal error, start found in element\n",
  5019. NULL, NULL);
  5020. break;
  5021. case XML_RELAXNG_PARAM:
  5022. xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_CONTENT,
  5023. "RNG Internal error, param found in element\n",
  5024. NULL, NULL);
  5025. break;
  5026. case XML_RELAXNG_EXCEPT:
  5027. xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_CONTENT,
  5028. "RNG Internal error, except found in element\n",
  5029. NULL, NULL);
  5030. break;
  5031. case XML_RELAXNG_NOOP:
  5032. xmlRngPErr(ctxt, node, XML_RNGP_ELEMENT_CONTENT,
  5033. "RNG Internal error, noop found in element\n",
  5034. NULL, NULL);
  5035. break;
  5036. }
  5037. }
  5038. child = child->next;
  5039. }
  5040. ctxt->define = olddefine;
  5041. return (ret);
  5042. }
  5043. /**
  5044. * xmlRelaxNGParsePatterns:
  5045. * @ctxt: a Relax-NG parser context
  5046. * @nodes: list of nodes
  5047. * @group: use an implicit <group> for elements
  5048. *
  5049. * parse the content of a RelaxNG start node.
  5050. *
  5051. * Returns the definition pointer or NULL in case of error.
  5052. */
  5053. static xmlRelaxNGDefinePtr
  5054. xmlRelaxNGParsePatterns(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr nodes,
  5055. int group)
  5056. {
  5057. xmlRelaxNGDefinePtr def = NULL, last = NULL, cur, parent;
  5058. parent = ctxt->def;
  5059. while (nodes != NULL) {
  5060. if (IS_RELAXNG(nodes, "element")) {
  5061. cur = xmlRelaxNGParseElement(ctxt, nodes);
  5062. if (cur == NULL)
  5063. return (NULL);
  5064. if (def == NULL) {
  5065. def = last = cur;
  5066. } else {
  5067. if ((group == 1) && (def->type == XML_RELAXNG_ELEMENT) &&
  5068. (def == last)) {
  5069. def = xmlRelaxNGNewDefine(ctxt, nodes);
  5070. if (def == NULL)
  5071. return (NULL);
  5072. def->type = XML_RELAXNG_GROUP;
  5073. def->content = last;
  5074. }
  5075. last->next = cur;
  5076. last = cur;
  5077. }
  5078. cur->parent = parent;
  5079. } else {
  5080. cur = xmlRelaxNGParsePattern(ctxt, nodes);
  5081. if (cur != NULL) {
  5082. if (def == NULL) {
  5083. def = last = cur;
  5084. } else {
  5085. last->next = cur;
  5086. last = cur;
  5087. }
  5088. }
  5089. }
  5090. nodes = nodes->next;
  5091. }
  5092. return (def);
  5093. }
  5094. /**
  5095. * xmlRelaxNGParseStart:
  5096. * @ctxt: a Relax-NG parser context
  5097. * @nodes: start children nodes
  5098. *
  5099. * parse the content of a RelaxNG start node.
  5100. *
  5101. * Returns 0 in case of success, -1 in case of error
  5102. */
  5103. static int
  5104. xmlRelaxNGParseStart(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr nodes)
  5105. {
  5106. int ret = 0;
  5107. xmlRelaxNGDefinePtr def = NULL, last;
  5108. if (nodes == NULL) {
  5109. xmlRngPErr(ctxt, nodes, XML_RNGP_START_EMPTY, "start has no children\n",
  5110. NULL, NULL);
  5111. return (-1);
  5112. }
  5113. if (IS_RELAXNG(nodes, "empty")) {
  5114. def = xmlRelaxNGNewDefine(ctxt, nodes);
  5115. if (def == NULL)
  5116. return (-1);
  5117. def->type = XML_RELAXNG_EMPTY;
  5118. if (nodes->children != NULL) {
  5119. xmlRngPErr(ctxt, nodes, XML_RNGP_EMPTY_CONTENT,
  5120. "element empty is not empty\n", NULL, NULL);
  5121. }
  5122. } else if (IS_RELAXNG(nodes, "notAllowed")) {
  5123. def = xmlRelaxNGNewDefine(ctxt, nodes);
  5124. if (def == NULL)
  5125. return (-1);
  5126. def->type = XML_RELAXNG_NOT_ALLOWED;
  5127. if (nodes->children != NULL) {
  5128. xmlRngPErr(ctxt, nodes, XML_RNGP_NOTALLOWED_NOT_EMPTY,
  5129. "element notAllowed is not empty\n", NULL, NULL);
  5130. }
  5131. } else {
  5132. def = xmlRelaxNGParsePatterns(ctxt, nodes, 1);
  5133. }
  5134. if (ctxt->grammar->start != NULL) {
  5135. last = ctxt->grammar->start;
  5136. while (last->next != NULL)
  5137. last = last->next;
  5138. last->next = def;
  5139. } else {
  5140. ctxt->grammar->start = def;
  5141. }
  5142. nodes = nodes->next;
  5143. if (nodes != NULL) {
  5144. xmlRngPErr(ctxt, nodes, XML_RNGP_START_CONTENT,
  5145. "start more than one children\n", NULL, NULL);
  5146. return (-1);
  5147. }
  5148. return (ret);
  5149. }
  5150. /**
  5151. * xmlRelaxNGParseGrammarContent:
  5152. * @ctxt: a Relax-NG parser context
  5153. * @nodes: grammar children nodes
  5154. *
  5155. * parse the content of a RelaxNG grammar node.
  5156. *
  5157. * Returns 0 in case of success, -1 in case of error
  5158. */
  5159. static int
  5160. xmlRelaxNGParseGrammarContent(xmlRelaxNGParserCtxtPtr ctxt,
  5161. xmlNodePtr nodes)
  5162. {
  5163. int ret = 0, tmp;
  5164. if (nodes == NULL) {
  5165. xmlRngPErr(ctxt, nodes, XML_RNGP_GRAMMAR_EMPTY,
  5166. "grammar has no children\n", NULL, NULL);
  5167. return (-1);
  5168. }
  5169. while (nodes != NULL) {
  5170. if (IS_RELAXNG(nodes, "start")) {
  5171. if (nodes->children == NULL) {
  5172. xmlRngPErr(ctxt, nodes, XML_RNGP_START_EMPTY,
  5173. "start has no children\n", NULL, NULL);
  5174. } else {
  5175. tmp = xmlRelaxNGParseStart(ctxt, nodes->children);
  5176. if (tmp != 0)
  5177. ret = -1;
  5178. }
  5179. } else if (IS_RELAXNG(nodes, "define")) {
  5180. tmp = xmlRelaxNGParseDefine(ctxt, nodes);
  5181. if (tmp != 0)
  5182. ret = -1;
  5183. } else if (IS_RELAXNG(nodes, "include")) {
  5184. tmp = xmlRelaxNGParseInclude(ctxt, nodes);
  5185. if (tmp != 0)
  5186. ret = -1;
  5187. } else {
  5188. xmlRngPErr(ctxt, nodes, XML_RNGP_GRAMMAR_CONTENT,
  5189. "grammar has unexpected child %s\n", nodes->name,
  5190. NULL);
  5191. ret = -1;
  5192. }
  5193. nodes = nodes->next;
  5194. }
  5195. return (ret);
  5196. }
  5197. /**
  5198. * xmlRelaxNGCheckReference:
  5199. * @ref: the ref
  5200. * @ctxt: a Relax-NG parser context
  5201. * @name: the name associated to the defines
  5202. *
  5203. * Applies the 4.17. combine attribute rule for all the define
  5204. * element of a given grammar using the same name.
  5205. */
  5206. static void
  5207. xmlRelaxNGCheckReference(void *payload, void *data, const xmlChar * name)
  5208. {
  5209. xmlRelaxNGDefinePtr ref = (xmlRelaxNGDefinePtr) payload;
  5210. xmlRelaxNGParserCtxtPtr ctxt = (xmlRelaxNGParserCtxtPtr) data;
  5211. xmlRelaxNGGrammarPtr grammar;
  5212. xmlRelaxNGDefinePtr def, cur;
  5213. /*
  5214. * Those rules don't apply to imported ref from xmlRelaxNGParseImportRef
  5215. */
  5216. if (ref->dflags & IS_EXTERNAL_REF)
  5217. return;
  5218. grammar = ctxt->grammar;
  5219. if (grammar == NULL) {
  5220. xmlRngPErr(ctxt, ref->node, XML_ERR_INTERNAL_ERROR,
  5221. "Internal error: no grammar in CheckReference %s\n",
  5222. name, NULL);
  5223. return;
  5224. }
  5225. if (ref->content != NULL) {
  5226. xmlRngPErr(ctxt, ref->node, XML_ERR_INTERNAL_ERROR,
  5227. "Internal error: reference has content in CheckReference %s\n",
  5228. name, NULL);
  5229. return;
  5230. }
  5231. if (grammar->defs != NULL) {
  5232. def = xmlHashLookup(grammar->defs, name);
  5233. if (def != NULL) {
  5234. cur = ref;
  5235. while (cur != NULL) {
  5236. cur->content = def;
  5237. cur = cur->nextHash;
  5238. }
  5239. } else {
  5240. xmlRngPErr(ctxt, ref->node, XML_RNGP_REF_NO_DEF,
  5241. "Reference %s has no matching definition\n", name,
  5242. NULL);
  5243. }
  5244. } else {
  5245. xmlRngPErr(ctxt, ref->node, XML_RNGP_REF_NO_DEF,
  5246. "Reference %s has no matching definition\n", name,
  5247. NULL);
  5248. }
  5249. }
  5250. /**
  5251. * xmlRelaxNGCheckCombine:
  5252. * @define: the define(s) list
  5253. * @ctxt: a Relax-NG parser context
  5254. * @name: the name associated to the defines
  5255. *
  5256. * Applies the 4.17. combine attribute rule for all the define
  5257. * element of a given grammar using the same name.
  5258. */
  5259. static void
  5260. xmlRelaxNGCheckCombine(void *payload, void *data, const xmlChar * name)
  5261. {
  5262. xmlRelaxNGDefinePtr define = (xmlRelaxNGDefinePtr) payload;
  5263. xmlRelaxNGParserCtxtPtr ctxt = (xmlRelaxNGParserCtxtPtr) data;
  5264. xmlChar *combine;
  5265. int choiceOrInterleave = -1;
  5266. int missing = 0;
  5267. xmlRelaxNGDefinePtr cur, last, tmp, tmp2;
  5268. if (define->nextHash == NULL)
  5269. return;
  5270. cur = define;
  5271. while (cur != NULL) {
  5272. combine = xmlGetProp(cur->node, BAD_CAST "combine");
  5273. if (combine != NULL) {
  5274. if (xmlStrEqual(combine, BAD_CAST "choice")) {
  5275. if (choiceOrInterleave == -1)
  5276. choiceOrInterleave = 1;
  5277. else if (choiceOrInterleave == 0) {
  5278. xmlRngPErr(ctxt, define->node, XML_RNGP_DEF_CHOICE_AND_INTERLEAVE,
  5279. "Defines for %s use both 'choice' and 'interleave'\n",
  5280. name, NULL);
  5281. }
  5282. } else if (xmlStrEqual(combine, BAD_CAST "interleave")) {
  5283. if (choiceOrInterleave == -1)
  5284. choiceOrInterleave = 0;
  5285. else if (choiceOrInterleave == 1) {
  5286. xmlRngPErr(ctxt, define->node, XML_RNGP_DEF_CHOICE_AND_INTERLEAVE,
  5287. "Defines for %s use both 'choice' and 'interleave'\n",
  5288. name, NULL);
  5289. }
  5290. } else {
  5291. xmlRngPErr(ctxt, define->node, XML_RNGP_UNKNOWN_COMBINE,
  5292. "Defines for %s use unknown combine value '%s''\n",
  5293. name, combine);
  5294. }
  5295. xmlFree(combine);
  5296. } else {
  5297. if (missing == 0)
  5298. missing = 1;
  5299. else {
  5300. xmlRngPErr(ctxt, define->node, XML_RNGP_NEED_COMBINE,
  5301. "Some defines for %s needs the combine attribute\n",
  5302. name, NULL);
  5303. }
  5304. }
  5305. cur = cur->nextHash;
  5306. }
  5307. if (choiceOrInterleave == -1)
  5308. choiceOrInterleave = 0;
  5309. cur = xmlRelaxNGNewDefine(ctxt, define->node);
  5310. if (cur == NULL)
  5311. return;
  5312. if (choiceOrInterleave == 0)
  5313. cur->type = XML_RELAXNG_INTERLEAVE;
  5314. else
  5315. cur->type = XML_RELAXNG_CHOICE;
  5316. tmp = define;
  5317. last = NULL;
  5318. while (tmp != NULL) {
  5319. if (tmp->content != NULL) {
  5320. if (tmp->content->next != NULL) {
  5321. /*
  5322. * we need first to create a wrapper.
  5323. */
  5324. tmp2 = xmlRelaxNGNewDefine(ctxt, tmp->content->node);
  5325. if (tmp2 == NULL)
  5326. break;
  5327. tmp2->type = XML_RELAXNG_GROUP;
  5328. tmp2->content = tmp->content;
  5329. } else {
  5330. tmp2 = tmp->content;
  5331. }
  5332. if (last == NULL) {
  5333. cur->content = tmp2;
  5334. } else {
  5335. last->next = tmp2;
  5336. }
  5337. last = tmp2;
  5338. }
  5339. tmp->content = cur;
  5340. tmp = tmp->nextHash;
  5341. }
  5342. define->content = cur;
  5343. if (choiceOrInterleave == 0) {
  5344. if (ctxt->interleaves == NULL)
  5345. ctxt->interleaves = xmlHashCreate(10);
  5346. if (ctxt->interleaves == NULL) {
  5347. xmlRngPErr(ctxt, define->node, XML_RNGP_INTERLEAVE_CREATE_FAILED,
  5348. "Failed to create interleaves hash table\n", NULL,
  5349. NULL);
  5350. } else {
  5351. char tmpname[32];
  5352. snprintf(tmpname, 32, "interleave%d", ctxt->nbInterleaves++);
  5353. if (xmlHashAddEntry(ctxt->interleaves, BAD_CAST tmpname, cur) <
  5354. 0) {
  5355. xmlRngPErr(ctxt, define->node, XML_RNGP_INTERLEAVE_CREATE_FAILED,
  5356. "Failed to add %s to hash table\n",
  5357. (const xmlChar *) tmpname, NULL);
  5358. }
  5359. }
  5360. }
  5361. }
  5362. /**
  5363. * xmlRelaxNGCombineStart:
  5364. * @ctxt: a Relax-NG parser context
  5365. * @grammar: the grammar
  5366. *
  5367. * Applies the 4.17. combine rule for all the start
  5368. * element of a given grammar.
  5369. */
  5370. static void
  5371. xmlRelaxNGCombineStart(xmlRelaxNGParserCtxtPtr ctxt,
  5372. xmlRelaxNGGrammarPtr grammar)
  5373. {
  5374. xmlRelaxNGDefinePtr starts;
  5375. xmlChar *combine;
  5376. int choiceOrInterleave = -1;
  5377. int missing = 0;
  5378. xmlRelaxNGDefinePtr cur;
  5379. starts = grammar->start;
  5380. if ((starts == NULL) || (starts->next == NULL))
  5381. return;
  5382. cur = starts;
  5383. while (cur != NULL) {
  5384. if ((cur->node == NULL) || (cur->node->parent == NULL) ||
  5385. (!xmlStrEqual(cur->node->parent->name, BAD_CAST "start"))) {
  5386. combine = NULL;
  5387. xmlRngPErr(ctxt, cur->node, XML_RNGP_START_MISSING,
  5388. "Internal error: start element not found\n", NULL,
  5389. NULL);
  5390. } else {
  5391. combine = xmlGetProp(cur->node->parent, BAD_CAST "combine");
  5392. }
  5393. if (combine != NULL) {
  5394. if (xmlStrEqual(combine, BAD_CAST "choice")) {
  5395. if (choiceOrInterleave == -1)
  5396. choiceOrInterleave = 1;
  5397. else if (choiceOrInterleave == 0) {
  5398. xmlRngPErr(ctxt, cur->node, XML_RNGP_START_CHOICE_AND_INTERLEAVE,
  5399. "<start> use both 'choice' and 'interleave'\n",
  5400. NULL, NULL);
  5401. }
  5402. } else if (xmlStrEqual(combine, BAD_CAST "interleave")) {
  5403. if (choiceOrInterleave == -1)
  5404. choiceOrInterleave = 0;
  5405. else if (choiceOrInterleave == 1) {
  5406. xmlRngPErr(ctxt, cur->node, XML_RNGP_START_CHOICE_AND_INTERLEAVE,
  5407. "<start> use both 'choice' and 'interleave'\n",
  5408. NULL, NULL);
  5409. }
  5410. } else {
  5411. xmlRngPErr(ctxt, cur->node, XML_RNGP_UNKNOWN_COMBINE,
  5412. "<start> uses unknown combine value '%s''\n",
  5413. combine, NULL);
  5414. }
  5415. xmlFree(combine);
  5416. } else {
  5417. if (missing == 0)
  5418. missing = 1;
  5419. else {
  5420. xmlRngPErr(ctxt, cur->node, XML_RNGP_NEED_COMBINE,
  5421. "Some <start> element miss the combine attribute\n",
  5422. NULL, NULL);
  5423. }
  5424. }
  5425. cur = cur->next;
  5426. }
  5427. if (choiceOrInterleave == -1)
  5428. choiceOrInterleave = 0;
  5429. cur = xmlRelaxNGNewDefine(ctxt, starts->node);
  5430. if (cur == NULL)
  5431. return;
  5432. if (choiceOrInterleave == 0)
  5433. cur->type = XML_RELAXNG_INTERLEAVE;
  5434. else
  5435. cur->type = XML_RELAXNG_CHOICE;
  5436. cur->content = grammar->start;
  5437. grammar->start = cur;
  5438. if (choiceOrInterleave == 0) {
  5439. if (ctxt->interleaves == NULL)
  5440. ctxt->interleaves = xmlHashCreate(10);
  5441. if (ctxt->interleaves == NULL) {
  5442. xmlRngPErr(ctxt, cur->node, XML_RNGP_INTERLEAVE_CREATE_FAILED,
  5443. "Failed to create interleaves hash table\n", NULL,
  5444. NULL);
  5445. } else {
  5446. char tmpname[32];
  5447. snprintf(tmpname, 32, "interleave%d", ctxt->nbInterleaves++);
  5448. if (xmlHashAddEntry(ctxt->interleaves, BAD_CAST tmpname, cur) <
  5449. 0) {
  5450. xmlRngPErr(ctxt, cur->node, XML_RNGP_INTERLEAVE_CREATE_FAILED,
  5451. "Failed to add %s to hash table\n",
  5452. (const xmlChar *) tmpname, NULL);
  5453. }
  5454. }
  5455. }
  5456. }
  5457. /**
  5458. * xmlRelaxNGCheckCycles:
  5459. * @ctxt: a Relax-NG parser context
  5460. * @nodes: grammar children nodes
  5461. * @depth: the counter
  5462. *
  5463. * Check for cycles.
  5464. *
  5465. * Returns 0 if check passed, and -1 in case of error
  5466. */
  5467. static int
  5468. xmlRelaxNGCheckCycles(xmlRelaxNGParserCtxtPtr ctxt,
  5469. xmlRelaxNGDefinePtr cur, int depth)
  5470. {
  5471. int ret = 0;
  5472. while ((ret == 0) && (cur != NULL)) {
  5473. if ((cur->type == XML_RELAXNG_REF) ||
  5474. (cur->type == XML_RELAXNG_PARENTREF)) {
  5475. if (cur->depth == -1) {
  5476. cur->depth = depth;
  5477. ret = xmlRelaxNGCheckCycles(ctxt, cur->content, depth);
  5478. cur->depth = -2;
  5479. } else if (depth == cur->depth) {
  5480. xmlRngPErr(ctxt, cur->node, XML_RNGP_REF_CYCLE,
  5481. "Detected a cycle in %s references\n",
  5482. cur->name, NULL);
  5483. return (-1);
  5484. }
  5485. } else if (cur->type == XML_RELAXNG_ELEMENT) {
  5486. ret = xmlRelaxNGCheckCycles(ctxt, cur->content, depth + 1);
  5487. } else {
  5488. ret = xmlRelaxNGCheckCycles(ctxt, cur->content, depth);
  5489. }
  5490. cur = cur->next;
  5491. }
  5492. return (ret);
  5493. }
  5494. /**
  5495. * xmlRelaxNGTryUnlink:
  5496. * @ctxt: a Relax-NG parser context
  5497. * @cur: the definition to unlink
  5498. * @parent: the parent definition
  5499. * @prev: the previous sibling definition
  5500. *
  5501. * Try to unlink a definition. If not possible make it a NOOP
  5502. *
  5503. * Returns the new prev definition
  5504. */
  5505. static xmlRelaxNGDefinePtr
  5506. xmlRelaxNGTryUnlink(xmlRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
  5507. xmlRelaxNGDefinePtr cur,
  5508. xmlRelaxNGDefinePtr parent, xmlRelaxNGDefinePtr prev)
  5509. {
  5510. if (prev != NULL) {
  5511. prev->next = cur->next;
  5512. } else {
  5513. if (parent != NULL) {
  5514. if (parent->content == cur)
  5515. parent->content = cur->next;
  5516. else if (parent->attrs == cur)
  5517. parent->attrs = cur->next;
  5518. else if (parent->nameClass == cur)
  5519. parent->nameClass = cur->next;
  5520. } else {
  5521. cur->type = XML_RELAXNG_NOOP;
  5522. prev = cur;
  5523. }
  5524. }
  5525. return (prev);
  5526. }
  5527. /**
  5528. * xmlRelaxNGSimplify:
  5529. * @ctxt: a Relax-NG parser context
  5530. * @nodes: grammar children nodes
  5531. *
  5532. * Check for simplification of empty and notAllowed
  5533. */
  5534. static void
  5535. xmlRelaxNGSimplify(xmlRelaxNGParserCtxtPtr ctxt,
  5536. xmlRelaxNGDefinePtr cur, xmlRelaxNGDefinePtr parent)
  5537. {
  5538. xmlRelaxNGDefinePtr prev = NULL;
  5539. while (cur != NULL) {
  5540. if ((cur->type == XML_RELAXNG_REF) ||
  5541. (cur->type == XML_RELAXNG_PARENTREF)) {
  5542. if (cur->depth != -3) {
  5543. cur->depth = -3;
  5544. xmlRelaxNGSimplify(ctxt, cur->content, cur);
  5545. }
  5546. } else if (cur->type == XML_RELAXNG_NOT_ALLOWED) {
  5547. cur->parent = parent;
  5548. if ((parent != NULL) &&
  5549. ((parent->type == XML_RELAXNG_ATTRIBUTE) ||
  5550. (parent->type == XML_RELAXNG_LIST) ||
  5551. (parent->type == XML_RELAXNG_GROUP) ||
  5552. (parent->type == XML_RELAXNG_INTERLEAVE) ||
  5553. (parent->type == XML_RELAXNG_ONEORMORE) ||
  5554. (parent->type == XML_RELAXNG_ZEROORMORE))) {
  5555. parent->type = XML_RELAXNG_NOT_ALLOWED;
  5556. break;
  5557. }
  5558. if ((parent != NULL) && (parent->type == XML_RELAXNG_CHOICE)) {
  5559. prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
  5560. } else
  5561. prev = cur;
  5562. } else if (cur->type == XML_RELAXNG_EMPTY) {
  5563. cur->parent = parent;
  5564. if ((parent != NULL) &&
  5565. ((parent->type == XML_RELAXNG_ONEORMORE) ||
  5566. (parent->type == XML_RELAXNG_ZEROORMORE))) {
  5567. parent->type = XML_RELAXNG_EMPTY;
  5568. break;
  5569. }
  5570. if ((parent != NULL) &&
  5571. ((parent->type == XML_RELAXNG_GROUP) ||
  5572. (parent->type == XML_RELAXNG_INTERLEAVE))) {
  5573. prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
  5574. } else
  5575. prev = cur;
  5576. } else {
  5577. cur->parent = parent;
  5578. if (cur->content != NULL)
  5579. xmlRelaxNGSimplify(ctxt, cur->content, cur);
  5580. if ((cur->type != XML_RELAXNG_VALUE) && (cur->attrs != NULL))
  5581. xmlRelaxNGSimplify(ctxt, cur->attrs, cur);
  5582. if (cur->nameClass != NULL)
  5583. xmlRelaxNGSimplify(ctxt, cur->nameClass, cur);
  5584. /*
  5585. * On Elements, try to move attribute only generating rules on
  5586. * the attrs rules.
  5587. */
  5588. if (cur->type == XML_RELAXNG_ELEMENT) {
  5589. int attronly;
  5590. xmlRelaxNGDefinePtr tmp, pre;
  5591. while (cur->content != NULL) {
  5592. attronly =
  5593. xmlRelaxNGGenerateAttributes(ctxt, cur->content);
  5594. if (attronly == 1) {
  5595. /*
  5596. * migrate cur->content to attrs
  5597. */
  5598. tmp = cur->content;
  5599. cur->content = tmp->next;
  5600. tmp->next = cur->attrs;
  5601. cur->attrs = tmp;
  5602. } else {
  5603. /*
  5604. * cur->content can generate elements or text
  5605. */
  5606. break;
  5607. }
  5608. }
  5609. pre = cur->content;
  5610. while ((pre != NULL) && (pre->next != NULL)) {
  5611. tmp = pre->next;
  5612. attronly = xmlRelaxNGGenerateAttributes(ctxt, tmp);
  5613. if (attronly == 1) {
  5614. /*
  5615. * migrate tmp to attrs
  5616. */
  5617. pre->next = tmp->next;
  5618. tmp->next = cur->attrs;
  5619. cur->attrs = tmp;
  5620. } else {
  5621. pre = tmp;
  5622. }
  5623. }
  5624. }
  5625. /*
  5626. * This may result in a simplification
  5627. */
  5628. if ((cur->type == XML_RELAXNG_GROUP) ||
  5629. (cur->type == XML_RELAXNG_INTERLEAVE)) {
  5630. if (cur->content == NULL)
  5631. cur->type = XML_RELAXNG_EMPTY;
  5632. else if (cur->content->next == NULL) {
  5633. if ((parent == NULL) && (prev == NULL)) {
  5634. cur->type = XML_RELAXNG_NOOP;
  5635. } else if (prev == NULL) {
  5636. parent->content = cur->content;
  5637. cur->content->next = cur->next;
  5638. cur = cur->content;
  5639. } else {
  5640. cur->content->next = cur->next;
  5641. prev->next = cur->content;
  5642. cur = cur->content;
  5643. }
  5644. }
  5645. }
  5646. /*
  5647. * the current node may have been transformed back
  5648. */
  5649. if ((cur->type == XML_RELAXNG_EXCEPT) &&
  5650. (cur->content != NULL) &&
  5651. (cur->content->type == XML_RELAXNG_NOT_ALLOWED)) {
  5652. prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
  5653. } else if (cur->type == XML_RELAXNG_NOT_ALLOWED) {
  5654. if ((parent != NULL) &&
  5655. ((parent->type == XML_RELAXNG_ATTRIBUTE) ||
  5656. (parent->type == XML_RELAXNG_LIST) ||
  5657. (parent->type == XML_RELAXNG_GROUP) ||
  5658. (parent->type == XML_RELAXNG_INTERLEAVE) ||
  5659. (parent->type == XML_RELAXNG_ONEORMORE) ||
  5660. (parent->type == XML_RELAXNG_ZEROORMORE))) {
  5661. parent->type = XML_RELAXNG_NOT_ALLOWED;
  5662. break;
  5663. }
  5664. if ((parent != NULL) &&
  5665. (parent->type == XML_RELAXNG_CHOICE)) {
  5666. prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
  5667. } else
  5668. prev = cur;
  5669. } else if (cur->type == XML_RELAXNG_EMPTY) {
  5670. if ((parent != NULL) &&
  5671. ((parent->type == XML_RELAXNG_ONEORMORE) ||
  5672. (parent->type == XML_RELAXNG_ZEROORMORE))) {
  5673. parent->type = XML_RELAXNG_EMPTY;
  5674. break;
  5675. }
  5676. if ((parent != NULL) &&
  5677. ((parent->type == XML_RELAXNG_GROUP) ||
  5678. (parent->type == XML_RELAXNG_INTERLEAVE) ||
  5679. (parent->type == XML_RELAXNG_CHOICE))) {
  5680. prev = xmlRelaxNGTryUnlink(ctxt, cur, parent, prev);
  5681. } else
  5682. prev = cur;
  5683. } else {
  5684. prev = cur;
  5685. }
  5686. }
  5687. cur = cur->next;
  5688. }
  5689. }
  5690. /**
  5691. * xmlRelaxNGGroupContentType:
  5692. * @ct1: the first content type
  5693. * @ct2: the second content type
  5694. *
  5695. * Try to group 2 content types
  5696. *
  5697. * Returns the content type
  5698. */
  5699. static xmlRelaxNGContentType
  5700. xmlRelaxNGGroupContentType(xmlRelaxNGContentType ct1,
  5701. xmlRelaxNGContentType ct2)
  5702. {
  5703. if ((ct1 == XML_RELAXNG_CONTENT_ERROR) ||
  5704. (ct2 == XML_RELAXNG_CONTENT_ERROR))
  5705. return (XML_RELAXNG_CONTENT_ERROR);
  5706. if (ct1 == XML_RELAXNG_CONTENT_EMPTY)
  5707. return (ct2);
  5708. if (ct2 == XML_RELAXNG_CONTENT_EMPTY)
  5709. return (ct1);
  5710. if ((ct1 == XML_RELAXNG_CONTENT_COMPLEX) &&
  5711. (ct2 == XML_RELAXNG_CONTENT_COMPLEX))
  5712. return (XML_RELAXNG_CONTENT_COMPLEX);
  5713. return (XML_RELAXNG_CONTENT_ERROR);
  5714. }
  5715. /**
  5716. * xmlRelaxNGMaxContentType:
  5717. * @ct1: the first content type
  5718. * @ct2: the second content type
  5719. *
  5720. * Compute the max content-type
  5721. *
  5722. * Returns the content type
  5723. */
  5724. static xmlRelaxNGContentType
  5725. xmlRelaxNGMaxContentType(xmlRelaxNGContentType ct1,
  5726. xmlRelaxNGContentType ct2)
  5727. {
  5728. if ((ct1 == XML_RELAXNG_CONTENT_ERROR) ||
  5729. (ct2 == XML_RELAXNG_CONTENT_ERROR))
  5730. return (XML_RELAXNG_CONTENT_ERROR);
  5731. if ((ct1 == XML_RELAXNG_CONTENT_SIMPLE) ||
  5732. (ct2 == XML_RELAXNG_CONTENT_SIMPLE))
  5733. return (XML_RELAXNG_CONTENT_SIMPLE);
  5734. if ((ct1 == XML_RELAXNG_CONTENT_COMPLEX) ||
  5735. (ct2 == XML_RELAXNG_CONTENT_COMPLEX))
  5736. return (XML_RELAXNG_CONTENT_COMPLEX);
  5737. return (XML_RELAXNG_CONTENT_EMPTY);
  5738. }
  5739. /**
  5740. * xmlRelaxNGCheckRules:
  5741. * @ctxt: a Relax-NG parser context
  5742. * @cur: the current definition
  5743. * @flags: some accumulated flags
  5744. * @ptype: the parent type
  5745. *
  5746. * Check for rules in section 7.1 and 7.2
  5747. *
  5748. * Returns the content type of @cur
  5749. */
  5750. static xmlRelaxNGContentType
  5751. xmlRelaxNGCheckRules(xmlRelaxNGParserCtxtPtr ctxt,
  5752. xmlRelaxNGDefinePtr cur, int flags,
  5753. xmlRelaxNGType ptype)
  5754. {
  5755. int nflags;
  5756. xmlRelaxNGContentType ret, tmp, val = XML_RELAXNG_CONTENT_EMPTY;
  5757. while (cur != NULL) {
  5758. ret = XML_RELAXNG_CONTENT_EMPTY;
  5759. if ((cur->type == XML_RELAXNG_REF) ||
  5760. (cur->type == XML_RELAXNG_PARENTREF)) {
  5761. /*
  5762. * This should actually be caught by list//element(ref) at the
  5763. * element boundaries, c.f. Bug #159968 local refs are dropped
  5764. * in step 4.19.
  5765. */
  5766. #if 0
  5767. if (flags & XML_RELAXNG_IN_LIST) {
  5768. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_REF,
  5769. "Found forbidden pattern list//ref\n", NULL,
  5770. NULL);
  5771. }
  5772. #endif
  5773. if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
  5774. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_REF,
  5775. "Found forbidden pattern data/except//ref\n",
  5776. NULL, NULL);
  5777. }
  5778. if (cur->content == NULL) {
  5779. if (cur->type == XML_RELAXNG_PARENTREF)
  5780. xmlRngPErr(ctxt, cur->node, XML_RNGP_REF_NO_DEF,
  5781. "Internal found no define for parent refs\n",
  5782. NULL, NULL);
  5783. else
  5784. xmlRngPErr(ctxt, cur->node, XML_RNGP_REF_NO_DEF,
  5785. "Internal found no define for ref %s\n",
  5786. (cur->name ? cur->name: BAD_CAST "null"), NULL);
  5787. }
  5788. if (cur->depth > -4) {
  5789. cur->depth = -4;
  5790. ret = xmlRelaxNGCheckRules(ctxt, cur->content,
  5791. flags, cur->type);
  5792. cur->depth = ret - 15;
  5793. } else if (cur->depth == -4) {
  5794. ret = XML_RELAXNG_CONTENT_COMPLEX;
  5795. } else {
  5796. ret = (xmlRelaxNGContentType) (cur->depth + 15);
  5797. }
  5798. } else if (cur->type == XML_RELAXNG_ELEMENT) {
  5799. /*
  5800. * The 7.3 Attribute derivation rule for groups is plugged there
  5801. */
  5802. xmlRelaxNGCheckGroupAttrs(ctxt, cur);
  5803. if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
  5804. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_ELEM,
  5805. "Found forbidden pattern data/except//element(ref)\n",
  5806. NULL, NULL);
  5807. }
  5808. if (flags & XML_RELAXNG_IN_LIST) {
  5809. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_ELEM,
  5810. "Found forbidden pattern list//element(ref)\n",
  5811. NULL, NULL);
  5812. }
  5813. if (flags & XML_RELAXNG_IN_ATTRIBUTE) {
  5814. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_ATTR_ELEM,
  5815. "Found forbidden pattern attribute//element(ref)\n",
  5816. NULL, NULL);
  5817. }
  5818. if (flags & XML_RELAXNG_IN_ATTRIBUTE) {
  5819. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_ATTR_ELEM,
  5820. "Found forbidden pattern attribute//element(ref)\n",
  5821. NULL, NULL);
  5822. }
  5823. /*
  5824. * reset since in the simple form elements are only child
  5825. * of grammar/define
  5826. */
  5827. nflags = 0;
  5828. ret =
  5829. xmlRelaxNGCheckRules(ctxt, cur->attrs, nflags, cur->type);
  5830. if (ret != XML_RELAXNG_CONTENT_EMPTY) {
  5831. xmlRngPErr(ctxt, cur->node, XML_RNGP_ELEM_CONTENT_EMPTY,
  5832. "Element %s attributes have a content type error\n",
  5833. cur->name, NULL);
  5834. }
  5835. ret =
  5836. xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
  5837. cur->type);
  5838. if (ret == XML_RELAXNG_CONTENT_ERROR) {
  5839. xmlRngPErr(ctxt, cur->node, XML_RNGP_ELEM_CONTENT_ERROR,
  5840. "Element %s has a content type error\n",
  5841. cur->name, NULL);
  5842. } else {
  5843. ret = XML_RELAXNG_CONTENT_COMPLEX;
  5844. }
  5845. } else if (cur->type == XML_RELAXNG_ATTRIBUTE) {
  5846. if (flags & XML_RELAXNG_IN_ATTRIBUTE) {
  5847. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_ATTR_ATTR,
  5848. "Found forbidden pattern attribute//attribute\n",
  5849. NULL, NULL);
  5850. }
  5851. if (flags & XML_RELAXNG_IN_LIST) {
  5852. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_ATTR,
  5853. "Found forbidden pattern list//attribute\n",
  5854. NULL, NULL);
  5855. }
  5856. if (flags & XML_RELAXNG_IN_OOMGROUP) {
  5857. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_ONEMORE_GROUP_ATTR,
  5858. "Found forbidden pattern oneOrMore//group//attribute\n",
  5859. NULL, NULL);
  5860. }
  5861. if (flags & XML_RELAXNG_IN_OOMINTERLEAVE) {
  5862. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_ONEMORE_INTERLEAVE_ATTR,
  5863. "Found forbidden pattern oneOrMore//interleave//attribute\n",
  5864. NULL, NULL);
  5865. }
  5866. if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
  5867. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_ATTR,
  5868. "Found forbidden pattern data/except//attribute\n",
  5869. NULL, NULL);
  5870. }
  5871. if (flags & XML_RELAXNG_IN_START) {
  5872. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_ATTR,
  5873. "Found forbidden pattern start//attribute\n",
  5874. NULL, NULL);
  5875. }
  5876. if ((!(flags & XML_RELAXNG_IN_ONEORMORE))
  5877. && cur->name == NULL
  5878. /* following is checking alternative name class readiness
  5879. in case it went the "choice" route */
  5880. && cur->nameClass == NULL) {
  5881. if (cur->ns == NULL) {
  5882. xmlRngPErr(ctxt, cur->node, XML_RNGP_ANYNAME_ATTR_ANCESTOR,
  5883. "Found anyName attribute without oneOrMore ancestor\n",
  5884. NULL, NULL);
  5885. } else {
  5886. xmlRngPErr(ctxt, cur->node, XML_RNGP_NSNAME_ATTR_ANCESTOR,
  5887. "Found nsName attribute without oneOrMore ancestor\n",
  5888. NULL, NULL);
  5889. }
  5890. }
  5891. nflags = flags | XML_RELAXNG_IN_ATTRIBUTE;
  5892. xmlRelaxNGCheckRules(ctxt, cur->content, nflags, cur->type);
  5893. ret = XML_RELAXNG_CONTENT_EMPTY;
  5894. } else if ((cur->type == XML_RELAXNG_ONEORMORE) ||
  5895. (cur->type == XML_RELAXNG_ZEROORMORE)) {
  5896. if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
  5897. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_ONEMORE,
  5898. "Found forbidden pattern data/except//oneOrMore\n",
  5899. NULL, NULL);
  5900. }
  5901. if (flags & XML_RELAXNG_IN_START) {
  5902. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_ONEMORE,
  5903. "Found forbidden pattern start//oneOrMore\n",
  5904. NULL, NULL);
  5905. }
  5906. nflags = flags | XML_RELAXNG_IN_ONEORMORE;
  5907. ret =
  5908. xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
  5909. cur->type);
  5910. ret = xmlRelaxNGGroupContentType(ret, ret);
  5911. } else if (cur->type == XML_RELAXNG_LIST) {
  5912. if (flags & XML_RELAXNG_IN_LIST) {
  5913. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_LIST,
  5914. "Found forbidden pattern list//list\n", NULL,
  5915. NULL);
  5916. }
  5917. if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
  5918. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_LIST,
  5919. "Found forbidden pattern data/except//list\n",
  5920. NULL, NULL);
  5921. }
  5922. if (flags & XML_RELAXNG_IN_START) {
  5923. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_LIST,
  5924. "Found forbidden pattern start//list\n", NULL,
  5925. NULL);
  5926. }
  5927. nflags = flags | XML_RELAXNG_IN_LIST;
  5928. ret =
  5929. xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
  5930. cur->type);
  5931. } else if (cur->type == XML_RELAXNG_GROUP) {
  5932. if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
  5933. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_GROUP,
  5934. "Found forbidden pattern data/except//group\n",
  5935. NULL, NULL);
  5936. }
  5937. if (flags & XML_RELAXNG_IN_START) {
  5938. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_GROUP,
  5939. "Found forbidden pattern start//group\n", NULL,
  5940. NULL);
  5941. }
  5942. if (flags & XML_RELAXNG_IN_ONEORMORE)
  5943. nflags = flags | XML_RELAXNG_IN_OOMGROUP;
  5944. else
  5945. nflags = flags;
  5946. ret =
  5947. xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
  5948. cur->type);
  5949. /*
  5950. * The 7.3 Attribute derivation rule for groups is plugged there
  5951. */
  5952. xmlRelaxNGCheckGroupAttrs(ctxt, cur);
  5953. } else if (cur->type == XML_RELAXNG_INTERLEAVE) {
  5954. if (flags & XML_RELAXNG_IN_LIST) {
  5955. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_INTERLEAVE,
  5956. "Found forbidden pattern list//interleave\n",
  5957. NULL, NULL);
  5958. }
  5959. if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
  5960. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_INTERLEAVE,
  5961. "Found forbidden pattern data/except//interleave\n",
  5962. NULL, NULL);
  5963. }
  5964. if (flags & XML_RELAXNG_IN_START) {
  5965. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_INTERLEAVE,
  5966. "Found forbidden pattern start//interleave\n",
  5967. NULL, NULL);
  5968. }
  5969. if (flags & XML_RELAXNG_IN_ONEORMORE)
  5970. nflags = flags | XML_RELAXNG_IN_OOMINTERLEAVE;
  5971. else
  5972. nflags = flags;
  5973. ret =
  5974. xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
  5975. cur->type);
  5976. } else if (cur->type == XML_RELAXNG_EXCEPT) {
  5977. if ((cur->parent != NULL) &&
  5978. (cur->parent->type == XML_RELAXNG_DATATYPE))
  5979. nflags = flags | XML_RELAXNG_IN_DATAEXCEPT;
  5980. else
  5981. nflags = flags;
  5982. ret =
  5983. xmlRelaxNGCheckRules(ctxt, cur->content, nflags,
  5984. cur->type);
  5985. } else if (cur->type == XML_RELAXNG_DATATYPE) {
  5986. if (flags & XML_RELAXNG_IN_START) {
  5987. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_DATA,
  5988. "Found forbidden pattern start//data\n", NULL,
  5989. NULL);
  5990. }
  5991. xmlRelaxNGCheckRules(ctxt, cur->content, flags, cur->type);
  5992. ret = XML_RELAXNG_CONTENT_SIMPLE;
  5993. } else if (cur->type == XML_RELAXNG_VALUE) {
  5994. if (flags & XML_RELAXNG_IN_START) {
  5995. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_VALUE,
  5996. "Found forbidden pattern start//value\n", NULL,
  5997. NULL);
  5998. }
  5999. xmlRelaxNGCheckRules(ctxt, cur->content, flags, cur->type);
  6000. ret = XML_RELAXNG_CONTENT_SIMPLE;
  6001. } else if (cur->type == XML_RELAXNG_TEXT) {
  6002. if (flags & XML_RELAXNG_IN_LIST) {
  6003. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_LIST_TEXT,
  6004. "Found forbidden pattern list//text\n", NULL,
  6005. NULL);
  6006. }
  6007. if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
  6008. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_TEXT,
  6009. "Found forbidden pattern data/except//text\n",
  6010. NULL, NULL);
  6011. }
  6012. if (flags & XML_RELAXNG_IN_START) {
  6013. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_TEXT,
  6014. "Found forbidden pattern start//text\n", NULL,
  6015. NULL);
  6016. }
  6017. ret = XML_RELAXNG_CONTENT_COMPLEX;
  6018. } else if (cur->type == XML_RELAXNG_EMPTY) {
  6019. if (flags & XML_RELAXNG_IN_DATAEXCEPT) {
  6020. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_DATA_EXCEPT_EMPTY,
  6021. "Found forbidden pattern data/except//empty\n",
  6022. NULL, NULL);
  6023. }
  6024. if (flags & XML_RELAXNG_IN_START) {
  6025. xmlRngPErr(ctxt, cur->node, XML_RNGP_PAT_START_EMPTY,
  6026. "Found forbidden pattern start//empty\n", NULL,
  6027. NULL);
  6028. }
  6029. ret = XML_RELAXNG_CONTENT_EMPTY;
  6030. } else if (cur->type == XML_RELAXNG_CHOICE) {
  6031. xmlRelaxNGCheckChoiceDeterminism(ctxt, cur);
  6032. ret =
  6033. xmlRelaxNGCheckRules(ctxt, cur->content, flags, cur->type);
  6034. } else {
  6035. ret =
  6036. xmlRelaxNGCheckRules(ctxt, cur->content, flags, cur->type);
  6037. }
  6038. cur = cur->next;
  6039. if (ptype == XML_RELAXNG_GROUP) {
  6040. val = xmlRelaxNGGroupContentType(val, ret);
  6041. } else if (ptype == XML_RELAXNG_INTERLEAVE) {
  6042. /*
  6043. * TODO: scan complain that tmp is never used, seems on purpose
  6044. * need double-checking
  6045. */
  6046. tmp = xmlRelaxNGGroupContentType(val, ret);
  6047. if (tmp != XML_RELAXNG_CONTENT_ERROR)
  6048. tmp = xmlRelaxNGMaxContentType(val, ret);
  6049. } else if (ptype == XML_RELAXNG_CHOICE) {
  6050. val = xmlRelaxNGMaxContentType(val, ret);
  6051. } else if (ptype == XML_RELAXNG_LIST) {
  6052. val = XML_RELAXNG_CONTENT_SIMPLE;
  6053. } else if (ptype == XML_RELAXNG_EXCEPT) {
  6054. if (ret == XML_RELAXNG_CONTENT_ERROR)
  6055. val = XML_RELAXNG_CONTENT_ERROR;
  6056. else
  6057. val = XML_RELAXNG_CONTENT_SIMPLE;
  6058. } else {
  6059. val = xmlRelaxNGGroupContentType(val, ret);
  6060. }
  6061. }
  6062. return (val);
  6063. }
  6064. /**
  6065. * xmlRelaxNGParseGrammar:
  6066. * @ctxt: a Relax-NG parser context
  6067. * @nodes: grammar children nodes
  6068. *
  6069. * parse a Relax-NG <grammar> node
  6070. *
  6071. * Returns the internal xmlRelaxNGGrammarPtr built or
  6072. * NULL in case of error
  6073. */
  6074. static xmlRelaxNGGrammarPtr
  6075. xmlRelaxNGParseGrammar(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr nodes)
  6076. {
  6077. xmlRelaxNGGrammarPtr ret, tmp, old;
  6078. ret = xmlRelaxNGNewGrammar(ctxt);
  6079. if (ret == NULL)
  6080. return (NULL);
  6081. /*
  6082. * Link the new grammar in the tree
  6083. */
  6084. ret->parent = ctxt->grammar;
  6085. if (ctxt->grammar != NULL) {
  6086. tmp = ctxt->grammar->children;
  6087. if (tmp == NULL) {
  6088. ctxt->grammar->children = ret;
  6089. } else {
  6090. while (tmp->next != NULL)
  6091. tmp = tmp->next;
  6092. tmp->next = ret;
  6093. }
  6094. }
  6095. old = ctxt->grammar;
  6096. ctxt->grammar = ret;
  6097. xmlRelaxNGParseGrammarContent(ctxt, nodes);
  6098. ctxt->grammar = ret;
  6099. if (ctxt->grammar == NULL) {
  6100. xmlRngPErr(ctxt, nodes, XML_RNGP_GRAMMAR_CONTENT,
  6101. "Failed to parse <grammar> content\n", NULL, NULL);
  6102. } else if (ctxt->grammar->start == NULL) {
  6103. xmlRngPErr(ctxt, nodes, XML_RNGP_GRAMMAR_NO_START,
  6104. "Element <grammar> has no <start>\n", NULL, NULL);
  6105. }
  6106. /*
  6107. * Apply 4.17 merging rules to defines and starts
  6108. */
  6109. xmlRelaxNGCombineStart(ctxt, ret);
  6110. if (ret->defs != NULL) {
  6111. xmlHashScan(ret->defs, xmlRelaxNGCheckCombine, ctxt);
  6112. }
  6113. /*
  6114. * link together defines and refs in this grammar
  6115. */
  6116. if (ret->refs != NULL) {
  6117. xmlHashScan(ret->refs, xmlRelaxNGCheckReference, ctxt);
  6118. }
  6119. /* @@@@ */
  6120. ctxt->grammar = old;
  6121. return (ret);
  6122. }
  6123. /**
  6124. * xmlRelaxNGParseDocument:
  6125. * @ctxt: a Relax-NG parser context
  6126. * @node: the root node of the RelaxNG schema
  6127. *
  6128. * parse a Relax-NG definition resource and build an internal
  6129. * xmlRelaxNG structure which can be used to validate instances.
  6130. *
  6131. * Returns the internal XML RelaxNG structure built or
  6132. * NULL in case of error
  6133. */
  6134. static xmlRelaxNGPtr
  6135. xmlRelaxNGParseDocument(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
  6136. {
  6137. xmlRelaxNGPtr schema = NULL;
  6138. const xmlChar *olddefine;
  6139. xmlRelaxNGGrammarPtr old;
  6140. if ((ctxt == NULL) || (node == NULL))
  6141. return (NULL);
  6142. schema = xmlRelaxNGNewRelaxNG(ctxt);
  6143. if (schema == NULL)
  6144. return (NULL);
  6145. olddefine = ctxt->define;
  6146. ctxt->define = NULL;
  6147. if (IS_RELAXNG(node, "grammar")) {
  6148. schema->topgrammar = xmlRelaxNGParseGrammar(ctxt, node->children);
  6149. if (schema->topgrammar == NULL) {
  6150. xmlRelaxNGFree(schema);
  6151. return (NULL);
  6152. }
  6153. } else {
  6154. xmlRelaxNGGrammarPtr tmp, ret;
  6155. schema->topgrammar = ret = xmlRelaxNGNewGrammar(ctxt);
  6156. if (schema->topgrammar == NULL) {
  6157. xmlRelaxNGFree(schema);
  6158. return (NULL);
  6159. }
  6160. /*
  6161. * Link the new grammar in the tree
  6162. */
  6163. ret->parent = ctxt->grammar;
  6164. if (ctxt->grammar != NULL) {
  6165. tmp = ctxt->grammar->children;
  6166. if (tmp == NULL) {
  6167. ctxt->grammar->children = ret;
  6168. } else {
  6169. while (tmp->next != NULL)
  6170. tmp = tmp->next;
  6171. tmp->next = ret;
  6172. }
  6173. }
  6174. old = ctxt->grammar;
  6175. ctxt->grammar = ret;
  6176. xmlRelaxNGParseStart(ctxt, node);
  6177. if (old != NULL)
  6178. ctxt->grammar = old;
  6179. }
  6180. ctxt->define = olddefine;
  6181. if (schema->topgrammar->start != NULL) {
  6182. xmlRelaxNGCheckCycles(ctxt, schema->topgrammar->start, 0);
  6183. if ((ctxt->flags & XML_RELAXNG_IN_EXTERNALREF) == 0) {
  6184. xmlRelaxNGSimplify(ctxt, schema->topgrammar->start, NULL);
  6185. while ((schema->topgrammar->start != NULL) &&
  6186. (schema->topgrammar->start->type == XML_RELAXNG_NOOP) &&
  6187. (schema->topgrammar->start->next != NULL))
  6188. schema->topgrammar->start =
  6189. schema->topgrammar->start->content;
  6190. xmlRelaxNGCheckRules(ctxt, schema->topgrammar->start,
  6191. XML_RELAXNG_IN_START, XML_RELAXNG_NOOP);
  6192. }
  6193. }
  6194. return (schema);
  6195. }
  6196. /************************************************************************
  6197. * *
  6198. * Reading RelaxNGs *
  6199. * *
  6200. ************************************************************************/
  6201. /**
  6202. * xmlRelaxNGNewParserCtxt:
  6203. * @URL: the location of the schema
  6204. *
  6205. * Create an XML RelaxNGs parse context for that file/resource expected
  6206. * to contain an XML RelaxNGs file.
  6207. *
  6208. * Returns the parser context or NULL in case of error
  6209. */
  6210. xmlRelaxNGParserCtxtPtr
  6211. xmlRelaxNGNewParserCtxt(const char *URL)
  6212. {
  6213. xmlRelaxNGParserCtxtPtr ret;
  6214. if (URL == NULL)
  6215. return (NULL);
  6216. ret =
  6217. (xmlRelaxNGParserCtxtPtr) xmlMalloc(sizeof(xmlRelaxNGParserCtxt));
  6218. if (ret == NULL) {
  6219. xmlRngPErrMemory(NULL, "building parser\n");
  6220. return (NULL);
  6221. }
  6222. memset(ret, 0, sizeof(xmlRelaxNGParserCtxt));
  6223. ret->URL = xmlStrdup((const xmlChar *) URL);
  6224. ret->error = xmlGenericError;
  6225. ret->userData = xmlGenericErrorContext;
  6226. return (ret);
  6227. }
  6228. /**
  6229. * xmlRelaxNGNewMemParserCtxt:
  6230. * @buffer: a pointer to a char array containing the schemas
  6231. * @size: the size of the array
  6232. *
  6233. * Create an XML RelaxNGs parse context for that memory buffer expected
  6234. * to contain an XML RelaxNGs file.
  6235. *
  6236. * Returns the parser context or NULL in case of error
  6237. */
  6238. xmlRelaxNGParserCtxtPtr
  6239. xmlRelaxNGNewMemParserCtxt(const char *buffer, int size)
  6240. {
  6241. xmlRelaxNGParserCtxtPtr ret;
  6242. if ((buffer == NULL) || (size <= 0))
  6243. return (NULL);
  6244. ret =
  6245. (xmlRelaxNGParserCtxtPtr) xmlMalloc(sizeof(xmlRelaxNGParserCtxt));
  6246. if (ret == NULL) {
  6247. xmlRngPErrMemory(NULL, "building parser\n");
  6248. return (NULL);
  6249. }
  6250. memset(ret, 0, sizeof(xmlRelaxNGParserCtxt));
  6251. ret->buffer = buffer;
  6252. ret->size = size;
  6253. ret->error = xmlGenericError;
  6254. ret->userData = xmlGenericErrorContext;
  6255. return (ret);
  6256. }
  6257. /**
  6258. * xmlRelaxNGNewDocParserCtxt:
  6259. * @doc: a preparsed document tree
  6260. *
  6261. * Create an XML RelaxNGs parser context for that document.
  6262. * Note: since the process of compiling a RelaxNG schemas modifies the
  6263. * document, the @doc parameter is duplicated internally.
  6264. *
  6265. * Returns the parser context or NULL in case of error
  6266. */
  6267. xmlRelaxNGParserCtxtPtr
  6268. xmlRelaxNGNewDocParserCtxt(xmlDocPtr doc)
  6269. {
  6270. xmlRelaxNGParserCtxtPtr ret;
  6271. xmlDocPtr copy;
  6272. if (doc == NULL)
  6273. return (NULL);
  6274. copy = xmlCopyDoc(doc, 1);
  6275. if (copy == NULL)
  6276. return (NULL);
  6277. ret =
  6278. (xmlRelaxNGParserCtxtPtr) xmlMalloc(sizeof(xmlRelaxNGParserCtxt));
  6279. if (ret == NULL) {
  6280. xmlRngPErrMemory(NULL, "building parser\n");
  6281. xmlFreeDoc(copy);
  6282. return (NULL);
  6283. }
  6284. memset(ret, 0, sizeof(xmlRelaxNGParserCtxt));
  6285. ret->document = copy;
  6286. ret->freedoc = 1;
  6287. ret->userData = xmlGenericErrorContext;
  6288. return (ret);
  6289. }
  6290. /**
  6291. * xmlRelaxNGFreeParserCtxt:
  6292. * @ctxt: the schema parser context
  6293. *
  6294. * Free the resources associated to the schema parser context
  6295. */
  6296. void
  6297. xmlRelaxNGFreeParserCtxt(xmlRelaxNGParserCtxtPtr ctxt)
  6298. {
  6299. if (ctxt == NULL)
  6300. return;
  6301. if (ctxt->URL != NULL)
  6302. xmlFree(ctxt->URL);
  6303. if (ctxt->doc != NULL)
  6304. xmlRelaxNGFreeDocument(ctxt->doc);
  6305. if (ctxt->interleaves != NULL)
  6306. xmlHashFree(ctxt->interleaves, NULL);
  6307. if (ctxt->documents != NULL)
  6308. xmlRelaxNGFreeDocumentList(ctxt->documents);
  6309. if (ctxt->includes != NULL)
  6310. xmlRelaxNGFreeIncludeList(ctxt->includes);
  6311. if (ctxt->docTab != NULL)
  6312. xmlFree(ctxt->docTab);
  6313. if (ctxt->incTab != NULL)
  6314. xmlFree(ctxt->incTab);
  6315. if (ctxt->defTab != NULL) {
  6316. int i;
  6317. for (i = 0; i < ctxt->defNr; i++)
  6318. xmlRelaxNGFreeDefine(ctxt->defTab[i]);
  6319. xmlFree(ctxt->defTab);
  6320. }
  6321. if ((ctxt->document != NULL) && (ctxt->freedoc))
  6322. xmlFreeDoc(ctxt->document);
  6323. xmlFree(ctxt);
  6324. }
  6325. /**
  6326. * xmlRelaxNGNormExtSpace:
  6327. * @value: a value
  6328. *
  6329. * Removes the leading and ending spaces of the value
  6330. * The string is modified "in situ"
  6331. */
  6332. static void
  6333. xmlRelaxNGNormExtSpace(xmlChar * value)
  6334. {
  6335. xmlChar *start = value;
  6336. xmlChar *cur = value;
  6337. if (value == NULL)
  6338. return;
  6339. while (IS_BLANK_CH(*cur))
  6340. cur++;
  6341. if (cur == start) {
  6342. do {
  6343. while ((*cur != 0) && (!IS_BLANK_CH(*cur)))
  6344. cur++;
  6345. if (*cur == 0)
  6346. return;
  6347. start = cur;
  6348. while (IS_BLANK_CH(*cur))
  6349. cur++;
  6350. if (*cur == 0) {
  6351. *start = 0;
  6352. return;
  6353. }
  6354. } while (1);
  6355. } else {
  6356. do {
  6357. while ((*cur != 0) && (!IS_BLANK_CH(*cur)))
  6358. *start++ = *cur++;
  6359. if (*cur == 0) {
  6360. *start = 0;
  6361. return;
  6362. }
  6363. /* don't try to normalize the inner spaces */
  6364. while (IS_BLANK_CH(*cur))
  6365. cur++;
  6366. if (*cur == 0) {
  6367. *start = 0;
  6368. return;
  6369. }
  6370. *start++ = *cur++;
  6371. } while (1);
  6372. }
  6373. }
  6374. /**
  6375. * xmlRelaxNGCleanupAttributes:
  6376. * @ctxt: a Relax-NG parser context
  6377. * @node: a Relax-NG node
  6378. *
  6379. * Check all the attributes on the given node
  6380. */
  6381. static void
  6382. xmlRelaxNGCleanupAttributes(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
  6383. {
  6384. xmlAttrPtr cur, next;
  6385. cur = node->properties;
  6386. while (cur != NULL) {
  6387. next = cur->next;
  6388. if ((cur->ns == NULL) ||
  6389. (xmlStrEqual(cur->ns->href, xmlRelaxNGNs))) {
  6390. if (xmlStrEqual(cur->name, BAD_CAST "name")) {
  6391. if ((!xmlStrEqual(node->name, BAD_CAST "element")) &&
  6392. (!xmlStrEqual(node->name, BAD_CAST "attribute")) &&
  6393. (!xmlStrEqual(node->name, BAD_CAST "ref")) &&
  6394. (!xmlStrEqual(node->name, BAD_CAST "parentRef")) &&
  6395. (!xmlStrEqual(node->name, BAD_CAST "param")) &&
  6396. (!xmlStrEqual(node->name, BAD_CAST "define"))) {
  6397. xmlRngPErr(ctxt, node, XML_RNGP_FORBIDDEN_ATTRIBUTE,
  6398. "Attribute %s is not allowed on %s\n",
  6399. cur->name, node->name);
  6400. }
  6401. } else if (xmlStrEqual(cur->name, BAD_CAST "type")) {
  6402. if ((!xmlStrEqual(node->name, BAD_CAST "value")) &&
  6403. (!xmlStrEqual(node->name, BAD_CAST "data"))) {
  6404. xmlRngPErr(ctxt, node, XML_RNGP_FORBIDDEN_ATTRIBUTE,
  6405. "Attribute %s is not allowed on %s\n",
  6406. cur->name, node->name);
  6407. }
  6408. } else if (xmlStrEqual(cur->name, BAD_CAST "href")) {
  6409. if ((!xmlStrEqual(node->name, BAD_CAST "externalRef")) &&
  6410. (!xmlStrEqual(node->name, BAD_CAST "include"))) {
  6411. xmlRngPErr(ctxt, node, XML_RNGP_FORBIDDEN_ATTRIBUTE,
  6412. "Attribute %s is not allowed on %s\n",
  6413. cur->name, node->name);
  6414. }
  6415. } else if (xmlStrEqual(cur->name, BAD_CAST "combine")) {
  6416. if ((!xmlStrEqual(node->name, BAD_CAST "start")) &&
  6417. (!xmlStrEqual(node->name, BAD_CAST "define"))) {
  6418. xmlRngPErr(ctxt, node, XML_RNGP_FORBIDDEN_ATTRIBUTE,
  6419. "Attribute %s is not allowed on %s\n",
  6420. cur->name, node->name);
  6421. }
  6422. } else if (xmlStrEqual(cur->name, BAD_CAST "datatypeLibrary")) {
  6423. xmlChar *val;
  6424. xmlURIPtr uri;
  6425. val = xmlNodeListGetString(node->doc, cur->children, 1);
  6426. if (val != NULL) {
  6427. if (val[0] != 0) {
  6428. uri = xmlParseURI((const char *) val);
  6429. if (uri == NULL) {
  6430. xmlRngPErr(ctxt, node, XML_RNGP_INVALID_URI,
  6431. "Attribute %s contains invalid URI %s\n",
  6432. cur->name, val);
  6433. } else {
  6434. if (uri->scheme == NULL) {
  6435. xmlRngPErr(ctxt, node, XML_RNGP_URI_NOT_ABSOLUTE,
  6436. "Attribute %s URI %s is not absolute\n",
  6437. cur->name, val);
  6438. }
  6439. if (uri->fragment != NULL) {
  6440. xmlRngPErr(ctxt, node, XML_RNGP_URI_FRAGMENT,
  6441. "Attribute %s URI %s has a fragment ID\n",
  6442. cur->name, val);
  6443. }
  6444. xmlFreeURI(uri);
  6445. }
  6446. }
  6447. xmlFree(val);
  6448. }
  6449. } else if (!xmlStrEqual(cur->name, BAD_CAST "ns")) {
  6450. xmlRngPErr(ctxt, node, XML_RNGP_UNKNOWN_ATTRIBUTE,
  6451. "Unknown attribute %s on %s\n", cur->name,
  6452. node->name);
  6453. }
  6454. }
  6455. cur = next;
  6456. }
  6457. }
  6458. /**
  6459. * xmlRelaxNGCleanupTree:
  6460. * @ctxt: a Relax-NG parser context
  6461. * @root: an xmlNodePtr subtree
  6462. *
  6463. * Cleanup the subtree from unwanted nodes for parsing, resolve
  6464. * Include and externalRef lookups.
  6465. */
  6466. static void
  6467. xmlRelaxNGCleanupTree(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr root)
  6468. {
  6469. xmlNodePtr cur, delete;
  6470. delete = NULL;
  6471. cur = root;
  6472. while (cur != NULL) {
  6473. if (delete != NULL) {
  6474. xmlUnlinkNode(delete);
  6475. xmlFreeNode(delete);
  6476. delete = NULL;
  6477. }
  6478. if (cur->type == XML_ELEMENT_NODE) {
  6479. /*
  6480. * Simplification 4.1. Annotations
  6481. */
  6482. if ((cur->ns == NULL) ||
  6483. (!xmlStrEqual(cur->ns->href, xmlRelaxNGNs))) {
  6484. if ((cur->parent != NULL) &&
  6485. (cur->parent->type == XML_ELEMENT_NODE) &&
  6486. ((xmlStrEqual(cur->parent->name, BAD_CAST "name")) ||
  6487. (xmlStrEqual(cur->parent->name, BAD_CAST "value")) ||
  6488. (xmlStrEqual(cur->parent->name, BAD_CAST "param")))) {
  6489. xmlRngPErr(ctxt, cur, XML_RNGP_FOREIGN_ELEMENT,
  6490. "element %s doesn't allow foreign elements\n",
  6491. cur->parent->name, NULL);
  6492. }
  6493. delete = cur;
  6494. goto skip_children;
  6495. } else {
  6496. xmlRelaxNGCleanupAttributes(ctxt, cur);
  6497. if (xmlStrEqual(cur->name, BAD_CAST "externalRef")) {
  6498. xmlChar *href, *ns, *base, *URL;
  6499. xmlRelaxNGDocumentPtr docu;
  6500. xmlNodePtr tmp;
  6501. xmlURIPtr uri;
  6502. ns = xmlGetProp(cur, BAD_CAST "ns");
  6503. if (ns == NULL) {
  6504. tmp = cur->parent;
  6505. while ((tmp != NULL) &&
  6506. (tmp->type == XML_ELEMENT_NODE)) {
  6507. ns = xmlGetProp(tmp, BAD_CAST "ns");
  6508. if (ns != NULL)
  6509. break;
  6510. tmp = tmp->parent;
  6511. }
  6512. }
  6513. href = xmlGetProp(cur, BAD_CAST "href");
  6514. if (href == NULL) {
  6515. xmlRngPErr(ctxt, cur, XML_RNGP_MISSING_HREF,
  6516. "xmlRelaxNGParse: externalRef has no href attribute\n",
  6517. NULL, NULL);
  6518. if (ns != NULL)
  6519. xmlFree(ns);
  6520. delete = cur;
  6521. goto skip_children;
  6522. }
  6523. uri = xmlParseURI((const char *) href);
  6524. if (uri == NULL) {
  6525. xmlRngPErr(ctxt, cur, XML_RNGP_HREF_ERROR,
  6526. "Incorrect URI for externalRef %s\n",
  6527. href, NULL);
  6528. if (ns != NULL)
  6529. xmlFree(ns);
  6530. if (href != NULL)
  6531. xmlFree(href);
  6532. delete = cur;
  6533. goto skip_children;
  6534. }
  6535. if (uri->fragment != NULL) {
  6536. xmlRngPErr(ctxt, cur, XML_RNGP_HREF_ERROR,
  6537. "Fragment forbidden in URI for externalRef %s\n",
  6538. href, NULL);
  6539. if (ns != NULL)
  6540. xmlFree(ns);
  6541. xmlFreeURI(uri);
  6542. if (href != NULL)
  6543. xmlFree(href);
  6544. delete = cur;
  6545. goto skip_children;
  6546. }
  6547. xmlFreeURI(uri);
  6548. base = xmlNodeGetBase(cur->doc, cur);
  6549. URL = xmlBuildURI(href, base);
  6550. if (URL == NULL) {
  6551. xmlRngPErr(ctxt, cur, XML_RNGP_HREF_ERROR,
  6552. "Failed to compute URL for externalRef %s\n",
  6553. href, NULL);
  6554. if (ns != NULL)
  6555. xmlFree(ns);
  6556. if (href != NULL)
  6557. xmlFree(href);
  6558. if (base != NULL)
  6559. xmlFree(base);
  6560. delete = cur;
  6561. goto skip_children;
  6562. }
  6563. if (href != NULL)
  6564. xmlFree(href);
  6565. if (base != NULL)
  6566. xmlFree(base);
  6567. docu = xmlRelaxNGLoadExternalRef(ctxt, URL, ns);
  6568. if (docu == NULL) {
  6569. xmlRngPErr(ctxt, cur, XML_RNGP_EXTERNAL_REF_FAILURE,
  6570. "Failed to load externalRef %s\n", URL,
  6571. NULL);
  6572. if (ns != NULL)
  6573. xmlFree(ns);
  6574. xmlFree(URL);
  6575. delete = cur;
  6576. goto skip_children;
  6577. }
  6578. if (ns != NULL)
  6579. xmlFree(ns);
  6580. xmlFree(URL);
  6581. cur->psvi = docu;
  6582. } else if (xmlStrEqual(cur->name, BAD_CAST "include")) {
  6583. xmlChar *href, *ns, *base, *URL;
  6584. xmlRelaxNGIncludePtr incl;
  6585. xmlNodePtr tmp;
  6586. href = xmlGetProp(cur, BAD_CAST "href");
  6587. if (href == NULL) {
  6588. xmlRngPErr(ctxt, cur, XML_RNGP_MISSING_HREF,
  6589. "xmlRelaxNGParse: include has no href attribute\n",
  6590. NULL, NULL);
  6591. delete = cur;
  6592. goto skip_children;
  6593. }
  6594. base = xmlNodeGetBase(cur->doc, cur);
  6595. URL = xmlBuildURI(href, base);
  6596. if (URL == NULL) {
  6597. xmlRngPErr(ctxt, cur, XML_RNGP_HREF_ERROR,
  6598. "Failed to compute URL for include %s\n",
  6599. href, NULL);
  6600. if (href != NULL)
  6601. xmlFree(href);
  6602. if (base != NULL)
  6603. xmlFree(base);
  6604. delete = cur;
  6605. goto skip_children;
  6606. }
  6607. if (href != NULL)
  6608. xmlFree(href);
  6609. if (base != NULL)
  6610. xmlFree(base);
  6611. ns = xmlGetProp(cur, BAD_CAST "ns");
  6612. if (ns == NULL) {
  6613. tmp = cur->parent;
  6614. while ((tmp != NULL) &&
  6615. (tmp->type == XML_ELEMENT_NODE)) {
  6616. ns = xmlGetProp(tmp, BAD_CAST "ns");
  6617. if (ns != NULL)
  6618. break;
  6619. tmp = tmp->parent;
  6620. }
  6621. }
  6622. incl = xmlRelaxNGLoadInclude(ctxt, URL, cur, ns);
  6623. if (ns != NULL)
  6624. xmlFree(ns);
  6625. if (incl == NULL) {
  6626. xmlRngPErr(ctxt, cur, XML_RNGP_INCLUDE_FAILURE,
  6627. "Failed to load include %s\n", URL,
  6628. NULL);
  6629. xmlFree(URL);
  6630. delete = cur;
  6631. goto skip_children;
  6632. }
  6633. xmlFree(URL);
  6634. cur->psvi = incl;
  6635. } else if ((xmlStrEqual(cur->name, BAD_CAST "element")) ||
  6636. (xmlStrEqual(cur->name, BAD_CAST "attribute")))
  6637. {
  6638. xmlChar *name, *ns;
  6639. xmlNodePtr text = NULL;
  6640. /*
  6641. * Simplification 4.8. name attribute of element
  6642. * and attribute elements
  6643. */
  6644. name = xmlGetProp(cur, BAD_CAST "name");
  6645. if (name != NULL) {
  6646. if (cur->children == NULL) {
  6647. text =
  6648. xmlNewChild(cur, cur->ns, BAD_CAST "name",
  6649. name);
  6650. } else {
  6651. xmlNodePtr node;
  6652. node = xmlNewDocNode(cur->doc, cur->ns,
  6653. BAD_CAST "name", NULL);
  6654. if (node != NULL) {
  6655. xmlAddPrevSibling(cur->children, node);
  6656. text = xmlNewDocText(node->doc, name);
  6657. xmlAddChild(node, text);
  6658. text = node;
  6659. }
  6660. }
  6661. if (text == NULL) {
  6662. xmlRngPErr(ctxt, cur, XML_RNGP_CREATE_FAILURE,
  6663. "Failed to create a name %s element\n",
  6664. name, NULL);
  6665. }
  6666. xmlUnsetProp(cur, BAD_CAST "name");
  6667. xmlFree(name);
  6668. ns = xmlGetProp(cur, BAD_CAST "ns");
  6669. if (ns != NULL) {
  6670. if (text != NULL) {
  6671. xmlSetProp(text, BAD_CAST "ns", ns);
  6672. /* xmlUnsetProp(cur, BAD_CAST "ns"); */
  6673. }
  6674. xmlFree(ns);
  6675. } else if (xmlStrEqual(cur->name,
  6676. BAD_CAST "attribute")) {
  6677. xmlSetProp(text, BAD_CAST "ns", BAD_CAST "");
  6678. }
  6679. }
  6680. } else if ((xmlStrEqual(cur->name, BAD_CAST "name")) ||
  6681. (xmlStrEqual(cur->name, BAD_CAST "nsName")) ||
  6682. (xmlStrEqual(cur->name, BAD_CAST "value"))) {
  6683. /*
  6684. * Simplification 4.8. name attribute of element
  6685. * and attribute elements
  6686. */
  6687. if (xmlHasProp(cur, BAD_CAST "ns") == NULL) {
  6688. xmlNodePtr node;
  6689. xmlChar *ns = NULL;
  6690. node = cur->parent;
  6691. while ((node != NULL) &&
  6692. (node->type == XML_ELEMENT_NODE)) {
  6693. ns = xmlGetProp(node, BAD_CAST "ns");
  6694. if (ns != NULL) {
  6695. break;
  6696. }
  6697. node = node->parent;
  6698. }
  6699. if (ns == NULL) {
  6700. xmlSetProp(cur, BAD_CAST "ns", BAD_CAST "");
  6701. } else {
  6702. xmlSetProp(cur, BAD_CAST "ns", ns);
  6703. xmlFree(ns);
  6704. }
  6705. }
  6706. if (xmlStrEqual(cur->name, BAD_CAST "name")) {
  6707. xmlChar *name, *local, *prefix;
  6708. /*
  6709. * Simplification: 4.10. QNames
  6710. */
  6711. name = xmlNodeGetContent(cur);
  6712. if (name != NULL) {
  6713. local = xmlSplitQName2(name, &prefix);
  6714. if (local != NULL) {
  6715. xmlNsPtr ns;
  6716. ns = xmlSearchNs(cur->doc, cur, prefix);
  6717. if (ns == NULL) {
  6718. xmlRngPErr(ctxt, cur,
  6719. XML_RNGP_PREFIX_UNDEFINED,
  6720. "xmlRelaxNGParse: no namespace for prefix %s\n",
  6721. prefix, NULL);
  6722. } else {
  6723. xmlSetProp(cur, BAD_CAST "ns",
  6724. ns->href);
  6725. xmlNodeSetContent(cur, local);
  6726. }
  6727. xmlFree(local);
  6728. xmlFree(prefix);
  6729. }
  6730. xmlFree(name);
  6731. }
  6732. }
  6733. /*
  6734. * 4.16
  6735. */
  6736. if (xmlStrEqual(cur->name, BAD_CAST "nsName")) {
  6737. if (ctxt->flags & XML_RELAXNG_IN_NSEXCEPT) {
  6738. xmlRngPErr(ctxt, cur,
  6739. XML_RNGP_PAT_NSNAME_EXCEPT_NSNAME,
  6740. "Found nsName/except//nsName forbidden construct\n",
  6741. NULL, NULL);
  6742. }
  6743. }
  6744. } else if ((xmlStrEqual(cur->name, BAD_CAST "except")) &&
  6745. (cur != root)) {
  6746. int oldflags = ctxt->flags;
  6747. /*
  6748. * 4.16
  6749. */
  6750. if ((cur->parent != NULL) &&
  6751. (xmlStrEqual
  6752. (cur->parent->name, BAD_CAST "anyName"))) {
  6753. ctxt->flags |= XML_RELAXNG_IN_ANYEXCEPT;
  6754. xmlRelaxNGCleanupTree(ctxt, cur);
  6755. ctxt->flags = oldflags;
  6756. goto skip_children;
  6757. } else if ((cur->parent != NULL) &&
  6758. (xmlStrEqual
  6759. (cur->parent->name, BAD_CAST "nsName"))) {
  6760. ctxt->flags |= XML_RELAXNG_IN_NSEXCEPT;
  6761. xmlRelaxNGCleanupTree(ctxt, cur);
  6762. ctxt->flags = oldflags;
  6763. goto skip_children;
  6764. }
  6765. } else if (xmlStrEqual(cur->name, BAD_CAST "anyName")) {
  6766. /*
  6767. * 4.16
  6768. */
  6769. if (ctxt->flags & XML_RELAXNG_IN_ANYEXCEPT) {
  6770. xmlRngPErr(ctxt, cur,
  6771. XML_RNGP_PAT_ANYNAME_EXCEPT_ANYNAME,
  6772. "Found anyName/except//anyName forbidden construct\n",
  6773. NULL, NULL);
  6774. } else if (ctxt->flags & XML_RELAXNG_IN_NSEXCEPT) {
  6775. xmlRngPErr(ctxt, cur,
  6776. XML_RNGP_PAT_NSNAME_EXCEPT_ANYNAME,
  6777. "Found nsName/except//anyName forbidden construct\n",
  6778. NULL, NULL);
  6779. }
  6780. }
  6781. /*
  6782. * This is not an else since "include" is transformed
  6783. * into a div
  6784. */
  6785. if (xmlStrEqual(cur->name, BAD_CAST "div")) {
  6786. xmlChar *ns;
  6787. xmlNodePtr child, ins, tmp;
  6788. /*
  6789. * implements rule 4.11
  6790. */
  6791. ns = xmlGetProp(cur, BAD_CAST "ns");
  6792. child = cur->children;
  6793. ins = cur;
  6794. while (child != NULL) {
  6795. if (ns != NULL) {
  6796. if (!xmlHasProp(child, BAD_CAST "ns")) {
  6797. xmlSetProp(child, BAD_CAST "ns", ns);
  6798. }
  6799. }
  6800. tmp = child->next;
  6801. xmlUnlinkNode(child);
  6802. ins = xmlAddNextSibling(ins, child);
  6803. child = tmp;
  6804. }
  6805. if (ns != NULL)
  6806. xmlFree(ns);
  6807. /*
  6808. * Since we are about to delete cur, if its nsDef is non-NULL we
  6809. * need to preserve it (it contains the ns definitions for the
  6810. * children we just moved). We'll just stick it on to the end
  6811. * of cur->parent's list, since it's never going to be re-serialized
  6812. * (bug 143738).
  6813. */
  6814. if ((cur->nsDef != NULL) && (cur->parent != NULL)) {
  6815. xmlNsPtr parDef = (xmlNsPtr)&cur->parent->nsDef;
  6816. while (parDef->next != NULL)
  6817. parDef = parDef->next;
  6818. parDef->next = cur->nsDef;
  6819. cur->nsDef = NULL;
  6820. }
  6821. delete = cur;
  6822. goto skip_children;
  6823. }
  6824. }
  6825. }
  6826. /*
  6827. * Simplification 4.2 whitespaces
  6828. */
  6829. else if ((cur->type == XML_TEXT_NODE) ||
  6830. (cur->type == XML_CDATA_SECTION_NODE)) {
  6831. if (IS_BLANK_NODE(cur)) {
  6832. if ((cur->parent != NULL) &&
  6833. (cur->parent->type == XML_ELEMENT_NODE)) {
  6834. if ((!xmlStrEqual(cur->parent->name, BAD_CAST "value"))
  6835. &&
  6836. (!xmlStrEqual
  6837. (cur->parent->name, BAD_CAST "param")))
  6838. delete = cur;
  6839. } else {
  6840. delete = cur;
  6841. goto skip_children;
  6842. }
  6843. }
  6844. } else {
  6845. delete = cur;
  6846. goto skip_children;
  6847. }
  6848. /*
  6849. * Skip to next node
  6850. */
  6851. if (cur->children != NULL) {
  6852. if ((cur->children->type != XML_ENTITY_DECL) &&
  6853. (cur->children->type != XML_ENTITY_REF_NODE) &&
  6854. (cur->children->type != XML_ENTITY_NODE)) {
  6855. cur = cur->children;
  6856. continue;
  6857. }
  6858. }
  6859. skip_children:
  6860. if (cur->next != NULL) {
  6861. cur = cur->next;
  6862. continue;
  6863. }
  6864. do {
  6865. cur = cur->parent;
  6866. if (cur == NULL)
  6867. break;
  6868. if (cur == root) {
  6869. cur = NULL;
  6870. break;
  6871. }
  6872. if (cur->next != NULL) {
  6873. cur = cur->next;
  6874. break;
  6875. }
  6876. } while (cur != NULL);
  6877. }
  6878. if (delete != NULL) {
  6879. xmlUnlinkNode(delete);
  6880. xmlFreeNode(delete);
  6881. delete = NULL;
  6882. }
  6883. }
  6884. /**
  6885. * xmlRelaxNGCleanupDoc:
  6886. * @ctxt: a Relax-NG parser context
  6887. * @doc: an xmldocPtr document pointer
  6888. *
  6889. * Cleanup the document from unwanted nodes for parsing, resolve
  6890. * Include and externalRef lookups.
  6891. *
  6892. * Returns the cleaned up document or NULL in case of error
  6893. */
  6894. static xmlDocPtr
  6895. xmlRelaxNGCleanupDoc(xmlRelaxNGParserCtxtPtr ctxt, xmlDocPtr doc)
  6896. {
  6897. xmlNodePtr root;
  6898. /*
  6899. * Extract the root
  6900. */
  6901. root = xmlDocGetRootElement(doc);
  6902. if (root == NULL) {
  6903. xmlRngPErr(ctxt, (xmlNodePtr) doc, XML_RNGP_EMPTY, "xmlRelaxNGParse: %s is empty\n",
  6904. ctxt->URL, NULL);
  6905. return (NULL);
  6906. }
  6907. xmlRelaxNGCleanupTree(ctxt, root);
  6908. return (doc);
  6909. }
  6910. /**
  6911. * xmlRelaxNGParse:
  6912. * @ctxt: a Relax-NG parser context
  6913. *
  6914. * parse a schema definition resource and build an internal
  6915. * XML Schema structure which can be used to validate instances.
  6916. *
  6917. * Returns the internal XML RelaxNG structure built from the resource or
  6918. * NULL in case of error
  6919. */
  6920. xmlRelaxNGPtr
  6921. xmlRelaxNGParse(xmlRelaxNGParserCtxtPtr ctxt)
  6922. {
  6923. xmlRelaxNGPtr ret = NULL;
  6924. xmlDocPtr doc;
  6925. xmlNodePtr root;
  6926. xmlRelaxNGInitTypes();
  6927. if (ctxt == NULL)
  6928. return (NULL);
  6929. /*
  6930. * First step is to parse the input document into an DOM/Infoset
  6931. */
  6932. if (ctxt->URL != NULL) {
  6933. doc = xmlReadFile((const char *) ctxt->URL,NULL,0);
  6934. if (doc == NULL) {
  6935. xmlRngPErr(ctxt, NULL, XML_RNGP_PARSE_ERROR,
  6936. "xmlRelaxNGParse: could not load %s\n", ctxt->URL,
  6937. NULL);
  6938. return (NULL);
  6939. }
  6940. } else if (ctxt->buffer != NULL) {
  6941. doc = xmlReadMemory(ctxt->buffer, ctxt->size,NULL,NULL,0);
  6942. if (doc == NULL) {
  6943. xmlRngPErr(ctxt, NULL, XML_RNGP_PARSE_ERROR,
  6944. "xmlRelaxNGParse: could not parse schemas\n", NULL,
  6945. NULL);
  6946. return (NULL);
  6947. }
  6948. doc->URL = xmlStrdup(BAD_CAST "in_memory_buffer");
  6949. ctxt->URL = xmlStrdup(BAD_CAST "in_memory_buffer");
  6950. } else if (ctxt->document != NULL) {
  6951. doc = ctxt->document;
  6952. } else {
  6953. xmlRngPErr(ctxt, NULL, XML_RNGP_EMPTY,
  6954. "xmlRelaxNGParse: nothing to parse\n", NULL, NULL);
  6955. return (NULL);
  6956. }
  6957. ctxt->document = doc;
  6958. /*
  6959. * Some preprocessing of the document content
  6960. */
  6961. doc = xmlRelaxNGCleanupDoc(ctxt, doc);
  6962. if (doc == NULL) {
  6963. xmlFreeDoc(ctxt->document);
  6964. ctxt->document = NULL;
  6965. return (NULL);
  6966. }
  6967. /*
  6968. * Then do the parsing for good
  6969. */
  6970. root = xmlDocGetRootElement(doc);
  6971. if (root == NULL) {
  6972. xmlRngPErr(ctxt, (xmlNodePtr) doc,
  6973. XML_RNGP_EMPTY, "xmlRelaxNGParse: %s is empty\n",
  6974. (ctxt->URL ? ctxt->URL : BAD_CAST "schemas"), NULL);
  6975. xmlFreeDoc(ctxt->document);
  6976. ctxt->document = NULL;
  6977. return (NULL);
  6978. }
  6979. ret = xmlRelaxNGParseDocument(ctxt, root);
  6980. if (ret == NULL) {
  6981. xmlFreeDoc(ctxt->document);
  6982. ctxt->document = NULL;
  6983. return (NULL);
  6984. }
  6985. /*
  6986. * Check the ref/defines links
  6987. */
  6988. /*
  6989. * try to preprocess interleaves
  6990. */
  6991. if (ctxt->interleaves != NULL) {
  6992. xmlHashScan(ctxt->interleaves, xmlRelaxNGComputeInterleaves, ctxt);
  6993. }
  6994. /*
  6995. * if there was a parsing error return NULL
  6996. */
  6997. if (ctxt->nbErrors > 0) {
  6998. xmlRelaxNGFree(ret);
  6999. ctxt->document = NULL;
  7000. xmlFreeDoc(doc);
  7001. return (NULL);
  7002. }
  7003. /*
  7004. * try to compile (parts of) the schemas
  7005. */
  7006. if ((ret->topgrammar != NULL) && (ret->topgrammar->start != NULL)) {
  7007. if (ret->topgrammar->start->type != XML_RELAXNG_START) {
  7008. xmlRelaxNGDefinePtr def;
  7009. def = xmlRelaxNGNewDefine(ctxt, NULL);
  7010. if (def != NULL) {
  7011. def->type = XML_RELAXNG_START;
  7012. def->content = ret->topgrammar->start;
  7013. ret->topgrammar->start = def;
  7014. }
  7015. }
  7016. xmlRelaxNGTryCompile(ctxt, ret->topgrammar->start);
  7017. }
  7018. /*
  7019. * Transfer the pointer for cleanup at the schema level.
  7020. */
  7021. ret->doc = doc;
  7022. ctxt->document = NULL;
  7023. ret->documents = ctxt->documents;
  7024. ctxt->documents = NULL;
  7025. ret->includes = ctxt->includes;
  7026. ctxt->includes = NULL;
  7027. ret->defNr = ctxt->defNr;
  7028. ret->defTab = ctxt->defTab;
  7029. ctxt->defTab = NULL;
  7030. if (ctxt->idref == 1)
  7031. ret->idref = 1;
  7032. return (ret);
  7033. }
  7034. /**
  7035. * xmlRelaxNGSetParserErrors:
  7036. * @ctxt: a Relax-NG validation context
  7037. * @err: the error callback
  7038. * @warn: the warning callback
  7039. * @ctx: contextual data for the callbacks
  7040. *
  7041. * Set the callback functions used to handle errors for a validation context
  7042. */
  7043. void
  7044. xmlRelaxNGSetParserErrors(xmlRelaxNGParserCtxtPtr ctxt,
  7045. xmlRelaxNGValidityErrorFunc err,
  7046. xmlRelaxNGValidityWarningFunc warn, void *ctx)
  7047. {
  7048. if (ctxt == NULL)
  7049. return;
  7050. ctxt->error = err;
  7051. ctxt->warning = warn;
  7052. ctxt->serror = NULL;
  7053. ctxt->userData = ctx;
  7054. }
  7055. /**
  7056. * xmlRelaxNGGetParserErrors:
  7057. * @ctxt: a Relax-NG validation context
  7058. * @err: the error callback result
  7059. * @warn: the warning callback result
  7060. * @ctx: contextual data for the callbacks result
  7061. *
  7062. * Get the callback information used to handle errors for a validation context
  7063. *
  7064. * Returns -1 in case of failure, 0 otherwise.
  7065. */
  7066. int
  7067. xmlRelaxNGGetParserErrors(xmlRelaxNGParserCtxtPtr ctxt,
  7068. xmlRelaxNGValidityErrorFunc * err,
  7069. xmlRelaxNGValidityWarningFunc * warn, void **ctx)
  7070. {
  7071. if (ctxt == NULL)
  7072. return (-1);
  7073. if (err != NULL)
  7074. *err = ctxt->error;
  7075. if (warn != NULL)
  7076. *warn = ctxt->warning;
  7077. if (ctx != NULL)
  7078. *ctx = ctxt->userData;
  7079. return (0);
  7080. }
  7081. /**
  7082. * xmlRelaxNGSetParserStructuredErrors:
  7083. * @ctxt: a Relax-NG parser context
  7084. * @serror: the error callback
  7085. * @ctx: contextual data for the callbacks
  7086. *
  7087. * Set the callback functions used to handle errors for a parsing context
  7088. */
  7089. void
  7090. xmlRelaxNGSetParserStructuredErrors(xmlRelaxNGParserCtxtPtr ctxt,
  7091. xmlStructuredErrorFunc serror,
  7092. void *ctx)
  7093. {
  7094. if (ctxt == NULL)
  7095. return;
  7096. ctxt->serror = serror;
  7097. ctxt->error = NULL;
  7098. ctxt->warning = NULL;
  7099. ctxt->userData = ctx;
  7100. }
  7101. #ifdef LIBXML_OUTPUT_ENABLED
  7102. /************************************************************************
  7103. * *
  7104. * Dump back a compiled form *
  7105. * *
  7106. ************************************************************************/
  7107. static void xmlRelaxNGDumpDefine(FILE * output,
  7108. xmlRelaxNGDefinePtr define);
  7109. /**
  7110. * xmlRelaxNGDumpDefines:
  7111. * @output: the file output
  7112. * @defines: a list of define structures
  7113. *
  7114. * Dump a RelaxNG structure back
  7115. */
  7116. static void
  7117. xmlRelaxNGDumpDefines(FILE * output, xmlRelaxNGDefinePtr defines)
  7118. {
  7119. while (defines != NULL) {
  7120. xmlRelaxNGDumpDefine(output, defines);
  7121. defines = defines->next;
  7122. }
  7123. }
  7124. /**
  7125. * xmlRelaxNGDumpDefine:
  7126. * @output: the file output
  7127. * @define: a define structure
  7128. *
  7129. * Dump a RelaxNG structure back
  7130. */
  7131. static void
  7132. xmlRelaxNGDumpDefine(FILE * output, xmlRelaxNGDefinePtr define)
  7133. {
  7134. if (define == NULL)
  7135. return;
  7136. switch (define->type) {
  7137. case XML_RELAXNG_EMPTY:
  7138. fprintf(output, "<empty/>\n");
  7139. break;
  7140. case XML_RELAXNG_NOT_ALLOWED:
  7141. fprintf(output, "<notAllowed/>\n");
  7142. break;
  7143. case XML_RELAXNG_TEXT:
  7144. fprintf(output, "<text/>\n");
  7145. break;
  7146. case XML_RELAXNG_ELEMENT:
  7147. fprintf(output, "<element>\n");
  7148. if (define->name != NULL) {
  7149. fprintf(output, "<name");
  7150. if (define->ns != NULL)
  7151. fprintf(output, " ns=\"%s\"", define->ns);
  7152. fprintf(output, ">%s</name>\n", define->name);
  7153. }
  7154. xmlRelaxNGDumpDefines(output, define->attrs);
  7155. xmlRelaxNGDumpDefines(output, define->content);
  7156. fprintf(output, "</element>\n");
  7157. break;
  7158. case XML_RELAXNG_LIST:
  7159. fprintf(output, "<list>\n");
  7160. xmlRelaxNGDumpDefines(output, define->content);
  7161. fprintf(output, "</list>\n");
  7162. break;
  7163. case XML_RELAXNG_ONEORMORE:
  7164. fprintf(output, "<oneOrMore>\n");
  7165. xmlRelaxNGDumpDefines(output, define->content);
  7166. fprintf(output, "</oneOrMore>\n");
  7167. break;
  7168. case XML_RELAXNG_ZEROORMORE:
  7169. fprintf(output, "<zeroOrMore>\n");
  7170. xmlRelaxNGDumpDefines(output, define->content);
  7171. fprintf(output, "</zeroOrMore>\n");
  7172. break;
  7173. case XML_RELAXNG_CHOICE:
  7174. fprintf(output, "<choice>\n");
  7175. xmlRelaxNGDumpDefines(output, define->content);
  7176. fprintf(output, "</choice>\n");
  7177. break;
  7178. case XML_RELAXNG_GROUP:
  7179. fprintf(output, "<group>\n");
  7180. xmlRelaxNGDumpDefines(output, define->content);
  7181. fprintf(output, "</group>\n");
  7182. break;
  7183. case XML_RELAXNG_INTERLEAVE:
  7184. fprintf(output, "<interleave>\n");
  7185. xmlRelaxNGDumpDefines(output, define->content);
  7186. fprintf(output, "</interleave>\n");
  7187. break;
  7188. case XML_RELAXNG_OPTIONAL:
  7189. fprintf(output, "<optional>\n");
  7190. xmlRelaxNGDumpDefines(output, define->content);
  7191. fprintf(output, "</optional>\n");
  7192. break;
  7193. case XML_RELAXNG_ATTRIBUTE:
  7194. fprintf(output, "<attribute>\n");
  7195. xmlRelaxNGDumpDefines(output, define->content);
  7196. fprintf(output, "</attribute>\n");
  7197. break;
  7198. case XML_RELAXNG_DEF:
  7199. fprintf(output, "<define");
  7200. if (define->name != NULL)
  7201. fprintf(output, " name=\"%s\"", define->name);
  7202. fprintf(output, ">\n");
  7203. xmlRelaxNGDumpDefines(output, define->content);
  7204. fprintf(output, "</define>\n");
  7205. break;
  7206. case XML_RELAXNG_REF:
  7207. fprintf(output, "<ref");
  7208. if (define->name != NULL)
  7209. fprintf(output, " name=\"%s\"", define->name);
  7210. fprintf(output, ">\n");
  7211. xmlRelaxNGDumpDefines(output, define->content);
  7212. fprintf(output, "</ref>\n");
  7213. break;
  7214. case XML_RELAXNG_PARENTREF:
  7215. fprintf(output, "<parentRef");
  7216. if (define->name != NULL)
  7217. fprintf(output, " name=\"%s\"", define->name);
  7218. fprintf(output, ">\n");
  7219. xmlRelaxNGDumpDefines(output, define->content);
  7220. fprintf(output, "</parentRef>\n");
  7221. break;
  7222. case XML_RELAXNG_EXTERNALREF:
  7223. fprintf(output, "<externalRef>");
  7224. xmlRelaxNGDumpDefines(output, define->content);
  7225. fprintf(output, "</externalRef>\n");
  7226. break;
  7227. case XML_RELAXNG_DATATYPE:
  7228. case XML_RELAXNG_VALUE:
  7229. TODO break;
  7230. case XML_RELAXNG_START:
  7231. case XML_RELAXNG_EXCEPT:
  7232. case XML_RELAXNG_PARAM:
  7233. TODO break;
  7234. case XML_RELAXNG_NOOP:
  7235. xmlRelaxNGDumpDefines(output, define->content);
  7236. break;
  7237. }
  7238. }
  7239. /**
  7240. * xmlRelaxNGDumpGrammar:
  7241. * @output: the file output
  7242. * @grammar: a grammar structure
  7243. * @top: is this a top grammar
  7244. *
  7245. * Dump a RelaxNG structure back
  7246. */
  7247. static void
  7248. xmlRelaxNGDumpGrammar(FILE * output, xmlRelaxNGGrammarPtr grammar, int top)
  7249. {
  7250. if (grammar == NULL)
  7251. return;
  7252. fprintf(output, "<grammar");
  7253. if (top)
  7254. fprintf(output, " xmlns=\"http://relaxng.org/ns/structure/1.0\"");
  7255. switch (grammar->combine) {
  7256. case XML_RELAXNG_COMBINE_UNDEFINED:
  7257. break;
  7258. case XML_RELAXNG_COMBINE_CHOICE:
  7259. fprintf(output, " combine=\"choice\"");
  7260. break;
  7261. case XML_RELAXNG_COMBINE_INTERLEAVE:
  7262. fprintf(output, " combine=\"interleave\"");
  7263. break;
  7264. default:
  7265. fprintf(output, " <!-- invalid combine value -->");
  7266. }
  7267. fprintf(output, ">\n");
  7268. if (grammar->start == NULL) {
  7269. fprintf(output, " <!-- grammar had no start -->");
  7270. } else {
  7271. fprintf(output, "<start>\n");
  7272. xmlRelaxNGDumpDefine(output, grammar->start);
  7273. fprintf(output, "</start>\n");
  7274. }
  7275. /* TODO ? Dump the defines ? */
  7276. fprintf(output, "</grammar>\n");
  7277. }
  7278. /**
  7279. * xmlRelaxNGDump:
  7280. * @output: the file output
  7281. * @schema: a schema structure
  7282. *
  7283. * Dump a RelaxNG structure back
  7284. */
  7285. void
  7286. xmlRelaxNGDump(FILE * output, xmlRelaxNGPtr schema)
  7287. {
  7288. if (output == NULL)
  7289. return;
  7290. if (schema == NULL) {
  7291. fprintf(output, "RelaxNG empty or failed to compile\n");
  7292. return;
  7293. }
  7294. fprintf(output, "RelaxNG: ");
  7295. if (schema->doc == NULL) {
  7296. fprintf(output, "no document\n");
  7297. } else if (schema->doc->URL != NULL) {
  7298. fprintf(output, "%s\n", schema->doc->URL);
  7299. } else {
  7300. fprintf(output, "\n");
  7301. }
  7302. if (schema->topgrammar == NULL) {
  7303. fprintf(output, "RelaxNG has no top grammar\n");
  7304. return;
  7305. }
  7306. xmlRelaxNGDumpGrammar(output, schema->topgrammar, 1);
  7307. }
  7308. /**
  7309. * xmlRelaxNGDumpTree:
  7310. * @output: the file output
  7311. * @schema: a schema structure
  7312. *
  7313. * Dump the transformed RelaxNG tree.
  7314. */
  7315. void
  7316. xmlRelaxNGDumpTree(FILE * output, xmlRelaxNGPtr schema)
  7317. {
  7318. if (output == NULL)
  7319. return;
  7320. if (schema == NULL) {
  7321. fprintf(output, "RelaxNG empty or failed to compile\n");
  7322. return;
  7323. }
  7324. if (schema->doc == NULL) {
  7325. fprintf(output, "no document\n");
  7326. } else {
  7327. xmlDocDump(output, schema->doc);
  7328. }
  7329. }
  7330. #endif /* LIBXML_OUTPUT_ENABLED */
  7331. /************************************************************************
  7332. * *
  7333. * Validation of compiled content *
  7334. * *
  7335. ************************************************************************/
  7336. static int xmlRelaxNGValidateDefinition(xmlRelaxNGValidCtxtPtr ctxt,
  7337. xmlRelaxNGDefinePtr define);
  7338. /**
  7339. * xmlRelaxNGValidateCompiledCallback:
  7340. * @exec: the regular expression instance
  7341. * @token: the token which matched
  7342. * @transdata: callback data, the define for the subelement if available
  7343. @ @inputdata: callback data, the Relax NG validation context
  7344. *
  7345. * Handle the callback and if needed validate the element children.
  7346. */
  7347. static void
  7348. xmlRelaxNGValidateCompiledCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED,
  7349. const xmlChar * token,
  7350. void *transdata, void *inputdata)
  7351. {
  7352. xmlRelaxNGValidCtxtPtr ctxt = (xmlRelaxNGValidCtxtPtr) inputdata;
  7353. xmlRelaxNGDefinePtr define = (xmlRelaxNGDefinePtr) transdata;
  7354. int ret;
  7355. if (ctxt == NULL) {
  7356. fprintf(stderr, "callback on %s missing context\n", token);
  7357. return;
  7358. }
  7359. if (define == NULL) {
  7360. if (token[0] == '#')
  7361. return;
  7362. fprintf(stderr, "callback on %s missing define\n", token);
  7363. if ((ctxt != NULL) && (ctxt->errNo == XML_RELAXNG_OK))
  7364. ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
  7365. return;
  7366. }
  7367. if (define->type != XML_RELAXNG_ELEMENT) {
  7368. fprintf(stderr, "callback on %s define is not element\n", token);
  7369. if (ctxt->errNo == XML_RELAXNG_OK)
  7370. ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
  7371. return;
  7372. }
  7373. ret = xmlRelaxNGValidateDefinition(ctxt, define);
  7374. if (ret != 0)
  7375. ctxt->perr = ret;
  7376. }
  7377. /**
  7378. * xmlRelaxNGValidateCompiledContent:
  7379. * @ctxt: the RelaxNG validation context
  7380. * @regexp: the regular expression as compiled
  7381. * @content: list of children to test against the regexp
  7382. *
  7383. * Validate the content model of an element or start using the regexp
  7384. *
  7385. * Returns 0 in case of success, -1 in case of error.
  7386. */
  7387. static int
  7388. xmlRelaxNGValidateCompiledContent(xmlRelaxNGValidCtxtPtr ctxt,
  7389. xmlRegexpPtr regexp, xmlNodePtr content)
  7390. {
  7391. xmlRegExecCtxtPtr exec;
  7392. xmlNodePtr cur;
  7393. int ret = 0;
  7394. int oldperr;
  7395. if ((ctxt == NULL) || (regexp == NULL))
  7396. return (-1);
  7397. oldperr = ctxt->perr;
  7398. exec = xmlRegNewExecCtxt(regexp,
  7399. xmlRelaxNGValidateCompiledCallback, ctxt);
  7400. ctxt->perr = 0;
  7401. cur = content;
  7402. while (cur != NULL) {
  7403. ctxt->state->seq = cur;
  7404. switch (cur->type) {
  7405. case XML_TEXT_NODE:
  7406. case XML_CDATA_SECTION_NODE:
  7407. if (xmlIsBlankNode(cur))
  7408. break;
  7409. ret = xmlRegExecPushString(exec, BAD_CAST "#text", ctxt);
  7410. if (ret < 0) {
  7411. VALID_ERR2(XML_RELAXNG_ERR_TEXTWRONG,
  7412. cur->parent->name);
  7413. }
  7414. break;
  7415. case XML_ELEMENT_NODE:
  7416. if (cur->ns != NULL) {
  7417. ret = xmlRegExecPushString2(exec, cur->name,
  7418. cur->ns->href, ctxt);
  7419. } else {
  7420. ret = xmlRegExecPushString(exec, cur->name, ctxt);
  7421. }
  7422. if (ret < 0) {
  7423. VALID_ERR2(XML_RELAXNG_ERR_ELEMWRONG, cur->name);
  7424. }
  7425. break;
  7426. default:
  7427. break;
  7428. }
  7429. if (ret < 0)
  7430. break;
  7431. /*
  7432. * Switch to next element
  7433. */
  7434. cur = cur->next;
  7435. }
  7436. ret = xmlRegExecPushString(exec, NULL, NULL);
  7437. if (ret == 1) {
  7438. ret = 0;
  7439. ctxt->state->seq = NULL;
  7440. } else if (ret == 0) {
  7441. /*
  7442. * TODO: get some of the names needed to exit the current state of exec
  7443. */
  7444. VALID_ERR2(XML_RELAXNG_ERR_NOELEM, BAD_CAST "");
  7445. ret = -1;
  7446. if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
  7447. xmlRelaxNGDumpValidError(ctxt);
  7448. } else {
  7449. ret = -1;
  7450. }
  7451. xmlRegFreeExecCtxt(exec);
  7452. /*
  7453. * There might be content model errors outside of the pure
  7454. * regexp validation, e.g. for attribute values.
  7455. */
  7456. if ((ret == 0) && (ctxt->perr != 0)) {
  7457. ret = ctxt->perr;
  7458. }
  7459. ctxt->perr = oldperr;
  7460. return (ret);
  7461. }
  7462. /************************************************************************
  7463. * *
  7464. * Progressive validation of when possible *
  7465. * *
  7466. ************************************************************************/
  7467. static int xmlRelaxNGValidateAttributeList(xmlRelaxNGValidCtxtPtr ctxt,
  7468. xmlRelaxNGDefinePtr defines);
  7469. static int xmlRelaxNGValidateElementEnd(xmlRelaxNGValidCtxtPtr ctxt,
  7470. int dolog);
  7471. static void xmlRelaxNGLogBestError(xmlRelaxNGValidCtxtPtr ctxt);
  7472. /**
  7473. * xmlRelaxNGElemPush:
  7474. * @ctxt: the validation context
  7475. * @exec: the regexp runtime for the new content model
  7476. *
  7477. * Push a new regexp for the current node content model on the stack
  7478. *
  7479. * Returns 0 in case of success and -1 in case of error.
  7480. */
  7481. static int
  7482. xmlRelaxNGElemPush(xmlRelaxNGValidCtxtPtr ctxt, xmlRegExecCtxtPtr exec)
  7483. {
  7484. if (ctxt->elemTab == NULL) {
  7485. ctxt->elemMax = 10;
  7486. ctxt->elemTab = (xmlRegExecCtxtPtr *) xmlMalloc(ctxt->elemMax *
  7487. sizeof
  7488. (xmlRegExecCtxtPtr));
  7489. if (ctxt->elemTab == NULL) {
  7490. xmlRngVErrMemory(ctxt, "validating\n");
  7491. return (-1);
  7492. }
  7493. }
  7494. if (ctxt->elemNr >= ctxt->elemMax) {
  7495. ctxt->elemMax *= 2;
  7496. ctxt->elemTab = (xmlRegExecCtxtPtr *) xmlRealloc(ctxt->elemTab,
  7497. ctxt->elemMax *
  7498. sizeof
  7499. (xmlRegExecCtxtPtr));
  7500. if (ctxt->elemTab == NULL) {
  7501. xmlRngVErrMemory(ctxt, "validating\n");
  7502. return (-1);
  7503. }
  7504. }
  7505. ctxt->elemTab[ctxt->elemNr++] = exec;
  7506. ctxt->elem = exec;
  7507. return (0);
  7508. }
  7509. /**
  7510. * xmlRelaxNGElemPop:
  7511. * @ctxt: the validation context
  7512. *
  7513. * Pop the regexp of the current node content model from the stack
  7514. *
  7515. * Returns the exec or NULL if empty
  7516. */
  7517. static xmlRegExecCtxtPtr
  7518. xmlRelaxNGElemPop(xmlRelaxNGValidCtxtPtr ctxt)
  7519. {
  7520. xmlRegExecCtxtPtr ret;
  7521. if (ctxt->elemNr <= 0)
  7522. return (NULL);
  7523. ctxt->elemNr--;
  7524. ret = ctxt->elemTab[ctxt->elemNr];
  7525. ctxt->elemTab[ctxt->elemNr] = NULL;
  7526. if (ctxt->elemNr > 0)
  7527. ctxt->elem = ctxt->elemTab[ctxt->elemNr - 1];
  7528. else
  7529. ctxt->elem = NULL;
  7530. return (ret);
  7531. }
  7532. /**
  7533. * xmlRelaxNGValidateProgressiveCallback:
  7534. * @exec: the regular expression instance
  7535. * @token: the token which matched
  7536. * @transdata: callback data, the define for the subelement if available
  7537. @ @inputdata: callback data, the Relax NG validation context
  7538. *
  7539. * Handle the callback and if needed validate the element children.
  7540. * some of the in/out information are passed via the context in @inputdata.
  7541. */
  7542. static void
  7543. xmlRelaxNGValidateProgressiveCallback(xmlRegExecCtxtPtr exec
  7544. ATTRIBUTE_UNUSED,
  7545. const xmlChar * token,
  7546. void *transdata, void *inputdata)
  7547. {
  7548. xmlRelaxNGValidCtxtPtr ctxt = (xmlRelaxNGValidCtxtPtr) inputdata;
  7549. xmlRelaxNGDefinePtr define = (xmlRelaxNGDefinePtr) transdata;
  7550. xmlRelaxNGValidStatePtr state, oldstate;
  7551. xmlNodePtr node;
  7552. int ret = 0, oldflags;
  7553. if (ctxt == NULL) {
  7554. fprintf(stderr, "callback on %s missing context\n", token);
  7555. return;
  7556. }
  7557. node = ctxt->pnode;
  7558. ctxt->pstate = 1;
  7559. if (define == NULL) {
  7560. if (token[0] == '#')
  7561. return;
  7562. fprintf(stderr, "callback on %s missing define\n", token);
  7563. if ((ctxt != NULL) && (ctxt->errNo == XML_RELAXNG_OK))
  7564. ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
  7565. ctxt->pstate = -1;
  7566. return;
  7567. }
  7568. if ((ctxt == NULL) || (define == NULL)) {
  7569. fprintf(stderr, "callback on %s missing info\n", token);
  7570. if ((ctxt != NULL) && (ctxt->errNo == XML_RELAXNG_OK))
  7571. ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
  7572. ctxt->pstate = -1;
  7573. return;
  7574. } else if (define->type != XML_RELAXNG_ELEMENT) {
  7575. fprintf(stderr, "callback on %s define is not element\n", token);
  7576. if (ctxt->errNo == XML_RELAXNG_OK)
  7577. ctxt->errNo = XML_RELAXNG_ERR_INTERNAL;
  7578. ctxt->pstate = -1;
  7579. return;
  7580. }
  7581. if (node->type != XML_ELEMENT_NODE) {
  7582. VALID_ERR(XML_RELAXNG_ERR_NOTELEM);
  7583. if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
  7584. xmlRelaxNGDumpValidError(ctxt);
  7585. ctxt->pstate = -1;
  7586. return;
  7587. }
  7588. if (define->contModel == NULL) {
  7589. /*
  7590. * this node cannot be validated in a streamable fashion
  7591. */
  7592. ctxt->pstate = 0;
  7593. ctxt->pdef = define;
  7594. return;
  7595. }
  7596. exec = xmlRegNewExecCtxt(define->contModel,
  7597. xmlRelaxNGValidateProgressiveCallback, ctxt);
  7598. if (exec == NULL) {
  7599. ctxt->pstate = -1;
  7600. return;
  7601. }
  7602. xmlRelaxNGElemPush(ctxt, exec);
  7603. /*
  7604. * Validate the attributes part of the content.
  7605. */
  7606. state = xmlRelaxNGNewValidState(ctxt, node);
  7607. if (state == NULL) {
  7608. ctxt->pstate = -1;
  7609. return;
  7610. }
  7611. oldstate = ctxt->state;
  7612. ctxt->state = state;
  7613. if (define->attrs != NULL) {
  7614. ret = xmlRelaxNGValidateAttributeList(ctxt, define->attrs);
  7615. if (ret != 0) {
  7616. ctxt->pstate = -1;
  7617. VALID_ERR2(XML_RELAXNG_ERR_ATTRVALID, node->name);
  7618. }
  7619. }
  7620. if (ctxt->state != NULL) {
  7621. ctxt->state->seq = NULL;
  7622. ret = xmlRelaxNGValidateElementEnd(ctxt, 1);
  7623. if (ret != 0) {
  7624. ctxt->pstate = -1;
  7625. }
  7626. xmlRelaxNGFreeValidState(ctxt, ctxt->state);
  7627. } else if (ctxt->states != NULL) {
  7628. int tmp = -1, i;
  7629. oldflags = ctxt->flags;
  7630. for (i = 0; i < ctxt->states->nbState; i++) {
  7631. state = ctxt->states->tabState[i];
  7632. ctxt->state = state;
  7633. ctxt->state->seq = NULL;
  7634. if (xmlRelaxNGValidateElementEnd(ctxt, 0) == 0) {
  7635. tmp = 0;
  7636. break;
  7637. }
  7638. }
  7639. if (tmp != 0) {
  7640. /*
  7641. * validation error, log the message for the "best" one
  7642. */
  7643. ctxt->flags |= FLAGS_IGNORABLE;
  7644. xmlRelaxNGLogBestError(ctxt);
  7645. }
  7646. for (i = 0; i < ctxt->states->nbState; i++) {
  7647. xmlRelaxNGFreeValidState(ctxt, ctxt->states->tabState[i]);
  7648. }
  7649. xmlRelaxNGFreeStates(ctxt, ctxt->states);
  7650. ctxt->states = NULL;
  7651. if ((ret == 0) && (tmp == -1))
  7652. ctxt->pstate = -1;
  7653. ctxt->flags = oldflags;
  7654. }
  7655. if (ctxt->pstate == -1) {
  7656. if ((ctxt->flags & FLAGS_IGNORABLE) == 0) {
  7657. xmlRelaxNGDumpValidError(ctxt);
  7658. }
  7659. }
  7660. ctxt->state = oldstate;
  7661. }
  7662. /**
  7663. * xmlRelaxNGValidatePushElement:
  7664. * @ctxt: the validation context
  7665. * @doc: a document instance
  7666. * @elem: an element instance
  7667. *
  7668. * Push a new element start on the RelaxNG validation stack.
  7669. *
  7670. * returns 1 if no validation problem was found or 0 if validating the
  7671. * element requires a full node, and -1 in case of error.
  7672. */
  7673. int
  7674. xmlRelaxNGValidatePushElement(xmlRelaxNGValidCtxtPtr ctxt,
  7675. xmlDocPtr doc ATTRIBUTE_UNUSED,
  7676. xmlNodePtr elem)
  7677. {
  7678. int ret = 1;
  7679. if ((ctxt == NULL) || (elem == NULL))
  7680. return (-1);
  7681. if (ctxt->elem == 0) {
  7682. xmlRelaxNGPtr schema;
  7683. xmlRelaxNGGrammarPtr grammar;
  7684. xmlRegExecCtxtPtr exec;
  7685. xmlRelaxNGDefinePtr define;
  7686. schema = ctxt->schema;
  7687. if (schema == NULL) {
  7688. VALID_ERR(XML_RELAXNG_ERR_NOGRAMMAR);
  7689. return (-1);
  7690. }
  7691. grammar = schema->topgrammar;
  7692. if ((grammar == NULL) || (grammar->start == NULL)) {
  7693. VALID_ERR(XML_RELAXNG_ERR_NOGRAMMAR);
  7694. return (-1);
  7695. }
  7696. define = grammar->start;
  7697. if (define->contModel == NULL) {
  7698. ctxt->pdef = define;
  7699. return (0);
  7700. }
  7701. exec = xmlRegNewExecCtxt(define->contModel,
  7702. xmlRelaxNGValidateProgressiveCallback,
  7703. ctxt);
  7704. if (exec == NULL) {
  7705. return (-1);
  7706. }
  7707. xmlRelaxNGElemPush(ctxt, exec);
  7708. }
  7709. ctxt->pnode = elem;
  7710. ctxt->pstate = 0;
  7711. if (elem->ns != NULL) {
  7712. ret =
  7713. xmlRegExecPushString2(ctxt->elem, elem->name, elem->ns->href,
  7714. ctxt);
  7715. } else {
  7716. ret = xmlRegExecPushString(ctxt->elem, elem->name, ctxt);
  7717. }
  7718. if (ret < 0) {
  7719. VALID_ERR2(XML_RELAXNG_ERR_ELEMWRONG, elem->name);
  7720. } else {
  7721. if (ctxt->pstate == 0)
  7722. ret = 0;
  7723. else if (ctxt->pstate < 0)
  7724. ret = -1;
  7725. else
  7726. ret = 1;
  7727. }
  7728. return (ret);
  7729. }
  7730. /**
  7731. * xmlRelaxNGValidatePushCData:
  7732. * @ctxt: the RelaxNG validation context
  7733. * @data: some character data read
  7734. * @len: the length of the data
  7735. *
  7736. * check the CData parsed for validation in the current stack
  7737. *
  7738. * returns 1 if no validation problem was found or -1 otherwise
  7739. */
  7740. int
  7741. xmlRelaxNGValidatePushCData(xmlRelaxNGValidCtxtPtr ctxt,
  7742. const xmlChar * data, int len ATTRIBUTE_UNUSED)
  7743. {
  7744. int ret = 1;
  7745. if ((ctxt == NULL) || (ctxt->elem == NULL) || (data == NULL))
  7746. return (-1);
  7747. while (*data != 0) {
  7748. if (!IS_BLANK_CH(*data))
  7749. break;
  7750. data++;
  7751. }
  7752. if (*data == 0)
  7753. return (1);
  7754. ret = xmlRegExecPushString(ctxt->elem, BAD_CAST "#text", ctxt);
  7755. if (ret < 0) {
  7756. VALID_ERR2(XML_RELAXNG_ERR_TEXTWRONG, BAD_CAST " TODO ");
  7757. return (-1);
  7758. }
  7759. return (1);
  7760. }
  7761. /**
  7762. * xmlRelaxNGValidatePopElement:
  7763. * @ctxt: the RelaxNG validation context
  7764. * @doc: a document instance
  7765. * @elem: an element instance
  7766. *
  7767. * Pop the element end from the RelaxNG validation stack.
  7768. *
  7769. * returns 1 if no validation problem was found or 0 otherwise
  7770. */
  7771. int
  7772. xmlRelaxNGValidatePopElement(xmlRelaxNGValidCtxtPtr ctxt,
  7773. xmlDocPtr doc ATTRIBUTE_UNUSED,
  7774. xmlNodePtr elem)
  7775. {
  7776. int ret;
  7777. xmlRegExecCtxtPtr exec;
  7778. if ((ctxt == NULL) || (ctxt->elem == NULL) || (elem == NULL))
  7779. return (-1);
  7780. /*
  7781. * verify that we reached a terminal state of the content model.
  7782. */
  7783. exec = xmlRelaxNGElemPop(ctxt);
  7784. ret = xmlRegExecPushString(exec, NULL, NULL);
  7785. if (ret == 0) {
  7786. /*
  7787. * TODO: get some of the names needed to exit the current state of exec
  7788. */
  7789. VALID_ERR2(XML_RELAXNG_ERR_NOELEM, BAD_CAST "");
  7790. ret = -1;
  7791. } else if (ret < 0) {
  7792. ret = -1;
  7793. } else {
  7794. ret = 1;
  7795. }
  7796. xmlRegFreeExecCtxt(exec);
  7797. return (ret);
  7798. }
  7799. /**
  7800. * xmlRelaxNGValidateFullElement:
  7801. * @ctxt: the validation context
  7802. * @doc: a document instance
  7803. * @elem: an element instance
  7804. *
  7805. * Validate a full subtree when xmlRelaxNGValidatePushElement() returned
  7806. * 0 and the content of the node has been expanded.
  7807. *
  7808. * returns 1 if no validation problem was found or -1 in case of error.
  7809. */
  7810. int
  7811. xmlRelaxNGValidateFullElement(xmlRelaxNGValidCtxtPtr ctxt,
  7812. xmlDocPtr doc ATTRIBUTE_UNUSED,
  7813. xmlNodePtr elem)
  7814. {
  7815. int ret;
  7816. xmlRelaxNGValidStatePtr state;
  7817. if ((ctxt == NULL) || (ctxt->pdef == NULL) || (elem == NULL))
  7818. return (-1);
  7819. state = xmlRelaxNGNewValidState(ctxt, elem->parent);
  7820. if (state == NULL) {
  7821. return (-1);
  7822. }
  7823. state->seq = elem;
  7824. ctxt->state = state;
  7825. ctxt->errNo = XML_RELAXNG_OK;
  7826. ret = xmlRelaxNGValidateDefinition(ctxt, ctxt->pdef);
  7827. if ((ret != 0) || (ctxt->errNo != XML_RELAXNG_OK))
  7828. ret = -1;
  7829. else
  7830. ret = 1;
  7831. xmlRelaxNGFreeValidState(ctxt, ctxt->state);
  7832. ctxt->state = NULL;
  7833. return (ret);
  7834. }
  7835. /************************************************************************
  7836. * *
  7837. * Generic interpreted validation implementation *
  7838. * *
  7839. ************************************************************************/
  7840. static int xmlRelaxNGValidateValue(xmlRelaxNGValidCtxtPtr ctxt,
  7841. xmlRelaxNGDefinePtr define);
  7842. /**
  7843. * xmlRelaxNGSkipIgnored:
  7844. * @ctxt: a schema validation context
  7845. * @node: the top node.
  7846. *
  7847. * Skip ignorable nodes in that context
  7848. *
  7849. * Returns the new sibling or NULL in case of error.
  7850. */
  7851. static xmlNodePtr
  7852. xmlRelaxNGSkipIgnored(xmlRelaxNGValidCtxtPtr ctxt ATTRIBUTE_UNUSED,
  7853. xmlNodePtr node)
  7854. {
  7855. /*
  7856. * TODO complete and handle entities
  7857. */
  7858. while ((node != NULL) &&
  7859. ((node->type == XML_COMMENT_NODE) ||
  7860. (node->type == XML_PI_NODE) ||
  7861. (node->type == XML_XINCLUDE_START) ||
  7862. (node->type == XML_XINCLUDE_END) ||
  7863. (((node->type == XML_TEXT_NODE) ||
  7864. (node->type == XML_CDATA_SECTION_NODE)) &&
  7865. ((ctxt->flags & FLAGS_MIXED_CONTENT) ||
  7866. (IS_BLANK_NODE(node)))))) {
  7867. node = node->next;
  7868. }
  7869. return (node);
  7870. }
  7871. /**
  7872. * xmlRelaxNGNormalize:
  7873. * @ctxt: a schema validation context
  7874. * @str: the string to normalize
  7875. *
  7876. * Implements the normalizeWhiteSpace( s ) function from
  7877. * section 6.2.9 of the spec
  7878. *
  7879. * Returns the new string or NULL in case of error.
  7880. */
  7881. static xmlChar *
  7882. xmlRelaxNGNormalize(xmlRelaxNGValidCtxtPtr ctxt, const xmlChar * str)
  7883. {
  7884. xmlChar *ret, *p;
  7885. const xmlChar *tmp;
  7886. int len;
  7887. if (str == NULL)
  7888. return (NULL);
  7889. tmp = str;
  7890. while (*tmp != 0)
  7891. tmp++;
  7892. len = tmp - str;
  7893. ret = (xmlChar *) xmlMallocAtomic(len + 1);
  7894. if (ret == NULL) {
  7895. xmlRngVErrMemory(ctxt, "validating\n");
  7896. return (NULL);
  7897. }
  7898. p = ret;
  7899. while (IS_BLANK_CH(*str))
  7900. str++;
  7901. while (*str != 0) {
  7902. if (IS_BLANK_CH(*str)) {
  7903. while (IS_BLANK_CH(*str))
  7904. str++;
  7905. if (*str == 0)
  7906. break;
  7907. *p++ = ' ';
  7908. } else
  7909. *p++ = *str++;
  7910. }
  7911. *p = 0;
  7912. return (ret);
  7913. }
  7914. /**
  7915. * xmlRelaxNGValidateDatatype:
  7916. * @ctxt: a Relax-NG validation context
  7917. * @value: the string value
  7918. * @type: the datatype definition
  7919. * @node: the node
  7920. *
  7921. * Validate the given value against the datatype
  7922. *
  7923. * Returns 0 if the validation succeeded or an error code.
  7924. */
  7925. static int
  7926. xmlRelaxNGValidateDatatype(xmlRelaxNGValidCtxtPtr ctxt,
  7927. const xmlChar * value,
  7928. xmlRelaxNGDefinePtr define, xmlNodePtr node)
  7929. {
  7930. int ret, tmp;
  7931. xmlRelaxNGTypeLibraryPtr lib;
  7932. void *result = NULL;
  7933. xmlRelaxNGDefinePtr cur;
  7934. if ((define == NULL) || (define->data == NULL)) {
  7935. return (-1);
  7936. }
  7937. lib = (xmlRelaxNGTypeLibraryPtr) define->data;
  7938. if (lib->check != NULL) {
  7939. if ((define->attrs != NULL) &&
  7940. (define->attrs->type == XML_RELAXNG_PARAM)) {
  7941. ret =
  7942. lib->check(lib->data, define->name, value, &result, node);
  7943. } else {
  7944. ret = lib->check(lib->data, define->name, value, NULL, node);
  7945. }
  7946. } else
  7947. ret = -1;
  7948. if (ret < 0) {
  7949. VALID_ERR2(XML_RELAXNG_ERR_TYPE, define->name);
  7950. if ((result != NULL) && (lib != NULL) && (lib->freef != NULL))
  7951. lib->freef(lib->data, result);
  7952. return (-1);
  7953. } else if (ret == 1) {
  7954. ret = 0;
  7955. } else if (ret == 2) {
  7956. VALID_ERR2P(XML_RELAXNG_ERR_DUPID, value);
  7957. } else {
  7958. VALID_ERR3P(XML_RELAXNG_ERR_TYPEVAL, define->name, value);
  7959. ret = -1;
  7960. }
  7961. cur = define->attrs;
  7962. while ((ret == 0) && (cur != NULL) && (cur->type == XML_RELAXNG_PARAM)) {
  7963. if (lib->facet != NULL) {
  7964. tmp = lib->facet(lib->data, define->name, cur->name,
  7965. cur->value, value, result);
  7966. if (tmp != 0)
  7967. ret = -1;
  7968. }
  7969. cur = cur->next;
  7970. }
  7971. if ((ret == 0) && (define->content != NULL)) {
  7972. const xmlChar *oldvalue, *oldendvalue;
  7973. oldvalue = ctxt->state->value;
  7974. oldendvalue = ctxt->state->endvalue;
  7975. ctxt->state->value = (xmlChar *) value;
  7976. ctxt->state->endvalue = NULL;
  7977. ret = xmlRelaxNGValidateValue(ctxt, define->content);
  7978. ctxt->state->value = (xmlChar *) oldvalue;
  7979. ctxt->state->endvalue = (xmlChar *) oldendvalue;
  7980. }
  7981. if ((result != NULL) && (lib != NULL) && (lib->freef != NULL))
  7982. lib->freef(lib->data, result);
  7983. return (ret);
  7984. }
  7985. /**
  7986. * xmlRelaxNGNextValue:
  7987. * @ctxt: a Relax-NG validation context
  7988. *
  7989. * Skip to the next value when validating within a list
  7990. *
  7991. * Returns 0 if the operation succeeded or an error code.
  7992. */
  7993. static int
  7994. xmlRelaxNGNextValue(xmlRelaxNGValidCtxtPtr ctxt)
  7995. {
  7996. xmlChar *cur;
  7997. cur = ctxt->state->value;
  7998. if ((cur == NULL) || (ctxt->state->endvalue == NULL)) {
  7999. ctxt->state->value = NULL;
  8000. ctxt->state->endvalue = NULL;
  8001. return (0);
  8002. }
  8003. while (*cur != 0)
  8004. cur++;
  8005. while ((cur != ctxt->state->endvalue) && (*cur == 0))
  8006. cur++;
  8007. if (cur == ctxt->state->endvalue)
  8008. ctxt->state->value = NULL;
  8009. else
  8010. ctxt->state->value = cur;
  8011. return (0);
  8012. }
  8013. /**
  8014. * xmlRelaxNGValidateValueList:
  8015. * @ctxt: a Relax-NG validation context
  8016. * @defines: the list of definitions to verify
  8017. *
  8018. * Validate the given set of definitions for the current value
  8019. *
  8020. * Returns 0 if the validation succeeded or an error code.
  8021. */
  8022. static int
  8023. xmlRelaxNGValidateValueList(xmlRelaxNGValidCtxtPtr ctxt,
  8024. xmlRelaxNGDefinePtr defines)
  8025. {
  8026. int ret = 0;
  8027. while (defines != NULL) {
  8028. ret = xmlRelaxNGValidateValue(ctxt, defines);
  8029. if (ret != 0)
  8030. break;
  8031. defines = defines->next;
  8032. }
  8033. return (ret);
  8034. }
  8035. /**
  8036. * xmlRelaxNGValidateValue:
  8037. * @ctxt: a Relax-NG validation context
  8038. * @define: the definition to verify
  8039. *
  8040. * Validate the given definition for the current value
  8041. *
  8042. * Returns 0 if the validation succeeded or an error code.
  8043. */
  8044. static int
  8045. xmlRelaxNGValidateValue(xmlRelaxNGValidCtxtPtr ctxt,
  8046. xmlRelaxNGDefinePtr define)
  8047. {
  8048. int ret = 0, oldflags;
  8049. xmlChar *value;
  8050. value = ctxt->state->value;
  8051. switch (define->type) {
  8052. case XML_RELAXNG_EMPTY:{
  8053. if ((value != NULL) && (value[0] != 0)) {
  8054. int idx = 0;
  8055. while (IS_BLANK_CH(value[idx]))
  8056. idx++;
  8057. if (value[idx] != 0)
  8058. ret = -1;
  8059. }
  8060. break;
  8061. }
  8062. case XML_RELAXNG_TEXT:
  8063. break;
  8064. case XML_RELAXNG_VALUE:{
  8065. if (!xmlStrEqual(value, define->value)) {
  8066. if (define->name != NULL) {
  8067. xmlRelaxNGTypeLibraryPtr lib;
  8068. lib = (xmlRelaxNGTypeLibraryPtr) define->data;
  8069. if ((lib != NULL) && (lib->comp != NULL)) {
  8070. ret = lib->comp(lib->data, define->name,
  8071. define->value, define->node,
  8072. (void *) define->attrs,
  8073. value, ctxt->state->node);
  8074. } else
  8075. ret = -1;
  8076. if (ret < 0) {
  8077. VALID_ERR2(XML_RELAXNG_ERR_TYPECMP,
  8078. define->name);
  8079. return (-1);
  8080. } else if (ret == 1) {
  8081. ret = 0;
  8082. } else {
  8083. ret = -1;
  8084. }
  8085. } else {
  8086. xmlChar *nval, *nvalue;
  8087. /*
  8088. * TODO: trivial optimizations are possible by
  8089. * computing at compile-time
  8090. */
  8091. nval = xmlRelaxNGNormalize(ctxt, define->value);
  8092. nvalue = xmlRelaxNGNormalize(ctxt, value);
  8093. if ((nval == NULL) || (nvalue == NULL) ||
  8094. (!xmlStrEqual(nval, nvalue)))
  8095. ret = -1;
  8096. if (nval != NULL)
  8097. xmlFree(nval);
  8098. if (nvalue != NULL)
  8099. xmlFree(nvalue);
  8100. }
  8101. }
  8102. if (ret == 0)
  8103. xmlRelaxNGNextValue(ctxt);
  8104. break;
  8105. }
  8106. case XML_RELAXNG_DATATYPE:{
  8107. ret = xmlRelaxNGValidateDatatype(ctxt, value, define,
  8108. ctxt->state->seq);
  8109. if (ret == 0)
  8110. xmlRelaxNGNextValue(ctxt);
  8111. break;
  8112. }
  8113. case XML_RELAXNG_CHOICE:{
  8114. xmlRelaxNGDefinePtr list = define->content;
  8115. xmlChar *oldvalue;
  8116. oldflags = ctxt->flags;
  8117. ctxt->flags |= FLAGS_IGNORABLE;
  8118. oldvalue = ctxt->state->value;
  8119. while (list != NULL) {
  8120. ret = xmlRelaxNGValidateValue(ctxt, list);
  8121. if (ret == 0) {
  8122. break;
  8123. }
  8124. ctxt->state->value = oldvalue;
  8125. list = list->next;
  8126. }
  8127. ctxt->flags = oldflags;
  8128. if (ret != 0) {
  8129. if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
  8130. xmlRelaxNGDumpValidError(ctxt);
  8131. } else {
  8132. if (ctxt->errNr > 0)
  8133. xmlRelaxNGPopErrors(ctxt, 0);
  8134. }
  8135. break;
  8136. }
  8137. case XML_RELAXNG_LIST:{
  8138. xmlRelaxNGDefinePtr list = define->content;
  8139. xmlChar *oldvalue, *oldend, *val, *cur;
  8140. oldvalue = ctxt->state->value;
  8141. oldend = ctxt->state->endvalue;
  8142. val = xmlStrdup(oldvalue);
  8143. if (val == NULL) {
  8144. val = xmlStrdup(BAD_CAST "");
  8145. }
  8146. if (val == NULL) {
  8147. VALID_ERR(XML_RELAXNG_ERR_NOSTATE);
  8148. return (-1);
  8149. }
  8150. cur = val;
  8151. while (*cur != 0) {
  8152. if (IS_BLANK_CH(*cur)) {
  8153. *cur = 0;
  8154. cur++;
  8155. while (IS_BLANK_CH(*cur))
  8156. *cur++ = 0;
  8157. } else
  8158. cur++;
  8159. }
  8160. ctxt->state->endvalue = cur;
  8161. cur = val;
  8162. while ((*cur == 0) && (cur != ctxt->state->endvalue))
  8163. cur++;
  8164. ctxt->state->value = cur;
  8165. while (list != NULL) {
  8166. if (ctxt->state->value == ctxt->state->endvalue)
  8167. ctxt->state->value = NULL;
  8168. ret = xmlRelaxNGValidateValue(ctxt, list);
  8169. if (ret != 0) {
  8170. break;
  8171. }
  8172. list = list->next;
  8173. }
  8174. if ((ret == 0) && (ctxt->state->value != NULL) &&
  8175. (ctxt->state->value != ctxt->state->endvalue)) {
  8176. VALID_ERR2(XML_RELAXNG_ERR_LISTEXTRA,
  8177. ctxt->state->value);
  8178. ret = -1;
  8179. }
  8180. xmlFree(val);
  8181. ctxt->state->value = oldvalue;
  8182. ctxt->state->endvalue = oldend;
  8183. break;
  8184. }
  8185. case XML_RELAXNG_ONEORMORE:
  8186. ret = xmlRelaxNGValidateValueList(ctxt, define->content);
  8187. if (ret != 0) {
  8188. break;
  8189. }
  8190. /* Falls through. */
  8191. case XML_RELAXNG_ZEROORMORE:{
  8192. xmlChar *cur, *temp;
  8193. if ((ctxt->state->value == NULL) ||
  8194. (*ctxt->state->value == 0)) {
  8195. ret = 0;
  8196. break;
  8197. }
  8198. oldflags = ctxt->flags;
  8199. ctxt->flags |= FLAGS_IGNORABLE;
  8200. cur = ctxt->state->value;
  8201. temp = NULL;
  8202. while ((cur != NULL) && (cur != ctxt->state->endvalue) &&
  8203. (temp != cur)) {
  8204. temp = cur;
  8205. ret =
  8206. xmlRelaxNGValidateValueList(ctxt, define->content);
  8207. if (ret != 0) {
  8208. ctxt->state->value = temp;
  8209. ret = 0;
  8210. break;
  8211. }
  8212. cur = ctxt->state->value;
  8213. }
  8214. ctxt->flags = oldflags;
  8215. if (ctxt->errNr > 0)
  8216. xmlRelaxNGPopErrors(ctxt, 0);
  8217. break;
  8218. }
  8219. case XML_RELAXNG_OPTIONAL:{
  8220. xmlChar *temp;
  8221. if ((ctxt->state->value == NULL) ||
  8222. (*ctxt->state->value == 0)) {
  8223. ret = 0;
  8224. break;
  8225. }
  8226. oldflags = ctxt->flags;
  8227. ctxt->flags |= FLAGS_IGNORABLE;
  8228. temp = ctxt->state->value;
  8229. ret = xmlRelaxNGValidateValue(ctxt, define->content);
  8230. ctxt->flags = oldflags;
  8231. if (ret != 0) {
  8232. ctxt->state->value = temp;
  8233. if (ctxt->errNr > 0)
  8234. xmlRelaxNGPopErrors(ctxt, 0);
  8235. ret = 0;
  8236. break;
  8237. }
  8238. if (ctxt->errNr > 0)
  8239. xmlRelaxNGPopErrors(ctxt, 0);
  8240. break;
  8241. }
  8242. case XML_RELAXNG_EXCEPT:{
  8243. xmlRelaxNGDefinePtr list;
  8244. list = define->content;
  8245. while (list != NULL) {
  8246. ret = xmlRelaxNGValidateValue(ctxt, list);
  8247. if (ret == 0) {
  8248. ret = -1;
  8249. break;
  8250. } else
  8251. ret = 0;
  8252. list = list->next;
  8253. }
  8254. break;
  8255. }
  8256. case XML_RELAXNG_DEF:
  8257. case XML_RELAXNG_GROUP:{
  8258. xmlRelaxNGDefinePtr list;
  8259. list = define->content;
  8260. while (list != NULL) {
  8261. ret = xmlRelaxNGValidateValue(ctxt, list);
  8262. if (ret != 0) {
  8263. ret = -1;
  8264. break;
  8265. } else
  8266. ret = 0;
  8267. list = list->next;
  8268. }
  8269. break;
  8270. }
  8271. case XML_RELAXNG_REF:
  8272. case XML_RELAXNG_PARENTREF:
  8273. if (define->content == NULL) {
  8274. VALID_ERR(XML_RELAXNG_ERR_NODEFINE);
  8275. ret = -1;
  8276. } else {
  8277. ret = xmlRelaxNGValidateValue(ctxt, define->content);
  8278. }
  8279. break;
  8280. default:
  8281. TODO ret = -1;
  8282. }
  8283. return (ret);
  8284. }
  8285. /**
  8286. * xmlRelaxNGValidateValueContent:
  8287. * @ctxt: a Relax-NG validation context
  8288. * @defines: the list of definitions to verify
  8289. *
  8290. * Validate the given definitions for the current value
  8291. *
  8292. * Returns 0 if the validation succeeded or an error code.
  8293. */
  8294. static int
  8295. xmlRelaxNGValidateValueContent(xmlRelaxNGValidCtxtPtr ctxt,
  8296. xmlRelaxNGDefinePtr defines)
  8297. {
  8298. int ret = 0;
  8299. while (defines != NULL) {
  8300. ret = xmlRelaxNGValidateValue(ctxt, defines);
  8301. if (ret != 0)
  8302. break;
  8303. defines = defines->next;
  8304. }
  8305. return (ret);
  8306. }
  8307. /**
  8308. * xmlRelaxNGAttributeMatch:
  8309. * @ctxt: a Relax-NG validation context
  8310. * @define: the definition to check
  8311. * @prop: the attribute
  8312. *
  8313. * Check if the attribute matches the definition nameClass
  8314. *
  8315. * Returns 1 if the attribute matches, 0 if no, or -1 in case of error
  8316. */
  8317. static int
  8318. xmlRelaxNGAttributeMatch(xmlRelaxNGValidCtxtPtr ctxt,
  8319. xmlRelaxNGDefinePtr define, xmlAttrPtr prop)
  8320. {
  8321. int ret;
  8322. if (define->name != NULL) {
  8323. if (!xmlStrEqual(define->name, prop->name))
  8324. return (0);
  8325. }
  8326. if (define->ns != NULL) {
  8327. if (define->ns[0] == 0) {
  8328. if (prop->ns != NULL)
  8329. return (0);
  8330. } else {
  8331. if ((prop->ns == NULL) ||
  8332. (!xmlStrEqual(define->ns, prop->ns->href)))
  8333. return (0);
  8334. }
  8335. }
  8336. if (define->nameClass == NULL)
  8337. return (1);
  8338. define = define->nameClass;
  8339. if (define->type == XML_RELAXNG_EXCEPT) {
  8340. xmlRelaxNGDefinePtr list;
  8341. list = define->content;
  8342. while (list != NULL) {
  8343. ret = xmlRelaxNGAttributeMatch(ctxt, list, prop);
  8344. if (ret == 1)
  8345. return (0);
  8346. if (ret < 0)
  8347. return (ret);
  8348. list = list->next;
  8349. }
  8350. } else if (define->type == XML_RELAXNG_CHOICE) {
  8351. xmlRelaxNGDefinePtr list;
  8352. list = define->nameClass;
  8353. while (list != NULL) {
  8354. ret = xmlRelaxNGAttributeMatch(ctxt, list, prop);
  8355. if (ret == 1)
  8356. return (1);
  8357. if (ret < 0)
  8358. return (ret);
  8359. list = list->next;
  8360. }
  8361. return (0);
  8362. } else {
  8363. TODO}
  8364. return (1);
  8365. }
  8366. /**
  8367. * xmlRelaxNGValidateAttribute:
  8368. * @ctxt: a Relax-NG validation context
  8369. * @define: the definition to verify
  8370. *
  8371. * Validate the given attribute definition for that node
  8372. *
  8373. * Returns 0 if the validation succeeded or an error code.
  8374. */
  8375. static int
  8376. xmlRelaxNGValidateAttribute(xmlRelaxNGValidCtxtPtr ctxt,
  8377. xmlRelaxNGDefinePtr define)
  8378. {
  8379. int ret = 0, i;
  8380. xmlChar *value, *oldvalue;
  8381. xmlAttrPtr prop = NULL, tmp;
  8382. xmlNodePtr oldseq;
  8383. if (ctxt->state->nbAttrLeft <= 0)
  8384. return (-1);
  8385. if (define->name != NULL) {
  8386. for (i = 0; i < ctxt->state->nbAttrs; i++) {
  8387. tmp = ctxt->state->attrs[i];
  8388. if ((tmp != NULL) && (xmlStrEqual(define->name, tmp->name))) {
  8389. if ((((define->ns == NULL) || (define->ns[0] == 0)) &&
  8390. (tmp->ns == NULL)) ||
  8391. ((tmp->ns != NULL) &&
  8392. (xmlStrEqual(define->ns, tmp->ns->href)))) {
  8393. prop = tmp;
  8394. break;
  8395. }
  8396. }
  8397. }
  8398. if (prop != NULL) {
  8399. value = xmlNodeListGetString(prop->doc, prop->children, 1);
  8400. oldvalue = ctxt->state->value;
  8401. oldseq = ctxt->state->seq;
  8402. ctxt->state->seq = (xmlNodePtr) prop;
  8403. ctxt->state->value = value;
  8404. ctxt->state->endvalue = NULL;
  8405. ret = xmlRelaxNGValidateValueContent(ctxt, define->content);
  8406. if (ctxt->state->value != NULL)
  8407. value = ctxt->state->value;
  8408. if (value != NULL)
  8409. xmlFree(value);
  8410. ctxt->state->value = oldvalue;
  8411. ctxt->state->seq = oldseq;
  8412. if (ret == 0) {
  8413. /*
  8414. * flag the attribute as processed
  8415. */
  8416. ctxt->state->attrs[i] = NULL;
  8417. ctxt->state->nbAttrLeft--;
  8418. }
  8419. } else {
  8420. ret = -1;
  8421. }
  8422. } else {
  8423. for (i = 0; i < ctxt->state->nbAttrs; i++) {
  8424. tmp = ctxt->state->attrs[i];
  8425. if ((tmp != NULL) &&
  8426. (xmlRelaxNGAttributeMatch(ctxt, define, tmp) == 1)) {
  8427. prop = tmp;
  8428. break;
  8429. }
  8430. }
  8431. if (prop != NULL) {
  8432. value = xmlNodeListGetString(prop->doc, prop->children, 1);
  8433. oldvalue = ctxt->state->value;
  8434. oldseq = ctxt->state->seq;
  8435. ctxt->state->seq = (xmlNodePtr) prop;
  8436. ctxt->state->value = value;
  8437. ret = xmlRelaxNGValidateValueContent(ctxt, define->content);
  8438. if (ctxt->state->value != NULL)
  8439. value = ctxt->state->value;
  8440. if (value != NULL)
  8441. xmlFree(value);
  8442. ctxt->state->value = oldvalue;
  8443. ctxt->state->seq = oldseq;
  8444. if (ret == 0) {
  8445. /*
  8446. * flag the attribute as processed
  8447. */
  8448. ctxt->state->attrs[i] = NULL;
  8449. ctxt->state->nbAttrLeft--;
  8450. }
  8451. } else {
  8452. ret = -1;
  8453. }
  8454. }
  8455. return (ret);
  8456. }
  8457. /**
  8458. * xmlRelaxNGValidateAttributeList:
  8459. * @ctxt: a Relax-NG validation context
  8460. * @define: the list of definition to verify
  8461. *
  8462. * Validate the given node against the list of attribute definitions
  8463. *
  8464. * Returns 0 if the validation succeeded or an error code.
  8465. */
  8466. static int
  8467. xmlRelaxNGValidateAttributeList(xmlRelaxNGValidCtxtPtr ctxt,
  8468. xmlRelaxNGDefinePtr defines)
  8469. {
  8470. int ret = 0, res;
  8471. int needmore = 0;
  8472. xmlRelaxNGDefinePtr cur;
  8473. cur = defines;
  8474. while (cur != NULL) {
  8475. if (cur->type == XML_RELAXNG_ATTRIBUTE) {
  8476. if (xmlRelaxNGValidateAttribute(ctxt, cur) != 0)
  8477. ret = -1;
  8478. } else
  8479. needmore = 1;
  8480. cur = cur->next;
  8481. }
  8482. if (!needmore)
  8483. return (ret);
  8484. cur = defines;
  8485. while (cur != NULL) {
  8486. if (cur->type != XML_RELAXNG_ATTRIBUTE) {
  8487. if ((ctxt->state != NULL) || (ctxt->states != NULL)) {
  8488. res = xmlRelaxNGValidateDefinition(ctxt, cur);
  8489. if (res < 0)
  8490. ret = -1;
  8491. } else {
  8492. VALID_ERR(XML_RELAXNG_ERR_NOSTATE);
  8493. return (-1);
  8494. }
  8495. if (res == -1) /* continues on -2 */
  8496. break;
  8497. }
  8498. cur = cur->next;
  8499. }
  8500. return (ret);
  8501. }
  8502. /**
  8503. * xmlRelaxNGNodeMatchesList:
  8504. * @node: the node
  8505. * @list: a NULL terminated array of definitions
  8506. *
  8507. * Check if a node can be matched by one of the definitions
  8508. *
  8509. * Returns 1 if matches 0 otherwise
  8510. */
  8511. static int
  8512. xmlRelaxNGNodeMatchesList(xmlNodePtr node, xmlRelaxNGDefinePtr * list)
  8513. {
  8514. xmlRelaxNGDefinePtr cur;
  8515. int i = 0, tmp;
  8516. if ((node == NULL) || (list == NULL))
  8517. return (0);
  8518. cur = list[i++];
  8519. while (cur != NULL) {
  8520. if ((node->type == XML_ELEMENT_NODE) &&
  8521. (cur->type == XML_RELAXNG_ELEMENT)) {
  8522. tmp = xmlRelaxNGElementMatch(NULL, cur, node);
  8523. if (tmp == 1)
  8524. return (1);
  8525. } else if (((node->type == XML_TEXT_NODE) ||
  8526. (node->type == XML_CDATA_SECTION_NODE)) &&
  8527. ((cur->type == XML_RELAXNG_DATATYPE) ||
  8528. (cur->type == XML_RELAXNG_LIST) ||
  8529. (cur->type == XML_RELAXNG_TEXT) ||
  8530. (cur->type == XML_RELAXNG_VALUE))) {
  8531. return (1);
  8532. }
  8533. cur = list[i++];
  8534. }
  8535. return (0);
  8536. }
  8537. /**
  8538. * xmlRelaxNGValidateInterleave:
  8539. * @ctxt: a Relax-NG validation context
  8540. * @define: the definition to verify
  8541. *
  8542. * Validate an interleave definition for a node.
  8543. *
  8544. * Returns 0 if the validation succeeded or an error code.
  8545. */
  8546. static int
  8547. xmlRelaxNGValidateInterleave(xmlRelaxNGValidCtxtPtr ctxt,
  8548. xmlRelaxNGDefinePtr define)
  8549. {
  8550. int ret = 0, i, nbgroups;
  8551. int errNr = ctxt->errNr;
  8552. int oldflags;
  8553. xmlRelaxNGValidStatePtr oldstate;
  8554. xmlRelaxNGPartitionPtr partitions;
  8555. xmlRelaxNGInterleaveGroupPtr group = NULL;
  8556. xmlNodePtr cur, start, last = NULL, lastchg = NULL, lastelem;
  8557. xmlNodePtr *list = NULL, *lasts = NULL;
  8558. if (define->data != NULL) {
  8559. partitions = (xmlRelaxNGPartitionPtr) define->data;
  8560. nbgroups = partitions->nbgroups;
  8561. } else {
  8562. VALID_ERR(XML_RELAXNG_ERR_INTERNODATA);
  8563. return (-1);
  8564. }
  8565. /*
  8566. * Optimizations for MIXED
  8567. */
  8568. oldflags = ctxt->flags;
  8569. if (define->dflags & IS_MIXED) {
  8570. ctxt->flags |= FLAGS_MIXED_CONTENT;
  8571. if (nbgroups == 2) {
  8572. /*
  8573. * this is a pure <mixed> case
  8574. */
  8575. if (ctxt->state != NULL)
  8576. ctxt->state->seq = xmlRelaxNGSkipIgnored(ctxt,
  8577. ctxt->state->seq);
  8578. if (partitions->groups[0]->rule->type == XML_RELAXNG_TEXT)
  8579. ret = xmlRelaxNGValidateDefinition(ctxt,
  8580. partitions->groups[1]->
  8581. rule);
  8582. else
  8583. ret = xmlRelaxNGValidateDefinition(ctxt,
  8584. partitions->groups[0]->
  8585. rule);
  8586. if (ret == 0) {
  8587. if (ctxt->state != NULL)
  8588. ctxt->state->seq = xmlRelaxNGSkipIgnored(ctxt,
  8589. ctxt->state->
  8590. seq);
  8591. }
  8592. ctxt->flags = oldflags;
  8593. return (ret);
  8594. }
  8595. }
  8596. /*
  8597. * Build arrays to store the first and last node of the chain
  8598. * pertaining to each group
  8599. */
  8600. list = (xmlNodePtr *) xmlMalloc(nbgroups * sizeof(xmlNodePtr));
  8601. if (list == NULL) {
  8602. xmlRngVErrMemory(ctxt, "validating\n");
  8603. return (-1);
  8604. }
  8605. memset(list, 0, nbgroups * sizeof(xmlNodePtr));
  8606. lasts = (xmlNodePtr *) xmlMalloc(nbgroups * sizeof(xmlNodePtr));
  8607. if (lasts == NULL) {
  8608. xmlRngVErrMemory(ctxt, "validating\n");
  8609. return (-1);
  8610. }
  8611. memset(lasts, 0, nbgroups * sizeof(xmlNodePtr));
  8612. /*
  8613. * Walk the sequence of children finding the right group and
  8614. * sorting them in sequences.
  8615. */
  8616. cur = ctxt->state->seq;
  8617. cur = xmlRelaxNGSkipIgnored(ctxt, cur);
  8618. start = cur;
  8619. while (cur != NULL) {
  8620. ctxt->state->seq = cur;
  8621. if ((partitions->triage != NULL) &&
  8622. (partitions->flags & IS_DETERMINIST)) {
  8623. void *tmp = NULL;
  8624. if ((cur->type == XML_TEXT_NODE) ||
  8625. (cur->type == XML_CDATA_SECTION_NODE)) {
  8626. tmp = xmlHashLookup2(partitions->triage, BAD_CAST "#text",
  8627. NULL);
  8628. } else if (cur->type == XML_ELEMENT_NODE) {
  8629. if (cur->ns != NULL) {
  8630. tmp = xmlHashLookup2(partitions->triage, cur->name,
  8631. cur->ns->href);
  8632. if (tmp == NULL)
  8633. tmp = xmlHashLookup2(partitions->triage,
  8634. BAD_CAST "#any",
  8635. cur->ns->href);
  8636. } else
  8637. tmp =
  8638. xmlHashLookup2(partitions->triage, cur->name,
  8639. NULL);
  8640. if (tmp == NULL)
  8641. tmp =
  8642. xmlHashLookup2(partitions->triage, BAD_CAST "#any",
  8643. NULL);
  8644. }
  8645. if (tmp == NULL) {
  8646. i = nbgroups;
  8647. } else {
  8648. i = ((ptrdiff_t) tmp) - 1;
  8649. if (partitions->flags & IS_NEEDCHECK) {
  8650. group = partitions->groups[i];
  8651. if (!xmlRelaxNGNodeMatchesList(cur, group->defs))
  8652. i = nbgroups;
  8653. }
  8654. }
  8655. } else {
  8656. for (i = 0; i < nbgroups; i++) {
  8657. group = partitions->groups[i];
  8658. if (group == NULL)
  8659. continue;
  8660. if (xmlRelaxNGNodeMatchesList(cur, group->defs))
  8661. break;
  8662. }
  8663. }
  8664. /*
  8665. * We break as soon as an element not matched is found
  8666. */
  8667. if (i >= nbgroups) {
  8668. break;
  8669. }
  8670. if (lasts[i] != NULL) {
  8671. lasts[i]->next = cur;
  8672. lasts[i] = cur;
  8673. } else {
  8674. list[i] = cur;
  8675. lasts[i] = cur;
  8676. }
  8677. if (cur->next != NULL)
  8678. lastchg = cur->next;
  8679. else
  8680. lastchg = cur;
  8681. cur = xmlRelaxNGSkipIgnored(ctxt, cur->next);
  8682. }
  8683. if (ret != 0) {
  8684. VALID_ERR(XML_RELAXNG_ERR_INTERSEQ);
  8685. ret = -1;
  8686. goto done;
  8687. }
  8688. lastelem = cur;
  8689. oldstate = ctxt->state;
  8690. for (i = 0; i < nbgroups; i++) {
  8691. ctxt->state = xmlRelaxNGCopyValidState(ctxt, oldstate);
  8692. if (ctxt->state == NULL) {
  8693. ret = -1;
  8694. break;
  8695. }
  8696. group = partitions->groups[i];
  8697. if (lasts[i] != NULL) {
  8698. last = lasts[i]->next;
  8699. lasts[i]->next = NULL;
  8700. }
  8701. ctxt->state->seq = list[i];
  8702. ret = xmlRelaxNGValidateDefinition(ctxt, group->rule);
  8703. if (ret != 0)
  8704. break;
  8705. if (ctxt->state != NULL) {
  8706. cur = ctxt->state->seq;
  8707. cur = xmlRelaxNGSkipIgnored(ctxt, cur);
  8708. xmlRelaxNGFreeValidState(ctxt, oldstate);
  8709. oldstate = ctxt->state;
  8710. ctxt->state = NULL;
  8711. if (cur != NULL
  8712. /* there's a nasty violation of context-free unambiguities,
  8713. since in open-name-class context, interleave in the
  8714. production shall finish without caring about anything
  8715. else that is OK to follow in that case -- it would
  8716. otherwise get marked as "extra content" and would
  8717. hence fail the validation, hence this perhaps
  8718. dirty attempt to rectify such a situation */
  8719. && (define->parent->type != XML_RELAXNG_DEF
  8720. || !xmlStrEqual(define->parent->name,
  8721. (const xmlChar *) "open-name-class"))) {
  8722. VALID_ERR2(XML_RELAXNG_ERR_INTEREXTRA, cur->name);
  8723. ret = -1;
  8724. ctxt->state = oldstate;
  8725. goto done;
  8726. }
  8727. } else if (ctxt->states != NULL) {
  8728. int j;
  8729. int found = 0;
  8730. int best = -1;
  8731. int lowattr = -1;
  8732. /*
  8733. * PBM: what happen if there is attributes checks in the interleaves
  8734. */
  8735. for (j = 0; j < ctxt->states->nbState; j++) {
  8736. cur = ctxt->states->tabState[j]->seq;
  8737. cur = xmlRelaxNGSkipIgnored(ctxt, cur);
  8738. if (cur == NULL) {
  8739. if (found == 0) {
  8740. lowattr = ctxt->states->tabState[j]->nbAttrLeft;
  8741. best = j;
  8742. }
  8743. found = 1;
  8744. if (ctxt->states->tabState[j]->nbAttrLeft <= lowattr) {
  8745. /* try to keep the latest one to mach old heuristic */
  8746. lowattr = ctxt->states->tabState[j]->nbAttrLeft;
  8747. best = j;
  8748. }
  8749. if (lowattr == 0)
  8750. break;
  8751. } else if (found == 0) {
  8752. if (lowattr == -1) {
  8753. lowattr = ctxt->states->tabState[j]->nbAttrLeft;
  8754. best = j;
  8755. } else
  8756. if (ctxt->states->tabState[j]->nbAttrLeft <= lowattr) {
  8757. /* try to keep the latest one to mach old heuristic */
  8758. lowattr = ctxt->states->tabState[j]->nbAttrLeft;
  8759. best = j;
  8760. }
  8761. }
  8762. }
  8763. /*
  8764. * BIG PBM: here we pick only one restarting point :-(
  8765. */
  8766. if (ctxt->states->nbState > 0) {
  8767. xmlRelaxNGFreeValidState(ctxt, oldstate);
  8768. if (best != -1) {
  8769. oldstate = ctxt->states->tabState[best];
  8770. ctxt->states->tabState[best] = NULL;
  8771. } else {
  8772. oldstate =
  8773. ctxt->states->tabState[ctxt->states->nbState - 1];
  8774. ctxt->states->tabState[ctxt->states->nbState - 1] = NULL;
  8775. ctxt->states->nbState--;
  8776. }
  8777. }
  8778. for (j = 0; j < ctxt->states->nbState ; j++) {
  8779. xmlRelaxNGFreeValidState(ctxt, ctxt->states->tabState[j]);
  8780. }
  8781. xmlRelaxNGFreeStates(ctxt, ctxt->states);
  8782. ctxt->states = NULL;
  8783. if (found == 0) {
  8784. if (cur == NULL) {
  8785. VALID_ERR2(XML_RELAXNG_ERR_INTEREXTRA,
  8786. (const xmlChar *) "noname");
  8787. } else {
  8788. VALID_ERR2(XML_RELAXNG_ERR_INTEREXTRA, cur->name);
  8789. }
  8790. ret = -1;
  8791. ctxt->state = oldstate;
  8792. goto done;
  8793. }
  8794. } else {
  8795. ret = -1;
  8796. break;
  8797. }
  8798. if (lasts[i] != NULL) {
  8799. lasts[i]->next = last;
  8800. }
  8801. }
  8802. if (ctxt->state != NULL)
  8803. xmlRelaxNGFreeValidState(ctxt, ctxt->state);
  8804. ctxt->state = oldstate;
  8805. ctxt->state->seq = lastelem;
  8806. if (ret != 0) {
  8807. VALID_ERR(XML_RELAXNG_ERR_INTERSEQ);
  8808. ret = -1;
  8809. goto done;
  8810. }
  8811. done:
  8812. ctxt->flags = oldflags;
  8813. /*
  8814. * builds the next links chain from the prev one
  8815. */
  8816. cur = lastchg;
  8817. while (cur != NULL) {
  8818. if ((cur == start) || (cur->prev == NULL))
  8819. break;
  8820. cur->prev->next = cur;
  8821. cur = cur->prev;
  8822. }
  8823. if (ret == 0) {
  8824. if (ctxt->errNr > errNr)
  8825. xmlRelaxNGPopErrors(ctxt, errNr);
  8826. }
  8827. xmlFree(list);
  8828. xmlFree(lasts);
  8829. return (ret);
  8830. }
  8831. /**
  8832. * xmlRelaxNGValidateDefinitionList:
  8833. * @ctxt: a Relax-NG validation context
  8834. * @define: the list of definition to verify
  8835. *
  8836. * Validate the given node content against the (list) of definitions
  8837. *
  8838. * Returns 0 if the validation succeeded or an error code.
  8839. */
  8840. static int
  8841. xmlRelaxNGValidateDefinitionList(xmlRelaxNGValidCtxtPtr ctxt,
  8842. xmlRelaxNGDefinePtr defines)
  8843. {
  8844. int ret = 0, res;
  8845. if (defines == NULL) {
  8846. VALID_ERR2(XML_RELAXNG_ERR_INTERNAL,
  8847. BAD_CAST "NULL definition list");
  8848. return (-1);
  8849. }
  8850. while (defines != NULL) {
  8851. if ((ctxt->state != NULL) || (ctxt->states != NULL)) {
  8852. res = xmlRelaxNGValidateDefinition(ctxt, defines);
  8853. if (res < 0)
  8854. ret = -1;
  8855. } else {
  8856. VALID_ERR(XML_RELAXNG_ERR_NOSTATE);
  8857. return (-1);
  8858. }
  8859. if (res == -1) /* continues on -2 */
  8860. break;
  8861. defines = defines->next;
  8862. }
  8863. return (ret);
  8864. }
  8865. /**
  8866. * xmlRelaxNGElementMatch:
  8867. * @ctxt: a Relax-NG validation context
  8868. * @define: the definition to check
  8869. * @elem: the element
  8870. *
  8871. * Check if the element matches the definition nameClass
  8872. *
  8873. * Returns 1 if the element matches, 0 if no, or -1 in case of error
  8874. */
  8875. static int
  8876. xmlRelaxNGElementMatch(xmlRelaxNGValidCtxtPtr ctxt,
  8877. xmlRelaxNGDefinePtr define, xmlNodePtr elem)
  8878. {
  8879. int ret = 0, oldflags = 0;
  8880. if (define->name != NULL) {
  8881. if (!xmlStrEqual(elem->name, define->name)) {
  8882. VALID_ERR3(XML_RELAXNG_ERR_ELEMNAME, define->name, elem->name);
  8883. return (0);
  8884. }
  8885. }
  8886. if ((define->ns != NULL) && (define->ns[0] != 0)) {
  8887. if (elem->ns == NULL) {
  8888. VALID_ERR2(XML_RELAXNG_ERR_ELEMNONS, elem->name);
  8889. return (0);
  8890. } else if (!xmlStrEqual(elem->ns->href, define->ns)) {
  8891. VALID_ERR3(XML_RELAXNG_ERR_ELEMWRONGNS,
  8892. elem->name, define->ns);
  8893. return (0);
  8894. }
  8895. } else if ((elem->ns != NULL) && (define->ns != NULL) &&
  8896. (define->name == NULL)) {
  8897. VALID_ERR2(XML_RELAXNG_ERR_ELEMEXTRANS, elem->name);
  8898. return (0);
  8899. } else if ((elem->ns != NULL) && (define->name != NULL)) {
  8900. VALID_ERR2(XML_RELAXNG_ERR_ELEMEXTRANS, define->name);
  8901. return (0);
  8902. }
  8903. if (define->nameClass == NULL)
  8904. return (1);
  8905. define = define->nameClass;
  8906. if (define->type == XML_RELAXNG_EXCEPT) {
  8907. xmlRelaxNGDefinePtr list;
  8908. if (ctxt != NULL) {
  8909. oldflags = ctxt->flags;
  8910. ctxt->flags |= FLAGS_IGNORABLE;
  8911. }
  8912. list = define->content;
  8913. while (list != NULL) {
  8914. ret = xmlRelaxNGElementMatch(ctxt, list, elem);
  8915. if (ret == 1) {
  8916. if (ctxt != NULL)
  8917. ctxt->flags = oldflags;
  8918. return (0);
  8919. }
  8920. if (ret < 0) {
  8921. if (ctxt != NULL)
  8922. ctxt->flags = oldflags;
  8923. return (ret);
  8924. }
  8925. list = list->next;
  8926. }
  8927. ret = 1;
  8928. if (ctxt != NULL) {
  8929. ctxt->flags = oldflags;
  8930. }
  8931. } else if (define->type == XML_RELAXNG_CHOICE) {
  8932. xmlRelaxNGDefinePtr list;
  8933. if (ctxt != NULL) {
  8934. oldflags = ctxt->flags;
  8935. ctxt->flags |= FLAGS_IGNORABLE;
  8936. }
  8937. list = define->nameClass;
  8938. while (list != NULL) {
  8939. ret = xmlRelaxNGElementMatch(ctxt, list, elem);
  8940. if (ret == 1) {
  8941. if (ctxt != NULL)
  8942. ctxt->flags = oldflags;
  8943. return (1);
  8944. }
  8945. if (ret < 0) {
  8946. if (ctxt != NULL)
  8947. ctxt->flags = oldflags;
  8948. return (ret);
  8949. }
  8950. list = list->next;
  8951. }
  8952. if (ctxt != NULL) {
  8953. if (ret != 0) {
  8954. if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
  8955. xmlRelaxNGDumpValidError(ctxt);
  8956. } else {
  8957. if (ctxt->errNr > 0)
  8958. xmlRelaxNGPopErrors(ctxt, 0);
  8959. }
  8960. }
  8961. ret = 0;
  8962. if (ctxt != NULL) {
  8963. ctxt->flags = oldflags;
  8964. }
  8965. } else {
  8966. TODO ret = -1;
  8967. }
  8968. return (ret);
  8969. }
  8970. /**
  8971. * xmlRelaxNGBestState:
  8972. * @ctxt: a Relax-NG validation context
  8973. *
  8974. * Find the "best" state in the ctxt->states list of states to report
  8975. * errors about. I.e. a state with no element left in the child list
  8976. * or the one with the less attributes left.
  8977. * This is called only if a validation error was detected
  8978. *
  8979. * Returns the index of the "best" state or -1 in case of error
  8980. */
  8981. static int
  8982. xmlRelaxNGBestState(xmlRelaxNGValidCtxtPtr ctxt)
  8983. {
  8984. xmlRelaxNGValidStatePtr state;
  8985. int i, tmp;
  8986. int best = -1;
  8987. int value = 1000000;
  8988. if ((ctxt == NULL) || (ctxt->states == NULL) ||
  8989. (ctxt->states->nbState <= 0))
  8990. return (-1);
  8991. for (i = 0; i < ctxt->states->nbState; i++) {
  8992. state = ctxt->states->tabState[i];
  8993. if (state == NULL)
  8994. continue;
  8995. if (state->seq != NULL) {
  8996. if ((best == -1) || (value > 100000)) {
  8997. value = 100000;
  8998. best = i;
  8999. }
  9000. } else {
  9001. tmp = state->nbAttrLeft;
  9002. if ((best == -1) || (value > tmp)) {
  9003. value = tmp;
  9004. best = i;
  9005. }
  9006. }
  9007. }
  9008. return (best);
  9009. }
  9010. /**
  9011. * xmlRelaxNGLogBestError:
  9012. * @ctxt: a Relax-NG validation context
  9013. *
  9014. * Find the "best" state in the ctxt->states list of states to report
  9015. * errors about and log it.
  9016. */
  9017. static void
  9018. xmlRelaxNGLogBestError(xmlRelaxNGValidCtxtPtr ctxt)
  9019. {
  9020. int best;
  9021. if ((ctxt == NULL) || (ctxt->states == NULL) ||
  9022. (ctxt->states->nbState <= 0))
  9023. return;
  9024. best = xmlRelaxNGBestState(ctxt);
  9025. if ((best >= 0) && (best < ctxt->states->nbState)) {
  9026. ctxt->state = ctxt->states->tabState[best];
  9027. xmlRelaxNGValidateElementEnd(ctxt, 1);
  9028. }
  9029. }
  9030. /**
  9031. * xmlRelaxNGValidateElementEnd:
  9032. * @ctxt: a Relax-NG validation context
  9033. * @dolog: indicate that error logging should be done
  9034. *
  9035. * Validate the end of the element, implements check that
  9036. * there is nothing left not consumed in the element content
  9037. * or in the attribute list.
  9038. *
  9039. * Returns 0 if the validation succeeded or an error code.
  9040. */
  9041. static int
  9042. xmlRelaxNGValidateElementEnd(xmlRelaxNGValidCtxtPtr ctxt, int dolog)
  9043. {
  9044. int i;
  9045. xmlRelaxNGValidStatePtr state;
  9046. state = ctxt->state;
  9047. if (state->seq != NULL) {
  9048. state->seq = xmlRelaxNGSkipIgnored(ctxt, state->seq);
  9049. if (state->seq != NULL) {
  9050. if (dolog) {
  9051. VALID_ERR3(XML_RELAXNG_ERR_EXTRACONTENT,
  9052. state->node->name, state->seq->name);
  9053. }
  9054. return (-1);
  9055. }
  9056. }
  9057. for (i = 0; i < state->nbAttrs; i++) {
  9058. if (state->attrs[i] != NULL) {
  9059. if (dolog) {
  9060. VALID_ERR3(XML_RELAXNG_ERR_INVALIDATTR,
  9061. state->attrs[i]->name, state->node->name);
  9062. }
  9063. return (-1 - i);
  9064. }
  9065. }
  9066. return (0);
  9067. }
  9068. /**
  9069. * xmlRelaxNGValidateState:
  9070. * @ctxt: a Relax-NG validation context
  9071. * @define: the definition to verify
  9072. *
  9073. * Validate the current state against the definition
  9074. *
  9075. * Returns 0 if the validation succeeded or an error code.
  9076. */
  9077. static int
  9078. xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
  9079. xmlRelaxNGDefinePtr define)
  9080. {
  9081. xmlNodePtr node;
  9082. int ret = 0, i, tmp, oldflags, errNr;
  9083. xmlRelaxNGValidStatePtr oldstate = NULL, state;
  9084. if (define == NULL) {
  9085. VALID_ERR(XML_RELAXNG_ERR_NODEFINE);
  9086. return (-1);
  9087. }
  9088. if (ctxt->state != NULL) {
  9089. node = ctxt->state->seq;
  9090. } else {
  9091. node = NULL;
  9092. }
  9093. ctxt->depth++;
  9094. switch (define->type) {
  9095. case XML_RELAXNG_EMPTY:
  9096. ret = 0;
  9097. break;
  9098. case XML_RELAXNG_NOT_ALLOWED:
  9099. ret = -1;
  9100. break;
  9101. case XML_RELAXNG_TEXT:
  9102. while ((node != NULL) &&
  9103. ((node->type == XML_TEXT_NODE) ||
  9104. (node->type == XML_COMMENT_NODE) ||
  9105. (node->type == XML_PI_NODE) ||
  9106. (node->type == XML_CDATA_SECTION_NODE)))
  9107. node = node->next;
  9108. ctxt->state->seq = node;
  9109. break;
  9110. case XML_RELAXNG_ELEMENT:
  9111. errNr = ctxt->errNr;
  9112. node = xmlRelaxNGSkipIgnored(ctxt, node);
  9113. if (node == NULL) {
  9114. VALID_ERR2(XML_RELAXNG_ERR_NOELEM, define->name);
  9115. ret = -1;
  9116. if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
  9117. xmlRelaxNGDumpValidError(ctxt);
  9118. break;
  9119. }
  9120. if (node->type != XML_ELEMENT_NODE) {
  9121. VALID_ERR(XML_RELAXNG_ERR_NOTELEM);
  9122. ret = -1;
  9123. if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
  9124. xmlRelaxNGDumpValidError(ctxt);
  9125. break;
  9126. }
  9127. /*
  9128. * This node was already validated successfully against
  9129. * this definition.
  9130. */
  9131. if (node->psvi == define) {
  9132. ctxt->state->seq = xmlRelaxNGSkipIgnored(ctxt, node->next);
  9133. if (ctxt->errNr > errNr)
  9134. xmlRelaxNGPopErrors(ctxt, errNr);
  9135. if (ctxt->errNr != 0) {
  9136. while ((ctxt->err != NULL) &&
  9137. (((ctxt->err->err == XML_RELAXNG_ERR_ELEMNAME)
  9138. && (xmlStrEqual(ctxt->err->arg2, node->name)))
  9139. ||
  9140. ((ctxt->err->err ==
  9141. XML_RELAXNG_ERR_ELEMEXTRANS)
  9142. && (xmlStrEqual(ctxt->err->arg1, node->name)))
  9143. || (ctxt->err->err == XML_RELAXNG_ERR_NOELEM)
  9144. || (ctxt->err->err ==
  9145. XML_RELAXNG_ERR_NOTELEM)))
  9146. xmlRelaxNGValidErrorPop(ctxt);
  9147. }
  9148. break;
  9149. }
  9150. ret = xmlRelaxNGElementMatch(ctxt, define, node);
  9151. if (ret <= 0) {
  9152. ret = -1;
  9153. if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
  9154. xmlRelaxNGDumpValidError(ctxt);
  9155. break;
  9156. }
  9157. ret = 0;
  9158. if (ctxt->errNr != 0) {
  9159. if (ctxt->errNr > errNr)
  9160. xmlRelaxNGPopErrors(ctxt, errNr);
  9161. while ((ctxt->err != NULL) &&
  9162. (((ctxt->err->err == XML_RELAXNG_ERR_ELEMNAME) &&
  9163. (xmlStrEqual(ctxt->err->arg2, node->name))) ||
  9164. ((ctxt->err->err == XML_RELAXNG_ERR_ELEMEXTRANS) &&
  9165. (xmlStrEqual(ctxt->err->arg1, node->name))) ||
  9166. (ctxt->err->err == XML_RELAXNG_ERR_NOELEM) ||
  9167. (ctxt->err->err == XML_RELAXNG_ERR_NOTELEM)))
  9168. xmlRelaxNGValidErrorPop(ctxt);
  9169. }
  9170. errNr = ctxt->errNr;
  9171. oldflags = ctxt->flags;
  9172. if (ctxt->flags & FLAGS_MIXED_CONTENT) {
  9173. ctxt->flags -= FLAGS_MIXED_CONTENT;
  9174. }
  9175. state = xmlRelaxNGNewValidState(ctxt, node);
  9176. if (state == NULL) {
  9177. ret = -1;
  9178. if ((ctxt->flags & FLAGS_IGNORABLE) == 0)
  9179. xmlRelaxNGDumpValidError(ctxt);
  9180. break;
  9181. }
  9182. oldstate = ctxt->state;
  9183. ctxt->state = state;
  9184. if (define->attrs != NULL) {
  9185. tmp = xmlRelaxNGValidateAttributeList(ctxt, define->attrs);
  9186. if (tmp != 0) {
  9187. ret = -1;
  9188. VALID_ERR2(XML_RELAXNG_ERR_ATTRVALID, node->name);
  9189. }
  9190. }
  9191. if (define->contModel != NULL) {
  9192. xmlRelaxNGValidStatePtr nstate, tmpstate = ctxt->state;
  9193. xmlRelaxNGStatesPtr tmpstates = ctxt->states;
  9194. xmlNodePtr nseq;
  9195. nstate = xmlRelaxNGNewValidState(ctxt, node);
  9196. ctxt->state = nstate;
  9197. ctxt->states = NULL;
  9198. tmp = xmlRelaxNGValidateCompiledContent(ctxt,
  9199. define->contModel,
  9200. ctxt->state->seq);
  9201. nseq = ctxt->state->seq;
  9202. ctxt->state = tmpstate;
  9203. ctxt->states = tmpstates;
  9204. xmlRelaxNGFreeValidState(ctxt, nstate);
  9205. if (tmp != 0)
  9206. ret = -1;
  9207. if (ctxt->states != NULL) {
  9208. tmp = -1;
  9209. for (i = 0; i < ctxt->states->nbState; i++) {
  9210. state = ctxt->states->tabState[i];
  9211. ctxt->state = state;
  9212. ctxt->state->seq = nseq;
  9213. if (xmlRelaxNGValidateElementEnd(ctxt, 0) == 0) {
  9214. tmp = 0;
  9215. break;
  9216. }
  9217. }
  9218. if (tmp != 0) {
  9219. /*
  9220. * validation error, log the message for the "best" one
  9221. */
  9222. ctxt->flags |= FLAGS_IGNORABLE;
  9223. xmlRelaxNGLogBestError(ctxt);
  9224. }
  9225. for (i = 0; i < ctxt->states->nbState; i++) {
  9226. xmlRelaxNGFreeValidState(ctxt,
  9227. ctxt->states->
  9228. tabState[i]);
  9229. }
  9230. xmlRelaxNGFreeStates(ctxt, ctxt->states);
  9231. ctxt->flags = oldflags;
  9232. ctxt->states = NULL;
  9233. if ((ret == 0) && (tmp == -1))
  9234. ret = -1;
  9235. } else {
  9236. state = ctxt->state;
  9237. if (ctxt->state != NULL)
  9238. ctxt->state->seq = nseq;
  9239. if (ret == 0)
  9240. ret = xmlRelaxNGValidateElementEnd(ctxt, 1);
  9241. xmlRelaxNGFreeValidState(ctxt, state);
  9242. }
  9243. } else {
  9244. if (define->content != NULL) {
  9245. tmp = xmlRelaxNGValidateDefinitionList(ctxt,
  9246. define->
  9247. content);
  9248. if (tmp != 0) {
  9249. ret = -1;
  9250. if (ctxt->state == NULL) {
  9251. ctxt->state = oldstate;
  9252. VALID_ERR2(XML_RELAXNG_ERR_CONTENTVALID,
  9253. node->name);
  9254. ctxt->state = NULL;
  9255. } else {
  9256. VALID_ERR2(XML_RELAXNG_ERR_CONTENTVALID,
  9257. node->name);
  9258. }
  9259. }
  9260. }
  9261. if (ctxt->states != NULL) {
  9262. tmp = -1;
  9263. for (i = 0; i < ctxt->states->nbState; i++) {
  9264. state = ctxt->states->tabState[i];
  9265. ctxt->state = state;
  9266. if (xmlRelaxNGValidateElementEnd(ctxt, 0) == 0) {
  9267. tmp = 0;
  9268. break;
  9269. }
  9270. }
  9271. if (tmp != 0) {
  9272. /*
  9273. * validation error, log the message for the "best" one
  9274. */
  9275. ctxt->flags |= FLAGS_IGNORABLE;
  9276. xmlRelaxNGLogBestError(ctxt);
  9277. }
  9278. for (i = 0; i < ctxt->states->nbState; i++) {
  9279. xmlRelaxNGFreeValidState(ctxt,
  9280. ctxt->states->tabState[i]);
  9281. ctxt->states->tabState[i] = NULL;
  9282. }
  9283. xmlRelaxNGFreeStates(ctxt, ctxt->states);
  9284. ctxt->flags = oldflags;
  9285. ctxt->states = NULL;
  9286. if ((ret == 0) && (tmp == -1))
  9287. ret = -1;
  9288. } else {
  9289. state = ctxt->state;
  9290. if (ret == 0)
  9291. ret = xmlRelaxNGValidateElementEnd(ctxt, 1);
  9292. xmlRelaxNGFreeValidState(ctxt, state);
  9293. }
  9294. }
  9295. if (ret == 0) {
  9296. node->psvi = define;
  9297. }
  9298. ctxt->flags = oldflags;
  9299. ctxt->state = oldstate;
  9300. if (oldstate != NULL)
  9301. oldstate->seq = xmlRelaxNGSkipIgnored(ctxt, node->next);
  9302. if (ret != 0) {
  9303. if ((ctxt->flags & FLAGS_IGNORABLE) == 0) {
  9304. xmlRelaxNGDumpValidError(ctxt);
  9305. ret = 0;
  9306. #if 0
  9307. } else {
  9308. ret = -2;
  9309. #endif
  9310. }
  9311. } else {
  9312. if (ctxt->errNr > errNr)
  9313. xmlRelaxNGPopErrors(ctxt, errNr);
  9314. }
  9315. break;
  9316. case XML_RELAXNG_OPTIONAL:{
  9317. errNr = ctxt->errNr;
  9318. oldflags = ctxt->flags;
  9319. ctxt->flags |= FLAGS_IGNORABLE;
  9320. oldstate = xmlRelaxNGCopyValidState(ctxt, ctxt->state);
  9321. ret =
  9322. xmlRelaxNGValidateDefinitionList(ctxt,
  9323. define->content);
  9324. if (ret != 0) {
  9325. if (ctxt->state != NULL)
  9326. xmlRelaxNGFreeValidState(ctxt, ctxt->state);
  9327. ctxt->state = oldstate;
  9328. ctxt->flags = oldflags;
  9329. ret = 0;
  9330. if (ctxt->errNr > errNr)
  9331. xmlRelaxNGPopErrors(ctxt, errNr);
  9332. break;
  9333. }
  9334. if (ctxt->states != NULL) {
  9335. xmlRelaxNGAddStates(ctxt, ctxt->states, oldstate);
  9336. } else {
  9337. ctxt->states = xmlRelaxNGNewStates(ctxt, 1);
  9338. if (ctxt->states == NULL) {
  9339. xmlRelaxNGFreeValidState(ctxt, oldstate);
  9340. ctxt->flags = oldflags;
  9341. ret = -1;
  9342. if (ctxt->errNr > errNr)
  9343. xmlRelaxNGPopErrors(ctxt, errNr);
  9344. break;
  9345. }
  9346. xmlRelaxNGAddStates(ctxt, ctxt->states, oldstate);
  9347. xmlRelaxNGAddStates(ctxt, ctxt->states, ctxt->state);
  9348. ctxt->state = NULL;
  9349. }
  9350. ctxt->flags = oldflags;
  9351. ret = 0;
  9352. if (ctxt->errNr > errNr)
  9353. xmlRelaxNGPopErrors(ctxt, errNr);
  9354. break;
  9355. }
  9356. case XML_RELAXNG_ONEORMORE:
  9357. errNr = ctxt->errNr;
  9358. ret = xmlRelaxNGValidateDefinitionList(ctxt, define->content);
  9359. if (ret != 0) {
  9360. break;
  9361. }
  9362. if (ctxt->errNr > errNr)
  9363. xmlRelaxNGPopErrors(ctxt, errNr);
  9364. /* Falls through. */
  9365. case XML_RELAXNG_ZEROORMORE:{
  9366. int progress;
  9367. xmlRelaxNGStatesPtr states = NULL, res = NULL;
  9368. int base, j;
  9369. errNr = ctxt->errNr;
  9370. res = xmlRelaxNGNewStates(ctxt, 1);
  9371. if (res == NULL) {
  9372. ret = -1;
  9373. break;
  9374. }
  9375. /*
  9376. * All the input states are also exit states
  9377. */
  9378. if (ctxt->state != NULL) {
  9379. xmlRelaxNGAddStates(ctxt, res,
  9380. xmlRelaxNGCopyValidState(ctxt,
  9381. ctxt->
  9382. state));
  9383. } else {
  9384. for (j = 0; j < ctxt->states->nbState; j++) {
  9385. xmlRelaxNGAddStates(ctxt, res,
  9386. xmlRelaxNGCopyValidState(ctxt,
  9387. ctxt->states->tabState[j]));
  9388. }
  9389. }
  9390. oldflags = ctxt->flags;
  9391. ctxt->flags |= FLAGS_IGNORABLE;
  9392. do {
  9393. progress = 0;
  9394. base = res->nbState;
  9395. if (ctxt->states != NULL) {
  9396. states = ctxt->states;
  9397. for (i = 0; i < states->nbState; i++) {
  9398. ctxt->state = states->tabState[i];
  9399. ctxt->states = NULL;
  9400. ret = xmlRelaxNGValidateDefinitionList(ctxt,
  9401. define->
  9402. content);
  9403. if (ret == 0) {
  9404. if (ctxt->state != NULL) {
  9405. tmp = xmlRelaxNGAddStates(ctxt, res,
  9406. ctxt->state);
  9407. ctxt->state = NULL;
  9408. if (tmp == 1)
  9409. progress = 1;
  9410. } else if (ctxt->states != NULL) {
  9411. for (j = 0; j < ctxt->states->nbState;
  9412. j++) {
  9413. tmp =
  9414. xmlRelaxNGAddStates(ctxt, res,
  9415. ctxt->states->tabState[j]);
  9416. if (tmp == 1)
  9417. progress = 1;
  9418. }
  9419. xmlRelaxNGFreeStates(ctxt,
  9420. ctxt->states);
  9421. ctxt->states = NULL;
  9422. }
  9423. } else {
  9424. if (ctxt->state != NULL) {
  9425. xmlRelaxNGFreeValidState(ctxt,
  9426. ctxt->state);
  9427. ctxt->state = NULL;
  9428. }
  9429. }
  9430. }
  9431. } else {
  9432. ret = xmlRelaxNGValidateDefinitionList(ctxt,
  9433. define->
  9434. content);
  9435. if (ret != 0) {
  9436. xmlRelaxNGFreeValidState(ctxt, ctxt->state);
  9437. ctxt->state = NULL;
  9438. } else {
  9439. base = res->nbState;
  9440. if (ctxt->state != NULL) {
  9441. tmp = xmlRelaxNGAddStates(ctxt, res,
  9442. ctxt->state);
  9443. ctxt->state = NULL;
  9444. if (tmp == 1)
  9445. progress = 1;
  9446. } else if (ctxt->states != NULL) {
  9447. for (j = 0; j < ctxt->states->nbState; j++) {
  9448. tmp = xmlRelaxNGAddStates(ctxt, res,
  9449. ctxt->states->tabState[j]);
  9450. if (tmp == 1)
  9451. progress = 1;
  9452. }
  9453. if (states == NULL) {
  9454. states = ctxt->states;
  9455. } else {
  9456. xmlRelaxNGFreeStates(ctxt,
  9457. ctxt->states);
  9458. }
  9459. ctxt->states = NULL;
  9460. }
  9461. }
  9462. }
  9463. if (progress) {
  9464. /*
  9465. * Collect all the new nodes added at that step
  9466. * and make them the new node set
  9467. */
  9468. if (res->nbState - base == 1) {
  9469. ctxt->state = xmlRelaxNGCopyValidState(ctxt,
  9470. res->
  9471. tabState
  9472. [base]);
  9473. } else {
  9474. if (states == NULL) {
  9475. xmlRelaxNGNewStates(ctxt,
  9476. res->nbState - base);
  9477. states = ctxt->states;
  9478. if (states == NULL) {
  9479. progress = 0;
  9480. break;
  9481. }
  9482. }
  9483. states->nbState = 0;
  9484. for (i = base; i < res->nbState; i++)
  9485. xmlRelaxNGAddStates(ctxt, states,
  9486. xmlRelaxNGCopyValidState
  9487. (ctxt, res->tabState[i]));
  9488. ctxt->states = states;
  9489. }
  9490. }
  9491. } while (progress == 1);
  9492. if (states != NULL) {
  9493. xmlRelaxNGFreeStates(ctxt, states);
  9494. }
  9495. ctxt->states = res;
  9496. ctxt->flags = oldflags;
  9497. #if 0
  9498. /*
  9499. * errors may have to be propagated back...
  9500. */
  9501. if (ctxt->errNr > errNr)
  9502. xmlRelaxNGPopErrors(ctxt, errNr);
  9503. #endif
  9504. ret = 0;
  9505. break;
  9506. }
  9507. case XML_RELAXNG_CHOICE:{
  9508. xmlRelaxNGDefinePtr list = NULL;
  9509. xmlRelaxNGStatesPtr states = NULL;
  9510. node = xmlRelaxNGSkipIgnored(ctxt, node);
  9511. errNr = ctxt->errNr;
  9512. if ((define->dflags & IS_TRIABLE) && (define->data != NULL) &&
  9513. (node != NULL)) {
  9514. /*
  9515. * node == NULL can't be optimized since IS_TRIABLE
  9516. * doesn't account for choice which may lead to
  9517. * only attributes.
  9518. */
  9519. xmlHashTablePtr triage =
  9520. (xmlHashTablePtr) define->data;
  9521. /*
  9522. * Something we can optimize cleanly there is only one
  9523. * possible branch out !
  9524. */
  9525. if ((node->type == XML_TEXT_NODE) ||
  9526. (node->type == XML_CDATA_SECTION_NODE)) {
  9527. list =
  9528. xmlHashLookup2(triage, BAD_CAST "#text", NULL);
  9529. } else if (node->type == XML_ELEMENT_NODE) {
  9530. if (node->ns != NULL) {
  9531. list = xmlHashLookup2(triage, node->name,
  9532. node->ns->href);
  9533. if (list == NULL)
  9534. list =
  9535. xmlHashLookup2(triage, BAD_CAST "#any",
  9536. node->ns->href);
  9537. } else
  9538. list =
  9539. xmlHashLookup2(triage, node->name, NULL);
  9540. if (list == NULL)
  9541. list =
  9542. xmlHashLookup2(triage, BAD_CAST "#any",
  9543. NULL);
  9544. }
  9545. if (list == NULL) {
  9546. ret = -1;
  9547. VALID_ERR2(XML_RELAXNG_ERR_ELEMWRONG, node->name);
  9548. break;
  9549. }
  9550. ret = xmlRelaxNGValidateDefinition(ctxt, list);
  9551. if (ret == 0) {
  9552. }
  9553. break;
  9554. }
  9555. list = define->content;
  9556. oldflags = ctxt->flags;
  9557. ctxt->flags |= FLAGS_IGNORABLE;
  9558. while (list != NULL) {
  9559. oldstate = xmlRelaxNGCopyValidState(ctxt, ctxt->state);
  9560. ret = xmlRelaxNGValidateDefinition(ctxt, list);
  9561. if (ret == 0) {
  9562. if (states == NULL) {
  9563. states = xmlRelaxNGNewStates(ctxt, 1);
  9564. }
  9565. if (ctxt->state != NULL) {
  9566. xmlRelaxNGAddStates(ctxt, states, ctxt->state);
  9567. } else if (ctxt->states != NULL) {
  9568. for (i = 0; i < ctxt->states->nbState; i++) {
  9569. xmlRelaxNGAddStates(ctxt, states,
  9570. ctxt->states->
  9571. tabState[i]);
  9572. }
  9573. xmlRelaxNGFreeStates(ctxt, ctxt->states);
  9574. ctxt->states = NULL;
  9575. }
  9576. } else {
  9577. xmlRelaxNGFreeValidState(ctxt, ctxt->state);
  9578. }
  9579. ctxt->state = oldstate;
  9580. list = list->next;
  9581. }
  9582. if (states != NULL) {
  9583. xmlRelaxNGFreeValidState(ctxt, oldstate);
  9584. ctxt->states = states;
  9585. ctxt->state = NULL;
  9586. ret = 0;
  9587. } else {
  9588. ctxt->states = NULL;
  9589. }
  9590. ctxt->flags = oldflags;
  9591. if (ret != 0) {
  9592. if ((ctxt->flags & FLAGS_IGNORABLE) == 0) {
  9593. xmlRelaxNGDumpValidError(ctxt);
  9594. }
  9595. } else {
  9596. if (ctxt->errNr > errNr)
  9597. xmlRelaxNGPopErrors(ctxt, errNr);
  9598. }
  9599. break;
  9600. }
  9601. case XML_RELAXNG_DEF:
  9602. case XML_RELAXNG_GROUP:
  9603. ret = xmlRelaxNGValidateDefinitionList(ctxt, define->content);
  9604. break;
  9605. case XML_RELAXNG_INTERLEAVE:
  9606. ret = xmlRelaxNGValidateInterleave(ctxt, define);
  9607. break;
  9608. case XML_RELAXNG_ATTRIBUTE:
  9609. ret = xmlRelaxNGValidateAttribute(ctxt, define);
  9610. break;
  9611. case XML_RELAXNG_START:
  9612. case XML_RELAXNG_NOOP:
  9613. case XML_RELAXNG_REF:
  9614. case XML_RELAXNG_EXTERNALREF:
  9615. case XML_RELAXNG_PARENTREF:
  9616. ret = xmlRelaxNGValidateDefinition(ctxt, define->content);
  9617. break;
  9618. case XML_RELAXNG_DATATYPE:{
  9619. xmlNodePtr child;
  9620. xmlChar *content = NULL;
  9621. child = node;
  9622. while (child != NULL) {
  9623. if (child->type == XML_ELEMENT_NODE) {
  9624. VALID_ERR2(XML_RELAXNG_ERR_DATAELEM,
  9625. node->parent->name);
  9626. ret = -1;
  9627. break;
  9628. } else if ((child->type == XML_TEXT_NODE) ||
  9629. (child->type == XML_CDATA_SECTION_NODE)) {
  9630. content = xmlStrcat(content, child->content);
  9631. }
  9632. /* TODO: handle entities ... */
  9633. child = child->next;
  9634. }
  9635. if (ret == -1) {
  9636. if (content != NULL)
  9637. xmlFree(content);
  9638. break;
  9639. }
  9640. if (content == NULL) {
  9641. content = xmlStrdup(BAD_CAST "");
  9642. if (content == NULL) {
  9643. xmlRngVErrMemory(ctxt, "validating\n");
  9644. ret = -1;
  9645. break;
  9646. }
  9647. }
  9648. ret = xmlRelaxNGValidateDatatype(ctxt, content, define,
  9649. ctxt->state->seq);
  9650. if (ret == -1) {
  9651. VALID_ERR2(XML_RELAXNG_ERR_DATATYPE, define->name);
  9652. } else if (ret == 0) {
  9653. ctxt->state->seq = NULL;
  9654. }
  9655. if (content != NULL)
  9656. xmlFree(content);
  9657. break;
  9658. }
  9659. case XML_RELAXNG_VALUE:{
  9660. xmlChar *content = NULL;
  9661. xmlChar *oldvalue;
  9662. xmlNodePtr child;
  9663. child = node;
  9664. while (child != NULL) {
  9665. if (child->type == XML_ELEMENT_NODE) {
  9666. VALID_ERR2(XML_RELAXNG_ERR_VALELEM,
  9667. node->parent->name);
  9668. ret = -1;
  9669. break;
  9670. } else if ((child->type == XML_TEXT_NODE) ||
  9671. (child->type == XML_CDATA_SECTION_NODE)) {
  9672. content = xmlStrcat(content, child->content);
  9673. }
  9674. /* TODO: handle entities ... */
  9675. child = child->next;
  9676. }
  9677. if (ret == -1) {
  9678. if (content != NULL)
  9679. xmlFree(content);
  9680. break;
  9681. }
  9682. if (content == NULL) {
  9683. content = xmlStrdup(BAD_CAST "");
  9684. if (content == NULL) {
  9685. xmlRngVErrMemory(ctxt, "validating\n");
  9686. ret = -1;
  9687. break;
  9688. }
  9689. }
  9690. oldvalue = ctxt->state->value;
  9691. ctxt->state->value = content;
  9692. ret = xmlRelaxNGValidateValue(ctxt, define);
  9693. ctxt->state->value = oldvalue;
  9694. if (ret == -1) {
  9695. VALID_ERR2(XML_RELAXNG_ERR_VALUE, define->name);
  9696. } else if (ret == 0) {
  9697. ctxt->state->seq = NULL;
  9698. }
  9699. if (content != NULL)
  9700. xmlFree(content);
  9701. break;
  9702. }
  9703. case XML_RELAXNG_LIST:{
  9704. xmlChar *content;
  9705. xmlNodePtr child;
  9706. xmlChar *oldvalue, *oldendvalue;
  9707. int len;
  9708. /*
  9709. * Make sure it's only text nodes
  9710. */
  9711. content = NULL;
  9712. child = node;
  9713. while (child != NULL) {
  9714. if (child->type == XML_ELEMENT_NODE) {
  9715. VALID_ERR2(XML_RELAXNG_ERR_LISTELEM,
  9716. node->parent->name);
  9717. ret = -1;
  9718. break;
  9719. } else if ((child->type == XML_TEXT_NODE) ||
  9720. (child->type == XML_CDATA_SECTION_NODE)) {
  9721. content = xmlStrcat(content, child->content);
  9722. }
  9723. /* TODO: handle entities ... */
  9724. child = child->next;
  9725. }
  9726. if (ret == -1) {
  9727. if (content != NULL)
  9728. xmlFree(content);
  9729. break;
  9730. }
  9731. if (content == NULL) {
  9732. content = xmlStrdup(BAD_CAST "");
  9733. if (content == NULL) {
  9734. xmlRngVErrMemory(ctxt, "validating\n");
  9735. ret = -1;
  9736. break;
  9737. }
  9738. }
  9739. len = xmlStrlen(content);
  9740. oldvalue = ctxt->state->value;
  9741. oldendvalue = ctxt->state->endvalue;
  9742. ctxt->state->value = content;
  9743. ctxt->state->endvalue = content + len;
  9744. ret = xmlRelaxNGValidateValue(ctxt, define);
  9745. ctxt->state->value = oldvalue;
  9746. ctxt->state->endvalue = oldendvalue;
  9747. if (ret == -1) {
  9748. VALID_ERR(XML_RELAXNG_ERR_LIST);
  9749. } else if ((ret == 0) && (node != NULL)) {
  9750. ctxt->state->seq = node->next;
  9751. }
  9752. if (content != NULL)
  9753. xmlFree(content);
  9754. break;
  9755. }
  9756. case XML_RELAXNG_EXCEPT:
  9757. case XML_RELAXNG_PARAM:
  9758. TODO ret = -1;
  9759. break;
  9760. }
  9761. ctxt->depth--;
  9762. return (ret);
  9763. }
  9764. /**
  9765. * xmlRelaxNGValidateDefinition:
  9766. * @ctxt: a Relax-NG validation context
  9767. * @define: the definition to verify
  9768. *
  9769. * Validate the current node lists against the definition
  9770. *
  9771. * Returns 0 if the validation succeeded or an error code.
  9772. */
  9773. static int
  9774. xmlRelaxNGValidateDefinition(xmlRelaxNGValidCtxtPtr ctxt,
  9775. xmlRelaxNGDefinePtr define)
  9776. {
  9777. xmlRelaxNGStatesPtr states, res;
  9778. int i, j, k, ret, oldflags;
  9779. /*
  9780. * We should NOT have both ctxt->state and ctxt->states
  9781. */
  9782. if ((ctxt->state != NULL) && (ctxt->states != NULL)) {
  9783. TODO xmlRelaxNGFreeValidState(ctxt, ctxt->state);
  9784. ctxt->state = NULL;
  9785. }
  9786. if ((ctxt->states == NULL) || (ctxt->states->nbState == 1)) {
  9787. if (ctxt->states != NULL) {
  9788. ctxt->state = ctxt->states->tabState[0];
  9789. xmlRelaxNGFreeStates(ctxt, ctxt->states);
  9790. ctxt->states = NULL;
  9791. }
  9792. ret = xmlRelaxNGValidateState(ctxt, define);
  9793. if ((ctxt->state != NULL) && (ctxt->states != NULL)) {
  9794. TODO xmlRelaxNGFreeValidState(ctxt, ctxt->state);
  9795. ctxt->state = NULL;
  9796. }
  9797. if ((ctxt->states != NULL) && (ctxt->states->nbState == 1)) {
  9798. ctxt->state = ctxt->states->tabState[0];
  9799. xmlRelaxNGFreeStates(ctxt, ctxt->states);
  9800. ctxt->states = NULL;
  9801. }
  9802. return (ret);
  9803. }
  9804. states = ctxt->states;
  9805. ctxt->states = NULL;
  9806. res = NULL;
  9807. j = 0;
  9808. oldflags = ctxt->flags;
  9809. ctxt->flags |= FLAGS_IGNORABLE;
  9810. for (i = 0; i < states->nbState; i++) {
  9811. ctxt->state = states->tabState[i];
  9812. ctxt->states = NULL;
  9813. ret = xmlRelaxNGValidateState(ctxt, define);
  9814. /*
  9815. * We should NOT have both ctxt->state and ctxt->states
  9816. */
  9817. if ((ctxt->state != NULL) && (ctxt->states != NULL)) {
  9818. TODO xmlRelaxNGFreeValidState(ctxt, ctxt->state);
  9819. ctxt->state = NULL;
  9820. }
  9821. if (ret == 0) {
  9822. if (ctxt->states == NULL) {
  9823. if (res != NULL) {
  9824. /* add the state to the container */
  9825. xmlRelaxNGAddStates(ctxt, res, ctxt->state);
  9826. ctxt->state = NULL;
  9827. } else {
  9828. /* add the state directly in states */
  9829. states->tabState[j++] = ctxt->state;
  9830. ctxt->state = NULL;
  9831. }
  9832. } else {
  9833. if (res == NULL) {
  9834. /* make it the new container and copy other results */
  9835. res = ctxt->states;
  9836. ctxt->states = NULL;
  9837. for (k = 0; k < j; k++)
  9838. xmlRelaxNGAddStates(ctxt, res,
  9839. states->tabState[k]);
  9840. } else {
  9841. /* add all the new results to res and reff the container */
  9842. for (k = 0; k < ctxt->states->nbState; k++)
  9843. xmlRelaxNGAddStates(ctxt, res,
  9844. ctxt->states->tabState[k]);
  9845. xmlRelaxNGFreeStates(ctxt, ctxt->states);
  9846. ctxt->states = NULL;
  9847. }
  9848. }
  9849. } else {
  9850. if (ctxt->state != NULL) {
  9851. xmlRelaxNGFreeValidState(ctxt, ctxt->state);
  9852. ctxt->state = NULL;
  9853. } else if (ctxt->states != NULL) {
  9854. for (k = 0; k < ctxt->states->nbState; k++)
  9855. xmlRelaxNGFreeValidState(ctxt,
  9856. ctxt->states->tabState[k]);
  9857. xmlRelaxNGFreeStates(ctxt, ctxt->states);
  9858. ctxt->states = NULL;
  9859. }
  9860. }
  9861. }
  9862. ctxt->flags = oldflags;
  9863. if (res != NULL) {
  9864. xmlRelaxNGFreeStates(ctxt, states);
  9865. ctxt->states = res;
  9866. ret = 0;
  9867. } else if (j > 1) {
  9868. states->nbState = j;
  9869. ctxt->states = states;
  9870. ret = 0;
  9871. } else if (j == 1) {
  9872. ctxt->state = states->tabState[0];
  9873. xmlRelaxNGFreeStates(ctxt, states);
  9874. ret = 0;
  9875. } else {
  9876. ret = -1;
  9877. xmlRelaxNGFreeStates(ctxt, states);
  9878. if (ctxt->states != NULL) {
  9879. xmlRelaxNGFreeStates(ctxt, ctxt->states);
  9880. ctxt->states = NULL;
  9881. }
  9882. }
  9883. if ((ctxt->state != NULL) && (ctxt->states != NULL)) {
  9884. TODO xmlRelaxNGFreeValidState(ctxt, ctxt->state);
  9885. ctxt->state = NULL;
  9886. }
  9887. return (ret);
  9888. }
  9889. /**
  9890. * xmlRelaxNGValidateDocument:
  9891. * @ctxt: a Relax-NG validation context
  9892. * @doc: the document
  9893. *
  9894. * Validate the given document
  9895. *
  9896. * Returns 0 if the validation succeeded or an error code.
  9897. */
  9898. static int
  9899. xmlRelaxNGValidateDocument(xmlRelaxNGValidCtxtPtr ctxt, xmlDocPtr doc)
  9900. {
  9901. int ret;
  9902. xmlRelaxNGPtr schema;
  9903. xmlRelaxNGGrammarPtr grammar;
  9904. xmlRelaxNGValidStatePtr state;
  9905. xmlNodePtr node;
  9906. if ((ctxt == NULL) || (ctxt->schema == NULL) || (doc == NULL))
  9907. return (-1);
  9908. ctxt->errNo = XML_RELAXNG_OK;
  9909. schema = ctxt->schema;
  9910. grammar = schema->topgrammar;
  9911. if (grammar == NULL) {
  9912. VALID_ERR(XML_RELAXNG_ERR_NOGRAMMAR);
  9913. return (-1);
  9914. }
  9915. state = xmlRelaxNGNewValidState(ctxt, NULL);
  9916. ctxt->state = state;
  9917. ret = xmlRelaxNGValidateDefinition(ctxt, grammar->start);
  9918. if ((ctxt->state != NULL) && (state->seq != NULL)) {
  9919. state = ctxt->state;
  9920. node = state->seq;
  9921. node = xmlRelaxNGSkipIgnored(ctxt, node);
  9922. if (node != NULL) {
  9923. if (ret != -1) {
  9924. VALID_ERR(XML_RELAXNG_ERR_EXTRADATA);
  9925. ret = -1;
  9926. }
  9927. }
  9928. } else if (ctxt->states != NULL) {
  9929. int i;
  9930. int tmp = -1;
  9931. for (i = 0; i < ctxt->states->nbState; i++) {
  9932. state = ctxt->states->tabState[i];
  9933. node = state->seq;
  9934. node = xmlRelaxNGSkipIgnored(ctxt, node);
  9935. if (node == NULL)
  9936. tmp = 0;
  9937. xmlRelaxNGFreeValidState(ctxt, state);
  9938. }
  9939. if (tmp == -1) {
  9940. if (ret != -1) {
  9941. VALID_ERR(XML_RELAXNG_ERR_EXTRADATA);
  9942. ret = -1;
  9943. }
  9944. }
  9945. }
  9946. if (ctxt->state != NULL) {
  9947. xmlRelaxNGFreeValidState(ctxt, ctxt->state);
  9948. ctxt->state = NULL;
  9949. }
  9950. if (ret != 0)
  9951. xmlRelaxNGDumpValidError(ctxt);
  9952. #ifdef LIBXML_VALID_ENABLED
  9953. if (ctxt->idref == 1) {
  9954. xmlValidCtxt vctxt;
  9955. memset(&vctxt, 0, sizeof(xmlValidCtxt));
  9956. vctxt.valid = 1;
  9957. vctxt.error = ctxt->error;
  9958. vctxt.warning = ctxt->warning;
  9959. vctxt.userData = ctxt->userData;
  9960. if (xmlValidateDocumentFinal(&vctxt, doc) != 1)
  9961. ret = -1;
  9962. }
  9963. #endif /* LIBXML_VALID_ENABLED */
  9964. if ((ret == 0) && (ctxt->errNo != XML_RELAXNG_OK))
  9965. ret = -1;
  9966. return (ret);
  9967. }
  9968. /**
  9969. * xmlRelaxNGCleanPSVI:
  9970. * @node: an input element or document
  9971. *
  9972. * Call this routine to speed up XPath computation on static documents.
  9973. * This stamps all the element nodes with the document order
  9974. * Like for line information, the order is kept in the element->content
  9975. * field, the value stored is actually - the node number (starting at -1)
  9976. * to be able to differentiate from line numbers.
  9977. *
  9978. * Returns the number of elements found in the document or -1 in case
  9979. * of error.
  9980. */
  9981. static void
  9982. xmlRelaxNGCleanPSVI(xmlNodePtr node) {
  9983. xmlNodePtr cur;
  9984. if ((node == NULL) ||
  9985. ((node->type != XML_ELEMENT_NODE) &&
  9986. (node->type != XML_DOCUMENT_NODE) &&
  9987. (node->type != XML_HTML_DOCUMENT_NODE)))
  9988. return;
  9989. if (node->type == XML_ELEMENT_NODE)
  9990. node->psvi = NULL;
  9991. cur = node->children;
  9992. while (cur != NULL) {
  9993. if (cur->type == XML_ELEMENT_NODE) {
  9994. cur->psvi = NULL;
  9995. if (cur->children != NULL) {
  9996. cur = cur->children;
  9997. continue;
  9998. }
  9999. }
  10000. if (cur->next != NULL) {
  10001. cur = cur->next;
  10002. continue;
  10003. }
  10004. do {
  10005. cur = cur->parent;
  10006. if (cur == NULL)
  10007. break;
  10008. if (cur == node) {
  10009. cur = NULL;
  10010. break;
  10011. }
  10012. if (cur->next != NULL) {
  10013. cur = cur->next;
  10014. break;
  10015. }
  10016. } while (cur != NULL);
  10017. }
  10018. return;
  10019. }
  10020. /************************************************************************
  10021. * *
  10022. * Validation interfaces *
  10023. * *
  10024. ************************************************************************/
  10025. /**
  10026. * xmlRelaxNGNewValidCtxt:
  10027. * @schema: a precompiled XML RelaxNGs
  10028. *
  10029. * Create an XML RelaxNGs validation context based on the given schema
  10030. *
  10031. * Returns the validation context or NULL in case of error
  10032. */
  10033. xmlRelaxNGValidCtxtPtr
  10034. xmlRelaxNGNewValidCtxt(xmlRelaxNGPtr schema)
  10035. {
  10036. xmlRelaxNGValidCtxtPtr ret;
  10037. ret = (xmlRelaxNGValidCtxtPtr) xmlMalloc(sizeof(xmlRelaxNGValidCtxt));
  10038. if (ret == NULL) {
  10039. xmlRngVErrMemory(NULL, "building context\n");
  10040. return (NULL);
  10041. }
  10042. memset(ret, 0, sizeof(xmlRelaxNGValidCtxt));
  10043. ret->schema = schema;
  10044. ret->error = xmlGenericError;
  10045. ret->userData = xmlGenericErrorContext;
  10046. ret->errNr = 0;
  10047. ret->errMax = 0;
  10048. ret->err = NULL;
  10049. ret->errTab = NULL;
  10050. if (schema != NULL)
  10051. ret->idref = schema->idref;
  10052. ret->states = NULL;
  10053. ret->freeState = NULL;
  10054. ret->freeStates = NULL;
  10055. ret->errNo = XML_RELAXNG_OK;
  10056. return (ret);
  10057. }
  10058. /**
  10059. * xmlRelaxNGFreeValidCtxt:
  10060. * @ctxt: the schema validation context
  10061. *
  10062. * Free the resources associated to the schema validation context
  10063. */
  10064. void
  10065. xmlRelaxNGFreeValidCtxt(xmlRelaxNGValidCtxtPtr ctxt)
  10066. {
  10067. int k;
  10068. if (ctxt == NULL)
  10069. return;
  10070. if (ctxt->states != NULL)
  10071. xmlRelaxNGFreeStates(NULL, ctxt->states);
  10072. if (ctxt->freeState != NULL) {
  10073. for (k = 0; k < ctxt->freeState->nbState; k++) {
  10074. xmlRelaxNGFreeValidState(NULL, ctxt->freeState->tabState[k]);
  10075. }
  10076. xmlRelaxNGFreeStates(NULL, ctxt->freeState);
  10077. }
  10078. if (ctxt->freeStates != NULL) {
  10079. for (k = 0; k < ctxt->freeStatesNr; k++) {
  10080. xmlRelaxNGFreeStates(NULL, ctxt->freeStates[k]);
  10081. }
  10082. xmlFree(ctxt->freeStates);
  10083. }
  10084. if (ctxt->errTab != NULL)
  10085. xmlFree(ctxt->errTab);
  10086. if (ctxt->elemTab != NULL) {
  10087. xmlRegExecCtxtPtr exec;
  10088. exec = xmlRelaxNGElemPop(ctxt);
  10089. while (exec != NULL) {
  10090. xmlRegFreeExecCtxt(exec);
  10091. exec = xmlRelaxNGElemPop(ctxt);
  10092. }
  10093. xmlFree(ctxt->elemTab);
  10094. }
  10095. xmlFree(ctxt);
  10096. }
  10097. /**
  10098. * xmlRelaxNGSetValidErrors:
  10099. * @ctxt: a Relax-NG validation context
  10100. * @err: the error function
  10101. * @warn: the warning function
  10102. * @ctx: the functions context
  10103. *
  10104. * Set the error and warning callback information
  10105. */
  10106. void
  10107. xmlRelaxNGSetValidErrors(xmlRelaxNGValidCtxtPtr ctxt,
  10108. xmlRelaxNGValidityErrorFunc err,
  10109. xmlRelaxNGValidityWarningFunc warn, void *ctx)
  10110. {
  10111. if (ctxt == NULL)
  10112. return;
  10113. ctxt->error = err;
  10114. ctxt->warning = warn;
  10115. ctxt->userData = ctx;
  10116. ctxt->serror = NULL;
  10117. }
  10118. /**
  10119. * xmlRelaxNGSetValidStructuredErrors:
  10120. * @ctxt: a Relax-NG validation context
  10121. * @serror: the structured error function
  10122. * @ctx: the functions context
  10123. *
  10124. * Set the structured error callback
  10125. */
  10126. void
  10127. xmlRelaxNGSetValidStructuredErrors(xmlRelaxNGValidCtxtPtr ctxt,
  10128. xmlStructuredErrorFunc serror, void *ctx)
  10129. {
  10130. if (ctxt == NULL)
  10131. return;
  10132. ctxt->serror = serror;
  10133. ctxt->error = NULL;
  10134. ctxt->warning = NULL;
  10135. ctxt->userData = ctx;
  10136. }
  10137. /**
  10138. * xmlRelaxNGGetValidErrors:
  10139. * @ctxt: a Relax-NG validation context
  10140. * @err: the error function result
  10141. * @warn: the warning function result
  10142. * @ctx: the functions context result
  10143. *
  10144. * Get the error and warning callback information
  10145. *
  10146. * Returns -1 in case of error and 0 otherwise
  10147. */
  10148. int
  10149. xmlRelaxNGGetValidErrors(xmlRelaxNGValidCtxtPtr ctxt,
  10150. xmlRelaxNGValidityErrorFunc * err,
  10151. xmlRelaxNGValidityWarningFunc * warn, void **ctx)
  10152. {
  10153. if (ctxt == NULL)
  10154. return (-1);
  10155. if (err != NULL)
  10156. *err = ctxt->error;
  10157. if (warn != NULL)
  10158. *warn = ctxt->warning;
  10159. if (ctx != NULL)
  10160. *ctx = ctxt->userData;
  10161. return (0);
  10162. }
  10163. /**
  10164. * xmlRelaxNGValidateDoc:
  10165. * @ctxt: a Relax-NG validation context
  10166. * @doc: a parsed document tree
  10167. *
  10168. * Validate a document tree in memory.
  10169. *
  10170. * Returns 0 if the document is valid, a positive error code
  10171. * number otherwise and -1 in case of internal or API error.
  10172. */
  10173. int
  10174. xmlRelaxNGValidateDoc(xmlRelaxNGValidCtxtPtr ctxt, xmlDocPtr doc)
  10175. {
  10176. int ret;
  10177. if ((ctxt == NULL) || (doc == NULL))
  10178. return (-1);
  10179. ctxt->doc = doc;
  10180. ret = xmlRelaxNGValidateDocument(ctxt, doc);
  10181. /*
  10182. * Remove all left PSVI
  10183. */
  10184. xmlRelaxNGCleanPSVI((xmlNodePtr) doc);
  10185. /*
  10186. * TODO: build error codes
  10187. */
  10188. if (ret == -1)
  10189. return (1);
  10190. return (ret);
  10191. }
  10192. #endif /* LIBXML_SCHEMAS_ENABLED */