relaxng.c 356 KB

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