xref: /onnv-gate/usr/src/cmd/man/src/util/nsgmls.src/lib/LinkProcess.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 "LinkProcess.h"
10 // ParserState is used for access to parser messages
11 #include "ParserState.h"
12 #include "MessageArg.h"
13 #include "ParserMessages.h"
14 
15 #ifdef SP_NAMESPACE
16 namespace SP_NAMESPACE {
17 #endif
18 
LinkProcess()19 LinkProcess::LinkProcess()
20 {
21 }
22 
init(const ConstPtr<ComplexLpd> & lpd)23 void LinkProcess::init(const ConstPtr<ComplexLpd> &lpd)
24 {
25   lpd_ = lpd;
26   open_.clear();
27   open_.insert(new LinkProcessOpenElement(lpd_->initialLinkSet()));
28 }
29 
startElement(const ElementType * element,const AttributeList & attributes,const Location & location,Messenger & mgr,const AttributeList * & linkAttributes,const ResultElementSpec * & resultElementSpec)30 Boolean LinkProcess::startElement(const ElementType *element,
31 				  const AttributeList &attributes,
32 				  const Location &location,
33 				  Messenger &mgr,
34 				  const AttributeList *&linkAttributes,
35 				  const ResultElementSpec *&resultElementSpec)
36 {
37   if (lpd_.isNull()) {
38     linkAttributes = 0;
39     resultElementSpec = 0;
40     return 1;
41   }
42   const StringC *id = attributes.getId();
43   if (id) {
44     const IdLinkRuleGroup *p = lpd_->lookupIdLink(*id);
45     if (p) {
46       size_t selected;
47       if (p->nLinkRules() > 1) {
48 	linkAttributes_.resize(p->nLinkRules());
49 	for (size_t i = 0; i < linkAttributes_.size(); i++)
50 	  linkAttributes_[i] = &p->linkRule(i).attributes();
51 	if (!selectLinkRule(linkAttributes_,
52 			    location,
53 			    selected))
54 	  return 0;
55       }
56       else
57 	selected = 0;
58       const IdLinkRule &rule = p->linkRule(selected);
59       open_.insert(new LinkProcessOpenElement(open_.head()->current,
60 					      rule));
61       linkAttributes = &rule.attributes();
62       resultElementSpec = &rule.resultElementSpec();
63       if (!rule.isAssociatedWith(element)) {
64 	mgr.setNextLocation(location);
65 	mgr.message(ParserMessages::idlinkElementType,
66 		    StringMessageArg(element->name()),
67 		    StringMessageArg(*id));
68       }
69       return 1;
70     }
71   }
72   const LinkSet *currentLinkSet = open_.head()->current;
73   size_t nRules = currentLinkSet->nLinkRules(element);
74   if (nRules > 0) {
75     size_t selected;
76     if (nRules > 1) {
77       linkAttributes_.resize(nRules);
78       for (size_t i = 0; i < nRules; i++)
79 	linkAttributes_[i]
80 	  = &currentLinkSet->linkRule(element, i).attributes();
81       if (!selectLinkRule(linkAttributes_,
82 			  location,
83 			  selected))
84 	return 0;
85     }
86     else
87       selected = 0;
88     const SourceLinkRule &rule = currentLinkSet->linkRule(element, selected);
89     open_.insert(new LinkProcessOpenElement(open_.head()->current,
90 					    rule));
91     linkAttributes = &rule.attributes();
92     resultElementSpec = &rule.resultElementSpec();
93     return 1;
94   }
95   // FIXME construct attributes from attribute definition list
96   linkAttributes = 0;
97   resultElementSpec = 0;
98   open_.insert(new LinkProcessOpenElement(open_.head()->current));
99   return 1;
100 }
101 
102 
endElement()103 void LinkProcess::endElement()
104 {
105   if (lpd_.isNull())
106     return;
107   LinkProcessOpenElement *top = open_.get();
108   if (top->post)
109     open_.head()->current = top->post;
110   else if (top->postRestore)
111     open_.head()->current = open_.head()->restore;
112   delete top;
113 }
114 
uselink(const LinkSet * linkSet,Boolean restore,const Lpd * lpd)115 void LinkProcess::uselink(const LinkSet *linkSet,
116 			  Boolean restore,
117 			  const Lpd *lpd)
118 {
119   if (lpd_.isNull())
120     return;
121   if (lpd != lpd_.pointer())
122     return;
123   if (restore)
124     open_.head()->current = open_.head()->restore;
125   else if (linkSet)
126     open_.head()->current = linkSet;
127 }
128 
nImpliedLinkRules() const129 size_t LinkProcess::nImpliedLinkRules() const
130 {
131   if (!open_.head())
132     return 0;
133   return open_.head()->current->nImpliedLinkRules();
134 }
135 
impliedLinkRule(size_t i) const136 const ResultElementSpec &LinkProcess::impliedLinkRule(size_t i) const
137 {
138   return open_.head()->current->impliedLinkRule(i);
139 }
140 
141 // Usually redefined by application.
142 
selectLinkRule(const Vector<const AttributeList * > &,const Location &,size_t & selected)143 Boolean LinkProcess::selectLinkRule(const Vector<const AttributeList *> &,
144 				    const Location &,
145 				    size_t &selected)
146 {
147   selected = 0;
148   return 1;
149 }
150 
clear()151 void LinkProcess::clear()
152 {
153   open_.clear();
154   lpd_.clear();
155   linkAttributes_.clear();
156 }
157 
swap(LinkProcess & to)158 void LinkProcess::swap(LinkProcess &to)
159 {
160   open_.swap(to.open_);
161   lpd_.swap(to.lpd_);
162   linkAttributes_.swap(to.linkAttributes_);
163 }
164 
LinkProcessOpenElement(const LinkSet * cur,const SourceLinkRule & rule)165 LinkProcessOpenElement::LinkProcessOpenElement(const LinkSet *cur,
166 					       const SourceLinkRule &rule)
167 {
168   current = rule.uselink();
169   if (!current)
170     current = cur;
171   restore = cur;
172   post = rule.postlink();
173   postRestore = rule.postlinkRestore();
174 }
175 
LinkProcessOpenElement(const LinkSet * cur)176 LinkProcessOpenElement::LinkProcessOpenElement(const LinkSet *cur)
177 {
178   restore = current = cur;
179   post = 0;
180   postRestore = 0;
181 }
182 
183 
184 #ifdef SP_NAMESPACE
185 }
186 #endif
187