xref: /onnv-gate/usr/src/cmd/man/src/util/nsgmls.src/lib/Location.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 "Location.h"
10 #include "Entity.h"
11 #include "Mutex.h"
12 
13 #ifdef SP_NAMESPACE
14 namespace SP_NAMESPACE {
15 #endif
16 
17 class InputSourceOriginImpl : public EntityOrigin {
18 public:
19   InputSourceOriginImpl();
20   InputSourceOriginImpl(const Location &refLocation);
21   const Location &parent() const;
22   const ExternalInfo *externalInfo() const;
23   Offset startOffset(Index ind) const;
24   void noteCharRef(Index replacementIndex, const NamedCharRef &);
25   Boolean isNamedCharRef(Index ind, NamedCharRef &ref) const;
26   void setExternalInfo(ExternalInfo *);
27   virtual InputSourceOrigin *copy() const;
28   const InputSourceOrigin *asInputSourceOrigin() const;
29 private:
30   InputSourceOriginImpl(const InputSourceOriginImpl &); // undefined
31   void operator=(const InputSourceOriginImpl &);	// undefined
32   size_t nPrecedingCharRefs(Index ind) const;
33   Vector<InputSourceOriginNamedCharRef> charRefs_;
34   StringC charRefOrigNames_;
35   Owner<ExternalInfo> externalInfo_; // 0 for internal entities
36   Location refLocation_;	// where referenced from
37   Mutex mutex_;
38 };
39 
40 class EntityOriginImpl : public InputSourceOriginImpl {
41 public:
operator new(size_t sz,Allocator & alloc)42   void *operator new(size_t sz, Allocator &alloc) {
43     return alloc.alloc(sz);
44   }
operator new(size_t sz)45   void *operator new(size_t sz) {
46     return Allocator::allocSimple(sz);
47   }
operator delete(void * p)48   void operator delete(void *p) {
49     Allocator::free(p);
50   }
51   EntityOriginImpl(const ConstPtr<Entity> &);
52   EntityOriginImpl(const ConstPtr<Entity> &,
53 		   const Location &refLocation);
54   EntityOriginImpl(const ConstPtr<Entity> &,
55 		   const Location &refLocation, Index refLength,
56 		   Owner<Markup> &markup);
57   ~EntityOriginImpl();
58   InputSourceOrigin *copy() const;
entity() const59   const Entity *entity() const { return entity_.pointer(); }
60   const EntityDecl *entityDecl() const;
61   const EntityOrigin *asEntityOrigin() const;
62   Boolean defLocation(Offset off, const Origin *&, Index &) const;
63   Index refLength() const;
64   const Markup *markup() const;
65 private:
66   EntityOriginImpl(const EntityOriginImpl &); // undefined
67   void operator=(const EntityOriginImpl &);	// undefined
68   ConstPtr<Entity> entity_;	// 0 for document entity
69   // total length of reference
70   // (characters that were replaced by the entity)
71   Index refLength_;
72   Owner<Markup> markup_;
73 };
74 
75 const size_t EntityOrigin::allocSize = sizeof(EntityOriginImpl);
76 
Location()77 Location::Location()
78 {
79 }
80 
Location(Origin * origin,Index i)81 Location::Location(Origin *origin, Index i)
82 : origin_(origin), index_(i)
83 {
84 }
85 
Location(ConstPtr<Origin> origin,Index i)86 Location::Location(ConstPtr<Origin> origin, Index i)
87 : origin_(origin), index_(i)
88 {
89 }
90 
~Origin()91 Origin::~Origin()
92 {
93 }
94 
asEntityOrigin() const95 const EntityOrigin *Origin::asEntityOrigin() const
96 {
97   return 0;
98 }
99 
asInputSourceOrigin() const100 const InputSourceOrigin *Origin::asInputSourceOrigin() const
101 {
102   return 0;
103 }
104 
refLength() const105 Index Origin::refLength() const
106 {
107   return 0;
108 }
109 
origChars(const Char * &) const110 Boolean Origin::origChars(const Char *&) const
111 {
112   return 0;
113 }
114 
inBracketedTextOpenDelim() const115 Boolean Origin::inBracketedTextOpenDelim() const
116 {
117   return 0;
118 }
119 
inBracketedTextCloseDelim() const120 Boolean Origin::inBracketedTextCloseDelim() const
121 {
122   return 0;
123 }
124 
isNumericCharRef(const Markup * &) const125 Boolean Origin::isNumericCharRef(const Markup *&) const
126 {
127   return 0;
128 }
129 
isNamedCharRef(Index,NamedCharRef &) const130 Boolean Origin::isNamedCharRef(Index, NamedCharRef &) const
131 {
132   return 0;
133 }
134 
entityDecl() const135 const EntityDecl *Origin::entityDecl() const
136 {
137   return 0;
138 }
139 
markup() const140 const Markup *Origin::markup() const
141 {
142   return 0;
143 }
144 
entity() const145 const Entity *Origin::entity() const
146 {
147   return 0;
148 }
149 
defLocation(Offset,const Origin * &,Index &) const150 Boolean Origin::defLocation(Offset, const Origin *&, Index &) const
151 {
152   return 0;
153 }
154 
externalInfo() const155 const ExternalInfo *Origin::externalInfo() const
156 {
157   return 0;
158 }
159 
startOffset(Index ind) const160 Offset Origin::startOffset(Index ind) const
161 {
162   return ind;
163 }
164 
entityName() const165 const StringC *Origin::entityName() const
166 {
167   const EntityDecl *ent = entityDecl();
168   if (ent)
169     return &ent->name();
170   else
171     return 0;
172 }
173 
BracketOrigin(const Location & loc,Position pos)174 BracketOrigin::BracketOrigin(const Location &loc, Position pos)
175 : loc_(loc), pos_(pos)
176 {
177 }
178 
parent() const179 const Location &BracketOrigin::parent() const
180 {
181   return loc_;
182 }
183 
inBracketedTextOpenDelim() const184 Boolean BracketOrigin::inBracketedTextOpenDelim() const
185 {
186   return pos_ == open;
187 }
188 
inBracketedTextCloseDelim() const189 Boolean BracketOrigin::inBracketedTextCloseDelim() const
190 {
191   return pos_ == close;
192 }
193 
make()194 InputSourceOrigin *InputSourceOrigin::make()
195 {
196   return new InputSourceOriginImpl;
197 }
198 
make(const Location & refLocation)199 InputSourceOrigin *InputSourceOrigin::make(const Location &refLocation)
200 {
201   return new InputSourceOriginImpl(refLocation);
202 }
203 
InputSourceOriginImpl()204 InputSourceOriginImpl::InputSourceOriginImpl()
205 {
206 }
207 
InputSourceOriginImpl(const Location & refLocation)208 InputSourceOriginImpl::InputSourceOriginImpl(const Location &refLocation)
209 : refLocation_(refLocation)
210 {
211 }
212 
asInputSourceOrigin() const213 const InputSourceOrigin *InputSourceOriginImpl::asInputSourceOrigin() const
214 {
215   return this;
216 }
217 
externalInfo() const218 const ExternalInfo *InputSourceOriginImpl::externalInfo() const
219 {
220   return externalInfo_.pointer();
221 }
222 
copy() const223 InputSourceOrigin *InputSourceOriginImpl::copy() const
224 {
225   return new InputSourceOriginImpl(refLocation_);
226 }
227 
parent() const228 const Location &InputSourceOriginImpl::parent() const
229 {
230   return refLocation_;
231 }
232 
setExternalInfo(ExternalInfo * info)233 void InputSourceOriginImpl::setExternalInfo(ExternalInfo *info)
234 {
235   externalInfo_ = info;
236 }
237 
noteCharRef(Index replacementIndex,const NamedCharRef & ref)238 void InputSourceOriginImpl::noteCharRef(Index replacementIndex,
239 					const NamedCharRef &ref)
240 {
241   Mutex::Lock lock(&mutex_);
242   charRefs_.resize(charRefs_.size() + 1);
243   charRefs_.back().replacementIndex = replacementIndex;
244   charRefs_.back().refStartIndex = ref.refStartIndex();
245   charRefs_.back().refEndType = ref.refEndType();
246   charRefs_.back().origNameOffset = charRefOrigNames_.size();
247   charRefOrigNames_ += ref.origName();
248 }
249 
250 // Number of character references whose replacement index < ind.
251 
nPrecedingCharRefs(Index ind) const252 size_t InputSourceOriginImpl::nPrecedingCharRefs(Index ind) const
253 {
254   size_t i;
255   // Find i such that
256   // charRefs_[I].replacementIndex >= ind
257   // charRefs_[i - 1].replacementIndex < ind
258   if (charRefs_.size() == 0
259       || ind > charRefs_.back().replacementIndex)
260     // This will be a common case, so optimize it.
261     i = charRefs_.size();
262   else {
263     // Binary search
264     // Invariant:
265     // charRefs_ < i have replacementIndex < ind
266     // charRefs_ >= lim have replacementIndex >= ind
267     i = 0;
268     size_t lim = charRefs_.size();
269     while (i < lim) {
270       size_t mid = i + (lim - i)/2;
271       if (charRefs_[mid].replacementIndex >= ind)
272 	lim = mid;
273       else
274 	i = mid + 1;
275     }
276   }
277   return i;
278 }
279 
startOffset(Index ind) const280 Offset InputSourceOriginImpl::startOffset(Index ind) const
281 {
282   Mutex::Lock lock(&((InputSourceOriginImpl *)this)->mutex_);
283   size_t n = nPrecedingCharRefs(ind);
284   if (n < charRefs_.size()
285       && ind == charRefs_[n].replacementIndex) {
286     for (;;) {
287       ind = charRefs_[n].refStartIndex;
288       if (n == 0 || charRefs_[n - 1].replacementIndex != ind)
289 	break;
290       --n;
291     }
292   }
293   // charRefs[n - 1].replacementIndex < ind
294   return Offset(ind - n);
295 }
296 
isNamedCharRef(Index ind,NamedCharRef & ref) const297 Boolean InputSourceOriginImpl::isNamedCharRef(Index ind, NamedCharRef &ref) const
298 {
299   Mutex::Lock lock(&((InputSourceOriginImpl *)this)->mutex_);
300   size_t n = nPrecedingCharRefs(ind);
301   if (n < charRefs_.size() && ind == charRefs_[n].replacementIndex) {
302     ref.set(charRefs_[n].refStartIndex,
303 	    charRefs_[n].refEndType,
304 	    charRefOrigNames_.data() + charRefs_[n].origNameOffset,
305 	    (n + 1 < charRefs_.size()
306 	     ? charRefs_[n + 1].origNameOffset
307 	     : charRefOrigNames_.size())
308 	    - charRefs_[n].origNameOffset);
309     return 1;
310   }
311   return 0;
312 }
313 
make(Allocator & alloc,const ConstPtr<Entity> & entity)314 EntityOrigin *EntityOrigin::make(Allocator &alloc,
315 				 const ConstPtr<Entity> &entity)
316 {
317   return new (alloc) EntityOriginImpl(entity);
318 }
319 
make(Allocator & alloc,const ConstPtr<Entity> & entity,const Location & refLocation)320 EntityOrigin *EntityOrigin::make(Allocator &alloc,
321 				 const ConstPtr<Entity> &entity,
322 				 const Location &refLocation)
323 {
324   return new (alloc) EntityOriginImpl(entity, refLocation);
325 }
326 
make(Allocator & alloc,const ConstPtr<Entity> & entity,const Location & refLocation,Index refLength,Owner<Markup> & markup)327 EntityOrigin *EntityOrigin::make(Allocator &alloc,
328 				 const ConstPtr<Entity> &entity,
329 				 const Location &refLocation,
330 				 Index refLength,
331 				 Owner<Markup> &markup)
332 {
333   return new (alloc) EntityOriginImpl(entity, refLocation, refLength, markup);
334 }
335 
make(const ConstPtr<Entity> & entity,const Location & refLocation,Index refLength,Owner<Markup> & markup)336 EntityOrigin *EntityOrigin::make(const ConstPtr<Entity> &entity,
337 				 const Location &refLocation,
338 				 Index refLength,
339 				 Owner<Markup> &markup)
340 {
341   return new EntityOriginImpl(entity, refLocation, refLength, markup);
342 }
343 
make(const ConstPtr<Entity> & entity,const Location & refLocation)344 EntityOrigin *EntityOrigin::make(const ConstPtr<Entity> &entity,
345 				 const Location &refLocation)
346 {
347   return new EntityOriginImpl(entity, refLocation);
348 }
349 
EntityOriginImpl(const ConstPtr<Entity> & entity)350 EntityOriginImpl::EntityOriginImpl(const ConstPtr<Entity> &entity)
351 : refLength_(0), entity_(entity)
352 {
353 }
354 
EntityOriginImpl(const ConstPtr<Entity> & entity,const Location & refLocation)355 EntityOriginImpl::EntityOriginImpl(const ConstPtr<Entity> &entity,
356 				   const Location &refLocation)
357 : InputSourceOriginImpl(refLocation), refLength_(0), entity_(entity)
358 {
359 }
360 
EntityOriginImpl(const ConstPtr<Entity> & entity,const Location & refLocation,Index refLength,Owner<Markup> & markup)361 EntityOriginImpl::EntityOriginImpl(const ConstPtr<Entity> &entity,
362 				   const Location &refLocation,
363 				   Index refLength,
364 				   Owner<Markup> &markup)
365 : InputSourceOriginImpl(refLocation), refLength_(refLength), entity_(entity)
366 {
367   markup.swap(markup_);
368 }
369 
~EntityOriginImpl()370 EntityOriginImpl::~EntityOriginImpl()
371 {
372 }
373 
copy() const374 InputSourceOrigin *EntityOriginImpl::copy() const
375 {
376   Owner<Markup> m;
377   if (markup_)
378     m = new Markup(*markup_);
379   return new EntityOriginImpl(entity_, parent(), refLength_, m);
380 }
381 
refLength() const382 Index EntityOriginImpl::refLength() const
383 {
384   return refLength_;
385 }
386 
asEntityOrigin() const387 const EntityOrigin *EntityOriginImpl::asEntityOrigin() const
388 {
389   return this;
390 }
391 
defLocation(Offset off,const Origin * & origin,Index & index) const392 Boolean EntityOriginImpl::defLocation(Offset off, const Origin *&origin, Index &index) const
393 {
394   if (entity_.isNull())
395     return 0;
396   const InternalEntity *internal = entity_->asInternalEntity();
397   if (!internal)
398     return 0;
399   return internal->text().charLocation(off, origin, index);
400 }
401 
entityDecl() const402 const EntityDecl *EntityOriginImpl::entityDecl() const
403 {
404   return entity_.pointer();
405 }
406 
markup() const407 const Markup *EntityOriginImpl::markup() const
408 {
409   return markup_.pointer();
410 }
411 
412 
ReplacementOrigin(const Location & loc,Char origChar)413 ReplacementOrigin::ReplacementOrigin(const Location &loc, Char origChar)
414 : loc_(loc), origChar_(origChar)
415 {
416 }
417 
parent() const418 const Location &ReplacementOrigin::parent() const
419 {
420   return loc_;
421 }
422 
origChars(const Char * & s) const423 Boolean ReplacementOrigin::origChars(const Char *&s) const
424 {
425   if (loc_.origin().isNull() || !loc_.origin()->origChars(s))
426     s = &origChar_;
427   return 1;
428 }
429 
MultiReplacementOrigin(const Location & loc,StringC & origChars)430 MultiReplacementOrigin::MultiReplacementOrigin(const Location &loc,
431 					       StringC &origChars)
432 : loc_(loc)
433 {
434   origChars.swap(origChars_);
435 }
436 
parent() const437 const Location &MultiReplacementOrigin::parent() const
438 {
439   return loc_;
440 }
441 
origChars(const Char * & s) const442 Boolean MultiReplacementOrigin::origChars(const Char *&s) const
443 {
444   if (loc_.origin().isNull() || !loc_.origin()->origChars(s))
445     s = origChars_.data();
446   return 1;
447 }
448 
ProxyOrigin(const Origin * origin)449 ProxyOrigin::ProxyOrigin(const Origin *origin)
450 : origin_(origin)
451 {
452 }
453 
asEntityOrigin() const454 const EntityOrigin *ProxyOrigin::asEntityOrigin() const
455 {
456   return origin_->asEntityOrigin();
457 }
458 
asInputSourceOrigin() const459 const InputSourceOrigin *ProxyOrigin::asInputSourceOrigin() const
460 {
461   return origin_->asInputSourceOrigin();
462 }
463 
parent() const464 const Location &ProxyOrigin::parent() const
465 {
466   return origin_->parent();
467 }
468 
refLength() const469 Index ProxyOrigin::refLength() const
470 {
471   return origin_->refLength();
472 }
473 
origChars(const Char * & p) const474 Boolean ProxyOrigin::origChars(const Char *&p) const
475 {
476   return origin_->origChars(p);
477 }
478 
inBracketedTextOpenDelim() const479 Boolean ProxyOrigin::inBracketedTextOpenDelim() const
480 {
481   return origin_->inBracketedTextOpenDelim();
482 }
483 
inBracketedTextCloseDelim() const484 Boolean ProxyOrigin::inBracketedTextCloseDelim() const
485 {
486   return origin_->inBracketedTextCloseDelim();
487 }
488 
isNumericCharRef(const Markup * & markup) const489 Boolean ProxyOrigin::isNumericCharRef(const Markup *&markup) const
490 {
491   return origin_->isNumericCharRef(markup);
492 }
493 
isNamedCharRef(Index ind,NamedCharRef & ref) const494 Boolean ProxyOrigin::isNamedCharRef(Index ind, NamedCharRef &ref) const
495 {
496   return origin_->isNamedCharRef(ind, ref);
497 }
498 
entityDecl() const499 const EntityDecl *ProxyOrigin::entityDecl() const
500 {
501   return origin_->entityDecl();
502 }
503 
defLocation(Offset off,const Origin * & origin,Index & index) const504 Boolean ProxyOrigin::defLocation(Offset off, const Origin *&origin, Index &index) const
505 {
506   return origin_->defLocation(off, origin, index);
507 }
508 
markup() const509 const Markup *ProxyOrigin::markup() const
510 {
511   return origin_->markup();
512 }
513 
entity() const514 const Entity *ProxyOrigin::entity() const
515 {
516   return origin_->entity();
517 }
518 
externalInfo() const519 const ExternalInfo *ProxyOrigin::externalInfo() const
520 {
521   return origin_->externalInfo();
522 }
523 
startOffset(Index ind) const524 Offset ProxyOrigin::startOffset(Index ind) const
525 {
526   return origin_->startOffset(ind);
527 }
528 
~ExternalInfo()529 ExternalInfo::~ExternalInfo()
530 {
531 }
532 
RTTI_DEF0(ExternalInfo)533 RTTI_DEF0(ExternalInfo)
534 
535 NamedCharRef::NamedCharRef()
536 {
537 }
538 
NamedCharRef(Index refStartIndex,RefEndType refEndType,const StringC & origName)539 NamedCharRef::NamedCharRef(Index refStartIndex, RefEndType refEndType,
540 			   const StringC &origName)
541 : refStartIndex_(refStartIndex),
542   refEndType_(refEndType),
543   origName_(origName)
544 {
545 }
546 
set(Index refStartIndex,RefEndType refEndType,const Char * s,size_t n)547 void NamedCharRef::set(Index refStartIndex, RefEndType refEndType,
548 		       const Char *s, size_t n)
549 {
550   refStartIndex_ = refStartIndex;
551   refEndType_ = refEndType;
552   origName_.assign(s, n);
553 }
554 
555 #ifdef SP_NAMESPACE
556 }
557 #endif
558