Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / programs / nsgmls / Parser.C
1 /* $XConsortium: Parser.C /main/1 1996/07/29 17:00:24 cde-hp $ */
2 // Copyright (c) 1994 James Clark
3 // See the file COPYING for copying permission.
4
5 #ifdef __GNUG__
6 #pragma implementation
7 #endif
8
9 #include "splib.h"
10 #include "Parser.h"
11 #include "ParserMessages.h"
12 #include "constant.h"
13
14 #ifdef SP_NAMESPACE
15 namespace SP_NAMESPACE {
16 #endif
17
18 Parser::Parser(const SgmlParser::Params &params)
19 : ParserState(params.parent
20               ? params.parent->parser_->entityManagerPtr()
21               : params.entityManager,
22               params.options
23               ? *params.options
24               : params.parent->parser_->options(),
25               paramsSubdocLevel(params),
26               params.entityType == SgmlParser::Params::dtd
27               ? declSubsetPhase
28               : contentPhase)
29 {
30   Parser *parent = 0;
31   if (params.parent)
32     parent = params.parent->parser_;
33   if (params.entityType == SgmlParser::Params::document) {
34     Sd *sd = new Sd();
35     const ParserOptions &opt = *params.options;
36     sd->setDocCharsetDesc(*params.initialCharset);
37     sd->setBooleanFeature(Sd::fDATATAG, opt.datatag);
38     sd->setBooleanFeature(Sd::fOMITTAG, opt.omittag);
39     sd->setBooleanFeature(Sd::fRANK, opt.rank);
40     sd->setBooleanFeature(Sd::fSHORTTAG, opt.shorttag);
41     sd->setNumberFeature(Sd::fSIMPLE, opt.linkSimple);
42     sd->setBooleanFeature(Sd::fIMPLICIT, opt.linkImplicit);
43     sd->setNumberFeature(Sd::fEXPLICIT, opt.linkExplicit);
44     sd->setNumberFeature(Sd::fCONCUR, opt.concur);
45     sd->setNumberFeature(Sd::fSUBDOC, opt.subdoc);
46     sd->setBooleanFeature(Sd::fFORMAL, opt.formal);
47     PublicId publicId;
48     CharsetDecl docCharsetDecl;
49     docCharsetDecl.addSection(publicId);
50     docCharsetDecl.addRange(0, charMax > 99999999 ? 99999999 : charMax + 1, 0);
51     sd->setDocCharsetDecl(docCharsetDecl);
52     setSd(sd);
53   }
54   else if (params.sd.isNull()) {
55     setSd(parent->sdPointer());
56     setSyntaxes(parent->prologSyntaxPointer(),
57                 parent->instanceSyntaxPointer());
58   }
59   else {
60     setSd(params.sd);
61     setSyntaxes(params.prologSyntax, params.instanceSyntax);
62   }
63
64   // Make catalog
65   StringC sysid(params.sysid);
66   ConstPtr<EntityCatalog> catalog
67     = entityManager().makeCatalog(sysid,
68                                   sd().docCharset(),
69                                   messenger());
70   if (!catalog.isNull())
71     setEntityCatalog(catalog);
72   else if (parent)
73     setEntityCatalog(parent->entityCatalogPtr());
74   else {
75     allDone();
76     return;
77   }
78   
79   // Set up the input stack.
80   if (sysid.size() == 0) {
81     allDone();
82     return;
83   }
84   Ptr<InputSourceOrigin> origin;
85   if (params.origin.isNull())
86     origin = new InputSourceOrigin;
87   else
88     origin = params.origin;
89   pushInput(entityManager().open(sysid,
90                                  sd().docCharset(),
91                                  origin.pointer(),
92                                  1,
93                                  messenger()));
94   if (inputLevel() == 0) {
95     allDone();
96     return;
97   }
98   switch (params.entityType) {
99   case SgmlParser::Params::document:
100     setPhase(initPhase);
101     break;
102   case SgmlParser::Params::subdoc:
103     if (params.subdocInheritActiveLinkTypes && parent)
104       inheritActiveLinkTypes(*parent);
105     if (subdocLevel() == sd().subdoc() + 1)
106       message(ParserMessages::subdocLevel, NumberMessageArg(sd().subdoc()));
107     setPhase(prologPhase);
108     compilePrologModes();
109     break;
110   case SgmlParser::Params::dtd:
111     compilePrologModes();
112     startDtd(params.doctypeName);
113     setPhase(declSubsetPhase);
114     break;
115   }
116 }
117
118 void Parser::giveUp()
119 {
120   if (subdocLevel() > 0)        // FIXME might be subdoc if level == 0
121     message(ParserMessages::subdocGiveUp);
122   else
123     message(ParserMessages::giveUp);
124   allDone();
125 }
126
127 unsigned Parser::paramsSubdocLevel(const SgmlParser::Params &params)
128 {
129   if (!params.parent)
130     return 0;
131   unsigned n = params.parent->parser_->subdocLevel();
132   if (params.subdocReferenced)
133     return n + 1;
134   else
135     return n;
136 }
137
138 Event *Parser::nextEvent()
139 {
140   while (eventQueueEmpty()) {
141     switch (phase()) {
142     case noPhase:
143       return 0;
144     case initPhase:
145       doInit();
146       break;
147     case prologPhase:
148       doProlog();
149       break;
150     case declSubsetPhase:
151       doDeclSubset();
152       break;
153     case instanceStartPhase:
154       doInstanceStart();
155       break;
156     case contentPhase:
157       doContent();
158       break;
159     }
160   }
161   return eventQueueGet();
162 }
163
164 void Parser::parseAll(EventHandler &handler,
165                       SP_CONST SP_VOLATILE sig_atomic_t *cancelPtr)
166 {
167   while (!eventQueueEmpty())
168     eventQueueGet()->handle(handler);
169   // FIXME catch exceptions and reset handler.
170   setHandler(&handler, cancelPtr);
171   for (;;) {
172     switch (phase()) {
173     case noPhase:
174       unsetHandler();
175       return;
176     case initPhase:
177       doInit();
178       break;
179     case prologPhase:
180       doProlog();
181       break;
182     case declSubsetPhase:
183       doDeclSubset();
184       break;
185     case instanceStartPhase:
186       doInstanceStart();
187       break;
188     case contentPhase:
189       doContent();
190       break;
191     }
192   }
193 }
194
195 #ifdef SP_NAMESPACE
196 }
197 #endif