rpc.cmsd: use TIRPC on Linux
[oweals/cde.git] / cde / programs / nsgmls / ContentState.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
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)
10  * any later version.
11  *
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
16  * details.
17  *
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
22  */
23 /* $XConsortium: ContentState.C /main/1 1996/07/29 16:48:21 cde-hp $ */
24 // Copyright (c) 1994, 1996 James Clark
25 // See the file COPYING for copying permission.
26
27 #ifdef __GNUG__
28 #pragma implementation
29 #endif
30
31 #include "splib.h"
32 #include "ContentState.h"
33 #include "IListIter.h"
34 #include "NCVector.h"
35 #include "macros.h"
36
37 #ifdef SP_NAMESPACE
38 namespace SP_NAMESPACE {
39 #endif
40
41 const ShortReferenceMap ContentState::theEmptyMap;
42
43 #ifdef __GNUG__
44 typedef IListIter<OpenElement> Dummy_IListIter_OpenElement;
45 #endif
46
47 ContentState::ContentState()
48 : documentElementContainer_(StringC(), size_t(-1)),
49 totalExcludeCount_(0),
50 tagLevel_(0),
51 netEnablingCount_(0),
52 lastEndedElementType_(NULL)
53 {
54 }
55
56 void ContentState::startContent(const Dtd &dtd)
57 {
58   NCVector<Owner<ContentToken> > tokens(1);
59   tokens[0] = new ElementToken(dtd.documentElementType(),
60                                ContentToken::none);
61   Owner<ModelGroup> model(new SeqModelGroup(tokens, ContentToken::none));
62   Owner<CompiledModelGroup> compiledModel(new CompiledModelGroup(model));
63   Vector<ContentModelAmbiguity> ambiguities;
64   Boolean pcdataUnreachable;
65   compiledModel->compile(dtd.nElementTypeIndex(), ambiguities,
66                          pcdataUnreachable);
67   ASSERT(ambiguities.size() == 0);
68   ConstPtr<ElementDefinition> def
69     = new ElementDefinition(Location(),
70                             0,
71                             0,
72                             ElementDefinition::modelGroup,
73                             compiledModel);
74   documentElementContainer_.setElementDefinition(def, 0);
75   tagLevel_ = 0;
76   while (!openElements_.empty())
77     delete openElements_.get();
78   openElements_.insert(new OpenElement(&documentElementContainer_,
79                                        0,
80                                        0,
81                                        &theEmptyMap,
82                                        Location()));
83   includeCount_.assign(dtd.nElementTypeIndex(), 0);
84   excludeCount_.assign(dtd.nElementTypeIndex(), 0);
85   openElementCount_.assign(dtd.nElementTypeIndex(), 0);
86   netEnablingCount_ = 0;
87   totalExcludeCount_ = 0;
88   lastEndedElementType_ = 0;
89   undefinedElementTypeTable_.clear();
90 }
91
92 void ContentState::pushElement(OpenElement *e)
93 {
94   tagLevel_++;
95   openElementCount_[e->type()->index()]++;
96   const ElementDefinition *def = e->type()->definition();
97   if (def) {
98     size_t i;
99     for (i = 0; i < def->nInclusions(); i++)
100       includeCount_[def->inclusion(i)->index()]++;
101     for (i = 0; i < def->nExclusions(); i++) {
102       excludeCount_[def->exclusion(i)->index()]++;
103       totalExcludeCount_++;
104     }
105   }
106   if (e->netEnabling())
107     netEnablingCount_++;
108   openElements_.insert(e);
109 }
110
111 OpenElement *ContentState::popSaveElement()
112 {
113   ASSERT(tagLevel_ > 0);
114   OpenElement *e = openElements_.get();
115   tagLevel_--;
116   openElementCount_[e->type()->index()]--;
117   const ElementDefinition *def = e->type()->definition();
118   if (def) {
119     size_t i;
120     for (i = 0; i < def->nInclusions(); i++)
121       includeCount_[def->inclusion(i)->index()]--;
122     for (i = 0; i < def->nExclusions(); i++) {
123       excludeCount_[def->exclusion(i)->index()]--;
124       totalExcludeCount_--;
125     }
126   }
127   if (e->netEnabling())
128     netEnablingCount_--;
129   lastEndedElementType_ = e->type();
130   return e;
131 }
132
133 void ContentState::popElement()
134 {
135   delete popSaveElement();
136 }
137                               
138 Boolean ContentState::checkImplyLoop(unsigned count)
139 {
140   for (IListIter<OpenElement> iter(openElements_);
141        count > 0;
142        iter.next(), count--)
143     if (iter.cur()->type() == openElements_.head()->type()
144         // I'm not sure whether this is necessary.
145         && iter.cur()->matchState() == openElements_.head()->matchState())
146       return 0;
147   return 1;
148 }
149
150 void ContentState::getOpenElementInfo(Vector<OpenElementInfo> &v,
151                                       const StringC &rniPcdata) const
152 {
153   v.clear();
154   v.resize(tagLevel_);
155   unsigned i = tagLevel_;
156   for (IListIter<OpenElement> iter(openElements_);
157        !iter.done() && i > 0;
158        iter.next()) {
159     OpenElementInfo &e = v[--i];
160     e.gi = iter.cur()->type()->name();
161     const LeafContentToken *token = iter.cur()->currentPosition();
162     if (token && !token->isInitial()) {
163       e.matchIndex = token->typeIndex() + 1;
164       const ElementType *type = token->elementType();
165       e.matchType = type ? type->name() : rniPcdata;
166     }
167     e.included = iter.cur()->included();
168   }
169 }
170
171 const ElementType *
172 ContentState::lookupCreateUndefinedElement(const StringC &name,
173                                            const Location &loc)
174 {
175   const ElementType *e = undefinedElementTypeTable_.lookup(name);
176   if (e)
177     return e;
178   ElementType *p = new ElementType(name,
179                                    openElementCount_.size());
180   p->setElementDefinition(new ElementDefinition(loc,
181                                                 ElementDefinition::undefinedIndex,
182                                                 (ElementDefinition::omitStart
183                                                  |ElementDefinition::omitEnd),
184                                                 ElementDefinition::any),
185                           0);
186   undefinedElementTypeTable_.insert(p);
187   includeCount_.push_back(0);
188   excludeCount_.push_back(0);
189   openElementCount_.push_back(0);
190   return p;
191 }
192
193
194 #ifdef SP_NAMESPACE
195 }
196 #endif