Link with C++ linker
[oweals/cde.git] / cde / programs / nsgmls / Markup.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 librararies 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: Markup.C /main/1 1996/07/29 16:56:39 cde-hp $ */
24 // Copyright (c) 1995 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 "Markup.h"
33 #include "InputSource.h"
34 #include "Location.h"
35 #include "macros.h"
36 #include "Entity.h"
37
38 #ifdef SP_NAMESPACE
39 namespace SP_NAMESPACE {
40 #endif
41
42 MarkupItem::MarkupItem()
43 : type(Markup::delimiter), index(0)
44 {
45 }
46
47 MarkupItem::~MarkupItem()
48 {
49   switch (type) {
50   case Markup::entityStart:
51     delete origin;
52     break;
53   case Markup::literal:
54     delete text;
55     break;
56   case Markup::sdLiteral:
57     delete sdText;
58     break;
59   }
60 }
61
62 MarkupItem::MarkupItem(const MarkupItem &item)
63 : type(item.type), index(item.index)
64 {
65   switch (item.type) {
66   case Markup::entityStart:
67     origin = new ConstPtr<Origin>(*item.origin);
68     break;
69   case Markup::literal:
70     text = new Text(*item.text);
71     break;
72   case Markup::sdLiteral:
73     sdText = new SdText(*item.sdText);
74     break;
75   case Markup::delimiter:
76     break;
77   default:
78     nChars = item.nChars;
79     break;
80   }
81 }
82
83 void MarkupItem::operator=(const MarkupItem &item)
84 {
85   switch (type) {
86   case Markup::entityStart:
87     if (item.type == Markup::entityStart) {
88       *origin = *item.origin;
89       return;
90     }
91     delete origin;
92     break;
93   case Markup::literal:
94     if (item.type == Markup::literal) {
95       *text = *item.text;
96       return;
97     }
98     delete text;
99     break;
100   case Markup::sdLiteral:
101     if (item.type == Markup::sdLiteral) {
102       *sdText = *item.sdText;
103       return;
104     }
105     delete sdText;
106     break;
107   }
108   type = item.type;
109   index = item.index;
110   switch (item.type) {
111   case Markup::entityStart:
112     origin = new ConstPtr<Origin>(*item.origin);
113     break;
114   case Markup::literal:
115     text = new Text(*item.text);
116     break;
117   case Markup::sdLiteral:
118     sdText = new SdText(*item.sdText);
119     break;
120   case Markup::delimiter:
121     break;
122   default:
123     nChars = item.nChars;
124     break;
125   }
126 }
127
128 Markup::Markup()
129 {
130 }
131
132 void Markup::resize(size_t n)
133 {
134   size_t chopChars = 0;
135   for (size_t i = n; i < items_.size(); i++)
136     switch (items_[i].type) {
137     case Markup::reservedName:
138     case Markup::sdReservedName:
139     case Markup::name:
140     case Markup::nameToken:
141     case Markup::number:
142     case Markup::attributeValue:
143     case Markup::s:
144     case Markup::comment:
145     case Markup::shortref:
146       chopChars += items_[i].nChars;
147       break;
148     }
149   items_.resize(n);
150   chars_.resize(chars_.size() - chopChars);
151 }
152
153 void Markup::addDelim(Syntax::DelimGeneral d)
154 {
155   items_.resize(items_.size() + 1);
156   MarkupItem &item = items_.back();
157   item.type = Markup::delimiter;
158   item.index = d;
159 }
160
161 void Markup::addReservedName(Syntax::ReservedName rn, const InputSource *in)
162 {
163   items_.resize(items_.size() + 1);
164   MarkupItem &item = items_.back();
165   size_t length = in->currentTokenLength();
166   item.nChars = length;
167   item.type = Markup::reservedName;
168   item.index = rn;
169   chars_.append(in->currentTokenStart(), length);
170 }
171
172 void Markup::addReservedName(Syntax::ReservedName rn, const StringC &str)
173 {
174   items_.resize(items_.size() + 1);
175   MarkupItem &item = items_.back();
176   item.nChars = str.size();
177   item.type = Markup::reservedName;
178   item.index = rn;
179   chars_.append(str.data(), str.size());
180 }
181
182 void Markup::addSdReservedName(Sd::ReservedName rn, const InputSource *in)
183 {
184   items_.resize(items_.size() + 1);
185   MarkupItem &item = items_.back();
186   size_t length = in->currentTokenLength();
187   item.nChars = length;
188   item.type = Markup::sdReservedName;
189   item.index = rn;
190   chars_.append(in->currentTokenStart(), length);
191 }
192
193 void Markup::addSdReservedName(Sd::ReservedName rn,
194                                const Char *str, size_t length)
195 {
196   items_.resize(items_.size() + 1);
197   MarkupItem &item = items_.back();
198   item.nChars = length;
199   item.type = Markup::sdReservedName;
200   item.index = rn;
201   chars_.append(str, length);
202 }
203
204 void Markup::addS(Char c)
205 {
206   if (items_.size() > 0) {
207     MarkupItem &item = items_.back();
208     if (item.type == Markup::s) {
209       item.nChars += 1;
210       chars_ += c;
211       return;
212     }
213   }
214   items_.resize(items_.size() + 1);
215   MarkupItem &item = items_.back();
216   item.type = Markup::s;
217   item.nChars = 1;
218   chars_ += c;
219 }
220
221 void Markup::addS(const InputSource *in)
222 {
223   items_.resize(items_.size() + 1);
224   MarkupItem &item = items_.back();
225   size_t length = in->currentTokenLength();
226   item.nChars = length;
227   item.type = Markup::s;
228   chars_.append(in->currentTokenStart(), length);
229 }
230
231 void Markup::addCommentStart()
232 {
233   items_.resize(items_.size() + 1);
234   MarkupItem &item = items_.back();
235   item.type = Markup::comment;
236   item.nChars = 0;
237 }
238
239 void Markup::addRefEndRe()
240 {
241   items_.resize(items_.size() + 1);
242   MarkupItem &item = items_.back();
243   item.type = Markup::refEndRe;
244 }
245
246 void Markup::addCommentChar(Char c)
247 {
248   items_.back().nChars += 1;
249   chars_ += c;
250 }
251
252 void Markup::addName(const InputSource *in)
253 {
254   items_.resize(items_.size() + 1);
255   MarkupItem &item = items_.back();
256   size_t length = in->currentTokenLength();
257   item.nChars = length;
258   item.type = Markup::name;
259   chars_.append(in->currentTokenStart(), length);
260 }
261
262 void Markup::addName(const Char *str, size_t length)
263 {
264   items_.resize(items_.size() + 1);
265   MarkupItem &item = items_.back();
266   item.nChars = length;
267   item.type = Markup::name;
268   chars_.append(str, length);
269 }
270
271 void Markup::addNumber(const InputSource *in)
272 {
273   items_.resize(items_.size() + 1);
274   MarkupItem &item = items_.back();
275   size_t length = in->currentTokenLength();
276   item.nChars = length;
277   item.type = Markup::number;
278   chars_.append(in->currentTokenStart(), length);
279 }
280
281 void Markup::addNameToken(const InputSource *in)
282 {
283   items_.resize(items_.size() + 1);
284   MarkupItem &item = items_.back();
285   size_t length = in->currentTokenLength();
286   item.nChars = length;
287   item.type = Markup::nameToken;
288   chars_.append(in->currentTokenStart(), length);
289 }
290
291 void Markup::addAttributeValue(const InputSource *in)
292 {
293   items_.resize(items_.size() + 1);
294   MarkupItem &item = items_.back();
295   size_t length = in->currentTokenLength();
296   item.nChars = length;
297   item.type = Markup::attributeValue;
298   chars_.append(in->currentTokenStart(), length);
299 }
300
301 void Markup::addShortref(const InputSource *in)
302 {
303   items_.resize(items_.size() + 1);
304   MarkupItem &item = items_.back();
305   size_t length = in->currentTokenLength();
306   item.nChars = length;
307   item.type = Markup::shortref;
308   chars_.append(in->currentTokenStart(), length);
309 }
310
311 void Markup::addEntityStart(const Ptr<EntityOrigin> &origin)
312 {
313   items_.resize(items_.size() + 1);
314   MarkupItem &item = items_.back();
315   item.type = Markup::entityStart;
316   item.origin = new ConstPtr<Origin>(origin.pointer());
317 }
318
319 void Markup::addEntityEnd()
320 {
321   items_.resize(items_.size() + 1);
322   items_.back().type = Markup::entityEnd;
323 }
324
325 void Markup::addLiteral(const Text &text)
326 {
327   items_.resize(items_.size() + 1);
328   MarkupItem &item = items_.back();
329   item.type = Markup::literal;
330   item.text = new Text(text);
331 }
332
333 void Markup::addSdLiteral(const SdText &sdText)
334 {
335   items_.resize(items_.size() + 1);
336   MarkupItem &item = items_.back();
337   item.type = Markup::sdLiteral;
338   item.sdText = new SdText(sdText);
339 }
340
341 void Markup::changeToAttributeValue(size_t i)
342 {
343   ASSERT(items_[i].type == Markup::name);
344   items_[i].type = Markup::attributeValue;
345 }
346
347 void Markup::swap(Markup &to)
348 {
349   chars_.swap(to.chars_);
350   items_.swap(to.items_);
351 }
352
353 MarkupIter::MarkupIter(const Markup &m)
354 : chars_(m.chars_.data()),
355   items_(m.items_.begin()),
356   nItems_(m.items_.size()),
357   index_(0),
358   charIndex_(0)
359 {
360 }
361
362 void MarkupIter::advance(Location &loc,
363                          const ConstPtr<Syntax> &syntax)
364 {
365   switch (items_[index_].type) {
366   case Markup::delimiter:
367     loc += syntax->delimGeneral(delimGeneral()).size();
368     break;
369   case Markup::refEndRe:
370     loc += 1;
371     break;
372   case Markup::reservedName:
373   case Markup::sdReservedName:
374   case Markup::name:
375   case Markup::nameToken:
376   case Markup::number:
377   case Markup::attributeValue:
378   case Markup::s:
379   case Markup::shortref:
380     loc += items_[index_].nChars;
381     charIndex_ += items_[index_].nChars;
382     break;
383   case Markup::comment:
384     loc += items_[index_].nChars + (2 * syntax->delimGeneral(Syntax::dCOM).size());
385     charIndex_ += items_[index_].nChars;
386     break;
387   case Markup::entityStart:
388     loc = Location(*items_[index_].origin, 0);
389     break;
390   case Markup::entityEnd:
391     {
392       ConstPtr<Origin> origin(loc.origin());
393       loc = origin->parent();
394       loc += origin->refLength();
395     }
396     break;
397   case Markup::literal:
398     {
399       const Text &text = *items_[index_].text;
400       text.endDelimLocation(loc);
401       Boolean lita;
402       text.delimType(lita);
403       loc
404         += syntax->delimGeneral(lita ? Syntax::dLITA : Syntax::dLIT).size();
405     }
406     break;
407   case Markup::sdLiteral:
408     {
409       const SdText &text = *items_[index_].sdText;
410       loc = text.endDelimLocation();
411       loc += 1;
412     }
413     break;
414   }
415   index_++;
416 }
417
418 void MarkupIter::advance()
419 {
420   switch (items_[index_].type) {
421   case Markup::reservedName:
422   case Markup::sdReservedName:
423   case Markup::name:
424   case Markup::nameToken:
425   case Markup::number:
426   case Markup::attributeValue:
427   case Markup::s:
428   case Markup::comment:
429   case Markup::shortref:
430     charIndex_ += items_[index_].nChars;
431     break;
432   }
433   index_++;
434 }
435
436 #ifdef SP_NAMESPACE
437 }
438 #endif