xref: /onnv-gate/usr/src/cmd/man/src/util/nsgmls.src/lib/Entity.cxx (revision 0:68f95e015346)
1 // Copyright (c) 1994 James Clark
2 // See the file COPYING for copying permission.
3 #pragma ident	"%Z%%M%	%I%	%E% SMI"
4 
5 #ifdef __GNUG__
6 #pragma implementation
7 #endif
8 #include "splib.h"
9 #include "Entity.h"
10 #include "ParserState.h"
11 #include "macros.h"
12 #include "InternalInputSource.h"
13 #include "MessageArg.h"
14 #include "ParserMessages.h"
15 
16 #ifdef SP_NAMESPACE
17 namespace SP_NAMESPACE {
18 #endif
19 
Entity(const StringC & name,DeclType declType,DataType dataType,const Location & defLocation)20 Entity::Entity(const StringC &name, DeclType declType, DataType dataType,
21 	       const Location &defLocation)
22 : EntityDecl(name, declType, dataType, defLocation),
23   used_(0), defaulted_(0)
24 {
25 }
26 
generateSystemId(ParserState &)27 void Entity::generateSystemId(ParserState &)
28 {
29 }
30 
InternalEntity(const StringC & name,DeclType declType,DataType dataType,const Location & defLocation,Text & text)31 InternalEntity::InternalEntity(const StringC &name,
32 			       DeclType declType,
33 			       DataType dataType,
34 			       const Location &defLocation,
35 			       Text &text)
36 : Entity(name, declType, dataType, defLocation)
37 {
38   text.swap(text_);
39 }
40 
PiEntity(const StringC & name,DeclType declType,const Location & defLocation,Text & text)41 PiEntity::PiEntity(const StringC &name, DeclType declType,
42 		   const Location &defLocation, Text &text)
43 : InternalEntity(name, declType, pi, defLocation, text)
44 {
45 }
46 
copy() const47 Entity *PiEntity::copy() const
48 {
49   return new PiEntity(*this);
50 }
51 
InternalDataEntity(const StringC & name,DataType dataType,const Location & defLocation,Text & text)52 InternalDataEntity::InternalDataEntity(const StringC &name, DataType dataType,
53 				       const Location &defLocation, Text &text)
54 : InternalEntity(name, generalEntity, dataType, defLocation, text)
55 {
56 }
57 
58 
InternalCdataEntity(const StringC & name,const Location & defLocation,Text & text)59 InternalCdataEntity::InternalCdataEntity(const StringC &name,
60 					 const Location &defLocation,
61 					 Text &text)
62 : InternalDataEntity(name, cdata, defLocation, text)
63 {
64 }
65 
copy() const66 Entity *InternalCdataEntity::copy() const
67 {
68   return new InternalCdataEntity(*this);
69 }
70 
InternalSdataEntity(const StringC & name,const Location & defLocation,Text & text)71 InternalSdataEntity::InternalSdataEntity(const StringC &name,
72 					 const Location &defLocation,
73 					 Text &text)
74 : InternalDataEntity(name, sdata, defLocation, text)
75 {
76 }
77 
copy() const78 Entity *InternalSdataEntity::copy() const
79 {
80   return new InternalSdataEntity(*this);
81 }
82 
InternalTextEntity(const StringC & name,DeclType declType,const Location & defLocation,Text & text,Bracketed bracketed)83 InternalTextEntity::InternalTextEntity(const StringC &name, DeclType declType,
84 				       const Location &defLocation, Text &text,
85 				       Bracketed bracketed)
86 : InternalEntity(name, declType, sgmlText, defLocation, text),
87   bracketed_(bracketed)
88 {
89 }
90 
copy() const91 Entity *InternalTextEntity::copy() const
92 {
93   return new InternalTextEntity(*this);
94 }
95 
96 
ExternalEntity(const StringC & name,DeclType declType,DataType dataType,const Location & defLocation,const ExternalId & id)97 ExternalEntity::ExternalEntity(const StringC &name,
98 			       DeclType declType,
99 			       DataType dataType,
100 			       const Location &defLocation,
101 			       const ExternalId &id)
102 : Entity(name, declType, dataType, defLocation), externalId_(id)
103 {
104 }
105 
asExternalEntity() const106 const ExternalEntity *ExternalEntity::asExternalEntity() const
107 {
108   return this;
109 }
110 
systemIdPointer() const111 const StringC *ExternalEntity::systemIdPointer() const
112 {
113   return externalId_.systemIdString();
114 }
115 
effectiveSystemIdPointer() const116 const StringC *ExternalEntity::effectiveSystemIdPointer() const
117 {
118   if (externalId_.effectiveSystemId().size() > 0)
119     return &externalId_.effectiveSystemId();
120   return 0;
121 }
122 
publicIdPointer() const123 const StringC *ExternalEntity::publicIdPointer() const
124 {
125   return externalId_.publicIdString();
126 }
127 
generateSystemId(ParserState & parser)128 void ExternalEntity::generateSystemId(ParserState &parser)
129 {
130   StringC str;
131   if (parser.entityCatalog().lookup(*this,
132 				    parser.syntax(),
133 				    parser.sd().docCharset(),
134 				    parser.messenger(),
135 				    str))
136     externalId_.setEffectiveSystem(str);
137   // Don't generate warning when declType == sgml.
138   else if (externalId_.publicIdString()) {
139     if (declType() != sgml)
140       parser.message(ParserMessages::cannotGenerateSystemIdPublic,
141 		     StringMessageArg(*externalId_.publicIdString()));
142   }
143   else {
144     switch (declType()) {
145     case generalEntity:
146       parser.message(ParserMessages::cannotGenerateSystemIdGeneral,
147 		     StringMessageArg(name()));
148       break;
149     case parameterEntity:
150       parser.message(ParserMessages::cannotGenerateSystemIdParameter,
151 		     StringMessageArg(name()));
152       break;
153     case doctype:
154       parser.message(ParserMessages::cannotGenerateSystemIdDoctype,
155 		     StringMessageArg(name()));
156       break;
157     case linktype:
158       parser.message(ParserMessages::cannotGenerateSystemIdLinktype,
159 		     StringMessageArg(name()));
160       break;
161     case sgml:
162       break;
163     default:
164       CANNOT_HAPPEN();
165     }
166   }
167 }
168 
ExternalTextEntity(const StringC & name,DeclType declType,const Location & defLocation,const ExternalId & id)169 ExternalTextEntity::ExternalTextEntity(const StringC &name,
170 				       DeclType declType,
171 				       const Location &defLocation,
172 				       const ExternalId &id)
173 : ExternalEntity(name, declType, sgmlText, defLocation, id)
174 {
175 }
176 
copy() const177 Entity *ExternalTextEntity::copy() const
178 {
179   return new ExternalTextEntity(*this);
180 }
181 
ExternalNonTextEntity(const StringC & name,DataType dataType,const Location & defLocation,const ExternalId & id)182 ExternalNonTextEntity::ExternalNonTextEntity(const StringC &name,
183 					     DataType dataType,
184 					     const Location &defLocation,
185 					     const ExternalId &id)
186 : ExternalEntity(name, generalEntity, dataType, defLocation, id)
187 {
188 }
189 
ExternalDataEntity(const StringC & name,DataType dataType,const Location & defLocation,const ExternalId & id,const ConstPtr<Notation> & nt,AttributeList & attributes)190 ExternalDataEntity::ExternalDataEntity(const StringC &name,
191 				       DataType dataType,
192 				       const Location &defLocation,
193 				       const ExternalId &id,
194 				       const ConstPtr<Notation> &nt,
195 
196 				       AttributeList &attributes)
197 : ExternalNonTextEntity(name, dataType, defLocation, id),
198   notation_(nt)
199 {
200   attributes.swap(attributes_);
201 }
202 
setNotation(const ConstPtr<Notation> & notation,AttributeList & attributes)203 void ExternalDataEntity::setNotation(const ConstPtr<Notation> &notation,
204 				     AttributeList &attributes)
205 {
206   notation_ = notation;
207   attributes.swap(attributes_);
208 }
209 
copy() const210 Entity *ExternalDataEntity::copy() const
211 {
212   return new ExternalDataEntity(*this);
213 }
214 
SubdocEntity(const StringC & name,const Location & defLocation,const ExternalId & id)215 SubdocEntity::SubdocEntity(const StringC &name,
216 			   const Location &defLocation,
217 			   const ExternalId &id)
218 : ExternalNonTextEntity(name, subdoc, defLocation, id)
219 {
220 }
221 
copy() const222 Entity *SubdocEntity::copy() const
223 {
224   return new SubdocEntity(*this);
225 }
226 
isDataOrSubdoc() const227 Boolean Entity::isDataOrSubdoc() const
228 {
229   return 0;
230 }
231 
isCharacterData() const232 Boolean Entity::isCharacterData() const
233 {
234   return 0;
235 }
236 
asExternalEntity() const237 const ExternalEntity *Entity::asExternalEntity() const
238 {
239   return 0;
240 }
241 
asExternalDataEntity() const242 const ExternalDataEntity *Entity::asExternalDataEntity() const
243 {
244   return 0;
245 }
246 
asSubdocEntity() const247 const SubdocEntity *Entity::asSubdocEntity() const
248 {
249   return 0;
250 }
251 
asInternalEntity() const252 const InternalEntity *Entity::asInternalEntity() const
253 {
254   return 0;
255 }
256 
dsReference(ParserState & parser,const Ptr<EntityOrigin> & origin) const257 void Entity::dsReference(ParserState &parser,
258 			 const Ptr<EntityOrigin> &origin)
259      const
260 {
261   normalReference(parser, origin, 1);
262 }
263 
declReference(ParserState & parser,const Ptr<EntityOrigin> & origin) const264 void Entity::declReference(ParserState &parser,
265 			   const Ptr<EntityOrigin> &origin)
266      const
267 {
268   normalReference(parser, origin, 0);
269   if (parser.currentMarkup())
270     parser.currentMarkup()->addEntityStart(origin);
271 }
272 
contentReference(ParserState & parser,const Ptr<EntityOrigin> & origin) const273 void Entity::contentReference(ParserState &parser,
274 			      const Ptr<EntityOrigin> &origin)
275      const
276 {
277   normalReference(parser, origin, 1);
278 }
279 
rcdataReference(ParserState & parser,const Ptr<EntityOrigin> & origin) const280 void Entity::rcdataReference(ParserState &parser,
281 			   const Ptr<EntityOrigin> &origin)
282      const
283 {
284   normalReference(parser, origin, 1);
285 }
286 
litReference(Text &,ParserState & parser,const Ptr<EntityOrigin> & origin,Boolean) const287 void Entity::litReference(Text &, ParserState &parser,
288 			  const Ptr<EntityOrigin> &origin,
289 			  Boolean)
290      const
291 {
292   normalReference(parser, origin, 0);
293 }
294 
asInternalEntity() const295 const InternalEntity *InternalEntity::asInternalEntity() const
296 {
297   return this;
298 }
299 
litReference(Text &,ParserState & parser,const Ptr<EntityOrigin> &,Boolean) const300 void PiEntity::litReference(Text &, ParserState &parser,
301 			    const Ptr<EntityOrigin> &,
302 			    Boolean) const
303 {
304   parser.message(ParserMessages::piEntityReference);
305 }
306 
normalReference(ParserState & parser,const Ptr<EntityOrigin> & origin,Boolean) const307 void PiEntity::normalReference(ParserState &parser,
308 			       const Ptr<EntityOrigin> &origin,
309 			       Boolean) const
310 {
311   parser.noteMarkup();
312   parser.eventHandler().pi(new (parser.eventAllocator())
313 			   PiEntityEvent(this, origin.pointer()));
314 }
315 
declReference(ParserState & parser,const Ptr<EntityOrigin> &) const316 void PiEntity::declReference(ParserState &parser,
317 			     const Ptr<EntityOrigin> &) const
318 {
319   parser.message(ParserMessages::piEntityReference);
320 }
321 
rcdataReference(ParserState & parser,const Ptr<EntityOrigin> &) const322 void PiEntity::rcdataReference(ParserState &parser,
323 			       const Ptr<EntityOrigin> &) const
324 {
325   parser.message(ParserMessages::piEntityRcdata);
326 }
327 
declReference(ParserState & parser,const Ptr<EntityOrigin> &) const328 void InternalDataEntity::declReference(ParserState &parser,
329 				       const Ptr<EntityOrigin> &) const
330 {
331   parser.message(ParserMessages::internalDataEntityReference);
332 }
333 
isDataOrSubdoc() const334 Boolean InternalDataEntity::isDataOrSubdoc() const
335 {
336   return 1;
337 }
338 
normalReference(ParserState & parser,const Ptr<EntityOrigin> & origin,Boolean) const339 void InternalCdataEntity::normalReference(ParserState &parser,
340 					  const Ptr<EntityOrigin> &origin,
341 					  Boolean) const
342 {
343   checkEntlvl(parser);
344   if (string().size() > 0) {
345     parser.noteData();
346     parser.eventHandler().data(new (parser.eventAllocator())
347 			       CdataEntityEvent(this, origin.pointer()));
348   }
349 }
350 
isCharacterData() const351 Boolean InternalCdataEntity::isCharacterData() const
352 {
353   return string().size() > 0;
354 }
355 
litReference(Text & text,ParserState & parser,const Ptr<EntityOrigin> & origin,Boolean squeeze) const356 void InternalCdataEntity::litReference(Text &text,
357 				       ParserState &parser,
358 				       const Ptr<EntityOrigin> &origin,
359 				       Boolean squeeze) const
360 {
361   checkEntlvl(parser);
362   if (squeeze) {
363     Location loc(origin.pointer(), 0);
364     text.addEntityStart(loc);
365     text.addCharsTokenize(text_.string(), loc, parser.syntax().space());
366     loc += text_.size();
367     text.addEntityEnd(loc);
368   }
369   else
370     text.addCdata(this, origin.pointer());
371 }
372 
373 
normalReference(ParserState & parser,const Ptr<EntityOrigin> & origin,Boolean) const374 void InternalSdataEntity::normalReference(ParserState &parser,
375 					  const Ptr<EntityOrigin> &origin,
376 					  Boolean) const
377 {
378   checkEntlvl(parser);
379   parser.noteData();
380   parser.eventHandler().sdataEntity(new (parser.eventAllocator())
381 				    SdataEntityEvent(this,
382 						     origin.pointer()));
383 }
384 
isCharacterData() const385 Boolean InternalSdataEntity::isCharacterData() const
386 {
387   return 1;
388 }
389 
litReference(Text & text,ParserState & parser,const Ptr<EntityOrigin> & origin,Boolean squeeze) const390 void InternalSdataEntity::litReference(Text &text,
391 				       ParserState &parser,
392 				       const Ptr<EntityOrigin> &origin,
393 				       Boolean squeeze) const
394 {
395   checkEntlvl(parser);
396   if (squeeze) {
397     Location loc(origin.pointer(), 0);
398     text.addEntityStart(loc);
399     text.addCharsTokenize(text_.string(), loc, parser.syntax().space());
400     loc += text_.size();
401     text.addEntityEnd(loc);
402   }
403   else
404     text.addSdata(this, origin.pointer());
405 }
406 
normalReference(ParserState & parser,const Ptr<EntityOrigin> & origin,Boolean generateEvent) const407 void InternalTextEntity::normalReference(ParserState &parser,
408 					 const Ptr<EntityOrigin> &origin,
409 					 Boolean generateEvent) const
410 {
411   checkEntlvl(parser);
412   if (checkNotOpen(parser)) {
413     if (generateEvent && parser.wantMarkup())
414       parser.eventHandler().entityStart(new (parser.eventAllocator())
415 					EntityStartEvent(origin));
416     parser.pushInput(new (parser.internalAllocator())
417 		     InternalInputSource(text_.string(), origin.pointer()));
418   }
419 }
420 
litReference(Text & text,ParserState & parser,const Ptr<EntityOrigin> & origin,Boolean) const421 void InternalTextEntity::litReference(Text &text,
422 				      ParserState &parser,
423 				      const Ptr<EntityOrigin> &origin,
424 				      Boolean) const
425 {
426   text.addEntityStart(Location(origin.pointer(), 0));
427   normalReference(parser, origin, 0);
428 }
429 
normalReference(ParserState & parser,const Ptr<EntityOrigin> & origin,Boolean generateEvent) const430 void ExternalTextEntity::normalReference(ParserState &parser,
431 					 const Ptr<EntityOrigin> &origin,
432 					 Boolean generateEvent) const
433 {
434   checkEntlvl(parser);
435   if (checkNotOpen(parser)) {
436     if (generateEvent && parser.wantMarkup())
437       parser.eventHandler().entityStart(new (parser.eventAllocator())
438 					EntityStartEvent(origin));
439     if (externalId().effectiveSystemId().size())
440       parser.pushInput(parser.entityManager()
441 		       .open(externalId().effectiveSystemId(),
442 			     parser.sd().docCharset(),
443 			     origin.pointer(),
444 			     0,
445 			     parser.messenger()));
446     else
447       parser.message(ParserMessages::nonExistentEntityRef,
448 		     StringMessageArg(name()),
449 		     defLocation());
450   }
451 }
452 
litReference(Text & text,ParserState & parser,const Ptr<EntityOrigin> & origin,Boolean) const453 void ExternalTextEntity::litReference(Text &text,
454 				      ParserState &parser,
455 				      const Ptr<EntityOrigin> &origin,
456 				      Boolean) const
457 {
458   if (parser.options().warnAttributeValueExternalEntityRef
459       && declType() == generalEntity)
460     parser.message(ParserMessages::attributeValueExternalEntityRef);
461   text.addEntityStart(Location(origin.pointer(), 0));
462   normalReference(parser, origin, 0);
463 }
464 
asExternalDataEntity() const465 const ExternalDataEntity *ExternalDataEntity::asExternalDataEntity() const
466 {
467   return this;
468 }
469 
contentReference(ParserState & parser,const Ptr<EntityOrigin> & origin) const470 void ExternalDataEntity::contentReference(ParserState &parser,
471 					  const Ptr<EntityOrigin> &origin) const
472 {
473   if (parser.options().warnExternalDataEntityRef)
474     parser.message(ParserMessages::externalDataEntityRef);
475   checkEntlvl(parser);
476   parser.noteData();
477   parser.eventHandler().externalDataEntity(new (parser.eventAllocator())
478 					   ExternalDataEntityEvent(this, origin.pointer()));
479 }
480 
isDataOrSubdoc() const481 Boolean ExternalNonTextEntity::isDataOrSubdoc() const
482 {
483   return 1;
484 }
485 
isCharacterData() const486 Boolean ExternalNonTextEntity::isCharacterData() const
487 {
488   return 1;
489 }
490 
491 
normalReference(ParserState & parser,const Ptr<EntityOrigin> &,Boolean) const492 void ExternalNonTextEntity::normalReference(ParserState &parser,
493 					    const Ptr<EntityOrigin> &,
494 					    Boolean) const
495 {
496   parser.message(ParserMessages::externalNonTextEntityReference);
497 }
498 
litReference(Text &,ParserState & parser,const Ptr<EntityOrigin> &,Boolean) const499 void ExternalNonTextEntity::litReference(Text &,
500 					 ParserState &parser,
501 					 const Ptr<EntityOrigin> &,
502 					 Boolean) const
503 {
504   parser.message(ParserMessages::externalNonTextEntityRcdata);
505 }
506 
rcdataReference(ParserState & parser,const Ptr<EntityOrigin> &) const507 void ExternalNonTextEntity::rcdataReference(ParserState &parser,
508 					    const Ptr<EntityOrigin> &) const
509 {
510   parser.message(ParserMessages::externalNonTextEntityRcdata);
511 }
512 
contentReference(ParserState & parser,const Ptr<EntityOrigin> & origin) const513 void SubdocEntity::contentReference(ParserState &parser,
514 				    const Ptr<EntityOrigin> &origin) const
515 {
516   checkEntlvl(parser);
517   parser.noteData();
518   parser.eventHandler().subdocEntity(new (parser.eventAllocator())
519 				     SubdocEntityEvent(this, origin.pointer()));
520 }
521 
asSubdocEntity() const522 const SubdocEntity *SubdocEntity::asSubdocEntity() const
523 {
524   return this;
525 }
526 
IgnoredEntity(const StringC & name,DeclType declType)527 IgnoredEntity::IgnoredEntity(const StringC &name, DeclType declType)
528 : Entity(name, declType, sgmlText, Location())
529 {
530 }
531 
copy() const532 Entity *IgnoredEntity::copy() const
533 {
534   return new IgnoredEntity(*this);
535 }
536 
declReference(ParserState & parser,const Ptr<EntityOrigin> & origin) const537 void IgnoredEntity::declReference(ParserState &parser,
538 				  const Ptr<EntityOrigin> &origin)
539      const
540 {
541   if (parser.currentMarkup()) {
542     parser.currentMarkup()->addEntityStart(origin);
543     parser.currentMarkup()->addEntityEnd();
544   }
545 }
546 
litReference(Text & text,ParserState &,const Ptr<EntityOrigin> & origin,Boolean) const547 void IgnoredEntity::litReference(Text &text,
548 				 ParserState &,
549 				 const Ptr<EntityOrigin> &origin,
550 				 Boolean) const
551 {
552   text.addEntityStart(Location(origin.pointer(), 0));
553   text.addEntityEnd(Location(origin.pointer(), 0));
554 }
555 
normalReference(ParserState & parser,const Ptr<EntityOrigin> & origin,Boolean generateEvent) const556 void IgnoredEntity::normalReference(ParserState &parser,
557 				    const Ptr<EntityOrigin> &origin,
558 				    Boolean generateEvent) const
559 {
560   if (generateEvent && parser.wantMarkup()) {
561     parser.eventHandler().entityStart(new (parser.eventAllocator())
562 				      EntityStartEvent(origin));
563     Location loc(origin.pointer(), 0);
564     parser.eventHandler().entityEnd(new (parser.eventAllocator())
565 				    EntityEndEvent(loc));
566   }
567 }
568 
checkEntlvl(ParserState & parser)569 void Entity::checkEntlvl(ParserState &parser)
570 {
571   // -1 because document entity isn't counted
572   if (parser.inputLevel() - 1 == parser.syntax().entlvl())
573     parser.message(ParserMessages::entlvl);
574 }
575 
checkNotOpen(ParserState & parser) const576 Boolean Entity::checkNotOpen(ParserState &parser) const
577 {
578   if (parser.entityIsOpen(this)) {
579     parser.message(ParserMessages::recursiveEntityReference,
580 		   StringMessageArg(name()));
581     return 0;
582   }
583   return 1;
584 }
585 
586 
587 #ifdef SP_NAMESPACE
588 }
589 #endif
590