xref: /onnv-gate/usr/src/cmd/man/src/util/nsgmls.src/lib/OutputState.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 "OutputState.h"
10 #include "Event.h"
11 #include "Allocator.h"
12 
13 #ifdef SP_NAMESPACE
14 namespace SP_NAMESPACE {
15 #endif
16 
OutputState()17 OutputState::OutputState()
18 {
19   init();
20 }
21 
init()22 void OutputState::init()
23 {
24   nextSerial_ = 0;
25   stack_.clear();
26   stack_.insert(new OutputStateLevel);
27 }
28 
OutputStateLevel()29 OutputStateLevel::OutputStateLevel()
30 : state(OutputState::afterStartTag)
31 {
32 }
33 
handleRe(EventHandler & handler,Allocator & alloc,const EventsWanted & eventsWanted,Char re,const Location & location)34 void OutputState::handleRe(EventHandler &handler, Allocator &alloc,
35 			   const EventsWanted &eventsWanted, Char re,
36 			   const Location &location)
37 {
38   re_ = re;
39   if (eventsWanted.wantInstanceMarkup())
40     handler.reOrigin(new (alloc) ReOriginEvent(re_, location, nextSerial_));
41   switch (top().state) {
42   case afterStartTag:
43     // it's the first RE in the element
44     if (eventsWanted.wantInstanceMarkup())
45       handler.ignoredRe(new (alloc) IgnoredReEvent(re_, location, nextSerial_++));
46     top().state = afterRsOrRe;
47     break;
48   case afterRsOrRe:
49   case afterData:
50     top().state = pendingAfterRsOrRe;
51     top().reLocation = location;
52     top().reSerial = nextSerial_++;
53     break;
54   case pendingAfterRsOrRe:
55     // We now know that the pending RE won't be ignored as the last RE.
56     handler.data(new (alloc) ReEvent(&re_, top().reLocation, top().reSerial));
57     top().state = pendingAfterRsOrRe;
58     top().reLocation = location;
59     top().reSerial = nextSerial_++;
60     break;
61   case pendingAfterMarkup:
62     // We've had only markup since the last RS or RE, so this
63     // RE is ignored.  Note that it's this RE that's ignored, not
64     // the pending one.
65     if (eventsWanted.wantInstanceMarkup())
66       handler.ignoredRe(new (alloc) IgnoredReEvent(re_, location, nextSerial_++));
67     top().state = pendingAfterRsOrRe;
68     break;
69   }
70 }
71 
noteRs(EventHandler &,Allocator &,const EventsWanted &)72 void OutputState::noteRs(EventHandler &, Allocator &, const EventsWanted &)
73 {
74   if (top().hasPendingRe())
75     top().state = pendingAfterRsOrRe;
76   else
77     top().state = afterRsOrRe;
78 }
79 
noteMarkup(EventHandler &,Allocator &,const EventsWanted &)80 void OutputState::noteMarkup(EventHandler &, Allocator &, const EventsWanted &)
81 {
82   switch (top().state) {
83   case afterRsOrRe:
84     top().state = afterStartTag;
85     break;
86   case pendingAfterRsOrRe:
87     top().state = pendingAfterMarkup;
88     break;
89   default:
90     break;			// avoid warning
91   }
92 }
93 
noteData(EventHandler & handler,Allocator & alloc,const EventsWanted &)94 void OutputState::noteData(EventHandler &handler, Allocator &alloc,
95 			   const EventsWanted &)
96 {
97   if (top().hasPendingRe())
98     handler.data(new (alloc) ReEvent(&re_, top().reLocation, top().reSerial));
99   top().state = afterData;
100 }
101 
noteStartElement(Boolean included,EventHandler & handler,Allocator & alloc,const EventsWanted &)102 void OutputState::noteStartElement(Boolean included,
103 				   EventHandler &handler, Allocator &alloc,
104 				   const EventsWanted &)
105 {
106   if (included)
107     stack_.insert(new OutputStateLevel);
108   else {
109     if (top().hasPendingRe())
110       handler.data(new (alloc) ReEvent(&re_, top().reLocation, top().reSerial));
111     top().state = afterStartTag;
112   }
113 }
114 
noteEndElement(Boolean included,EventHandler & handler,Allocator & alloc,const EventsWanted & eventsWanted)115 void OutputState::noteEndElement(Boolean included, EventHandler &handler,
116 				 Allocator &alloc,
117 				 const EventsWanted &eventsWanted)
118 {
119   if (eventsWanted.wantInstanceMarkup() && top().hasPendingRe())
120     handler.ignoredRe(new (alloc) IgnoredReEvent(re_, top().reLocation,
121 						 top().reSerial));
122   if (included) {
123     delete stack_.get();
124     noteMarkup(handler, alloc, eventsWanted);
125   }
126   else
127     top().state = afterData;
128 }
129 
130 #ifdef SP_NAMESPACE
131 }
132 #endif
133