12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830 |
- /**
- * 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 */
|