2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: SOEntityCatalog.C /main/1 1996/07/29 17:03:30 cde-hp $ */
24 // Copyright (c) 1994, 1995, 1996 James Clark
25 // See the file COPYING for copying permission.
28 #pragma implementation
32 #include "CharsetInfo.h"
33 #include "MessageArg.h"
34 #include "CatalogMessages.h"
35 #include "SOEntityCatalog.h"
36 #include "EntityDecl.h"
37 #include "EntityCatalog.h"
41 #include "HashTable.h"
42 #include "InputSource.h"
44 #include "SubstTable.h"
45 #include "CatalogEntry.h"
47 #include "StorageManager.h"
51 namespace SP_NAMESPACE {
55 class SOEntityCatalog;
57 class SOCatalogManagerImpl : public SOCatalogManager {
59 SOCatalogManagerImpl(const Vector<StringC> &sysids,
60 size_t nSysidsMustExist,
61 const CharsetInfo &sysidCharset,
62 const CharsetInfo &catalogCharset);
63 ConstPtr<EntityCatalog> makeCatalog(StringC &systemId,
64 const CharsetInfo &charset,
65 ExtendEntityManager *,
67 Boolean mapCatalog(ParsedSystemId &systemId,
68 ExtendEntityManager *em,
69 Messenger &mgr) const;
71 void addCatalogsForDocument(CatalogParser &parser,
74 const CharsetInfo &charset,
75 Messenger &mgr) const;
76 size_t nSystemCatalogsMustExist_;
77 Vector<StringC> systemCatalogs_;
78 CharsetInfo sysidCharset_;
79 CharsetInfo catalogCharset_;
82 class SOEntityCatalog : public EntityCatalog {
84 SOEntityCatalog(Ptr<ExtendEntityManager> em);
85 typedef EntityDecl::DeclType DeclType;
86 Boolean document(const CharsetInfo &, Messenger &, StringC &) const;
87 Boolean sgmlDecl(const CharsetInfo &, Messenger &, StringC &) const;
88 Boolean defaultDoctype(const CharsetInfo &,
92 Boolean lookup(const EntityDecl &entity,
97 Boolean lookupPublic(const StringC &,
101 void addPublicId(StringC &publicId, StringC &systemId, const Location &,
103 void addDelegate(StringC &prefix, StringC &systemId, const Location &,
105 void addSystemId(StringC &systemId, StringC &replSystemId, const Location &);
106 void addName(StringC &name, DeclType, StringC &systemId, const Location &,
108 void setSgmlDecl(StringC &str, const Location &loc);
109 void setDocument(StringC &str, const Location &loc);
110 void setBase(const Location &loc);
112 const Ptr<ExtendEntityManager> &entityManager() {
116 SOEntityCatalog(const SOEntityCatalog &); // undefined
117 void operator=(const SOEntityCatalog &); // undefined
119 Boolean expandCatalogSystemId(const StringC &str,
123 const CharsetInfo &charset,
124 const StringC *lookupPublicId,
126 StringC &result) const;
128 findBestPublicEntry(const StringC &publicId, Boolean overrideOnly,
129 const CharsetInfo &charset, Boolean &delegated) const;
134 const CatalogEntry *lookup(const StringC &, Boolean overrideOnly) const;
135 const CatalogEntry *lookup(const StringC &key,
136 const SubstTable<Char> &substTable,
137 Boolean overrideOnly) const;
138 void insert(const StringC &, const CatalogEntry &, Boolean override);
139 size_t count() const;
141 Table(const Table &); // undefined
142 void operator=(const Table &); // undefined
143 // These are entries that are applicable when an explicit system id
144 // was specified in the external identifier.
145 HashTable<StringC,CatalogEntry> overrideEntries_;
146 // This specifies the entries that should substitute for the
147 // overrideEntries_ when an explicit system identifier was not specified.
148 HashTable<StringC,CatalogEntry> normalEntries_;
153 HashTable<StringC,CatalogEntry> systemIds_;
155 size_t catalogNumber_;
156 Boolean haveSgmlDecl_;
158 Location sgmlDeclLoc_;
159 size_t sgmlDeclBaseNumber_;
161 Boolean haveDocument_;
162 Location documentLoc_;
163 size_t documentBaseNumber_;
164 StringC defaultDoctype_;
165 Boolean haveCurrentBase_;
166 Vector<Location> base_;
167 Ptr<ExtendEntityManager> em_;
170 class CatalogParser : private Messenger {
172 CatalogParser(const CharsetInfo &);
173 void parseCatalog(const StringC &sysid,
175 const CharsetInfo &sysidCharset,
176 const CharsetInfo &catalogCharset,
177 InputSourceOrigin *origin,
178 SOEntityCatalog *catalog,
181 // Since it's a return type, it has to be public to keep some
182 // (broken) compilers happy.
198 min // other minimum data characters
200 enum { minimumLiteral = 01 };
202 Messenger &messenger() { return *this; }
203 void dispatchMessage(Message &);
204 void dispatchMessage(const Message &);
205 void initMessage(Message &);
207 void parseDelegate();
209 void parseNameMap(EntityDecl::DeclType declType);
210 void parseOverride();
211 Param parseParam(unsigned flags = 0);
213 void parseLiteral(Char delim, unsigned flags);
216 void upcase(StringC &);
217 Boolean inLoop(const Location &loc);
218 Boolean isMinimumData(Xchar c) {
219 int cat = categoryTable_[c];
220 return (cat == min || (cat == s && c != tab_)
221 || cat == minus || cat == lita);
223 Xchar get() { return in_->get(messenger()); }
224 void unget() { in_->ungetToken(); }
227 SOEntityCatalog *catalog_;
239 StringC linktypeKey_;
240 StringC notationKey_;
241 StringC overrideKey_;
242 StringC sgmlDeclKey_;
243 StringC documentKey_;
248 StringC delegateKey_;
249 XcharMap<unsigned char> categoryTable_;
250 SubstTable<Char> substTable_;
254 ExtendEntityManager::CatalogManager *
255 SOCatalogManager::make(const Vector<StringC> &sysids,
256 size_t nSysidsMustExist,
257 const CharsetInfo &sysidCharset,
258 const CharsetInfo &catalogCharset)
260 return new SOCatalogManagerImpl(sysids,
266 SOCatalogManagerImpl::SOCatalogManagerImpl(const Vector<StringC> &systemCatalogs,
267 size_t nSystemCatalogsMustExist,
268 const CharsetInfo &sysidCharset,
269 const CharsetInfo &catalogCharset)
270 : systemCatalogs_(systemCatalogs),
271 nSystemCatalogsMustExist_(nSystemCatalogsMustExist),
272 sysidCharset_(sysidCharset),
273 catalogCharset_(catalogCharset)
277 Boolean SOCatalogManagerImpl::mapCatalog(ParsedSystemId &systemId,
278 ExtendEntityManager *em,
279 Messenger &mgr) const
281 Vector<ParsedSystemIdMap> maps;
282 systemId.maps.swap(maps);
283 while (maps.size() > 0) {
284 StringC catalogSystemId;
285 systemId.unparse(sysidCharset_, catalogSystemId);
286 SOEntityCatalog *catalog = new SOEntityCatalog(em);
287 ConstPtr<EntityCatalog> deleter(catalog);
288 CatalogParser parser(catalogCharset_);
289 parser.parseCatalog(catalogSystemId, 1, sysidCharset_, catalogCharset_,
290 new InputSourceOrigin, catalog, mgr);
291 // FIXME do catalog caching here
293 if (maps.back().type == ParsedSystemIdMap::catalogDocument) {
294 if (!catalog->document(sysidCharset_, mgr, s)) {
295 mgr.message(CatalogMessages::noDocumentEntry,
296 StringMessageArg(catalogSystemId));
301 ASSERT(maps.back().type == ParsedSystemIdMap::catalogPublic);
302 if (!catalog->lookupPublic(maps.back().publicId, sysidCharset_, mgr,
304 mgr.message(CatalogMessages::noPublicEntry,
305 StringMessageArg(maps.back().publicId),
306 StringMessageArg(catalogSystemId));
311 if (!em->parseSystemId(s, sysidCharset_, 0, 0, mgr, tem))
314 maps.resize(maps.size() - 1);
315 for (size_t i = 0; i < systemId.maps.size(); i++)
316 maps.push_back(systemId.maps[i]);
317 systemId.maps.clear();
322 ConstPtr<EntityCatalog>
323 SOCatalogManagerImpl::makeCatalog(StringC &systemId,
324 const CharsetInfo &charset,
325 ExtendEntityManager *em,
326 Messenger &mgr) const
328 SOEntityCatalog *entityCatalog = new SOEntityCatalog(em);
329 CatalogParser parser(catalogCharset_);
331 for (i = 0; i < nSystemCatalogsMustExist_; i++)
332 parser.parseCatalog(systemCatalogs_[i], 1,
333 sysidCharset_, catalogCharset_,
334 new InputSourceOrigin, entityCatalog,
336 addCatalogsForDocument(parser, systemId, entityCatalog, charset, mgr);
337 for (i = nSystemCatalogsMustExist_; i < systemCatalogs_.size(); i++)
338 parser.parseCatalog(systemCatalogs_[i], 0,
339 sysidCharset_, catalogCharset_,
340 new InputSourceOrigin, entityCatalog,
343 return entityCatalog;
347 void SOCatalogManagerImpl::addCatalogsForDocument(CatalogParser &parser,
349 SOEntityCatalog *impl,
350 const CharsetInfo &charset,
351 Messenger &mgr) const
354 if (!impl->entityManager()->parseSystemId(sysid, charset, 0, 0, mgr, v))
356 if (v.maps.size() > 0) {
357 if (v.maps[0].type == ParsedSystemIdMap::catalogDocument) {
358 v.maps.erase(v.maps.begin(), v.maps.begin() + 1);
360 v.unparse(charset, tem);
361 parser.parseCatalog(tem, 1, charset, catalogCharset_,
362 new InputSourceOrigin, impl, mgr);
363 if (!impl->document(charset, mgr, sysid)) {
364 mgr.message(CatalogMessages::noDocumentEntry, StringMessageArg(tem));
370 Vector<StringC> catalogs;
372 for (i = 0; i < v.size(); i++)
373 if (v[i].storageManager->inheritable()) {
374 ParsedSystemId catalogId;
376 StorageObjectSpec &spec = catalogId.back();
377 spec.storageManager = v[i].storageManager;
378 spec.codingSystemName = v[i].codingSystemName;
379 spec.specId = spec.storageManager->idCharset()->execToDesc("catalog");
380 spec.storageManager->resolveRelative(v[i].specId, spec.specId, 0);
381 spec.baseId = v[i].baseId;
382 spec.records = v[i].records;
384 catalogId.unparse(charset, tem);
385 for (size_t j = 0; j < catalogs.size(); j++)
386 if (tem == catalogs[j]) {
390 if (tem.size() > 0) {
391 catalogs.resize(catalogs.size() + 1);
392 tem.swap(catalogs.back());
395 for (i = 0; i < catalogs.size(); i++)
396 parser.parseCatalog(catalogs[i], 0, charset,
397 catalogCharset_, new InputSourceOrigin, impl,
401 SOEntityCatalog::SOEntityCatalog(Ptr<ExtendEntityManager> em)
402 : em_(em), catalogNumber_(0), haveSgmlDecl_(0), haveDocument_(0),
403 haveCurrentBase_(0), sgmlDeclBaseNumber_(0), documentBaseNumber_(0)
407 void SOEntityCatalog::endCatalog()
410 haveCurrentBase_ = 0;
413 Boolean SOEntityCatalog::expandCatalogSystemId(const StringC &str,
417 const CharsetInfo &charset,
418 const StringC *lookupPublicId,
420 StringC &result) const
422 return em_->expandSystemId(str,
423 (baseNumber ? base_[baseNumber - 1] : loc),
431 Boolean SOEntityCatalog::lookup(const EntityDecl &entity,
432 const Syntax &syntax,
433 const CharsetInfo &charset,
435 StringC &result) const
437 const CatalogEntry *entry = 0;
438 const CatalogEntry *delegatedEntry = 0;
439 if (entity.systemIdPointer())
440 entry = systemIds_.lookup(*entity.systemIdPointer());
441 if (entity.publicIdPointer()) {
442 const CatalogEntry *publicEntry;
444 publicEntry = findBestPublicEntry(*entity.publicIdPointer(),
445 entity.systemIdPointer() != 0,
448 if (publicEntry && delegated)
449 delegatedEntry = publicEntry;
450 // match for system id has priority over match for public id in same
453 && (!entry || publicEntry->catalogNumber < entry->catalogNumber))
456 if (entity.name().size() > 0
457 && (!entry || entry->catalogNumber > 0)) {
458 const CatalogEntry *entityEntry;
459 int tableIndex = (entity.declType() >= EntityDecl::parameterEntity
460 ? int(entity.declType()) - 1
461 : int(entity.declType()));
462 StringC name(entity.name());
464 switch (entity.declType()) {
465 case EntityDecl::parameterEntity:
468 name = syntax.peroDelim();
472 case EntityDecl::generalEntity:
473 subst = syntax.namecaseEntity();
476 subst = syntax.namecaseGeneral();
480 entityEntry = names_[tableIndex].lookup(name,
481 entity.systemIdPointer() != 0);
483 entityEntry = names_[tableIndex].lookup(entity.name(),
484 syntax.upperSubstTable(),
485 entity.systemIdPointer() != 0);
486 // match for public id has priority over match for entity in same
489 && (!entry || entityEntry->catalogNumber < entry->catalogNumber))
493 return expandCatalogSystemId(entry->to,
496 entity.dataType() == EntityDecl::ndata,
498 entry == delegatedEntry
499 ? entity.publicIdPointer()
503 if (entity.systemIdPointer())
504 return em_->expandSystemId(*entity.systemIdPointer(),
505 entity.defLocation(),
506 entity.dataType() == EntityDecl::ndata,
514 Boolean SOEntityCatalog::lookupPublic(const StringC &publicId,
515 const CharsetInfo &charset,
517 StringC &result) const
520 const CatalogEntry *entry = findBestPublicEntry(publicId, 0, charset,
523 && expandCatalogSystemId(entry->to, entry->loc, entry->baseNumber,
524 0, charset, delegated ? &publicId : 0,
530 SOEntityCatalog::findBestPublicEntry(const StringC &publicId,
531 Boolean overrideOnly,
532 const CharsetInfo &charset,
533 Boolean &delegated) const
535 Char slash = charset.execToDesc('/');
536 Char colon = charset.execToDesc(':');
537 const CatalogEntry *bestEntry = 0;
538 for (size_t i = 0; i <= publicId.size(); i++) {
539 if ((i + 1 < publicId.size()
540 && (publicId[i] == slash || publicId[i] == colon)
541 && publicId[i + 1] == publicId[i])
543 && (publicId[i - 1] == slash || publicId[i - 1] == colon)
544 && publicId[i - 2] == publicId[i - 1])) {
545 StringC tem(publicId.data(), i);
546 const CatalogEntry *entry = delegates_.lookup(tem, overrideOnly);
549 || entry->catalogNumber <= bestEntry->catalogNumber)) {
555 const CatalogEntry *entry = publicIds_.lookup(publicId, overrideOnly);
557 && (!bestEntry || entry->catalogNumber <= bestEntry->catalogNumber)) {
564 Boolean SOEntityCatalog::sgmlDecl(const CharsetInfo &charset,
566 StringC &result) const
569 return haveSgmlDecl_ && expandCatalogSystemId(sgmlDecl_, sgmlDeclLoc_,
571 0, charset, 0, mgr, result);
574 Boolean SOEntityCatalog::document(const CharsetInfo &charset,
576 StringC &result) const
579 return haveDocument_ && expandCatalogSystemId(document_, documentLoc_,
581 0, charset, 0, mgr, result);
584 Boolean SOEntityCatalog::defaultDoctype(const CharsetInfo &charset,
587 StringC &sysid) const
589 if (defaultDoctype_.size() == 0)
591 int tableIndex = EntityDecl::doctype;
592 if (tableIndex >= EntityDecl::parameterEntity)
594 const CatalogEntry *entry
595 = names_[tableIndex].lookup(defaultDoctype_, 0);
596 name = defaultDoctype_;
597 return expandCatalogSystemId(entry->to,
607 void SOEntityCatalog::addPublicId(StringC &publicId, StringC &systemId,
608 const Location &loc, Boolean override)
612 entry.catalogNumber = catalogNumber_;
613 entry.baseNumber = haveCurrentBase_ ? base_.size() : 0;
614 systemId.swap(entry.to);
615 publicIds_.insert(publicId, entry, override);
618 void SOEntityCatalog::addDelegate(StringC &prefix, StringC &systemId,
619 const Location &loc, Boolean override)
623 entry.catalogNumber = catalogNumber_;
624 entry.baseNumber = haveCurrentBase_ ? base_.size() : 0;
625 systemId.swap(entry.to);
626 delegates_.insert(prefix, entry, override);
629 void SOEntityCatalog::addSystemId(StringC &systemId, StringC &toSystemId,
634 entry.catalogNumber = catalogNumber_;
635 entry.baseNumber = haveCurrentBase_ ? base_.size() : 0;
636 toSystemId.swap(entry.to);
637 systemIds_.insert(systemId, entry, false);
640 void SOEntityCatalog::addName(StringC &name, DeclType declType,
641 StringC &systemId, const Location &loc,
644 if (declType == EntityDecl::doctype
645 && defaultDoctype_.size() == 0)
646 defaultDoctype_ = name;
649 entry.catalogNumber = catalogNumber_;
650 entry.baseNumber = haveCurrentBase_ ? base_.size() : 0;
651 int tableIndex = (declType >= EntityDecl::parameterEntity
654 entry.serial = names_[tableIndex].count();
655 systemId.swap(entry.to);
656 names_[tableIndex].insert(name, entry, override);
659 void SOEntityCatalog::setSgmlDecl(StringC &str, const Location &loc)
661 if (!haveSgmlDecl_) {
662 haveSgmlDecl_ = true;
665 sgmlDeclBaseNumber_ = haveCurrentBase_ ? base_.size() : 0;
670 void SOEntityCatalog::setDocument(StringC &str, const Location &loc)
672 if (!haveDocument_) {
673 haveDocument_ = true;
676 documentBaseNumber_ = haveCurrentBase_ ? base_.size() : 0;
680 void SOEntityCatalog::setBase(const Location &loc)
682 if (loc.origin().isNull())
683 haveCurrentBase_ = 0;
685 haveCurrentBase_ = 1;
686 base_.push_back(loc);
690 SOEntityCatalog::Table::Table()
694 void SOEntityCatalog::Table::insert(const StringC &key,
695 const CatalogEntry &entry,
699 overrideEntries_.insert(key, entry, false);
701 const CatalogEntry *e = overrideEntries_.lookup(key);
703 normalEntries_.insert(key, entry, false);
707 const CatalogEntry *SOEntityCatalog::Table::lookup(const StringC &key,
708 Boolean overrideOnly) const
711 const CatalogEntry *e = normalEntries_.lookup(key);
715 return overrideEntries_.lookup(key);
719 SOEntityCatalog::Table::lookup(const StringC &name,
720 const SubstTable<Char> &substTable,
721 Boolean overrideOnly) const
723 HashTableIter<StringC,CatalogEntry> iter1(overrideEntries_);
724 HashTableIter<StringC,CatalogEntry> iter2(normalEntries_);
725 HashTableIter<StringC,CatalogEntry> *iters[2];
727 iters[nIter++] = &iter1;
729 iters[nIter++] = &iter2;
730 const CatalogEntry *entry = 0;
731 for (int i = 0; i < nIter; i++) {
732 HashTableIter<StringC,CatalogEntry> &iter = *iters[i];
734 const CatalogEntry *value;
736 while (iter.next(key, value)) {
738 for (size_t j = 0; j < buffer.size(); j++)
739 substTable.subst(buffer[j]);
740 if (buffer == name) {
741 if (!entry || value->serial < entry->serial)
749 size_t SOEntityCatalog::Table::count() const
751 return normalEntries_.count() + overrideEntries_.count();
754 CatalogParser::CatalogParser(const CharsetInfo &charset)
755 : categoryTable_(data),
756 entityKey_(charset.execToDesc("ENTITY")),
757 publicKey_(charset.execToDesc("PUBLIC")),
758 systemKey_(charset.execToDesc("SYSTEM")),
759 doctypeKey_(charset.execToDesc("DOCTYPE")),
760 linktypeKey_(charset.execToDesc("LINKTYPE")),
761 notationKey_(charset.execToDesc("NOTATION")),
762 overrideKey_(charset.execToDesc("OVERRIDE")),
763 sgmlDeclKey_(charset.execToDesc("SGMLDECL")),
764 documentKey_(charset.execToDesc("DOCUMENT")),
765 catalogKey_(charset.execToDesc("CATALOG")),
766 yesKey_(charset.execToDesc("YES")),
767 noKey_(charset.execToDesc("NO")),
768 baseKey_(charset.execToDesc("BASE")),
769 delegateKey_(charset.execToDesc("DELEGATE"))
771 static const char lcletters[] = "abcdefghijklmnopqrstuvwxyz";
772 static const char ucletters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
773 // minimum data other than lcletter, ucletter
774 static const char minChars[] = "0123456789-.'()+,/:=?";
775 static const char sChars[] = " \n\r\t";
776 categoryTable_.setChar(0, nul);
779 for (p = lcletters, q = ucletters; *p; p++, q++) {
780 Char lc = charset.execToDesc(*p);
781 Char uc = charset.execToDesc(*q);
782 substTable_.addSubst(lc, uc);
783 categoryTable_.setChar(lc, min);
784 categoryTable_.setChar(uc, min);
786 for (p = sChars; *p; p++)
787 categoryTable_.setChar(charset.execToDesc(*p), s);
788 for (p = minChars; *p; p++)
789 categoryTable_.setChar(charset.execToDesc(*p), min);
790 categoryTable_.setChar(charset.execToDesc('\''), lita);
791 categoryTable_.setChar(charset.execToDesc('"'), lit);
792 minus_ = charset.execToDesc('-');
793 categoryTable_.setChar(minus_, minus);
794 tab_ = charset.execToDesc('\t');
795 re_ = charset.execToDesc('\r');
796 rs_ = charset.execToDesc('\n');
797 space_ = charset.execToDesc(' ');
798 categoryTable_.setEe(eof);
801 void CatalogParser::parseCatalog(const StringC &sysid,
803 const CharsetInfo &sysidCharset,
804 const CharsetInfo &catalogCharset,
805 InputSourceOrigin *origin,
806 SOEntityCatalog *catalog,
809 const Ptr<ExtendEntityManager> &em = catalog->entityManager();
811 ? em->open(sysid, sysidCharset, origin, 0, mgr)
812 : em->openIfExists(sysid, sysidCharset, origin, 0, mgr));
818 Boolean recovering = false;
819 Vector<StringC> subSysids;
820 Vector<Location> subSysidLocs;
822 Param parm = parseParam();
823 if (parm == nameParam) {
826 if (param_ == publicKey_)
828 else if (param_ == systemKey_)
830 else if (param_ == entityKey_)
831 parseNameMap(EntityDecl::generalEntity);
832 else if (param_ == doctypeKey_)
833 parseNameMap(EntityDecl::doctype);
834 else if (param_ == linktypeKey_)
835 parseNameMap(EntityDecl::linktype);
836 else if (param_ == notationKey_)
837 parseNameMap(EntityDecl::notation);
838 else if (param_ == sgmlDeclKey_) {
840 catalog_->setSgmlDecl(param_, paramLoc_);
842 else if (param_ == documentKey_) {
844 catalog_->setDocument(param_, paramLoc_);
846 else if (param_ == overrideKey_)
848 else if (param_ == catalogKey_) {
850 if (inLoop(paramLoc_))
852 subSysids.resize(subSysids.size() + 1);
853 param_.swap(subSysids.back());
854 subSysidLocs.push_back(paramLoc_);
857 else if (param_ == baseKey_) {
860 if (em->expandSystemId(param_,
867 InputSource *in = em->open(tem,
869 new InputSourceOrigin(paramLoc_),
873 catalog->setBase(in->currentLocation());
877 else if (param_ == delegateKey_)
880 if (parseParam() == eofParam)
885 else if (parm == eofParam)
887 else if (!recovering) {
889 message(CatalogMessages::nameExpected);
893 catalog->endCatalog();
894 for (size_t i = 0; i < subSysids.size(); i++) {
896 if (em->expandSystemId(subSysids[i], subSysidLocs[i], 0, catalogCharset,
898 parseCatalog(tem, 1, catalogCharset, catalogCharset,
899 new InputSourceOrigin(subSysidLocs[i]), catalog, mgr);
903 Boolean CatalogParser::inLoop(const Location &loc)
905 const InputSourceOrigin *origin = paramLoc_.origin()->asInputSourceOrigin();
908 const ExternalInfo *info = origin->externalInfo();
911 StorageObjectLocation soLoc;
912 if (!ExtendEntityManager::externalize(info,
913 origin->startOffset(paramLoc_.index()),
917 const Location &parent = origin->parent();
918 if (parent.origin().isNull())
920 origin = parent.origin()->asInputSourceOrigin();
923 const ExternalInfo *info1 = origin->externalInfo();
925 StorageObjectLocation soLoc1;
926 if (ExtendEntityManager::externalize(info1,
927 origin->startOffset(parent.index()),
929 const StorageObjectSpec *sos = soLoc.storageObjectSpec;
930 const StorageObjectSpec *sos1 = soLoc1.storageObjectSpec;
931 if (sos->storageManager == sos1->storageManager
932 && sos->id == sos1->id) {
933 setNextLocation(loc.origin()->parent());
934 message(CatalogMessages::inLoop);
943 void CatalogParser::parseOverride()
945 if (parseParam() != nameParam) {
946 message(CatalogMessages::overrideYesOrNo);
950 if (param_ == yesKey_)
952 else if (param_ == noKey_)
955 message(CatalogMessages::overrideYesOrNo);
958 void CatalogParser::parsePublic()
960 if (parseParam(minimumLiteral) != literalParam) {
961 message(CatalogMessages::literalExpected);
965 param_.swap(publicId);
968 catalog_->addPublicId(publicId, param_, paramLoc_, override_);
971 void CatalogParser::parseDelegate()
973 if (parseParam(minimumLiteral) != literalParam) {
974 message(CatalogMessages::literalExpected);
978 param_.swap(publicId);
981 catalog_->addDelegate(publicId, param_, paramLoc_, override_);
984 void CatalogParser::parseSystem()
989 param_.swap(systemId);
990 Param parm = parseParam();
991 if (parm == nameParam)
992 message(CatalogMessages::systemShouldQuote);
993 else if (parm != literalParam) {
994 message(CatalogMessages::literalExpected);
997 catalog_->addSystemId(systemId, param_, paramLoc_);
1000 void CatalogParser::parseNameMap(EntityDecl::DeclType declType)
1008 catalog_->addName(name, declType, param_, paramLoc_, override_);
1011 Boolean CatalogParser::parseArg()
1013 Param parm = parseParam();
1014 if (parm != nameParam && parm != literalParam) {
1015 message(CatalogMessages::nameOrLiteralExpected);
1021 CatalogParser::Param CatalogParser::parseParam(unsigned flags)
1025 switch (categoryTable_[c]) {
1030 parseLiteral(c, flags);
1031 return literalParam;
1035 message(CatalogMessages::nulChar);
1052 void CatalogParser::skipComment()
1061 if (c == InputSource::eE) {
1062 message(CatalogMessages::eofInComment);
1068 void CatalogParser::parseLiteral(Char delim, unsigned flags)
1070 paramLoc_ = in_->currentLocation();
1071 enum { no, yesBegin, yesMiddle } skipping = yesBegin;
1075 if (c == InputSource::eE) {
1076 message(CatalogMessages::eofInLiteral);
1079 if (Char(c) == delim)
1081 if (flags & minimumLiteral) {
1082 if (!isMinimumData(c))
1083 message(CatalogMessages::minimumData);
1086 else if (c == space_ || c == re_) {
1087 if (skipping == no) {
1089 skipping = yesMiddle;
1100 if (skipping == yesMiddle)
1101 param_.resize(param_.size() - 1);
1104 void CatalogParser::parseName()
1106 paramLoc_ = in_->currentLocation();
1108 for (length = 1;; length++) {
1109 Xchar c = in_->tokenChar(messenger());
1110 int cat = categoryTable_[c];
1111 if (cat == eof || cat == s)
1113 // FIXME maybe check for LIT or LITA
1115 message(CatalogMessages::nulChar);
1117 in_->endToken(length);
1118 param_.assign(in_->currentTokenStart(), in_->currentTokenLength());
1121 void CatalogParser::upcase(StringC &str)
1123 for (size_t i = 0; i < str.size(); i++)
1124 substTable_.subst(str[i]);
1127 void CatalogParser::dispatchMessage(const Message &msg)
1129 mgr_->dispatchMessage(msg);
1132 void CatalogParser::dispatchMessage(Message &msg)
1134 mgr_->dispatchMessage(msg);
1137 void CatalogParser::initMessage(Message &msg)
1139 msg.loc = in_->currentLocation();