libDtSearch: Remove optional code for NO_DBN which is not used on CDE
[oweals/cde.git] / cde / programs / nsgmls / Entity.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: Entity.C /main/1 1996/07/29 16:49:46 cde-hp $ */
24 // Copyright (c) 1994 James Clark
25 // See the file COPYING for copying permission.
26
27 #ifdef __GNUG__
28 #pragma implementation
29 #endif
30 #include "splib.h"
31 #include "Entity.h"
32 #include "ParserState.h"
33 #include "macros.h"
34 #include "InternalInputSource.h"
35 #include "MessageArg.h"
36 #include "ParserMessages.h"
37
38 #ifdef SP_NAMESPACE
39 namespace SP_NAMESPACE {
40 #endif
41
42 Entity::Entity(const StringC &name, DeclType declType, DataType dataType,
43                const Location &defLocation)
44 : EntityDecl(name, declType, dataType, defLocation),
45   used_(0), defaulted_(0)
46 {
47 }
48
49 void Entity::generateSystemId(ParserState &)
50 {
51 }
52
53 InternalEntity::InternalEntity(const StringC &name,
54                                DeclType declType,
55                                DataType dataType,
56                                const Location &defLocation,
57                                Text &text)
58 : Entity(name, declType, dataType, defLocation)
59 {
60   text.swap(text_);
61 }
62
63 PiEntity::PiEntity(const StringC &name, DeclType declType,
64                    const Location &defLocation, Text &text)
65 : InternalEntity(name, declType, pi, defLocation, text)
66 {
67 }
68
69 Entity *PiEntity::copy() const
70 {
71   return new PiEntity(*this);
72 }
73
74 InternalDataEntity::InternalDataEntity(const StringC &name, DataType dataType,
75                                        const Location &defLocation, Text &text)
76 : InternalEntity(name, generalEntity, dataType, defLocation, text)
77 {
78 }
79
80
81 InternalCdataEntity::InternalCdataEntity(const StringC &name,
82                                          const Location &defLocation,
83                                          Text &text)
84 : InternalDataEntity(name, cdata, defLocation, text)
85 {
86 }
87
88 Entity *InternalCdataEntity::copy() const
89 {
90   return new InternalCdataEntity(*this);
91 }
92
93 InternalSdataEntity::InternalSdataEntity(const StringC &name,
94                                          const Location &defLocation,
95                                          Text &text)
96 : InternalDataEntity(name, sdata, defLocation, text)
97 {
98 }
99
100 Entity *InternalSdataEntity::copy() const
101 {
102   return new InternalSdataEntity(*this);
103 }
104
105 InternalTextEntity::InternalTextEntity(const StringC &name, DeclType declType,
106                                        const Location &defLocation, Text &text,
107                                        Bracketed bracketed)
108 : InternalEntity(name, declType, sgmlText, defLocation, text),
109   bracketed_(bracketed)
110 {
111 }
112
113 Entity *InternalTextEntity::copy() const
114 {
115   return new InternalTextEntity(*this);
116 }
117
118
119 ExternalEntity::ExternalEntity(const StringC &name,
120                                DeclType declType,
121                                DataType dataType,
122                                const Location &defLocation,
123                                const ExternalId &id)
124 : Entity(name, declType, dataType, defLocation), externalId_(id)
125 {
126 }
127
128 const ExternalEntity *ExternalEntity::asExternalEntity() const
129 {
130   return this;
131 }
132
133 const StringC *ExternalEntity::systemIdPointer() const
134 {
135   return externalId_.systemIdString();
136 }
137
138 const StringC *ExternalEntity::effectiveSystemIdPointer() const
139 {
140   if (externalId_.effectiveSystemId().size() > 0)
141     return &externalId_.effectiveSystemId();
142   return 0;
143 }
144
145 const StringC *ExternalEntity::publicIdPointer() const
146 {
147   return externalId_.publicIdString();
148 }
149
150 void ExternalEntity::generateSystemId(ParserState &parser)
151 {
152   StringC str;
153   if (parser.entityCatalog().lookup(*this,
154                                     parser.syntax(),
155                                     parser.sd().docCharset(),
156                                     parser.messenger(),
157                                     str))
158     externalId_.setEffectiveSystem(str);
159   else if (externalId_.publicIdString())
160     parser.message(ParserMessages::cannotGenerateSystemIdPublic,
161                    StringMessageArg(*externalId_.publicIdString()));
162   else {
163     switch (declType()) {
164     case generalEntity:
165       parser.message(ParserMessages::cannotGenerateSystemIdGeneral,
166                      StringMessageArg(name()));
167       break;
168     case parameterEntity:
169       parser.message(ParserMessages::cannotGenerateSystemIdParameter,
170                      StringMessageArg(name()));
171       break;
172     case doctype:
173       parser.message(ParserMessages::cannotGenerateSystemIdDoctype,
174                      StringMessageArg(name()));
175       break;
176     case linktype:
177       parser.message(ParserMessages::cannotGenerateSystemIdLinktype,
178                      StringMessageArg(name()));
179       break;
180     default:
181       CANNOT_HAPPEN();
182     }
183   }
184 }
185
186 ExternalTextEntity::ExternalTextEntity(const StringC &name,
187                                        DeclType declType,
188                                        const Location &defLocation,
189                                        const ExternalId &id)
190 : ExternalEntity(name, declType, sgmlText, defLocation, id)
191 {
192 }
193
194 Entity *ExternalTextEntity::copy() const
195 {
196   return new ExternalTextEntity(*this);
197 }
198
199 ExternalNonTextEntity::ExternalNonTextEntity(const StringC &name,
200                                              DataType dataType,
201                                              const Location &defLocation,
202                                              const ExternalId &id)
203 : ExternalEntity(name, generalEntity, dataType, defLocation, id)
204 {
205 }
206
207 ExternalDataEntity::ExternalDataEntity(const StringC &name,
208                                        DataType dataType,
209                                        const Location &defLocation,
210                                        const ExternalId &id,
211                                        const ConstPtr<Notation> &nt,
212                                        
213                                        AttributeList &attributes)
214 : ExternalNonTextEntity(name, dataType, defLocation, id),
215   notation_(nt)
216 {
217   attributes.swap(attributes_);
218 }
219
220 void ExternalDataEntity::setNotation(const ConstPtr<Notation> &notation,
221                                      AttributeList &attributes)
222 {
223   notation_ = notation;
224   attributes.swap(attributes_);
225 }
226
227 Entity *ExternalDataEntity::copy() const
228 {
229   return new ExternalDataEntity(*this);
230 }
231
232 SubdocEntity::SubdocEntity(const StringC &name,
233                            const Location &defLocation,
234                            const ExternalId &id)
235 : ExternalNonTextEntity(name, subdoc, defLocation, id)
236 {
237 }
238
239 Entity *SubdocEntity::copy() const
240 {
241   return new SubdocEntity(*this);
242 }
243
244 Boolean Entity::isDataOrSubdoc() const
245 {
246   return 0;
247 }
248
249 Boolean Entity::isCharacterData() const
250 {
251   return 0;
252 }
253
254 const ExternalEntity *Entity::asExternalEntity() const
255 {
256   return 0;
257 }
258
259 const ExternalDataEntity *Entity::asExternalDataEntity() const
260 {
261   return 0;
262 }
263
264 const SubdocEntity *Entity::asSubdocEntity() const
265 {
266   return 0;
267 }
268
269 const InternalEntity *Entity::asInternalEntity() const
270 {
271   return 0;
272 }
273
274 void Entity::dsReference(ParserState &parser,
275                          const Ptr<EntityOrigin> &origin)
276      const
277 {
278   normalReference(parser, origin, 1);
279 }
280
281 void Entity::declReference(ParserState &parser,
282                            const Ptr<EntityOrigin> &origin)
283      const
284 {
285   normalReference(parser, origin, 0);
286   if (parser.currentMarkup())
287     parser.currentMarkup()->addEntityStart(origin);
288 }
289
290 void Entity::contentReference(ParserState &parser,
291                               const Ptr<EntityOrigin> &origin)
292      const
293 {
294   normalReference(parser, origin, 1);
295 }
296
297 void Entity::rcdataReference(ParserState &parser,
298                            const Ptr<EntityOrigin> &origin)
299      const
300 {
301   normalReference(parser, origin, 1);
302 }
303
304 void Entity::litReference(Text &, ParserState &parser,
305                           const Ptr<EntityOrigin> &origin,
306                           Boolean)
307      const
308 {
309   normalReference(parser, origin, 0);
310 }
311
312 const InternalEntity *InternalEntity::asInternalEntity() const
313 {
314   return this;
315 }
316
317 void PiEntity::litReference(Text &, ParserState &parser,
318                             const Ptr<EntityOrigin> &,
319                             Boolean) const
320 {
321   parser.message(ParserMessages::piEntityReference);
322 }
323
324 void PiEntity::normalReference(ParserState &parser,
325                                const Ptr<EntityOrigin> &origin,
326                                Boolean) const
327 {
328   parser.noteMarkup();
329   parser.eventHandler().pi(new (parser.eventAllocator())
330                            PiEntityEvent(this, origin.pointer()));
331 }
332
333 void PiEntity::declReference(ParserState &parser,
334                              const Ptr<EntityOrigin> &) const
335 {
336   parser.message(ParserMessages::piEntityReference);
337 }
338
339 void PiEntity::rcdataReference(ParserState &parser,
340                                const Ptr<EntityOrigin> &) const
341 {
342   parser.message(ParserMessages::piEntityRcdata);
343 }
344
345 void InternalDataEntity::declReference(ParserState &parser,
346                                        const Ptr<EntityOrigin> &) const
347 {
348   parser.message(ParserMessages::internalDataEntityReference);
349 }
350
351 Boolean InternalDataEntity::isDataOrSubdoc() const
352 {
353   return 1;
354 }
355
356 void InternalCdataEntity::normalReference(ParserState &parser,
357                                           const Ptr<EntityOrigin> &origin,
358                                           Boolean) const
359 {
360   checkEntlvl(parser);
361   if (string().size() > 0) {
362     parser.noteData();
363     parser.eventHandler().data(new (parser.eventAllocator())
364                                CdataEntityEvent(this, origin.pointer()));
365   }
366 }
367
368 Boolean InternalCdataEntity::isCharacterData() const
369 {
370   return string().size() > 0;
371 }
372
373 void InternalCdataEntity::litReference(Text &text,
374                                        ParserState &parser,
375                                        const Ptr<EntityOrigin> &origin,
376                                        Boolean squeeze) const
377 {
378   checkEntlvl(parser);
379   if (squeeze) {
380     Location loc(origin.pointer(), 0);
381     text.addEntityStart(loc);
382     text.addCharsTokenize(text_.string(), loc, parser.syntax().space());
383     loc += text_.size();
384     text.addEntityEnd(loc);
385   }
386   else
387     text.addCdata(this, origin.pointer());
388 }
389
390
391 void InternalSdataEntity::normalReference(ParserState &parser,
392                                           const Ptr<EntityOrigin> &origin,
393                                           Boolean) const
394 {
395   checkEntlvl(parser);
396   parser.noteData();
397   parser.eventHandler().sdataEntity(new (parser.eventAllocator())
398                                     SdataEntityEvent(this,
399                                                      origin.pointer()));
400 }
401
402 Boolean InternalSdataEntity::isCharacterData() const
403 {
404   return 1;
405 }
406
407 void InternalSdataEntity::litReference(Text &text,
408                                        ParserState &parser,
409                                        const Ptr<EntityOrigin> &origin,
410                                        Boolean squeeze) const
411 {
412   checkEntlvl(parser);
413   if (squeeze) {
414     Location loc(origin.pointer(), 0);
415     text.addEntityStart(loc);
416     text.addCharsTokenize(text_.string(), loc, parser.syntax().space());
417     loc += text_.size();
418     text.addEntityEnd(loc);
419   }
420   else
421     text.addSdata(this, origin.pointer());
422 }
423
424 void InternalTextEntity::normalReference(ParserState &parser,
425                                          const Ptr<EntityOrigin> &origin,
426                                          Boolean generateEvent) const
427 {
428   checkEntlvl(parser);
429   if (checkNotOpen(parser)) {
430     if (generateEvent && parser.wantMarkup())
431       parser.eventHandler().entityStart(new (parser.eventAllocator())
432                                         EntityStartEvent(origin));
433     parser.pushInput(new (parser.internalAllocator())
434                      InternalInputSource(text_.string(), origin.pointer()));
435   }
436 }
437
438 void InternalTextEntity::litReference(Text &text,
439                                       ParserState &parser,
440                                       const Ptr<EntityOrigin> &origin,
441                                       Boolean) const
442 {
443   text.addEntityStart(Location(origin.pointer(), 0));
444   normalReference(parser, origin, 0);
445 }
446
447 void ExternalTextEntity::normalReference(ParserState &parser,
448                                          const Ptr<EntityOrigin> &origin,
449                                          Boolean generateEvent) const
450 {
451   checkEntlvl(parser);
452   if (checkNotOpen(parser)) {
453     if (generateEvent && parser.wantMarkup())
454       parser.eventHandler().entityStart(new (parser.eventAllocator())
455                                         EntityStartEvent(origin));
456     if (externalId().effectiveSystemId().size())
457       parser.pushInput(parser.entityManager()
458                        .open(externalId().effectiveSystemId(),
459                              parser.sd().docCharset(),
460                              origin.pointer(),
461                              0,
462                              parser.messenger()));
463     else
464       parser.message(ParserMessages::nonExistentEntityRef,
465                      StringMessageArg(name()),
466                      defLocation());
467   }
468 }
469
470 void ExternalTextEntity::litReference(Text &text,
471                                       ParserState &parser,
472                                       const Ptr<EntityOrigin> &origin,
473                                       Boolean) const
474 {
475   text.addEntityStart(Location(origin.pointer(), 0));
476   normalReference(parser, origin, 0);
477 }
478
479 const ExternalDataEntity *ExternalDataEntity::asExternalDataEntity() const
480 {
481   return this;
482 }
483
484 void ExternalDataEntity::contentReference(ParserState &parser,
485                                           const Ptr<EntityOrigin> &origin) const
486 {
487   checkEntlvl(parser);
488   parser.noteData();
489   parser.eventHandler().externalDataEntity(new (parser.eventAllocator())
490                                            ExternalDataEntityEvent(this, origin.pointer()));
491 }
492
493 Boolean ExternalNonTextEntity::isDataOrSubdoc() const
494 {
495   return 1;
496 }
497
498 Boolean ExternalNonTextEntity::isCharacterData() const
499 {
500   return 1;
501 }
502
503
504 void ExternalNonTextEntity::normalReference(ParserState &parser,
505                                             const Ptr<EntityOrigin> &,
506                                             Boolean) const
507 {
508   parser.message(ParserMessages::externalNonTextEntityReference);
509 }
510
511 void ExternalNonTextEntity::litReference(Text &,
512                                          ParserState &parser,
513                                          const Ptr<EntityOrigin> &,
514                                          Boolean) const
515 {
516   parser.message(ParserMessages::externalNonTextEntityRcdata);
517 }
518
519 void ExternalNonTextEntity::rcdataReference(ParserState &parser,
520                                             const Ptr<EntityOrigin> &) const
521 {
522   parser.message(ParserMessages::externalNonTextEntityRcdata);
523 }
524
525 void SubdocEntity::contentReference(ParserState &parser,
526                                     const Ptr<EntityOrigin> &origin) const
527 {
528   checkEntlvl(parser);
529   parser.noteData();
530   parser.eventHandler().subdocEntity(new (parser.eventAllocator())
531                                      SubdocEntityEvent(this, origin.pointer()));
532 }
533
534 const SubdocEntity *SubdocEntity::asSubdocEntity() const
535 {
536   return this;
537 }
538
539 IgnoredEntity::IgnoredEntity(const StringC &name, DeclType declType)
540 : Entity(name, declType, sgmlText, Location())
541 {
542 }
543
544 Entity *IgnoredEntity::copy() const
545 {
546   return new IgnoredEntity(*this);
547 }
548
549 void IgnoredEntity::declReference(ParserState &parser,
550                                   const Ptr<EntityOrigin> &origin)
551      const
552 {
553   if (parser.currentMarkup()) {
554     parser.currentMarkup()->addEntityStart(origin);
555     parser.currentMarkup()->addEntityEnd();
556   }
557 }
558
559 void IgnoredEntity::litReference(Text &text,
560                                  ParserState &,
561                                  const Ptr<EntityOrigin> &origin,
562                                  Boolean) const
563 {
564   text.addEntityStart(Location(origin.pointer(), 0));
565   text.addEntityEnd(Location(origin.pointer(), 0));
566 }
567
568 void IgnoredEntity::normalReference(ParserState &parser,
569                                     const Ptr<EntityOrigin> &origin,
570                                     Boolean generateEvent) const
571 {
572   if (generateEvent && parser.wantMarkup()) {
573     parser.eventHandler().entityStart(new (parser.eventAllocator())
574                                       EntityStartEvent(origin));
575     Location loc(origin.pointer(), 0);
576     parser.eventHandler().entityEnd(new (parser.eventAllocator())
577                                     EntityEndEvent(loc));
578   }
579 }
580
581 void Entity::checkEntlvl(ParserState &parser)
582 {
583   // -1 because document entity isn't counted
584   if (parser.inputLevel() - 1 == parser.syntax().entlvl())
585     parser.message(ParserMessages::entlvl);
586 }
587
588 Boolean Entity::checkNotOpen(ParserState &parser) const
589 {
590   if (parser.entityIsOpen(this)) {
591     parser.message(ParserMessages::recursiveEntityReference,
592                    StringMessageArg(name()));
593     return 0;
594   }
595   return 1;
596 }
597
598 EntityOrigin::EntityOrigin()
599 : refLength_(0)
600 {
601 }
602
603 EntityOrigin::EntityOrigin(const Location &refLocation)
604 : InputSourceOrigin(refLocation), refLength_(0)
605 {
606 }
607
608 EntityOrigin::EntityOrigin(const ConstPtr<Entity> &entity,
609                            const Location &refLocation)
610 : InputSourceOrigin(refLocation), refLength_(0), entity_(entity)
611 {
612 }
613
614 EntityOrigin::EntityOrigin(const ConstPtr<Entity> &entity,
615                            const Location &refLocation,
616                            Index refLength,
617                            Owner<Markup> &markup)
618 : InputSourceOrigin(refLocation), refLength_(refLength), entity_(entity)
619 {
620   markup.swap(markup_);
621 }
622
623 EntityOrigin::~EntityOrigin()
624 {
625 }
626
627 InputSourceOrigin *EntityOrigin::copy() const
628 {
629   Owner<Markup> m;
630   if (markup_)
631     m = new Markup(*markup_);
632   return new EntityOrigin(entity_, parent(), refLength_, m);
633 }
634
635 const StringC *EntityOrigin::entityName() const
636 {
637   if (entity_.isNull())
638     return 0;
639   return entity_->namePointer();
640 }
641
642 Index EntityOrigin::refLength() const
643 {
644   return refLength_;
645 }
646
647 const EntityOrigin *EntityOrigin::asEntityOrigin() const
648 {
649   return this;
650 }
651
652 Boolean EntityOrigin::defLocation(Offset off, Location &loc) const
653 {
654   if (entity_.isNull())
655     return 0;
656   const InternalEntity *internal = entity_->asInternalEntity();
657   if (!internal)
658     return 0;
659   loc = internal->text().charLocation(off);
660   return 1;
661 }
662
663 const EntityDecl *EntityOrigin::entityDecl() const
664 {
665   return entity_.pointer();
666 }
667
668 #ifdef SP_NAMESPACE
669 }
670 #endif