Introduction of BSDArchitecture
[oweals/cde.git] / cde / programs / nsgmls / OutputState.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 librararies 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: OutputState.C /main/1 1996/07/29 16:59:44 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 "OutputState.h"
32 #include "Event.h"
33 #include "Allocator.h"
34
35 #ifdef SP_NAMESPACE
36 namespace SP_NAMESPACE {
37 #endif
38
39 OutputState::OutputState()
40 {
41   init();
42 }
43
44 void OutputState::init()
45 {
46   nextSerial_ = 0;
47   stack_.clear();
48   stack_.insert(new OutputStateLevel);
49 }
50
51 OutputStateLevel::OutputStateLevel()
52 : state(OutputState::afterStartTag)
53 {
54 }
55
56 void OutputState::handleRe(EventHandler &handler, Allocator &alloc,
57                            const EventsWanted &eventsWanted, Char re,
58                            const Location &location)
59 {
60   re_ = re;
61   if (eventsWanted.wantInstanceMarkup())
62     handler.reOrigin(new (alloc) ReOriginEvent(re_, location, nextSerial_));
63   switch (top().state) {
64   case afterStartTag:
65     // it's the first RE in the element
66     if (eventsWanted.wantInstanceMarkup())
67       handler.ignoredRe(new (alloc) IgnoredReEvent(re_, location, nextSerial_++));
68     top().state = afterRsOrRe;
69     break;
70   case afterRsOrRe:
71   case afterData:
72     top().state = pendingAfterRsOrRe;
73     top().reLocation = location;
74     top().reSerial = nextSerial_++;
75     break;
76   case pendingAfterRsOrRe:
77     // We now know that the pending RE won't be ignored as the last RE.
78     handler.data(new (alloc) ReEvent(&re_, top().reLocation, top().reSerial));
79     top().state = pendingAfterRsOrRe;
80     top().reLocation = location;
81     top().reSerial = nextSerial_++;
82     break;
83   case pendingAfterMarkup:
84     // We've had only markup since the last RS or RE, so this
85     // RE is ignored.  Note that it's this RE that's ignored, not
86     // the pending one.
87     if (eventsWanted.wantInstanceMarkup())
88       handler.ignoredRe(new (alloc) IgnoredReEvent(re_, location, nextSerial_++));
89     top().state = pendingAfterRsOrRe;
90     break;
91   }
92 }
93
94 void OutputState::noteRs(EventHandler &, Allocator &, const EventsWanted &)
95 {
96   if (top().hasPendingRe())
97     top().state = pendingAfterRsOrRe;
98   else
99     top().state = afterRsOrRe;
100 }
101
102 void OutputState::noteMarkup(EventHandler &, Allocator &, const EventsWanted &)
103 {
104   switch (top().state) {
105   case afterRsOrRe:
106     top().state = afterStartTag;
107     break;
108   case pendingAfterRsOrRe:
109     top().state = pendingAfterMarkup;
110     break;
111   default:
112     break;                      // avoid warning
113   }
114 }
115
116 void OutputState::noteData(EventHandler &handler, Allocator &alloc,
117                            const EventsWanted &)
118 {
119   if (top().hasPendingRe())
120     handler.data(new (alloc) ReEvent(&re_, top().reLocation, top().reSerial));
121   top().state = afterData;
122 }
123
124 void OutputState::noteStartElement(Boolean included,
125                                    EventHandler &handler, Allocator &alloc,
126                                    const EventsWanted &)
127 {
128   if (included)
129     stack_.insert(new OutputStateLevel);
130   else {
131     if (top().hasPendingRe())
132       handler.data(new (alloc) ReEvent(&re_, top().reLocation, top().reSerial));
133     top().state = afterStartTag;
134   }
135 }
136
137 void OutputState::noteEndElement(Boolean included, EventHandler &handler,
138                                  Allocator &alloc,
139                                  const EventsWanted &eventsWanted)
140 {
141   if (eventsWanted.wantInstanceMarkup() && top().hasPendingRe())
142     handler.ignoredRe(new (alloc) IgnoredReEvent(re_, top().reLocation,
143                                                  top().reSerial));
144   if (included) {
145     delete stack_.get();
146     noteMarkup(handler, alloc, eventsWanted);
147   }
148   else
149     top().state = afterData;
150 }
151
152 #ifdef SP_NAMESPACE
153 }
154 #endif