123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831 |
- /**
- * catalog.c: set of generic Catalog related routines
- *
- * Reference: SGML Open Technical Resolution TR9401:1997.
- * http://www.jclark.com/sp/catalog.htm
- *
- * XML Catalogs Working Draft 06 August 2001
- * http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
- *
- * See Copyright for the status of this software.
- *
- * Daniel.Veillard@imag.fr
- */
- #define IN_LIBXML
- #include "libxml.h"
- #ifdef LIBXML_CATALOG_ENABLED
- #ifdef HAVE_SYS_TYPES_H
- #include <sys/types.h>
- #endif
- #ifdef HAVE_SYS_STAT_H
- #include <sys/stat.h>
- #endif
- #ifdef HAVE_UNISTD_H
- #include <unistd.h>
- #endif
- #ifdef HAVE_FCNTL_H
- #include <fcntl.h>
- #endif
- #ifdef HAVE_STDLIB_H
- #include <stdlib.h>
- #endif
- #include <string.h>
- #include <libxml/xmlmemory.h>
- #include <libxml/hash.h>
- #include <libxml/uri.h>
- #include <libxml/parserInternals.h>
- #include <libxml/catalog.h>
- #include <libxml/xmlerror.h>
- #include <libxml/threads.h>
- #include <libxml/globals.h>
- #include "buf.h"
- #define MAX_DELEGATE 50
- #define MAX_CATAL_DEPTH 50
- #ifdef _WIN32
- # define PATH_SEPARATOR ';'
- #else
- # define PATH_SEPARATOR ':'
- #endif
- /**
- * TODO:
- *
- * macro to flag unimplemented blocks
- * XML_CATALOG_PREFER user env to select between system/public preferred
- * option. C.f. Richard Tobin <richard@cogsci.ed.ac.uk>
- *> Just FYI, I am using an environment variable XML_CATALOG_PREFER with
- *> values "system" and "public". I have made the default be "system" to
- *> match yours.
- */
- #define TODO \
- xmlGenericError(xmlGenericErrorContext, \
- "Unimplemented block at %s:%d\n", \
- __FILE__, __LINE__);
- #define XML_URN_PUBID "urn:publicid:"
- #define XML_CATAL_BREAK ((xmlChar *) -1)
- #ifndef XML_XML_DEFAULT_CATALOG
- #define XML_XML_DEFAULT_CATALOG "file:///etc/xml/catalog"
- #endif
- #ifndef XML_SGML_DEFAULT_CATALOG
- #define XML_SGML_DEFAULT_CATALOG "file:///etc/sgml/catalog"
- #endif
- #if defined(_WIN32) && defined(_MSC_VER)
- #undef XML_XML_DEFAULT_CATALOG
- static char XML_XML_DEFAULT_CATALOG[256] = "file:///etc/xml/catalog";
- #if defined(_WIN32_WCE)
- /* Windows CE don't have a A variant */
- #define GetModuleHandleA GetModuleHandle
- #define GetModuleFileNameA GetModuleFileName
- #else
- #if !defined(_WINDOWS_)
- void* __stdcall GetModuleHandleA(const char*);
- unsigned long __stdcall GetModuleFileNameA(void*, char*, unsigned long);
- #endif
- #endif
- #endif
- static xmlChar *xmlCatalogNormalizePublic(const xmlChar *pubID);
- static int xmlExpandCatalog(xmlCatalogPtr catal, const char *filename);
- /************************************************************************
- * *
- * Types, all private *
- * *
- ************************************************************************/
- typedef enum {
- XML_CATA_REMOVED = -1,
- XML_CATA_NONE = 0,
- XML_CATA_CATALOG,
- XML_CATA_BROKEN_CATALOG,
- XML_CATA_NEXT_CATALOG,
- XML_CATA_GROUP,
- XML_CATA_PUBLIC,
- XML_CATA_SYSTEM,
- XML_CATA_REWRITE_SYSTEM,
- XML_CATA_DELEGATE_PUBLIC,
- XML_CATA_DELEGATE_SYSTEM,
- XML_CATA_URI,
- XML_CATA_REWRITE_URI,
- XML_CATA_DELEGATE_URI,
- SGML_CATA_SYSTEM,
- SGML_CATA_PUBLIC,
- SGML_CATA_ENTITY,
- SGML_CATA_PENTITY,
- SGML_CATA_DOCTYPE,
- SGML_CATA_LINKTYPE,
- SGML_CATA_NOTATION,
- SGML_CATA_DELEGATE,
- SGML_CATA_BASE,
- SGML_CATA_CATALOG,
- SGML_CATA_DOCUMENT,
- SGML_CATA_SGMLDECL
- } xmlCatalogEntryType;
- typedef struct _xmlCatalogEntry xmlCatalogEntry;
- typedef xmlCatalogEntry *xmlCatalogEntryPtr;
- struct _xmlCatalogEntry {
- struct _xmlCatalogEntry *next;
- struct _xmlCatalogEntry *parent;
- struct _xmlCatalogEntry *children;
- xmlCatalogEntryType type;
- xmlChar *name;
- xmlChar *value;
- xmlChar *URL; /* The expanded URL using the base */
- xmlCatalogPrefer prefer;
- int dealloc;
- int depth;
- struct _xmlCatalogEntry *group;
- };
- typedef enum {
- XML_XML_CATALOG_TYPE = 1,
- XML_SGML_CATALOG_TYPE
- } xmlCatalogType;
- #define XML_MAX_SGML_CATA_DEPTH 10
- struct _xmlCatalog {
- xmlCatalogType type; /* either XML or SGML */
- /*
- * SGML Catalogs are stored as a simple hash table of catalog entries
- * Catalog stack to check against overflows when building the
- * SGML catalog
- */
- char *catalTab[XML_MAX_SGML_CATA_DEPTH]; /* stack of catals */
- int catalNr; /* Number of current catal streams */
- int catalMax; /* Max number of catal streams */
- xmlHashTablePtr sgml;
- /*
- * XML Catalogs are stored as a tree of Catalog entries
- */
- xmlCatalogPrefer prefer;
- xmlCatalogEntryPtr xml;
- };
- /************************************************************************
- * *
- * Global variables *
- * *
- ************************************************************************/
- /*
- * Those are preferences
- */
- static int xmlDebugCatalogs = 0; /* used for debugging */
- static xmlCatalogAllow xmlCatalogDefaultAllow = XML_CATA_ALLOW_ALL;
- static xmlCatalogPrefer xmlCatalogDefaultPrefer = XML_CATA_PREFER_PUBLIC;
- /*
- * Hash table containing all the trees of XML catalogs parsed by
- * the application.
- */
- static xmlHashTablePtr xmlCatalogXMLFiles = NULL;
- /*
- * The default catalog in use by the application
- */
- static xmlCatalogPtr xmlDefaultCatalog = NULL;
- /*
- * A mutex for modifying the shared global catalog(s)
- * xmlDefaultCatalog tree.
- * It also protects xmlCatalogXMLFiles
- * The core of this readers/writer scheme is in xmlFetchXMLCatalogFile()
- */
- static xmlRMutexPtr xmlCatalogMutex = NULL;
- /*
- * Whether the catalog support was initialized.
- */
- static int xmlCatalogInitialized = 0;
- /************************************************************************
- * *
- * Catalog error handlers *
- * *
- ************************************************************************/
- /**
- * xmlCatalogErrMemory:
- * @extra: extra information
- *
- * Handle an out of memory condition
- */
- static void
- xmlCatalogErrMemory(const char *extra)
- {
- __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_CATALOG,
- XML_ERR_NO_MEMORY, XML_ERR_ERROR, NULL, 0,
- extra, NULL, NULL, 0, 0,
- "Memory allocation failed : %s\n", extra);
- }
- /**
- * xmlCatalogErr:
- * @catal: the Catalog entry
- * @node: the context node
- * @msg: the error message
- * @extra: extra information
- *
- * Handle a catalog error
- */
- static void LIBXML_ATTR_FORMAT(4,0)
- xmlCatalogErr(xmlCatalogEntryPtr catal, xmlNodePtr node, int error,
- const char *msg, const xmlChar *str1, const xmlChar *str2,
- const xmlChar *str3)
- {
- __xmlRaiseError(NULL, NULL, NULL, catal, node, XML_FROM_CATALOG,
- error, XML_ERR_ERROR, NULL, 0,
- (const char *) str1, (const char *) str2,
- (const char *) str3, 0, 0,
- msg, str1, str2, str3);
- }
- /************************************************************************
- * *
- * Allocation and Freeing *
- * *
- ************************************************************************/
- /**
- * xmlNewCatalogEntry:
- * @type: type of entry
- * @name: name of the entry
- * @value: value of the entry
- * @prefer: the PUBLIC vs. SYSTEM current preference value
- * @group: for members of a group, the group entry
- *
- * create a new Catalog entry, this type is shared both by XML and
- * SGML catalogs, but the acceptable types values differs.
- *
- * Returns the xmlCatalogEntryPtr or NULL in case of error
- */
- static xmlCatalogEntryPtr
- xmlNewCatalogEntry(xmlCatalogEntryType type, const xmlChar *name,
- const xmlChar *value, const xmlChar *URL, xmlCatalogPrefer prefer,
- xmlCatalogEntryPtr group) {
- xmlCatalogEntryPtr ret;
- xmlChar *normid = NULL;
- ret = (xmlCatalogEntryPtr) xmlMalloc(sizeof(xmlCatalogEntry));
- if (ret == NULL) {
- xmlCatalogErrMemory("allocating catalog entry");
- return(NULL);
- }
- ret->next = NULL;
- ret->parent = NULL;
- ret->children = NULL;
- ret->type = type;
- if (type == XML_CATA_PUBLIC || type == XML_CATA_DELEGATE_PUBLIC) {
- normid = xmlCatalogNormalizePublic(name);
- if (normid != NULL)
- name = (*normid != 0 ? normid : NULL);
- }
- if (name != NULL)
- ret->name = xmlStrdup(name);
- else
- ret->name = NULL;
- if (normid != NULL)
- xmlFree(normid);
- if (value != NULL)
- ret->value = xmlStrdup(value);
- else
- ret->value = NULL;
- if (URL == NULL)
- URL = value;
- if (URL != NULL)
- ret->URL = xmlStrdup(URL);
- else
- ret->URL = NULL;
- ret->prefer = prefer;
- ret->dealloc = 0;
- ret->depth = 0;
- ret->group = group;
- return(ret);
- }
- static void
- xmlFreeCatalogEntryList(xmlCatalogEntryPtr ret);
- /**
- * xmlFreeCatalogEntry:
- * @payload: a Catalog entry
- *
- * Free the memory allocated to a Catalog entry
- */
- static void
- xmlFreeCatalogEntry(void *payload, const xmlChar *name ATTRIBUTE_UNUSED) {
- xmlCatalogEntryPtr ret = (xmlCatalogEntryPtr) payload;
- if (ret == NULL)
- return;
- /*
- * Entries stored in the file hash must be deallocated
- * only by the file hash cleaner !
- */
- if (ret->dealloc == 1)
- return;
- if (xmlDebugCatalogs) {
- if (ret->name != NULL)
- xmlGenericError(xmlGenericErrorContext,
- "Free catalog entry %s\n", ret->name);
- else if (ret->value != NULL)
- xmlGenericError(xmlGenericErrorContext,
- "Free catalog entry %s\n", ret->value);
- else
- xmlGenericError(xmlGenericErrorContext,
- "Free catalog entry\n");
- }
- if (ret->name != NULL)
- xmlFree(ret->name);
- if (ret->value != NULL)
- xmlFree(ret->value);
- if (ret->URL != NULL)
- xmlFree(ret->URL);
- xmlFree(ret);
- }
- /**
- * xmlFreeCatalogEntryList:
- * @ret: a Catalog entry list
- *
- * Free the memory allocated to a full chained list of Catalog entries
- */
- static void
- xmlFreeCatalogEntryList(xmlCatalogEntryPtr ret) {
- xmlCatalogEntryPtr next;
- while (ret != NULL) {
- next = ret->next;
- xmlFreeCatalogEntry(ret, NULL);
- ret = next;
- }
- }
- /**
- * xmlFreeCatalogHashEntryList:
- * @payload: a Catalog entry list
- *
- * Free the memory allocated to list of Catalog entries from the
- * catalog file hash.
- */
- static void
- xmlFreeCatalogHashEntryList(void *payload,
- const xmlChar *name ATTRIBUTE_UNUSED) {
- xmlCatalogEntryPtr catal = (xmlCatalogEntryPtr) payload;
- xmlCatalogEntryPtr children, next;
- if (catal == NULL)
- return;
- children = catal->children;
- while (children != NULL) {
- next = children->next;
- children->dealloc = 0;
- children->children = NULL;
- xmlFreeCatalogEntry(children, NULL);
- children = next;
- }
- catal->dealloc = 0;
- xmlFreeCatalogEntry(catal, NULL);
- }
- /**
- * xmlCreateNewCatalog:
- * @type: type of catalog
- * @prefer: the PUBLIC vs. SYSTEM current preference value
- *
- * create a new Catalog, this type is shared both by XML and
- * SGML catalogs, but the acceptable types values differs.
- *
- * Returns the xmlCatalogPtr or NULL in case of error
- */
- static xmlCatalogPtr
- xmlCreateNewCatalog(xmlCatalogType type, xmlCatalogPrefer prefer) {
- xmlCatalogPtr ret;
- ret = (xmlCatalogPtr) xmlMalloc(sizeof(xmlCatalog));
- if (ret == NULL) {
- xmlCatalogErrMemory("allocating catalog");
- return(NULL);
- }
- memset(ret, 0, sizeof(xmlCatalog));
- ret->type = type;
- ret->catalNr = 0;
- ret->catalMax = XML_MAX_SGML_CATA_DEPTH;
- ret->prefer = prefer;
- if (ret->type == XML_SGML_CATALOG_TYPE)
- ret->sgml = xmlHashCreate(10);
- return(ret);
- }
- /**
- * xmlFreeCatalog:
- * @catal: a Catalog
- *
- * Free the memory allocated to a Catalog
- */
- void
- xmlFreeCatalog(xmlCatalogPtr catal) {
- if (catal == NULL)
- return;
- if (catal->xml != NULL)
- xmlFreeCatalogEntryList(catal->xml);
- if (catal->sgml != NULL)
- xmlHashFree(catal->sgml, xmlFreeCatalogEntry);
- xmlFree(catal);
- }
- /************************************************************************
- * *
- * Serializing Catalogs *
- * *
- ************************************************************************/
- #ifdef LIBXML_OUTPUT_ENABLED
- /**
- * xmlCatalogDumpEntry:
- * @entry: the catalog entry
- * @out: the file.
- *
- * Serialize an SGML Catalog entry
- */
- static void
- xmlCatalogDumpEntry(void *payload, void *data,
- const xmlChar *name ATTRIBUTE_UNUSED) {
- xmlCatalogEntryPtr entry = (xmlCatalogEntryPtr) payload;
- FILE *out = (FILE *) data;
- if ((entry == NULL) || (out == NULL))
- return;
- switch (entry->type) {
- case SGML_CATA_ENTITY:
- fprintf(out, "ENTITY "); break;
- case SGML_CATA_PENTITY:
- fprintf(out, "ENTITY %%"); break;
- case SGML_CATA_DOCTYPE:
- fprintf(out, "DOCTYPE "); break;
- case SGML_CATA_LINKTYPE:
- fprintf(out, "LINKTYPE "); break;
- case SGML_CATA_NOTATION:
- fprintf(out, "NOTATION "); break;
- case SGML_CATA_PUBLIC:
- fprintf(out, "PUBLIC "); break;
- case SGML_CATA_SYSTEM:
- fprintf(out, "SYSTEM "); break;
- case SGML_CATA_DELEGATE:
- fprintf(out, "DELEGATE "); break;
- case SGML_CATA_BASE:
- fprintf(out, "BASE "); break;
- case SGML_CATA_CATALOG:
- fprintf(out, "CATALOG "); break;
- case SGML_CATA_DOCUMENT:
- fprintf(out, "DOCUMENT "); break;
- case SGML_CATA_SGMLDECL:
- fprintf(out, "SGMLDECL "); break;
- default:
- return;
- }
- switch (entry->type) {
- case SGML_CATA_ENTITY:
- case SGML_CATA_PENTITY:
- case SGML_CATA_DOCTYPE:
- case SGML_CATA_LINKTYPE:
- case SGML_CATA_NOTATION:
- fprintf(out, "%s", (const char *) entry->name); break;
- case SGML_CATA_PUBLIC:
- case SGML_CATA_SYSTEM:
- case SGML_CATA_SGMLDECL:
- case SGML_CATA_DOCUMENT:
- case SGML_CATA_CATALOG:
- case SGML_CATA_BASE:
- case SGML_CATA_DELEGATE:
- fprintf(out, "\"%s\"", entry->name); break;
- default:
- break;
- }
- switch (entry->type) {
- case SGML_CATA_ENTITY:
- case SGML_CATA_PENTITY:
- case SGML_CATA_DOCTYPE:
- case SGML_CATA_LINKTYPE:
- case SGML_CATA_NOTATION:
- case SGML_CATA_PUBLIC:
- case SGML_CATA_SYSTEM:
- case SGML_CATA_DELEGATE:
- fprintf(out, " \"%s\"", entry->value); break;
- default:
- break;
- }
- fprintf(out, "\n");
- }
- /**
- * xmlDumpXMLCatalogNode:
- * @catal: top catalog entry
- * @catalog: pointer to the xml tree
- * @doc: the containing document
- * @ns: the current namespace
- * @cgroup: group node for group members
- *
- * Serializes a Catalog entry, called by xmlDumpXMLCatalog and recursively
- * for group entries
- */
- static void xmlDumpXMLCatalogNode(xmlCatalogEntryPtr catal, xmlNodePtr catalog,
- xmlDocPtr doc, xmlNsPtr ns, xmlCatalogEntryPtr cgroup) {
- xmlNodePtr node;
- xmlCatalogEntryPtr cur;
- /*
- * add all the catalog entries
- */
- cur = catal;
- while (cur != NULL) {
- if (cur->group == cgroup) {
- switch (cur->type) {
- case XML_CATA_REMOVED:
- break;
- case XML_CATA_BROKEN_CATALOG:
- case XML_CATA_CATALOG:
- if (cur == catal) {
- cur = cur->children;
- continue;
- }
- break;
- case XML_CATA_NEXT_CATALOG:
- node = xmlNewDocNode(doc, ns, BAD_CAST "nextCatalog", NULL);
- xmlSetProp(node, BAD_CAST "catalog", cur->value);
- xmlAddChild(catalog, node);
- break;
- case XML_CATA_NONE:
- break;
- case XML_CATA_GROUP:
- node = xmlNewDocNode(doc, ns, BAD_CAST "group", NULL);
- xmlSetProp(node, BAD_CAST "id", cur->name);
- if (cur->value != NULL) {
- xmlNsPtr xns;
- xns = xmlSearchNsByHref(doc, node, XML_XML_NAMESPACE);
- if (xns != NULL)
- xmlSetNsProp(node, xns, BAD_CAST "base",
- cur->value);
- }
- switch (cur->prefer) {
- case XML_CATA_PREFER_NONE:
- break;
- case XML_CATA_PREFER_PUBLIC:
- xmlSetProp(node, BAD_CAST "prefer", BAD_CAST "public");
- break;
- case XML_CATA_PREFER_SYSTEM:
- xmlSetProp(node, BAD_CAST "prefer", BAD_CAST "system");
- break;
- }
- xmlDumpXMLCatalogNode(cur->next, node, doc, ns, cur);
- xmlAddChild(catalog, node);
- break;
- case XML_CATA_PUBLIC:
- node = xmlNewDocNode(doc, ns, BAD_CAST "public", NULL);
- xmlSetProp(node, BAD_CAST "publicId", cur->name);
- xmlSetProp(node, BAD_CAST "uri", cur->value);
- xmlAddChild(catalog, node);
- break;
- case XML_CATA_SYSTEM:
- node = xmlNewDocNode(doc, ns, BAD_CAST "system", NULL);
- xmlSetProp(node, BAD_CAST "systemId", cur->name);
- xmlSetProp(node, BAD_CAST "uri", cur->value);
- xmlAddChild(catalog, node);
- break;
- case XML_CATA_REWRITE_SYSTEM:
- node = xmlNewDocNode(doc, ns, BAD_CAST "rewriteSystem", NULL);
- xmlSetProp(node, BAD_CAST "systemIdStartString", cur->name);
- xmlSetProp(node, BAD_CAST "rewritePrefix", cur->value);
- xmlAddChild(catalog, node);
- break;
- case XML_CATA_DELEGATE_PUBLIC:
- node = xmlNewDocNode(doc, ns, BAD_CAST "delegatePublic", NULL);
- xmlSetProp(node, BAD_CAST "publicIdStartString", cur->name);
- xmlSetProp(node, BAD_CAST "catalog", cur->value);
- xmlAddChild(catalog, node);
- break;
- case XML_CATA_DELEGATE_SYSTEM:
- node = xmlNewDocNode(doc, ns, BAD_CAST "delegateSystem", NULL);
- xmlSetProp(node, BAD_CAST "systemIdStartString", cur->name);
- xmlSetProp(node, BAD_CAST "catalog", cur->value);
- xmlAddChild(catalog, node);
- break;
- case XML_CATA_URI:
- node = xmlNewDocNode(doc, ns, BAD_CAST "uri", NULL);
- xmlSetProp(node, BAD_CAST "name", cur->name);
- xmlSetProp(node, BAD_CAST "uri", cur->value);
- xmlAddChild(catalog, node);
- break;
- case XML_CATA_REWRITE_URI:
- node = xmlNewDocNode(doc, ns, BAD_CAST "rewriteURI", NULL);
- xmlSetProp(node, BAD_CAST "uriStartString", cur->name);
- xmlSetProp(node, BAD_CAST "rewritePrefix", cur->value);
- xmlAddChild(catalog, node);
- break;
- case XML_CATA_DELEGATE_URI:
- node = xmlNewDocNode(doc, ns, BAD_CAST "delegateURI", NULL);
- xmlSetProp(node, BAD_CAST "uriStartString", cur->name);
- xmlSetProp(node, BAD_CAST "catalog", cur->value);
- xmlAddChild(catalog, node);
- break;
- case SGML_CATA_SYSTEM:
- case SGML_CATA_PUBLIC:
- case SGML_CATA_ENTITY:
- case SGML_CATA_PENTITY:
- case SGML_CATA_DOCTYPE:
- case SGML_CATA_LINKTYPE:
- case SGML_CATA_NOTATION:
- case SGML_CATA_DELEGATE:
- case SGML_CATA_BASE:
- case SGML_CATA_CATALOG:
- case SGML_CATA_DOCUMENT:
- case SGML_CATA_SGMLDECL:
- break;
- }
- }
- cur = cur->next;
- }
- }
- static int
- xmlDumpXMLCatalog(FILE *out, xmlCatalogEntryPtr catal) {
- int ret;
- xmlDocPtr doc;
- xmlNsPtr ns;
- xmlDtdPtr dtd;
- xmlNodePtr catalog;
- xmlOutputBufferPtr buf;
- /*
- * Rebuild a catalog
- */
- doc = xmlNewDoc(NULL);
- if (doc == NULL)
- return(-1);
- dtd = xmlNewDtd(doc, BAD_CAST "catalog",
- BAD_CAST "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN",
- BAD_CAST "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd");
- xmlAddChild((xmlNodePtr) doc, (xmlNodePtr) dtd);
- ns = xmlNewNs(NULL, XML_CATALOGS_NAMESPACE, NULL);
- if (ns == NULL) {
- xmlFreeDoc(doc);
- return(-1);
- }
- catalog = xmlNewDocNode(doc, ns, BAD_CAST "catalog", NULL);
- if (catalog == NULL) {
- xmlFreeNs(ns);
- xmlFreeDoc(doc);
- return(-1);
- }
- catalog->nsDef = ns;
- xmlAddChild((xmlNodePtr) doc, catalog);
- xmlDumpXMLCatalogNode(catal, catalog, doc, ns, NULL);
- /*
- * reserialize it
- */
- buf = xmlOutputBufferCreateFile(out, NULL);
- if (buf == NULL) {
- xmlFreeDoc(doc);
- return(-1);
- }
- ret = xmlSaveFormatFileTo(buf, doc, NULL, 1);
- /*
- * Free it
- */
- xmlFreeDoc(doc);
- return(ret);
- }
- #endif /* LIBXML_OUTPUT_ENABLED */
- /************************************************************************
- * *
- * Converting SGML Catalogs to XML *
- * *
- ************************************************************************/
- /**
- * xmlCatalogConvertEntry:
- * @entry: the entry
- * @catal: pointer to the catalog being converted
- *
- * Convert one entry from the catalog
- */
- static void
- xmlCatalogConvertEntry(void *payload, void *data,
- const xmlChar *name ATTRIBUTE_UNUSED) {
- xmlCatalogEntryPtr entry = (xmlCatalogEntryPtr) payload;
- xmlCatalogPtr catal = (xmlCatalogPtr) data;
- if ((entry == NULL) || (catal == NULL) || (catal->sgml == NULL) ||
- (catal->xml == NULL))
- return;
- switch (entry->type) {
- case SGML_CATA_ENTITY:
- entry->type = XML_CATA_PUBLIC;
- break;
- case SGML_CATA_PENTITY:
- entry->type = XML_CATA_PUBLIC;
- break;
- case SGML_CATA_DOCTYPE:
- entry->type = XML_CATA_PUBLIC;
- break;
- case SGML_CATA_LINKTYPE:
- entry->type = XML_CATA_PUBLIC;
- break;
- case SGML_CATA_NOTATION:
- entry->type = XML_CATA_PUBLIC;
- break;
- case SGML_CATA_PUBLIC:
- entry->type = XML_CATA_PUBLIC;
- break;
- case SGML_CATA_SYSTEM:
- entry->type = XML_CATA_SYSTEM;
- break;
- case SGML_CATA_DELEGATE:
- entry->type = XML_CATA_DELEGATE_PUBLIC;
- break;
- case SGML_CATA_CATALOG:
- entry->type = XML_CATA_CATALOG;
- break;
- default:
- xmlHashRemoveEntry(catal->sgml, entry->name, xmlFreeCatalogEntry);
- return;
- }
- /*
- * Conversion successful, remove from the SGML catalog
- * and add it to the default XML one
- */
- xmlHashRemoveEntry(catal->sgml, entry->name, NULL);
- entry->parent = catal->xml;
- entry->next = NULL;
- if (catal->xml->children == NULL)
- catal->xml->children = entry;
- else {
- xmlCatalogEntryPtr prev;
- prev = catal->xml->children;
- while (prev->next != NULL)
- prev = prev->next;
- prev->next = entry;
- }
- }
- /**
- * xmlConvertSGMLCatalog:
- * @catal: the catalog
- *
- * Convert all the SGML catalog entries as XML ones
- *
- * Returns the number of entries converted if successful, -1 otherwise
- */
- int
- xmlConvertSGMLCatalog(xmlCatalogPtr catal) {
- if ((catal == NULL) || (catal->type != XML_SGML_CATALOG_TYPE))
- return(-1);
- if (xmlDebugCatalogs) {
- xmlGenericError(xmlGenericErrorContext,
- "Converting SGML catalog to XML\n");
- }
- xmlHashScan(catal->sgml, xmlCatalogConvertEntry, &catal);
- return(0);
- }
- /************************************************************************
- * *
- * Helper function *
- * *
- ************************************************************************/
- /**
- * xmlCatalogUnWrapURN:
- * @urn: an "urn:publicid:" to unwrap
- *
- * Expand the URN into the equivalent Public Identifier
- *
- * Returns the new identifier or NULL, the string must be deallocated
- * by the caller.
- */
- static xmlChar *
- xmlCatalogUnWrapURN(const xmlChar *urn) {
- xmlChar result[2000];
- unsigned int i = 0;
- if (xmlStrncmp(urn, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1))
- return(NULL);
- urn += sizeof(XML_URN_PUBID) - 1;
- while (*urn != 0) {
- if (i > sizeof(result) - 4)
- break;
- if (*urn == '+') {
- result[i++] = ' ';
- urn++;
- } else if (*urn == ':') {
- result[i++] = '/';
- result[i++] = '/';
- urn++;
- } else if (*urn == ';') {
- result[i++] = ':';
- result[i++] = ':';
- urn++;
- } else if (*urn == '%') {
- if ((urn[1] == '2') && (urn[2] == 'B'))
- result[i++] = '+';
- else if ((urn[1] == '3') && (urn[2] == 'A'))
- result[i++] = ':';
- else if ((urn[1] == '2') && (urn[2] == 'F'))
- result[i++] = '/';
- else if ((urn[1] == '3') && (urn[2] == 'B'))
- result[i++] = ';';
- else if ((urn[1] == '2') && (urn[2] == '7'))
- result[i++] = '\'';
- else if ((urn[1] == '3') && (urn[2] == 'F'))
- result[i++] = '?';
- else if ((urn[1] == '2') && (urn[2] == '3'))
- result[i++] = '#';
- else if ((urn[1] == '2') && (urn[2] == '5'))
- result[i++] = '%';
- else {
- result[i++] = *urn;
- urn++;
- continue;
- }
- urn += 3;
- } else {
- result[i++] = *urn;
- urn++;
- }
- }
- result[i] = 0;
- return(xmlStrdup(result));
- }
- /**
- * xmlParseCatalogFile:
- * @filename: the filename
- *
- * parse an XML file and build a tree. It's like xmlParseFile()
- * except it bypass all catalog lookups.
- *
- * Returns the resulting document tree or NULL in case of error
- */
- xmlDocPtr
- xmlParseCatalogFile(const char *filename) {
- xmlDocPtr ret;
- xmlParserCtxtPtr ctxt;
- char *directory = NULL;
- xmlParserInputPtr inputStream;
- xmlParserInputBufferPtr buf;
- ctxt = xmlNewParserCtxt();
- if (ctxt == NULL) {
- #ifdef LIBXML_SAX1_ENABLED
- if (xmlDefaultSAXHandler.error != NULL) {
- xmlDefaultSAXHandler.error(NULL, "out of memory\n");
- }
- #endif
- return(NULL);
- }
- buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
- if (buf == NULL) {
- xmlFreeParserCtxt(ctxt);
- return(NULL);
- }
- inputStream = xmlNewInputStream(ctxt);
- if (inputStream == NULL) {
- xmlFreeParserInputBuffer(buf);
- xmlFreeParserCtxt(ctxt);
- return(NULL);
- }
- inputStream->filename = (char *) xmlCanonicPath((const xmlChar *)filename);
- inputStream->buf = buf;
- xmlBufResetInput(buf->buffer, inputStream);
- inputPush(ctxt, inputStream);
- if (ctxt->directory == NULL)
- directory = xmlParserGetDirectory(filename);
- if ((ctxt->directory == NULL) && (directory != NULL))
- ctxt->directory = directory;
- ctxt->valid = 0;
- ctxt->validate = 0;
- ctxt->loadsubset = 0;
- ctxt->pedantic = 0;
- ctxt->dictNames = 1;
- xmlParseDocument(ctxt);
- if (ctxt->wellFormed)
- ret = ctxt->myDoc;
- else {
- ret = NULL;
- xmlFreeDoc(ctxt->myDoc);
- ctxt->myDoc = NULL;
- }
- xmlFreeParserCtxt(ctxt);
- return(ret);
- }
- /**
- * xmlLoadFileContent:
- * @filename: a file path
- *
- * Load a file content into memory.
- *
- * Returns a pointer to the 0 terminated string or NULL in case of error
- */
- static xmlChar *
- xmlLoadFileContent(const char *filename)
- {
- #ifdef HAVE_STAT
- int fd;
- #else
- FILE *fd;
- #endif
- int len;
- long size;
- #ifdef HAVE_STAT
- struct stat info;
- #endif
- xmlChar *content;
- if (filename == NULL)
- return (NULL);
- #ifdef HAVE_STAT
- if (stat(filename, &info) < 0)
- return (NULL);
- #endif
- #ifdef HAVE_STAT
- if ((fd = open(filename, O_RDONLY)) < 0)
- #else
- if ((fd = fopen(filename, "rb")) == NULL)
- #endif
- {
- return (NULL);
- }
- #ifdef HAVE_STAT
- size = info.st_size;
- #else
- if (fseek(fd, 0, SEEK_END) || (size = ftell(fd)) == EOF || fseek(fd, 0, SEEK_SET)) { /* File operations denied? ok, just close and return failure */
- fclose(fd);
- return (NULL);
- }
- #endif
- content = (xmlChar*)xmlMallocAtomic(size + 10);
- if (content == NULL) {
- xmlCatalogErrMemory("allocating catalog data");
- #ifdef HAVE_STAT
- close(fd);
- #else
- fclose(fd);
- #endif
- return (NULL);
- }
- #ifdef HAVE_STAT
- len = read(fd, content, size);
- close(fd);
- #else
- len = fread(content, 1, size, fd);
- fclose(fd);
- #endif
- if (len < 0) {
- xmlFree(content);
- return (NULL);
- }
- content[len] = 0;
- return(content);
- }
- /**
- * xmlCatalogNormalizePublic:
- * @pubID: the public ID string
- *
- * Normalizes the Public Identifier
- *
- * Implements 6.2. Public Identifier Normalization
- * from http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
- *
- * Returns the new string or NULL, the string must be deallocated
- * by the caller.
- */
- static xmlChar *
- xmlCatalogNormalizePublic(const xmlChar *pubID)
- {
- int ok = 1;
- int white;
- const xmlChar *p;
- xmlChar *ret;
- xmlChar *q;
- if (pubID == NULL)
- return(NULL);
- white = 1;
- for (p = pubID;*p != 0 && ok;p++) {
- if (!xmlIsBlank_ch(*p))
- white = 0;
- else if (*p == 0x20 && !white)
- white = 1;
- else
- ok = 0;
- }
- if (ok && !white) /* is normalized */
- return(NULL);
- ret = xmlStrdup(pubID);
- q = ret;
- white = 0;
- for (p = pubID;*p != 0;p++) {
- if (xmlIsBlank_ch(*p)) {
- if (q != ret)
- white = 1;
- } else {
- if (white) {
- *(q++) = 0x20;
- white = 0;
- }
- *(q++) = *p;
- }
- }
- *q = 0;
- return(ret);
- }
- /************************************************************************
- * *
- * The XML Catalog parser *
- * *
- ************************************************************************/
- static xmlCatalogEntryPtr
- xmlParseXMLCatalogFile(xmlCatalogPrefer prefer, const xmlChar *filename);
- static void
- xmlParseXMLCatalogNodeList(xmlNodePtr cur, xmlCatalogPrefer prefer,
- xmlCatalogEntryPtr parent, xmlCatalogEntryPtr cgroup);
- static xmlChar *
- xmlCatalogListXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
- const xmlChar *sysID);
- static xmlChar *
- xmlCatalogListXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI);
- /**
- * xmlGetXMLCatalogEntryType:
- * @name: the name
- *
- * lookup the internal type associated to an XML catalog entry name
- *
- * Returns the type associated with that name
- */
- static xmlCatalogEntryType
- xmlGetXMLCatalogEntryType(const xmlChar *name) {
- xmlCatalogEntryType type = XML_CATA_NONE;
- if (xmlStrEqual(name, (const xmlChar *) "system"))
- type = XML_CATA_SYSTEM;
- else if (xmlStrEqual(name, (const xmlChar *) "public"))
- type = XML_CATA_PUBLIC;
- else if (xmlStrEqual(name, (const xmlChar *) "rewriteSystem"))
- type = XML_CATA_REWRITE_SYSTEM;
- else if (xmlStrEqual(name, (const xmlChar *) "delegatePublic"))
- type = XML_CATA_DELEGATE_PUBLIC;
- else if (xmlStrEqual(name, (const xmlChar *) "delegateSystem"))
- type = XML_CATA_DELEGATE_SYSTEM;
- else if (xmlStrEqual(name, (const xmlChar *) "uri"))
- type = XML_CATA_URI;
- else if (xmlStrEqual(name, (const xmlChar *) "rewriteURI"))
- type = XML_CATA_REWRITE_URI;
- else if (xmlStrEqual(name, (const xmlChar *) "delegateURI"))
- type = XML_CATA_DELEGATE_URI;
- else if (xmlStrEqual(name, (const xmlChar *) "nextCatalog"))
- type = XML_CATA_NEXT_CATALOG;
- else if (xmlStrEqual(name, (const xmlChar *) "catalog"))
- type = XML_CATA_CATALOG;
- return(type);
- }
- /**
- * xmlParseXMLCatalogOneNode:
- * @cur: the XML node
- * @type: the type of Catalog entry
- * @name: the name of the node
- * @attrName: the attribute holding the value
- * @uriAttrName: the attribute holding the URI-Reference
- * @prefer: the PUBLIC vs. SYSTEM current preference value
- * @cgroup: the group which includes this node
- *
- * Finishes the examination of an XML tree node of a catalog and build
- * a Catalog entry from it.
- *
- * Returns the new Catalog entry node or NULL in case of error.
- */
- static xmlCatalogEntryPtr
- xmlParseXMLCatalogOneNode(xmlNodePtr cur, xmlCatalogEntryType type,
- const xmlChar *name, const xmlChar *attrName,
- const xmlChar *uriAttrName, xmlCatalogPrefer prefer,
- xmlCatalogEntryPtr cgroup) {
- int ok = 1;
- xmlChar *uriValue;
- xmlChar *nameValue = NULL;
- xmlChar *base = NULL;
- xmlChar *URL = NULL;
- xmlCatalogEntryPtr ret = NULL;
- if (attrName != NULL) {
- nameValue = xmlGetProp(cur, attrName);
- if (nameValue == NULL) {
- xmlCatalogErr(ret, cur, XML_CATALOG_MISSING_ATTR,
- "%s entry lacks '%s'\n", name, attrName, NULL);
- ok = 0;
- }
- }
- uriValue = xmlGetProp(cur, uriAttrName);
- if (uriValue == NULL) {
- xmlCatalogErr(ret, cur, XML_CATALOG_MISSING_ATTR,
- "%s entry lacks '%s'\n", name, uriAttrName, NULL);
- ok = 0;
- }
- if (!ok) {
- if (nameValue != NULL)
- xmlFree(nameValue);
- if (uriValue != NULL)
- xmlFree(uriValue);
- return(NULL);
- }
- base = xmlNodeGetBase(cur->doc, cur);
- URL = xmlBuildURI(uriValue, base);
- if (URL != NULL) {
- if (xmlDebugCatalogs > 1) {
- if (nameValue != NULL)
- xmlGenericError(xmlGenericErrorContext,
- "Found %s: '%s' '%s'\n", name, nameValue, URL);
- else
- xmlGenericError(xmlGenericErrorContext,
- "Found %s: '%s'\n", name, URL);
- }
- ret = xmlNewCatalogEntry(type, nameValue, uriValue, URL, prefer, cgroup);
- } else {
- xmlCatalogErr(ret, cur, XML_CATALOG_ENTRY_BROKEN,
- "%s entry '%s' broken ?: %s\n", name, uriAttrName, uriValue);
- }
- if (nameValue != NULL)
- xmlFree(nameValue);
- if (uriValue != NULL)
- xmlFree(uriValue);
- if (base != NULL)
- xmlFree(base);
- if (URL != NULL)
- xmlFree(URL);
- return(ret);
- }
- /**
- * xmlParseXMLCatalogNode:
- * @cur: the XML node
- * @prefer: the PUBLIC vs. SYSTEM current preference value
- * @parent: the parent Catalog entry
- * @cgroup: the group which includes this node
- *
- * Examines an XML tree node of a catalog and build
- * a Catalog entry from it adding it to its parent. The examination can
- * be recursive.
- */
- static void
- xmlParseXMLCatalogNode(xmlNodePtr cur, xmlCatalogPrefer prefer,
- xmlCatalogEntryPtr parent, xmlCatalogEntryPtr cgroup)
- {
- xmlChar *base = NULL;
- xmlCatalogEntryPtr entry = NULL;
- if (cur == NULL)
- return;
- if (xmlStrEqual(cur->name, BAD_CAST "group")) {
- xmlChar *prop;
- xmlCatalogPrefer pref = XML_CATA_PREFER_NONE;
- prop = xmlGetProp(cur, BAD_CAST "prefer");
- if (prop != NULL) {
- if (xmlStrEqual(prop, BAD_CAST "system")) {
- prefer = XML_CATA_PREFER_SYSTEM;
- } else if (xmlStrEqual(prop, BAD_CAST "public")) {
- prefer = XML_CATA_PREFER_PUBLIC;
- } else {
- xmlCatalogErr(parent, cur, XML_CATALOG_PREFER_VALUE,
- "Invalid value for prefer: '%s'\n",
- prop, NULL, NULL);
- }
- xmlFree(prop);
- pref = prefer;
- }
- prop = xmlGetProp(cur, BAD_CAST "id");
- base = xmlGetNsProp(cur, BAD_CAST "base", XML_XML_NAMESPACE);
- entry = xmlNewCatalogEntry(XML_CATA_GROUP, prop, base, NULL, pref, cgroup);
- xmlFree(prop);
- } else if (xmlStrEqual(cur->name, BAD_CAST "public")) {
- entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_PUBLIC,
- BAD_CAST "public", BAD_CAST "publicId", BAD_CAST "uri", prefer, cgroup);
- } else if (xmlStrEqual(cur->name, BAD_CAST "system")) {
- entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_SYSTEM,
- BAD_CAST "system", BAD_CAST "systemId", BAD_CAST "uri", prefer, cgroup);
- } else if (xmlStrEqual(cur->name, BAD_CAST "rewriteSystem")) {
- entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_REWRITE_SYSTEM,
- BAD_CAST "rewriteSystem", BAD_CAST "systemIdStartString",
- BAD_CAST "rewritePrefix", prefer, cgroup);
- } else if (xmlStrEqual(cur->name, BAD_CAST "delegatePublic")) {
- entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_PUBLIC,
- BAD_CAST "delegatePublic", BAD_CAST "publicIdStartString",
- BAD_CAST "catalog", prefer, cgroup);
- } else if (xmlStrEqual(cur->name, BAD_CAST "delegateSystem")) {
- entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_SYSTEM,
- BAD_CAST "delegateSystem", BAD_CAST "systemIdStartString",
- BAD_CAST "catalog", prefer, cgroup);
- } else if (xmlStrEqual(cur->name, BAD_CAST "uri")) {
- entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_URI,
- BAD_CAST "uri", BAD_CAST "name",
- BAD_CAST "uri", prefer, cgroup);
- } else if (xmlStrEqual(cur->name, BAD_CAST "rewriteURI")) {
- entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_REWRITE_URI,
- BAD_CAST "rewriteURI", BAD_CAST "uriStartString",
- BAD_CAST "rewritePrefix", prefer, cgroup);
- } else if (xmlStrEqual(cur->name, BAD_CAST "delegateURI")) {
- entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_URI,
- BAD_CAST "delegateURI", BAD_CAST "uriStartString",
- BAD_CAST "catalog", prefer, cgroup);
- } else if (xmlStrEqual(cur->name, BAD_CAST "nextCatalog")) {
- entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_NEXT_CATALOG,
- BAD_CAST "nextCatalog", NULL,
- BAD_CAST "catalog", prefer, cgroup);
- }
- if (entry != NULL) {
- if (parent != NULL) {
- entry->parent = parent;
- if (parent->children == NULL)
- parent->children = entry;
- else {
- xmlCatalogEntryPtr prev;
- prev = parent->children;
- while (prev->next != NULL)
- prev = prev->next;
- prev->next = entry;
- }
- }
- if (entry->type == XML_CATA_GROUP) {
- /*
- * Recurse to propagate prefer to the subtree
- * (xml:base handling is automated)
- */
- xmlParseXMLCatalogNodeList(cur->children, prefer, parent, entry);
- }
- }
- if (base != NULL)
- xmlFree(base);
- }
- /**
- * xmlParseXMLCatalogNodeList:
- * @cur: the XML node list of siblings
- * @prefer: the PUBLIC vs. SYSTEM current preference value
- * @parent: the parent Catalog entry
- * @cgroup: the group which includes this list
- *
- * Examines a list of XML sibling nodes of a catalog and build
- * a list of Catalog entry from it adding it to the parent.
- * The examination will recurse to examine node subtrees.
- */
- static void
- xmlParseXMLCatalogNodeList(xmlNodePtr cur, xmlCatalogPrefer prefer,
- xmlCatalogEntryPtr parent, xmlCatalogEntryPtr cgroup) {
- while (cur != NULL) {
- if ((cur->ns != NULL) && (cur->ns->href != NULL) &&
- (xmlStrEqual(cur->ns->href, XML_CATALOGS_NAMESPACE))) {
- xmlParseXMLCatalogNode(cur, prefer, parent, cgroup);
- }
- cur = cur->next;
- }
- /* TODO: sort the list according to REWRITE lengths and prefer value */
- }
- /**
- * xmlParseXMLCatalogFile:
- * @prefer: the PUBLIC vs. SYSTEM current preference value
- * @filename: the filename for the catalog
- *
- * Parses the catalog file to extract the XML tree and then analyze the
- * tree to build a list of Catalog entries corresponding to this catalog
- *
- * Returns the resulting Catalog entries list
- */
- static xmlCatalogEntryPtr
- xmlParseXMLCatalogFile(xmlCatalogPrefer prefer, const xmlChar *filename) {
- xmlDocPtr doc;
- xmlNodePtr cur;
- xmlChar *prop;
- xmlCatalogEntryPtr parent = NULL;
- if (filename == NULL)
- return(NULL);
- doc = xmlParseCatalogFile((const char *) filename);
- if (doc == NULL) {
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Failed to parse catalog %s\n", filename);
- return(NULL);
- }
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "%d Parsing catalog %s\n", xmlGetThreadId(), filename);
- cur = xmlDocGetRootElement(doc);
- if ((cur != NULL) && (xmlStrEqual(cur->name, BAD_CAST "catalog")) &&
- (cur->ns != NULL) && (cur->ns->href != NULL) &&
- (xmlStrEqual(cur->ns->href, XML_CATALOGS_NAMESPACE))) {
- parent = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
- (const xmlChar *)filename, NULL, prefer, NULL);
- if (parent == NULL) {
- xmlFreeDoc(doc);
- return(NULL);
- }
- prop = xmlGetProp(cur, BAD_CAST "prefer");
- if (prop != NULL) {
- if (xmlStrEqual(prop, BAD_CAST "system")) {
- prefer = XML_CATA_PREFER_SYSTEM;
- } else if (xmlStrEqual(prop, BAD_CAST "public")) {
- prefer = XML_CATA_PREFER_PUBLIC;
- } else {
- xmlCatalogErr(NULL, cur, XML_CATALOG_PREFER_VALUE,
- "Invalid value for prefer: '%s'\n",
- prop, NULL, NULL);
- }
- xmlFree(prop);
- }
- cur = cur->children;
- xmlParseXMLCatalogNodeList(cur, prefer, parent, NULL);
- } else {
- xmlCatalogErr(NULL, (xmlNodePtr) doc, XML_CATALOG_NOT_CATALOG,
- "File %s is not an XML Catalog\n",
- filename, NULL, NULL);
- xmlFreeDoc(doc);
- return(NULL);
- }
- xmlFreeDoc(doc);
- return(parent);
- }
- /**
- * xmlFetchXMLCatalogFile:
- * @catal: an existing but incomplete catalog entry
- *
- * Fetch and parse the subcatalog referenced by an entry
- *
- * Returns 0 in case of success, -1 otherwise
- */
- static int
- xmlFetchXMLCatalogFile(xmlCatalogEntryPtr catal) {
- xmlCatalogEntryPtr doc;
- if (catal == NULL)
- return(-1);
- if (catal->URL == NULL)
- return(-1);
- /*
- * lock the whole catalog for modification
- */
- xmlRMutexLock(xmlCatalogMutex);
- if (catal->children != NULL) {
- /* Okay someone else did it in the meantime */
- xmlRMutexUnlock(xmlCatalogMutex);
- return(0);
- }
- if (xmlCatalogXMLFiles != NULL) {
- doc = (xmlCatalogEntryPtr)
- xmlHashLookup(xmlCatalogXMLFiles, catal->URL);
- if (doc != NULL) {
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Found %s in file hash\n", catal->URL);
- if (catal->type == XML_CATA_CATALOG)
- catal->children = doc->children;
- else
- catal->children = doc;
- catal->dealloc = 0;
- xmlRMutexUnlock(xmlCatalogMutex);
- return(0);
- }
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "%s not found in file hash\n", catal->URL);
- }
- /*
- * Fetch and parse. Note that xmlParseXMLCatalogFile does not
- * use the existing catalog, there is no recursion allowed at
- * that level.
- */
- doc = xmlParseXMLCatalogFile(catal->prefer, catal->URL);
- if (doc == NULL) {
- catal->type = XML_CATA_BROKEN_CATALOG;
- xmlRMutexUnlock(xmlCatalogMutex);
- return(-1);
- }
- if (catal->type == XML_CATA_CATALOG)
- catal->children = doc->children;
- else
- catal->children = doc;
- doc->dealloc = 1;
- if (xmlCatalogXMLFiles == NULL)
- xmlCatalogXMLFiles = xmlHashCreate(10);
- if (xmlCatalogXMLFiles != NULL) {
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "%s added to file hash\n", catal->URL);
- xmlHashAddEntry(xmlCatalogXMLFiles, catal->URL, doc);
- }
- xmlRMutexUnlock(xmlCatalogMutex);
- return(0);
- }
- /************************************************************************
- * *
- * XML Catalog handling *
- * *
- ************************************************************************/
- /**
- * xmlAddXMLCatalog:
- * @catal: top of an XML catalog
- * @type: the type of record to add to the catalog
- * @orig: the system, public or prefix to match (or NULL)
- * @replace: the replacement value for the match
- *
- * Add an entry in the XML catalog, it may overwrite existing but
- * different entries.
- *
- * Returns 0 if successful, -1 otherwise
- */
- static int
- xmlAddXMLCatalog(xmlCatalogEntryPtr catal, const xmlChar *type,
- const xmlChar *orig, const xmlChar *replace) {
- xmlCatalogEntryPtr cur;
- xmlCatalogEntryType typ;
- int doregister = 0;
- if ((catal == NULL) ||
- ((catal->type != XML_CATA_CATALOG) &&
- (catal->type != XML_CATA_BROKEN_CATALOG)))
- return(-1);
- if (catal->children == NULL) {
- xmlFetchXMLCatalogFile(catal);
- }
- if (catal->children == NULL)
- doregister = 1;
- typ = xmlGetXMLCatalogEntryType(type);
- if (typ == XML_CATA_NONE) {
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Failed to add unknown element %s to catalog\n", type);
- return(-1);
- }
- cur = catal->children;
- /*
- * Might be a simple "update in place"
- */
- if (cur != NULL) {
- while (cur != NULL) {
- if ((orig != NULL) && (cur->type == typ) &&
- (xmlStrEqual(orig, cur->name))) {
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Updating element %s to catalog\n", type);
- if (cur->value != NULL)
- xmlFree(cur->value);
- if (cur->URL != NULL)
- xmlFree(cur->URL);
- cur->value = xmlStrdup(replace);
- cur->URL = xmlStrdup(replace);
- return(0);
- }
- if (cur->next == NULL)
- break;
- cur = cur->next;
- }
- }
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Adding element %s to catalog\n", type);
- if (cur == NULL)
- catal->children = xmlNewCatalogEntry(typ, orig, replace,
- NULL, catal->prefer, NULL);
- else
- cur->next = xmlNewCatalogEntry(typ, orig, replace,
- NULL, catal->prefer, NULL);
- if (doregister) {
- catal->type = XML_CATA_CATALOG;
- cur = (xmlCatalogEntryPtr)xmlHashLookup(xmlCatalogXMLFiles, catal->URL);
- if (cur != NULL)
- cur->children = catal->children;
- }
- return(0);
- }
- /**
- * xmlDelXMLCatalog:
- * @catal: top of an XML catalog
- * @value: the value to remove from the catalog
- *
- * Remove entries in the XML catalog where the value or the URI
- * is equal to @value
- *
- * Returns the number of entries removed if successful, -1 otherwise
- */
- static int
- xmlDelXMLCatalog(xmlCatalogEntryPtr catal, const xmlChar *value) {
- xmlCatalogEntryPtr cur;
- int ret = 0;
- if ((catal == NULL) ||
- ((catal->type != XML_CATA_CATALOG) &&
- (catal->type != XML_CATA_BROKEN_CATALOG)))
- return(-1);
- if (value == NULL)
- return(-1);
- if (catal->children == NULL) {
- xmlFetchXMLCatalogFile(catal);
- }
- /*
- * Scan the children
- */
- cur = catal->children;
- while (cur != NULL) {
- if (((cur->name != NULL) && (xmlStrEqual(value, cur->name))) ||
- (xmlStrEqual(value, cur->value))) {
- if (xmlDebugCatalogs) {
- if (cur->name != NULL)
- xmlGenericError(xmlGenericErrorContext,
- "Removing element %s from catalog\n", cur->name);
- else
- xmlGenericError(xmlGenericErrorContext,
- "Removing element %s from catalog\n", cur->value);
- }
- cur->type = XML_CATA_REMOVED;
- }
- cur = cur->next;
- }
- return(ret);
- }
- /**
- * xmlCatalogXMLResolve:
- * @catal: a catalog list
- * @pubID: the public ID string
- * @sysID: the system ID string
- *
- * Do a complete resolution lookup of an External Identifier for a
- * list of catalog entries.
- *
- * Implements (or tries to) 7.1. External Identifier Resolution
- * from http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
- *
- * Returns the URI of the resource or NULL if not found
- */
- static xmlChar *
- xmlCatalogXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
- const xmlChar *sysID) {
- xmlChar *ret = NULL;
- xmlCatalogEntryPtr cur;
- int haveDelegate = 0;
- int haveNext = 0;
- /*
- * protection against loops
- */
- if (catal->depth > MAX_CATAL_DEPTH) {
- xmlCatalogErr(catal, NULL, XML_CATALOG_RECURSION,
- "Detected recursion in catalog %s\n",
- catal->name, NULL, NULL);
- return(NULL);
- }
- catal->depth++;
- /*
- * First tries steps 2/ 3/ 4/ if a system ID is provided.
- */
- if (sysID != NULL) {
- xmlCatalogEntryPtr rewrite = NULL;
- int lenrewrite = 0, len;
- cur = catal;
- haveDelegate = 0;
- while (cur != NULL) {
- switch (cur->type) {
- case XML_CATA_SYSTEM:
- if (xmlStrEqual(sysID, cur->name)) {
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Found system match %s, using %s\n",
- cur->name, cur->URL);
- catal->depth--;
- return(xmlStrdup(cur->URL));
- }
- break;
- case XML_CATA_REWRITE_SYSTEM:
- len = xmlStrlen(cur->name);
- if ((len > lenrewrite) &&
- (!xmlStrncmp(sysID, cur->name, len))) {
- lenrewrite = len;
- rewrite = cur;
- }
- break;
- case XML_CATA_DELEGATE_SYSTEM:
- if (!xmlStrncmp(sysID, cur->name, xmlStrlen(cur->name)))
- haveDelegate++;
- break;
- case XML_CATA_NEXT_CATALOG:
- haveNext++;
- break;
- default:
- break;
- }
- cur = cur->next;
- }
- if (rewrite != NULL) {
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Using rewriting rule %s\n", rewrite->name);
- ret = xmlStrdup(rewrite->URL);
- if (ret != NULL)
- ret = xmlStrcat(ret, &sysID[lenrewrite]);
- catal->depth--;
- return(ret);
- }
- if (haveDelegate) {
- const xmlChar *delegates[MAX_DELEGATE];
- int nbList = 0, i;
- /*
- * Assume the entries have been sorted by decreasing substring
- * matches when the list was produced.
- */
- cur = catal;
- while (cur != NULL) {
- if ((cur->type == XML_CATA_DELEGATE_SYSTEM) &&
- (!xmlStrncmp(sysID, cur->name, xmlStrlen(cur->name)))) {
- for (i = 0;i < nbList;i++)
- if (xmlStrEqual(cur->URL, delegates[i]))
- break;
- if (i < nbList) {
- cur = cur->next;
- continue;
- }
- if (nbList < MAX_DELEGATE)
- delegates[nbList++] = cur->URL;
- if (cur->children == NULL) {
- xmlFetchXMLCatalogFile(cur);
- }
- if (cur->children != NULL) {
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Trying system delegate %s\n", cur->URL);
- ret = xmlCatalogListXMLResolve(
- cur->children, NULL, sysID);
- if (ret != NULL) {
- catal->depth--;
- return(ret);
- }
- }
- }
- cur = cur->next;
- }
- /*
- * Apply the cut algorithm explained in 4/
- */
- catal->depth--;
- return(XML_CATAL_BREAK);
- }
- }
- /*
- * Then tries 5/ 6/ if a public ID is provided
- */
- if (pubID != NULL) {
- cur = catal;
- haveDelegate = 0;
- while (cur != NULL) {
- switch (cur->type) {
- case XML_CATA_PUBLIC:
- if (xmlStrEqual(pubID, cur->name)) {
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Found public match %s\n", cur->name);
- catal->depth--;
- return(xmlStrdup(cur->URL));
- }
- break;
- case XML_CATA_DELEGATE_PUBLIC:
- if (!xmlStrncmp(pubID, cur->name, xmlStrlen(cur->name)) &&
- (cur->prefer == XML_CATA_PREFER_PUBLIC))
- haveDelegate++;
- break;
- case XML_CATA_NEXT_CATALOG:
- if (sysID == NULL)
- haveNext++;
- break;
- default:
- break;
- }
- cur = cur->next;
- }
- if (haveDelegate) {
- const xmlChar *delegates[MAX_DELEGATE];
- int nbList = 0, i;
- /*
- * Assume the entries have been sorted by decreasing substring
- * matches when the list was produced.
- */
- cur = catal;
- while (cur != NULL) {
- if ((cur->type == XML_CATA_DELEGATE_PUBLIC) &&
- (cur->prefer == XML_CATA_PREFER_PUBLIC) &&
- (!xmlStrncmp(pubID, cur->name, xmlStrlen(cur->name)))) {
- for (i = 0;i < nbList;i++)
- if (xmlStrEqual(cur->URL, delegates[i]))
- break;
- if (i < nbList) {
- cur = cur->next;
- continue;
- }
- if (nbList < MAX_DELEGATE)
- delegates[nbList++] = cur->URL;
- if (cur->children == NULL) {
- xmlFetchXMLCatalogFile(cur);
- }
- if (cur->children != NULL) {
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Trying public delegate %s\n", cur->URL);
- ret = xmlCatalogListXMLResolve(
- cur->children, pubID, NULL);
- if (ret != NULL) {
- catal->depth--;
- return(ret);
- }
- }
- }
- cur = cur->next;
- }
- /*
- * Apply the cut algorithm explained in 4/
- */
- catal->depth--;
- return(XML_CATAL_BREAK);
- }
- }
- if (haveNext) {
- cur = catal;
- while (cur != NULL) {
- if (cur->type == XML_CATA_NEXT_CATALOG) {
- if (cur->children == NULL) {
- xmlFetchXMLCatalogFile(cur);
- }
- if (cur->children != NULL) {
- ret = xmlCatalogListXMLResolve(cur->children, pubID, sysID);
- if (ret != NULL) {
- catal->depth--;
- return(ret);
- } else if (catal->depth > MAX_CATAL_DEPTH) {
- return(NULL);
- }
- }
- }
- cur = cur->next;
- }
- }
- catal->depth--;
- return(NULL);
- }
- /**
- * xmlCatalogXMLResolveURI:
- * @catal: a catalog list
- * @URI: the URI
- * @sysID: the system ID string
- *
- * Do a complete resolution lookup of an External Identifier for a
- * list of catalog entries.
- *
- * Implements (or tries to) 7.2.2. URI Resolution
- * from http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
- *
- * Returns the URI of the resource or NULL if not found
- */
- static xmlChar *
- xmlCatalogXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI) {
- xmlChar *ret = NULL;
- xmlCatalogEntryPtr cur;
- int haveDelegate = 0;
- int haveNext = 0;
- xmlCatalogEntryPtr rewrite = NULL;
- int lenrewrite = 0, len;
- if (catal == NULL)
- return(NULL);
- if (URI == NULL)
- return(NULL);
- if (catal->depth > MAX_CATAL_DEPTH) {
- xmlCatalogErr(catal, NULL, XML_CATALOG_RECURSION,
- "Detected recursion in catalog %s\n",
- catal->name, NULL, NULL);
- return(NULL);
- }
- /*
- * First tries steps 2/ 3/ 4/ if a system ID is provided.
- */
- cur = catal;
- haveDelegate = 0;
- while (cur != NULL) {
- switch (cur->type) {
- case XML_CATA_URI:
- if (xmlStrEqual(URI, cur->name)) {
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Found URI match %s\n", cur->name);
- return(xmlStrdup(cur->URL));
- }
- break;
- case XML_CATA_REWRITE_URI:
- len = xmlStrlen(cur->name);
- if ((len > lenrewrite) &&
- (!xmlStrncmp(URI, cur->name, len))) {
- lenrewrite = len;
- rewrite = cur;
- }
- break;
- case XML_CATA_DELEGATE_URI:
- if (!xmlStrncmp(URI, cur->name, xmlStrlen(cur->name)))
- haveDelegate++;
- break;
- case XML_CATA_NEXT_CATALOG:
- haveNext++;
- break;
- default:
- break;
- }
- cur = cur->next;
- }
- if (rewrite != NULL) {
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Using rewriting rule %s\n", rewrite->name);
- ret = xmlStrdup(rewrite->URL);
- if (ret != NULL)
- ret = xmlStrcat(ret, &URI[lenrewrite]);
- return(ret);
- }
- if (haveDelegate) {
- const xmlChar *delegates[MAX_DELEGATE];
- int nbList = 0, i;
- /*
- * Assume the entries have been sorted by decreasing substring
- * matches when the list was produced.
- */
- cur = catal;
- while (cur != NULL) {
- if (((cur->type == XML_CATA_DELEGATE_SYSTEM) ||
- (cur->type == XML_CATA_DELEGATE_URI)) &&
- (!xmlStrncmp(URI, cur->name, xmlStrlen(cur->name)))) {
- for (i = 0;i < nbList;i++)
- if (xmlStrEqual(cur->URL, delegates[i]))
- break;
- if (i < nbList) {
- cur = cur->next;
- continue;
- }
- if (nbList < MAX_DELEGATE)
- delegates[nbList++] = cur->URL;
- if (cur->children == NULL) {
- xmlFetchXMLCatalogFile(cur);
- }
- if (cur->children != NULL) {
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Trying URI delegate %s\n", cur->URL);
- ret = xmlCatalogListXMLResolveURI(
- cur->children, URI);
- if (ret != NULL)
- return(ret);
- }
- }
- cur = cur->next;
- }
- /*
- * Apply the cut algorithm explained in 4/
- */
- return(XML_CATAL_BREAK);
- }
- if (haveNext) {
- cur = catal;
- while (cur != NULL) {
- if (cur->type == XML_CATA_NEXT_CATALOG) {
- if (cur->children == NULL) {
- xmlFetchXMLCatalogFile(cur);
- }
- if (cur->children != NULL) {
- ret = xmlCatalogListXMLResolveURI(cur->children, URI);
- if (ret != NULL)
- return(ret);
- }
- }
- cur = cur->next;
- }
- }
- return(NULL);
- }
- /**
- * xmlCatalogListXMLResolve:
- * @catal: a catalog list
- * @pubID: the public ID string
- * @sysID: the system ID string
- *
- * Do a complete resolution lookup of an External Identifier for a
- * list of catalogs
- *
- * Implements (or tries to) 7.1. External Identifier Resolution
- * from http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
- *
- * Returns the URI of the resource or NULL if not found
- */
- static xmlChar *
- xmlCatalogListXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
- const xmlChar *sysID) {
- xmlChar *ret = NULL;
- xmlChar *urnID = NULL;
- xmlChar *normid;
- if (catal == NULL)
- return(NULL);
- if ((pubID == NULL) && (sysID == NULL))
- return(NULL);
- normid = xmlCatalogNormalizePublic(pubID);
- if (normid != NULL)
- pubID = (*normid != 0 ? normid : NULL);
- if (!xmlStrncmp(pubID, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1)) {
- urnID = xmlCatalogUnWrapURN(pubID);
- if (xmlDebugCatalogs) {
- if (urnID == NULL)
- xmlGenericError(xmlGenericErrorContext,
- "Public URN ID %s expanded to NULL\n", pubID);
- else
- xmlGenericError(xmlGenericErrorContext,
- "Public URN ID expanded to %s\n", urnID);
- }
- ret = xmlCatalogListXMLResolve(catal, urnID, sysID);
- if (urnID != NULL)
- xmlFree(urnID);
- if (normid != NULL)
- xmlFree(normid);
- return(ret);
- }
- if (!xmlStrncmp(sysID, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1)) {
- urnID = xmlCatalogUnWrapURN(sysID);
- if (xmlDebugCatalogs) {
- if (urnID == NULL)
- xmlGenericError(xmlGenericErrorContext,
- "System URN ID %s expanded to NULL\n", sysID);
- else
- xmlGenericError(xmlGenericErrorContext,
- "System URN ID expanded to %s\n", urnID);
- }
- if (pubID == NULL)
- ret = xmlCatalogListXMLResolve(catal, urnID, NULL);
- else if (xmlStrEqual(pubID, urnID))
- ret = xmlCatalogListXMLResolve(catal, pubID, NULL);
- else {
- ret = xmlCatalogListXMLResolve(catal, pubID, urnID);
- }
- if (urnID != NULL)
- xmlFree(urnID);
- if (normid != NULL)
- xmlFree(normid);
- return(ret);
- }
- while (catal != NULL) {
- if (catal->type == XML_CATA_CATALOG) {
- if (catal->children == NULL) {
- xmlFetchXMLCatalogFile(catal);
- }
- if (catal->children != NULL) {
- ret = xmlCatalogXMLResolve(catal->children, pubID, sysID);
- if (ret != NULL) {
- break;
- } else if (catal->children->depth > MAX_CATAL_DEPTH) {
- ret = NULL;
- break;
- }
- }
- }
- catal = catal->next;
- }
- if (normid != NULL)
- xmlFree(normid);
- return(ret);
- }
- /**
- * xmlCatalogListXMLResolveURI:
- * @catal: a catalog list
- * @URI: the URI
- *
- * Do a complete resolution lookup of an URI for a list of catalogs
- *
- * Implements (or tries to) 7.2. URI Resolution
- * from http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
- *
- * Returns the URI of the resource or NULL if not found
- */
- static xmlChar *
- xmlCatalogListXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI) {
- xmlChar *ret = NULL;
- xmlChar *urnID = NULL;
- if (catal == NULL)
- return(NULL);
- if (URI == NULL)
- return(NULL);
- if (!xmlStrncmp(URI, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1)) {
- urnID = xmlCatalogUnWrapURN(URI);
- if (xmlDebugCatalogs) {
- if (urnID == NULL)
- xmlGenericError(xmlGenericErrorContext,
- "URN ID %s expanded to NULL\n", URI);
- else
- xmlGenericError(xmlGenericErrorContext,
- "URN ID expanded to %s\n", urnID);
- }
- ret = xmlCatalogListXMLResolve(catal, urnID, NULL);
- if (urnID != NULL)
- xmlFree(urnID);
- return(ret);
- }
- while (catal != NULL) {
- if (catal->type == XML_CATA_CATALOG) {
- if (catal->children == NULL) {
- xmlFetchXMLCatalogFile(catal);
- }
- if (catal->children != NULL) {
- ret = xmlCatalogXMLResolveURI(catal->children, URI);
- if (ret != NULL)
- return(ret);
- }
- }
- catal = catal->next;
- }
- return(ret);
- }
- /************************************************************************
- * *
- * The SGML Catalog parser *
- * *
- ************************************************************************/
- #define RAW *cur
- #define NEXT cur++;
- #define SKIP(x) cur += x;
- #define SKIP_BLANKS while (IS_BLANK_CH(*cur)) NEXT;
- /**
- * xmlParseSGMLCatalogComment:
- * @cur: the current character
- *
- * Skip a comment in an SGML catalog
- *
- * Returns new current character
- */
- static const xmlChar *
- xmlParseSGMLCatalogComment(const xmlChar *cur) {
- if ((cur[0] != '-') || (cur[1] != '-'))
- return(cur);
- SKIP(2);
- while ((cur[0] != 0) && ((cur[0] != '-') || ((cur[1] != '-'))))
- NEXT;
- if (cur[0] == 0) {
- return(NULL);
- }
- return(cur + 2);
- }
- /**
- * xmlParseSGMLCatalogPubid:
- * @cur: the current character
- * @id: the return location
- *
- * Parse an SGML catalog ID
- *
- * Returns new current character and store the value in @id
- */
- static const xmlChar *
- xmlParseSGMLCatalogPubid(const xmlChar *cur, xmlChar **id) {
- xmlChar *buf = NULL, *tmp;
- int len = 0;
- int size = 50;
- xmlChar stop;
- int count = 0;
- *id = NULL;
- if (RAW == '"') {
- NEXT;
- stop = '"';
- } else if (RAW == '\'') {
- NEXT;
- stop = '\'';
- } else {
- stop = ' ';
- }
- buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlCatalogErrMemory("allocating public ID");
- return(NULL);
- }
- while (IS_PUBIDCHAR_CH(*cur) || (*cur == '?')) {
- if ((*cur == stop) && (stop != ' '))
- break;
- if ((stop == ' ') && (IS_BLANK_CH(*cur)))
- break;
- if (len + 1 >= size) {
- size *= 2;
- tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
- if (tmp == NULL) {
- xmlCatalogErrMemory("allocating public ID");
- xmlFree(buf);
- return(NULL);
- }
- buf = tmp;
- }
- buf[len++] = *cur;
- count++;
- NEXT;
- }
- buf[len] = 0;
- if (stop == ' ') {
- if (!IS_BLANK_CH(*cur)) {
- xmlFree(buf);
- return(NULL);
- }
- } else {
- if (*cur != stop) {
- xmlFree(buf);
- return(NULL);
- }
- NEXT;
- }
- *id = buf;
- return(cur);
- }
- /**
- * xmlParseSGMLCatalogName:
- * @cur: the current character
- * @name: the return location
- *
- * Parse an SGML catalog name
- *
- * Returns new current character and store the value in @name
- */
- static const xmlChar *
- xmlParseSGMLCatalogName(const xmlChar *cur, xmlChar **name) {
- xmlChar buf[XML_MAX_NAMELEN + 5];
- int len = 0;
- int c;
- *name = NULL;
- /*
- * Handler for more complex cases
- */
- c = *cur;
- if ((!IS_LETTER(c) && (c != '_') && (c != ':'))) {
- return(NULL);
- }
- while (((IS_LETTER(c)) || (IS_DIGIT(c)) ||
- (c == '.') || (c == '-') ||
- (c == '_') || (c == ':'))) {
- buf[len++] = c;
- cur++;
- c = *cur;
- if (len >= XML_MAX_NAMELEN)
- return(NULL);
- }
- *name = xmlStrndup(buf, len);
- return(cur);
- }
- /**
- * xmlGetSGMLCatalogEntryType:
- * @name: the entry name
- *
- * Get the Catalog entry type for a given SGML Catalog name
- *
- * Returns Catalog entry type
- */
- static xmlCatalogEntryType
- xmlGetSGMLCatalogEntryType(const xmlChar *name) {
- xmlCatalogEntryType type = XML_CATA_NONE;
- if (xmlStrEqual(name, (const xmlChar *) "SYSTEM"))
- type = SGML_CATA_SYSTEM;
- else if (xmlStrEqual(name, (const xmlChar *) "PUBLIC"))
- type = SGML_CATA_PUBLIC;
- else if (xmlStrEqual(name, (const xmlChar *) "DELEGATE"))
- type = SGML_CATA_DELEGATE;
- else if (xmlStrEqual(name, (const xmlChar *) "ENTITY"))
- type = SGML_CATA_ENTITY;
- else if (xmlStrEqual(name, (const xmlChar *) "DOCTYPE"))
- type = SGML_CATA_DOCTYPE;
- else if (xmlStrEqual(name, (const xmlChar *) "LINKTYPE"))
- type = SGML_CATA_LINKTYPE;
- else if (xmlStrEqual(name, (const xmlChar *) "NOTATION"))
- type = SGML_CATA_NOTATION;
- else if (xmlStrEqual(name, (const xmlChar *) "SGMLDECL"))
- type = SGML_CATA_SGMLDECL;
- else if (xmlStrEqual(name, (const xmlChar *) "DOCUMENT"))
- type = SGML_CATA_DOCUMENT;
- else if (xmlStrEqual(name, (const xmlChar *) "CATALOG"))
- type = SGML_CATA_CATALOG;
- else if (xmlStrEqual(name, (const xmlChar *) "BASE"))
- type = SGML_CATA_BASE;
- return(type);
- }
- /**
- * xmlParseSGMLCatalog:
- * @catal: the SGML Catalog
- * @value: the content of the SGML Catalog serialization
- * @file: the filepath for the catalog
- * @super: should this be handled as a Super Catalog in which case
- * parsing is not recursive
- *
- * Parse an SGML catalog content and fill up the @catal hash table with
- * the new entries found.
- *
- * Returns 0 in case of success, -1 in case of error.
- */
- static int
- xmlParseSGMLCatalog(xmlCatalogPtr catal, const xmlChar *value,
- const char *file, int super) {
- const xmlChar *cur = value;
- xmlChar *base = NULL;
- int res;
- if ((cur == NULL) || (file == NULL))
- return(-1);
- base = xmlStrdup((const xmlChar *) file);
- while ((cur != NULL) && (cur[0] != 0)) {
- SKIP_BLANKS;
- if (cur[0] == 0)
- break;
- if ((cur[0] == '-') && (cur[1] == '-')) {
- cur = xmlParseSGMLCatalogComment(cur);
- if (cur == NULL) {
- /* error */
- break;
- }
- } else {
- xmlChar *sysid = NULL;
- xmlChar *name = NULL;
- xmlCatalogEntryType type = XML_CATA_NONE;
- cur = xmlParseSGMLCatalogName(cur, &name);
- if (cur == NULL || name == NULL) {
- /* error */
- break;
- }
- if (!IS_BLANK_CH(*cur)) {
- /* error */
- xmlFree(name);
- break;
- }
- SKIP_BLANKS;
- if (xmlStrEqual(name, (const xmlChar *) "SYSTEM"))
- type = SGML_CATA_SYSTEM;
- else if (xmlStrEqual(name, (const xmlChar *) "PUBLIC"))
- type = SGML_CATA_PUBLIC;
- else if (xmlStrEqual(name, (const xmlChar *) "DELEGATE"))
- type = SGML_CATA_DELEGATE;
- else if (xmlStrEqual(name, (const xmlChar *) "ENTITY"))
- type = SGML_CATA_ENTITY;
- else if (xmlStrEqual(name, (const xmlChar *) "DOCTYPE"))
- type = SGML_CATA_DOCTYPE;
- else if (xmlStrEqual(name, (const xmlChar *) "LINKTYPE"))
- type = SGML_CATA_LINKTYPE;
- else if (xmlStrEqual(name, (const xmlChar *) "NOTATION"))
- type = SGML_CATA_NOTATION;
- else if (xmlStrEqual(name, (const xmlChar *) "SGMLDECL"))
- type = SGML_CATA_SGMLDECL;
- else if (xmlStrEqual(name, (const xmlChar *) "DOCUMENT"))
- type = SGML_CATA_DOCUMENT;
- else if (xmlStrEqual(name, (const xmlChar *) "CATALOG"))
- type = SGML_CATA_CATALOG;
- else if (xmlStrEqual(name, (const xmlChar *) "BASE"))
- type = SGML_CATA_BASE;
- else if (xmlStrEqual(name, (const xmlChar *) "OVERRIDE")) {
- xmlFree(name);
- cur = xmlParseSGMLCatalogName(cur, &name);
- if (name == NULL) {
- /* error */
- break;
- }
- xmlFree(name);
- continue;
- }
- xmlFree(name);
- name = NULL;
- switch(type) {
- case SGML_CATA_ENTITY:
- if (*cur == '%')
- type = SGML_CATA_PENTITY;
- /* Falls through. */
- case SGML_CATA_PENTITY:
- case SGML_CATA_DOCTYPE:
- case SGML_CATA_LINKTYPE:
- case SGML_CATA_NOTATION:
- cur = xmlParseSGMLCatalogName(cur, &name);
- if (cur == NULL) {
- /* error */
- break;
- }
- if (!IS_BLANK_CH(*cur)) {
- /* error */
- break;
- }
- SKIP_BLANKS;
- cur = xmlParseSGMLCatalogPubid(cur, &sysid);
- if (cur == NULL) {
- /* error */
- break;
- }
- break;
- case SGML_CATA_PUBLIC:
- case SGML_CATA_SYSTEM:
- case SGML_CATA_DELEGATE:
- cur = xmlParseSGMLCatalogPubid(cur, &name);
- if (cur == NULL) {
- /* error */
- break;
- }
- if (type != SGML_CATA_SYSTEM) {
- xmlChar *normid;
- normid = xmlCatalogNormalizePublic(name);
- if (normid != NULL) {
- if (name != NULL)
- xmlFree(name);
- if (*normid != 0)
- name = normid;
- else {
- xmlFree(normid);
- name = NULL;
- }
- }
- }
- if (!IS_BLANK_CH(*cur)) {
- /* error */
- break;
- }
- SKIP_BLANKS;
- cur = xmlParseSGMLCatalogPubid(cur, &sysid);
- if (cur == NULL) {
- /* error */
- break;
- }
- break;
- case SGML_CATA_BASE:
- case SGML_CATA_CATALOG:
- case SGML_CATA_DOCUMENT:
- case SGML_CATA_SGMLDECL:
- cur = xmlParseSGMLCatalogPubid(cur, &sysid);
- if (cur == NULL) {
- /* error */
- break;
- }
- break;
- default:
- break;
- }
- if (cur == NULL) {
- if (name != NULL)
- xmlFree(name);
- if (sysid != NULL)
- xmlFree(sysid);
- break;
- } else if (type == SGML_CATA_BASE) {
- if (base != NULL)
- xmlFree(base);
- base = xmlStrdup(sysid);
- } else if ((type == SGML_CATA_PUBLIC) ||
- (type == SGML_CATA_SYSTEM)) {
- xmlChar *filename;
- filename = xmlBuildURI(sysid, base);
- if (filename != NULL) {
- xmlCatalogEntryPtr entry;
- entry = xmlNewCatalogEntry(type, name, filename,
- NULL, XML_CATA_PREFER_NONE, NULL);
- res = xmlHashAddEntry(catal->sgml, name, entry);
- if (res < 0) {
- xmlFreeCatalogEntry(entry, NULL);
- }
- xmlFree(filename);
- }
- } else if (type == SGML_CATA_CATALOG) {
- if (super) {
- xmlCatalogEntryPtr entry;
- entry = xmlNewCatalogEntry(type, sysid, NULL, NULL,
- XML_CATA_PREFER_NONE, NULL);
- res = xmlHashAddEntry(catal->sgml, sysid, entry);
- if (res < 0) {
- xmlFreeCatalogEntry(entry, NULL);
- }
- } else {
- xmlChar *filename;
- filename = xmlBuildURI(sysid, base);
- if (filename != NULL) {
- xmlExpandCatalog(catal, (const char *)filename);
- xmlFree(filename);
- }
- }
- }
- /*
- * drop anything else we won't handle it
- */
- if (name != NULL)
- xmlFree(name);
- if (sysid != NULL)
- xmlFree(sysid);
- }
- }
- if (base != NULL)
- xmlFree(base);
- if (cur == NULL)
- return(-1);
- return(0);
- }
- /************************************************************************
- * *
- * SGML Catalog handling *
- * *
- ************************************************************************/
- /**
- * xmlCatalogGetSGMLPublic:
- * @catal: an SGML catalog hash
- * @pubID: the public ID string
- *
- * Try to lookup the catalog local reference associated to a public ID
- *
- * Returns the local resource if found or NULL otherwise.
- */
- static const xmlChar *
- xmlCatalogGetSGMLPublic(xmlHashTablePtr catal, const xmlChar *pubID) {
- xmlCatalogEntryPtr entry;
- xmlChar *normid;
- if (catal == NULL)
- return(NULL);
- normid = xmlCatalogNormalizePublic(pubID);
- if (normid != NULL)
- pubID = (*normid != 0 ? normid : NULL);
- entry = (xmlCatalogEntryPtr) xmlHashLookup(catal, pubID);
- if (entry == NULL) {
- if (normid != NULL)
- xmlFree(normid);
- return(NULL);
- }
- if (entry->type == SGML_CATA_PUBLIC) {
- if (normid != NULL)
- xmlFree(normid);
- return(entry->URL);
- }
- if (normid != NULL)
- xmlFree(normid);
- return(NULL);
- }
- /**
- * xmlCatalogGetSGMLSystem:
- * @catal: an SGML catalog hash
- * @sysID: the system ID string
- *
- * Try to lookup the catalog local reference for a system ID
- *
- * Returns the local resource if found or NULL otherwise.
- */
- static const xmlChar *
- xmlCatalogGetSGMLSystem(xmlHashTablePtr catal, const xmlChar *sysID) {
- xmlCatalogEntryPtr entry;
- if (catal == NULL)
- return(NULL);
- entry = (xmlCatalogEntryPtr) xmlHashLookup(catal, sysID);
- if (entry == NULL)
- return(NULL);
- if (entry->type == SGML_CATA_SYSTEM)
- return(entry->URL);
- return(NULL);
- }
- /**
- * xmlCatalogSGMLResolve:
- * @catal: the SGML catalog
- * @pubID: the public ID string
- * @sysID: the system ID string
- *
- * Do a complete resolution lookup of an External Identifier
- *
- * Returns the URI of the resource or NULL if not found
- */
- static const xmlChar *
- xmlCatalogSGMLResolve(xmlCatalogPtr catal, const xmlChar *pubID,
- const xmlChar *sysID) {
- const xmlChar *ret = NULL;
- if (catal->sgml == NULL)
- return(NULL);
- if (pubID != NULL)
- ret = xmlCatalogGetSGMLPublic(catal->sgml, pubID);
- if (ret != NULL)
- return(ret);
- if (sysID != NULL)
- ret = xmlCatalogGetSGMLSystem(catal->sgml, sysID);
- if (ret != NULL)
- return(ret);
- return(NULL);
- }
- /************************************************************************
- * *
- * Specific Public interfaces *
- * *
- ************************************************************************/
- /**
- * xmlLoadSGMLSuperCatalog:
- * @filename: a file path
- *
- * Load an SGML super catalog. It won't expand CATALOG or DELEGATE
- * references. This is only needed for manipulating SGML Super Catalogs
- * like adding and removing CATALOG or DELEGATE entries.
- *
- * Returns the catalog parsed or NULL in case of error
- */
- xmlCatalogPtr
- xmlLoadSGMLSuperCatalog(const char *filename)
- {
- xmlChar *content;
- xmlCatalogPtr catal;
- int ret;
- content = xmlLoadFileContent(filename);
- if (content == NULL)
- return(NULL);
- catal = xmlCreateNewCatalog(XML_SGML_CATALOG_TYPE, xmlCatalogDefaultPrefer);
- if (catal == NULL) {
- xmlFree(content);
- return(NULL);
- }
- ret = xmlParseSGMLCatalog(catal, content, filename, 1);
- xmlFree(content);
- if (ret < 0) {
- xmlFreeCatalog(catal);
- return(NULL);
- }
- return (catal);
- }
- /**
- * xmlLoadACatalog:
- * @filename: a file path
- *
- * Load the catalog and build the associated data structures.
- * This can be either an XML Catalog or an SGML Catalog
- * It will recurse in SGML CATALOG entries. On the other hand XML
- * Catalogs are not handled recursively.
- *
- * Returns the catalog parsed or NULL in case of error
- */
- xmlCatalogPtr
- xmlLoadACatalog(const char *filename)
- {
- xmlChar *content;
- xmlChar *first;
- xmlCatalogPtr catal;
- int ret;
- content = xmlLoadFileContent(filename);
- if (content == NULL)
- return(NULL);
- first = content;
- while ((*first != 0) && (*first != '-') && (*first != '<') &&
- (!(((*first >= 'A') && (*first <= 'Z')) ||
- ((*first >= 'a') && (*first <= 'z')))))
- first++;
- if (*first != '<') {
- catal = xmlCreateNewCatalog(XML_SGML_CATALOG_TYPE, xmlCatalogDefaultPrefer);
- if (catal == NULL) {
- xmlFree(content);
- return(NULL);
- }
- ret = xmlParseSGMLCatalog(catal, content, filename, 0);
- if (ret < 0) {
- xmlFreeCatalog(catal);
- xmlFree(content);
- return(NULL);
- }
- } else {
- catal = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE, xmlCatalogDefaultPrefer);
- if (catal == NULL) {
- xmlFree(content);
- return(NULL);
- }
- catal->xml = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
- NULL, BAD_CAST filename, xmlCatalogDefaultPrefer, NULL);
- }
- xmlFree(content);
- return (catal);
- }
- /**
- * xmlExpandCatalog:
- * @catal: a catalog
- * @filename: a file path
- *
- * Load the catalog and expand the existing catal structure.
- * This can be either an XML Catalog or an SGML Catalog
- *
- * Returns 0 in case of success, -1 in case of error
- */
- static int
- xmlExpandCatalog(xmlCatalogPtr catal, const char *filename)
- {
- int ret;
- if ((catal == NULL) || (filename == NULL))
- return(-1);
- if (catal->type == XML_SGML_CATALOG_TYPE) {
- xmlChar *content;
- content = xmlLoadFileContent(filename);
- if (content == NULL)
- return(-1);
- ret = xmlParseSGMLCatalog(catal, content, filename, 0);
- if (ret < 0) {
- xmlFree(content);
- return(-1);
- }
- xmlFree(content);
- } else {
- xmlCatalogEntryPtr tmp, cur;
- tmp = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
- NULL, BAD_CAST filename, xmlCatalogDefaultPrefer, NULL);
- cur = catal->xml;
- if (cur == NULL) {
- catal->xml = tmp;
- } else {
- while (cur->next != NULL) cur = cur->next;
- cur->next = tmp;
- }
- }
- return (0);
- }
- /**
- * xmlACatalogResolveSystem:
- * @catal: a Catalog
- * @sysID: the system ID string
- *
- * Try to lookup the catalog resource for a system ID
- *
- * Returns the resource if found or NULL otherwise, the value returned
- * must be freed by the caller.
- */
- xmlChar *
- xmlACatalogResolveSystem(xmlCatalogPtr catal, const xmlChar *sysID) {
- xmlChar *ret = NULL;
- if ((sysID == NULL) || (catal == NULL))
- return(NULL);
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Resolve sysID %s\n", sysID);
- if (catal->type == XML_XML_CATALOG_TYPE) {
- ret = xmlCatalogListXMLResolve(catal->xml, NULL, sysID);
- if (ret == XML_CATAL_BREAK)
- ret = NULL;
- } else {
- const xmlChar *sgml;
- sgml = xmlCatalogGetSGMLSystem(catal->sgml, sysID);
- if (sgml != NULL)
- ret = xmlStrdup(sgml);
- }
- return(ret);
- }
- /**
- * xmlACatalogResolvePublic:
- * @catal: a Catalog
- * @pubID: the public ID string
- *
- * Try to lookup the catalog local reference associated to a public ID in that catalog
- *
- * Returns the local resource if found or NULL otherwise, the value returned
- * must be freed by the caller.
- */
- xmlChar *
- xmlACatalogResolvePublic(xmlCatalogPtr catal, const xmlChar *pubID) {
- xmlChar *ret = NULL;
- if ((pubID == NULL) || (catal == NULL))
- return(NULL);
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Resolve pubID %s\n", pubID);
- if (catal->type == XML_XML_CATALOG_TYPE) {
- ret = xmlCatalogListXMLResolve(catal->xml, pubID, NULL);
- if (ret == XML_CATAL_BREAK)
- ret = NULL;
- } else {
- const xmlChar *sgml;
- sgml = xmlCatalogGetSGMLPublic(catal->sgml, pubID);
- if (sgml != NULL)
- ret = xmlStrdup(sgml);
- }
- return(ret);
- }
- /**
- * xmlACatalogResolve:
- * @catal: a Catalog
- * @pubID: the public ID string
- * @sysID: the system ID string
- *
- * Do a complete resolution lookup of an External Identifier
- *
- * Returns the URI of the resource or NULL if not found, it must be freed
- * by the caller.
- */
- xmlChar *
- xmlACatalogResolve(xmlCatalogPtr catal, const xmlChar * pubID,
- const xmlChar * sysID)
- {
- xmlChar *ret = NULL;
- if (((pubID == NULL) && (sysID == NULL)) || (catal == NULL))
- return (NULL);
- if (xmlDebugCatalogs) {
- if ((pubID != NULL) && (sysID != NULL)) {
- xmlGenericError(xmlGenericErrorContext,
- "Resolve: pubID %s sysID %s\n", pubID, sysID);
- } else if (pubID != NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "Resolve: pubID %s\n", pubID);
- } else {
- xmlGenericError(xmlGenericErrorContext,
- "Resolve: sysID %s\n", sysID);
- }
- }
- if (catal->type == XML_XML_CATALOG_TYPE) {
- ret = xmlCatalogListXMLResolve(catal->xml, pubID, sysID);
- if (ret == XML_CATAL_BREAK)
- ret = NULL;
- } else {
- const xmlChar *sgml;
- sgml = xmlCatalogSGMLResolve(catal, pubID, sysID);
- if (sgml != NULL)
- ret = xmlStrdup(sgml);
- }
- return (ret);
- }
- /**
- * xmlACatalogResolveURI:
- * @catal: a Catalog
- * @URI: the URI
- *
- * Do a complete resolution lookup of an URI
- *
- * Returns the URI of the resource or NULL if not found, it must be freed
- * by the caller.
- */
- xmlChar *
- xmlACatalogResolveURI(xmlCatalogPtr catal, const xmlChar *URI) {
- xmlChar *ret = NULL;
- if ((URI == NULL) || (catal == NULL))
- return(NULL);
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Resolve URI %s\n", URI);
- if (catal->type == XML_XML_CATALOG_TYPE) {
- ret = xmlCatalogListXMLResolveURI(catal->xml, URI);
- if (ret == XML_CATAL_BREAK)
- ret = NULL;
- } else {
- const xmlChar *sgml;
- sgml = xmlCatalogSGMLResolve(catal, NULL, URI);
- if (sgml != NULL)
- ret = xmlStrdup(sgml);
- }
- return(ret);
- }
- #ifdef LIBXML_OUTPUT_ENABLED
- /**
- * xmlACatalogDump:
- * @catal: a Catalog
- * @out: the file.
- *
- * Dump the given catalog to the given file.
- */
- void
- xmlACatalogDump(xmlCatalogPtr catal, FILE *out) {
- if ((out == NULL) || (catal == NULL))
- return;
- if (catal->type == XML_XML_CATALOG_TYPE) {
- xmlDumpXMLCatalog(out, catal->xml);
- } else {
- xmlHashScan(catal->sgml, xmlCatalogDumpEntry, out);
- }
- }
- #endif /* LIBXML_OUTPUT_ENABLED */
- /**
- * xmlACatalogAdd:
- * @catal: a Catalog
- * @type: the type of record to add to the catalog
- * @orig: the system, public or prefix to match
- * @replace: the replacement value for the match
- *
- * Add an entry in the catalog, it may overwrite existing but
- * different entries.
- *
- * Returns 0 if successful, -1 otherwise
- */
- int
- xmlACatalogAdd(xmlCatalogPtr catal, const xmlChar * type,
- const xmlChar * orig, const xmlChar * replace)
- {
- int res = -1;
- if (catal == NULL)
- return(-1);
- if (catal->type == XML_XML_CATALOG_TYPE) {
- res = xmlAddXMLCatalog(catal->xml, type, orig, replace);
- } else {
- xmlCatalogEntryType cattype;
- cattype = xmlGetSGMLCatalogEntryType(type);
- if (cattype != XML_CATA_NONE) {
- xmlCatalogEntryPtr entry;
- entry = xmlNewCatalogEntry(cattype, orig, replace, NULL,
- XML_CATA_PREFER_NONE, NULL);
- if (catal->sgml == NULL)
- catal->sgml = xmlHashCreate(10);
- res = xmlHashAddEntry(catal->sgml, orig, entry);
- }
- }
- return (res);
- }
- /**
- * xmlACatalogRemove:
- * @catal: a Catalog
- * @value: the value to remove
- *
- * Remove an entry from the catalog
- *
- * Returns the number of entries removed if successful, -1 otherwise
- */
- int
- xmlACatalogRemove(xmlCatalogPtr catal, const xmlChar *value) {
- int res = -1;
- if ((catal == NULL) || (value == NULL))
- return(-1);
- if (catal->type == XML_XML_CATALOG_TYPE) {
- res = xmlDelXMLCatalog(catal->xml, value);
- } else {
- res = xmlHashRemoveEntry(catal->sgml, value, xmlFreeCatalogEntry);
- if (res == 0)
- res = 1;
- }
- return(res);
- }
- /**
- * xmlNewCatalog:
- * @sgml: should this create an SGML catalog
- *
- * create a new Catalog.
- *
- * Returns the xmlCatalogPtr or NULL in case of error
- */
- xmlCatalogPtr
- xmlNewCatalog(int sgml) {
- xmlCatalogPtr catal = NULL;
- if (sgml) {
- catal = xmlCreateNewCatalog(XML_SGML_CATALOG_TYPE,
- xmlCatalogDefaultPrefer);
- if ((catal != NULL) && (catal->sgml == NULL))
- catal->sgml = xmlHashCreate(10);
- } else
- catal = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE,
- xmlCatalogDefaultPrefer);
- return(catal);
- }
- /**
- * xmlCatalogIsEmpty:
- * @catal: should this create an SGML catalog
- *
- * Check is a catalog is empty
- *
- * Returns 1 if the catalog is empty, 0 if not, amd -1 in case of error.
- */
- int
- xmlCatalogIsEmpty(xmlCatalogPtr catal) {
- if (catal == NULL)
- return(-1);
- if (catal->type == XML_XML_CATALOG_TYPE) {
- if (catal->xml == NULL)
- return(1);
- if ((catal->xml->type != XML_CATA_CATALOG) &&
- (catal->xml->type != XML_CATA_BROKEN_CATALOG))
- return(-1);
- if (catal->xml->children == NULL)
- return(1);
- return(0);
- } else {
- int res;
- if (catal->sgml == NULL)
- return(1);
- res = xmlHashSize(catal->sgml);
- if (res == 0)
- return(1);
- if (res < 0)
- return(-1);
- }
- return(0);
- }
- /************************************************************************
- * *
- * Public interfaces manipulating the global shared default catalog *
- * *
- ************************************************************************/
- /**
- * xmlInitializeCatalogData:
- *
- * Do the catalog initialization only of global data, doesn't try to load
- * any catalog actually.
- * this function is not thread safe, catalog initialization should
- * preferably be done once at startup
- */
- static void
- xmlInitializeCatalogData(void) {
- if (xmlCatalogInitialized != 0)
- return;
- if (getenv("XML_DEBUG_CATALOG"))
- xmlDebugCatalogs = 1;
- xmlCatalogMutex = xmlNewRMutex();
- xmlCatalogInitialized = 1;
- }
- /**
- * xmlInitializeCatalog:
- *
- * Do the catalog initialization.
- * this function is not thread safe, catalog initialization should
- * preferably be done once at startup
- */
- void
- xmlInitializeCatalog(void) {
- if (xmlCatalogInitialized != 0)
- return;
- xmlInitializeCatalogData();
- xmlRMutexLock(xmlCatalogMutex);
- if (getenv("XML_DEBUG_CATALOG"))
- xmlDebugCatalogs = 1;
- if (xmlDefaultCatalog == NULL) {
- const char *catalogs;
- char *path;
- const char *cur, *paths;
- xmlCatalogPtr catal;
- xmlCatalogEntryPtr *nextent;
- catalogs = (const char *) getenv("XML_CATALOG_FILES");
- if (catalogs == NULL)
- #if defined(_WIN32) && defined(_MSC_VER)
- {
- void* hmodule;
- hmodule = GetModuleHandleA("libxml2.dll");
- if (hmodule == NULL)
- hmodule = GetModuleHandleA(NULL);
- if (hmodule != NULL) {
- char buf[256];
- unsigned long len = GetModuleFileNameA(hmodule, buf, 255);
- if (len != 0) {
- char* p = &(buf[len]);
- while (*p != '\\' && p > buf)
- p--;
- if (p != buf) {
- xmlChar* uri;
- strncpy(p, "\\..\\etc\\catalog", 255 - (p - buf));
- uri = xmlCanonicPath((const xmlChar*)buf);
- if (uri != NULL) {
- strncpy(XML_XML_DEFAULT_CATALOG, uri, 255);
- xmlFree(uri);
- }
- }
- }
- }
- catalogs = XML_XML_DEFAULT_CATALOG;
- }
- #else
- catalogs = XML_XML_DEFAULT_CATALOG;
- #endif
- catal = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE,
- xmlCatalogDefaultPrefer);
- if (catal != NULL) {
- /* the XML_CATALOG_FILES envvar is allowed to contain a
- space-separated list of entries. */
- cur = catalogs;
- nextent = &catal->xml;
- while (*cur != '\0') {
- while (xmlIsBlank_ch(*cur))
- cur++;
- if (*cur != 0) {
- paths = cur;
- while ((*cur != 0) && (!xmlIsBlank_ch(*cur)))
- cur++;
- path = (char *) xmlStrndup((const xmlChar *)paths, cur - paths);
- if (path != NULL) {
- *nextent = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
- NULL, BAD_CAST path, xmlCatalogDefaultPrefer, NULL);
- if (*nextent != NULL)
- nextent = &((*nextent)->next);
- xmlFree(path);
- }
- }
- }
- xmlDefaultCatalog = catal;
- }
- }
- xmlRMutexUnlock(xmlCatalogMutex);
- }
- /**
- * xmlLoadCatalog:
- * @filename: a file path
- *
- * Load the catalog and makes its definitions effective for the default
- * external entity loader. It will recurse in SGML CATALOG entries.
- * this function is not thread safe, catalog initialization should
- * preferably be done once at startup
- *
- * Returns 0 in case of success -1 in case of error
- */
- int
- xmlLoadCatalog(const char *filename)
- {
- int ret;
- xmlCatalogPtr catal;
- if (!xmlCatalogInitialized)
- xmlInitializeCatalogData();
- xmlRMutexLock(xmlCatalogMutex);
- if (xmlDefaultCatalog == NULL) {
- catal = xmlLoadACatalog(filename);
- if (catal == NULL) {
- xmlRMutexUnlock(xmlCatalogMutex);
- return(-1);
- }
- xmlDefaultCatalog = catal;
- xmlRMutexUnlock(xmlCatalogMutex);
- return(0);
- }
- ret = xmlExpandCatalog(xmlDefaultCatalog, filename);
- xmlRMutexUnlock(xmlCatalogMutex);
- return(ret);
- }
- /**
- * xmlLoadCatalogs:
- * @pathss: a list of directories separated by a colon or a space.
- *
- * Load the catalogs and makes their definitions effective for the default
- * external entity loader.
- * this function is not thread safe, catalog initialization should
- * preferably be done once at startup
- */
- void
- xmlLoadCatalogs(const char *pathss) {
- const char *cur;
- const char *paths;
- xmlChar *path;
- #ifdef _WIN32
- int i, iLen;
- #endif
- if (pathss == NULL)
- return;
- cur = pathss;
- while (*cur != 0) {
- while (xmlIsBlank_ch(*cur)) cur++;
- if (*cur != 0) {
- paths = cur;
- while ((*cur != 0) && (*cur != PATH_SEPARATOR) && (!xmlIsBlank_ch(*cur)))
- cur++;
- path = xmlStrndup((const xmlChar *)paths, cur - paths);
- if (path != NULL) {
- #ifdef _WIN32
- iLen = strlen((const char*)path);
- for(i = 0; i < iLen; i++) {
- if(path[i] == '\\') {
- path[i] = '/';
- }
- }
- #endif
- xmlLoadCatalog((const char *) path);
- xmlFree(path);
- }
- }
- while (*cur == PATH_SEPARATOR)
- cur++;
- }
- }
- /**
- * xmlCatalogCleanup:
- *
- * Free up all the memory associated with catalogs
- */
- void
- xmlCatalogCleanup(void) {
- if (xmlCatalogInitialized == 0)
- return;
- xmlRMutexLock(xmlCatalogMutex);
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Catalogs cleanup\n");
- if (xmlCatalogXMLFiles != NULL)
- xmlHashFree(xmlCatalogXMLFiles, xmlFreeCatalogHashEntryList);
- xmlCatalogXMLFiles = NULL;
- if (xmlDefaultCatalog != NULL)
- xmlFreeCatalog(xmlDefaultCatalog);
- xmlDefaultCatalog = NULL;
- xmlDebugCatalogs = 0;
- xmlCatalogInitialized = 0;
- xmlRMutexUnlock(xmlCatalogMutex);
- xmlFreeRMutex(xmlCatalogMutex);
- }
- /**
- * xmlCatalogResolveSystem:
- * @sysID: the system ID string
- *
- * Try to lookup the catalog resource for a system ID
- *
- * Returns the resource if found or NULL otherwise, the value returned
- * must be freed by the caller.
- */
- xmlChar *
- xmlCatalogResolveSystem(const xmlChar *sysID) {
- xmlChar *ret;
- if (!xmlCatalogInitialized)
- xmlInitializeCatalog();
- ret = xmlACatalogResolveSystem(xmlDefaultCatalog, sysID);
- return(ret);
- }
- /**
- * xmlCatalogResolvePublic:
- * @pubID: the public ID string
- *
- * Try to lookup the catalog reference associated to a public ID
- *
- * Returns the resource if found or NULL otherwise, the value returned
- * must be freed by the caller.
- */
- xmlChar *
- xmlCatalogResolvePublic(const xmlChar *pubID) {
- xmlChar *ret;
- if (!xmlCatalogInitialized)
- xmlInitializeCatalog();
- ret = xmlACatalogResolvePublic(xmlDefaultCatalog, pubID);
- return(ret);
- }
- /**
- * xmlCatalogResolve:
- * @pubID: the public ID string
- * @sysID: the system ID string
- *
- * Do a complete resolution lookup of an External Identifier
- *
- * Returns the URI of the resource or NULL if not found, it must be freed
- * by the caller.
- */
- xmlChar *
- xmlCatalogResolve(const xmlChar *pubID, const xmlChar *sysID) {
- xmlChar *ret;
- if (!xmlCatalogInitialized)
- xmlInitializeCatalog();
- ret = xmlACatalogResolve(xmlDefaultCatalog, pubID, sysID);
- return(ret);
- }
- /**
- * xmlCatalogResolveURI:
- * @URI: the URI
- *
- * Do a complete resolution lookup of an URI
- *
- * Returns the URI of the resource or NULL if not found, it must be freed
- * by the caller.
- */
- xmlChar *
- xmlCatalogResolveURI(const xmlChar *URI) {
- xmlChar *ret;
- if (!xmlCatalogInitialized)
- xmlInitializeCatalog();
- ret = xmlACatalogResolveURI(xmlDefaultCatalog, URI);
- return(ret);
- }
- #ifdef LIBXML_OUTPUT_ENABLED
- /**
- * xmlCatalogDump:
- * @out: the file.
- *
- * Dump all the global catalog content to the given file.
- */
- void
- xmlCatalogDump(FILE *out) {
- if (out == NULL)
- return;
- if (!xmlCatalogInitialized)
- xmlInitializeCatalog();
- xmlACatalogDump(xmlDefaultCatalog, out);
- }
- #endif /* LIBXML_OUTPUT_ENABLED */
- /**
- * xmlCatalogAdd:
- * @type: the type of record to add to the catalog
- * @orig: the system, public or prefix to match
- * @replace: the replacement value for the match
- *
- * Add an entry in the catalog, it may overwrite existing but
- * different entries.
- * If called before any other catalog routine, allows to override the
- * default shared catalog put in place by xmlInitializeCatalog();
- *
- * Returns 0 if successful, -1 otherwise
- */
- int
- xmlCatalogAdd(const xmlChar *type, const xmlChar *orig, const xmlChar *replace) {
- int res = -1;
- if (!xmlCatalogInitialized)
- xmlInitializeCatalogData();
- xmlRMutexLock(xmlCatalogMutex);
- /*
- * Specific case where one want to override the default catalog
- * put in place by xmlInitializeCatalog();
- */
- if ((xmlDefaultCatalog == NULL) &&
- (xmlStrEqual(type, BAD_CAST "catalog"))) {
- xmlDefaultCatalog = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE,
- xmlCatalogDefaultPrefer);
- if (xmlDefaultCatalog != NULL) {
- xmlDefaultCatalog->xml = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
- orig, NULL, xmlCatalogDefaultPrefer, NULL);
- }
- xmlRMutexUnlock(xmlCatalogMutex);
- return(0);
- }
- res = xmlACatalogAdd(xmlDefaultCatalog, type, orig, replace);
- xmlRMutexUnlock(xmlCatalogMutex);
- return(res);
- }
- /**
- * xmlCatalogRemove:
- * @value: the value to remove
- *
- * Remove an entry from the catalog
- *
- * Returns the number of entries removed if successful, -1 otherwise
- */
- int
- xmlCatalogRemove(const xmlChar *value) {
- int res;
- if (!xmlCatalogInitialized)
- xmlInitializeCatalog();
- xmlRMutexLock(xmlCatalogMutex);
- res = xmlACatalogRemove(xmlDefaultCatalog, value);
- xmlRMutexUnlock(xmlCatalogMutex);
- return(res);
- }
- /**
- * xmlCatalogConvert:
- *
- * Convert all the SGML catalog entries as XML ones
- *
- * Returns the number of entries converted if successful, -1 otherwise
- */
- int
- xmlCatalogConvert(void) {
- int res = -1;
- if (!xmlCatalogInitialized)
- xmlInitializeCatalog();
- xmlRMutexLock(xmlCatalogMutex);
- res = xmlConvertSGMLCatalog(xmlDefaultCatalog);
- xmlRMutexUnlock(xmlCatalogMutex);
- return(res);
- }
- /************************************************************************
- * *
- * Public interface manipulating the common preferences *
- * *
- ************************************************************************/
- /**
- * xmlCatalogGetDefaults:
- *
- * Used to get the user preference w.r.t. to what catalogs should
- * be accepted
- *
- * Returns the current xmlCatalogAllow value
- */
- xmlCatalogAllow
- xmlCatalogGetDefaults(void) {
- return(xmlCatalogDefaultAllow);
- }
- /**
- * xmlCatalogSetDefaults:
- * @allow: what catalogs should be accepted
- *
- * Used to set the user preference w.r.t. to what catalogs should
- * be accepted
- */
- void
- xmlCatalogSetDefaults(xmlCatalogAllow allow) {
- if (xmlDebugCatalogs) {
- switch (allow) {
- case XML_CATA_ALLOW_NONE:
- xmlGenericError(xmlGenericErrorContext,
- "Disabling catalog usage\n");
- break;
- case XML_CATA_ALLOW_GLOBAL:
- xmlGenericError(xmlGenericErrorContext,
- "Allowing only global catalogs\n");
- break;
- case XML_CATA_ALLOW_DOCUMENT:
- xmlGenericError(xmlGenericErrorContext,
- "Allowing only catalogs from the document\n");
- break;
- case XML_CATA_ALLOW_ALL:
- xmlGenericError(xmlGenericErrorContext,
- "Allowing all catalogs\n");
- break;
- }
- }
- xmlCatalogDefaultAllow = allow;
- }
- /**
- * xmlCatalogSetDefaultPrefer:
- * @prefer: the default preference for delegation
- *
- * Allows to set the preference between public and system for deletion
- * in XML Catalog resolution. C.f. section 4.1.1 of the spec
- * Values accepted are XML_CATA_PREFER_PUBLIC or XML_CATA_PREFER_SYSTEM
- *
- * Returns the previous value of the default preference for delegation
- */
- xmlCatalogPrefer
- xmlCatalogSetDefaultPrefer(xmlCatalogPrefer prefer) {
- xmlCatalogPrefer ret = xmlCatalogDefaultPrefer;
- if (prefer == XML_CATA_PREFER_NONE)
- return(ret);
- if (xmlDebugCatalogs) {
- switch (prefer) {
- case XML_CATA_PREFER_PUBLIC:
- xmlGenericError(xmlGenericErrorContext,
- "Setting catalog preference to PUBLIC\n");
- break;
- case XML_CATA_PREFER_SYSTEM:
- xmlGenericError(xmlGenericErrorContext,
- "Setting catalog preference to SYSTEM\n");
- break;
- default:
- return(ret);
- }
- }
- xmlCatalogDefaultPrefer = prefer;
- return(ret);
- }
- /**
- * xmlCatalogSetDebug:
- * @level: the debug level of catalogs required
- *
- * Used to set the debug level for catalog operation, 0 disable
- * debugging, 1 enable it
- *
- * Returns the previous value of the catalog debugging level
- */
- int
- xmlCatalogSetDebug(int level) {
- int ret = xmlDebugCatalogs;
- if (level <= 0)
- xmlDebugCatalogs = 0;
- else
- xmlDebugCatalogs = level;
- return(ret);
- }
- /************************************************************************
- * *
- * Minimal interfaces used for per-document catalogs by the parser *
- * *
- ************************************************************************/
- /**
- * xmlCatalogFreeLocal:
- * @catalogs: a document's list of catalogs
- *
- * Free up the memory associated to the catalog list
- */
- void
- xmlCatalogFreeLocal(void *catalogs) {
- xmlCatalogEntryPtr catal;
- if (!xmlCatalogInitialized)
- xmlInitializeCatalog();
- catal = (xmlCatalogEntryPtr) catalogs;
- if (catal != NULL)
- xmlFreeCatalogEntryList(catal);
- }
- /**
- * xmlCatalogAddLocal:
- * @catalogs: a document's list of catalogs
- * @URL: the URL to a new local catalog
- *
- * Add the new entry to the catalog list
- *
- * Returns the updated list
- */
- void *
- xmlCatalogAddLocal(void *catalogs, const xmlChar *URL) {
- xmlCatalogEntryPtr catal, add;
- if (!xmlCatalogInitialized)
- xmlInitializeCatalog();
- if (URL == NULL)
- return(catalogs);
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Adding document catalog %s\n", URL);
- add = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL, URL, NULL,
- xmlCatalogDefaultPrefer, NULL);
- if (add == NULL)
- return(catalogs);
- catal = (xmlCatalogEntryPtr) catalogs;
- if (catal == NULL)
- return((void *) add);
- while (catal->next != NULL)
- catal = catal->next;
- catal->next = add;
- return(catalogs);
- }
- /**
- * xmlCatalogLocalResolve:
- * @catalogs: a document's list of catalogs
- * @pubID: the public ID string
- * @sysID: the system ID string
- *
- * Do a complete resolution lookup of an External Identifier using a
- * document's private catalog list
- *
- * Returns the URI of the resource or NULL if not found, it must be freed
- * by the caller.
- */
- xmlChar *
- xmlCatalogLocalResolve(void *catalogs, const xmlChar *pubID,
- const xmlChar *sysID) {
- xmlCatalogEntryPtr catal;
- xmlChar *ret;
- if (!xmlCatalogInitialized)
- xmlInitializeCatalog();
- if ((pubID == NULL) && (sysID == NULL))
- return(NULL);
- if (xmlDebugCatalogs) {
- if ((pubID != NULL) && (sysID != NULL)) {
- xmlGenericError(xmlGenericErrorContext,
- "Local Resolve: pubID %s sysID %s\n", pubID, sysID);
- } else if (pubID != NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "Local Resolve: pubID %s\n", pubID);
- } else {
- xmlGenericError(xmlGenericErrorContext,
- "Local Resolve: sysID %s\n", sysID);
- }
- }
- catal = (xmlCatalogEntryPtr) catalogs;
- if (catal == NULL)
- return(NULL);
- ret = xmlCatalogListXMLResolve(catal, pubID, sysID);
- if ((ret != NULL) && (ret != XML_CATAL_BREAK))
- return(ret);
- return(NULL);
- }
- /**
- * xmlCatalogLocalResolveURI:
- * @catalogs: a document's list of catalogs
- * @URI: the URI
- *
- * Do a complete resolution lookup of an URI using a
- * document's private catalog list
- *
- * Returns the URI of the resource or NULL if not found, it must be freed
- * by the caller.
- */
- xmlChar *
- xmlCatalogLocalResolveURI(void *catalogs, const xmlChar *URI) {
- xmlCatalogEntryPtr catal;
- xmlChar *ret;
- if (!xmlCatalogInitialized)
- xmlInitializeCatalog();
- if (URI == NULL)
- return(NULL);
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Resolve URI %s\n", URI);
- catal = (xmlCatalogEntryPtr) catalogs;
- if (catal == NULL)
- return(NULL);
- ret = xmlCatalogListXMLResolveURI(catal, URI);
- if ((ret != NULL) && (ret != XML_CATAL_BREAK))
- return(ret);
- return(NULL);
- }
- /************************************************************************
- * *
- * Deprecated interfaces *
- * *
- ************************************************************************/
- /**
- * xmlCatalogGetSystem:
- * @sysID: the system ID string
- *
- * Try to lookup the catalog reference associated to a system ID
- * DEPRECATED, use xmlCatalogResolveSystem()
- *
- * Returns the resource if found or NULL otherwise.
- */
- const xmlChar *
- xmlCatalogGetSystem(const xmlChar *sysID) {
- xmlChar *ret;
- static xmlChar result[1000];
- static int msg = 0;
- if (!xmlCatalogInitialized)
- xmlInitializeCatalog();
- if (msg == 0) {
- xmlGenericError(xmlGenericErrorContext,
- "Use of deprecated xmlCatalogGetSystem() call\n");
- msg++;
- }
- if (sysID == NULL)
- return(NULL);
- /*
- * Check first the XML catalogs
- */
- if (xmlDefaultCatalog != NULL) {
- ret = xmlCatalogListXMLResolve(xmlDefaultCatalog->xml, NULL, sysID);
- if ((ret != NULL) && (ret != XML_CATAL_BREAK)) {
- snprintf((char *) result, sizeof(result) - 1, "%s", (char *) ret);
- result[sizeof(result) - 1] = 0;
- return(result);
- }
- }
- if (xmlDefaultCatalog != NULL)
- return(xmlCatalogGetSGMLSystem(xmlDefaultCatalog->sgml, sysID));
- return(NULL);
- }
- /**
- * xmlCatalogGetPublic:
- * @pubID: the public ID string
- *
- * Try to lookup the catalog reference associated to a public ID
- * DEPRECATED, use xmlCatalogResolvePublic()
- *
- * Returns the resource if found or NULL otherwise.
- */
- const xmlChar *
- xmlCatalogGetPublic(const xmlChar *pubID) {
- xmlChar *ret;
- static xmlChar result[1000];
- static int msg = 0;
- if (!xmlCatalogInitialized)
- xmlInitializeCatalog();
- if (msg == 0) {
- xmlGenericError(xmlGenericErrorContext,
- "Use of deprecated xmlCatalogGetPublic() call\n");
- msg++;
- }
- if (pubID == NULL)
- return(NULL);
- /*
- * Check first the XML catalogs
- */
- if (xmlDefaultCatalog != NULL) {
- ret = xmlCatalogListXMLResolve(xmlDefaultCatalog->xml, pubID, NULL);
- if ((ret != NULL) && (ret != XML_CATAL_BREAK)) {
- snprintf((char *) result, sizeof(result) - 1, "%s", (char *) ret);
- result[sizeof(result) - 1] = 0;
- return(result);
- }
- }
- if (xmlDefaultCatalog != NULL)
- return(xmlCatalogGetSGMLPublic(xmlDefaultCatalog->sgml, pubID));
- return(NULL);
- }
- #define bottom_catalog
- #include "elfgcchack.h"
- #endif /* LIBXML_CATALOG_ENABLED */
|