-
Notifications
You must be signed in to change notification settings - Fork 131
Expand file tree
/
Copy pathentlist.cc
More file actions
136 lines (119 loc) · 4.17 KB
/
entlist.cc
File metadata and controls
136 lines (119 loc) · 4.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*************************************************************************//**
* entlist.cc \class EntList *
* *
* Description: EntList is a class type which supports the concept of com- *
* plex inheritance. EntLists capture information on the *
* allowable types of complex entities. They represent this *
* information internally and may be used to validate a user *
* attempt to instantiate a complex instance. This file con- *
* tains member function definitions for EntList and for its *
* SimpleList subtype. *
* *
* Created by: David Rosenfeld *
* Date: 9/18/96 *
*****************************************************************************/
#include "complexSupport.h"
/**
* Returns the number of EntLists in this's list (EntList->next, next->next
* etc.) including this.
*/
int EntList::siblings() {
int count;
EntList * el;
for( count = 1, el = next; el; count++, el = el->next ) {
;
}
return count;
}
/**
* Returns the first EntList not of type join, starting from this.
*/
EntList * EntList::firstNot( JoinType j ) {
EntList * sibling = this;
while( sibling != NULL && sibling->join == j ) {
sibling = sibling->next;
}
return sibling; // (may = NULL)
}
/**
* Returns the first EntList where viable = match, starting from this.
*/
EntList * EntList::firstWanted( MatchType match ) {
EntList * sibling = this;
while( sibling != NULL && sibling->viable != match ) {
sibling = sibling->next;
}
return sibling; // (may = NULL)
}
/**
* Returns the last EntList not of type join, searching backwards from
* this.
*/
EntList * EntList::lastNot( JoinType j ) {
EntList * sibling = this;
while( sibling != NULL && sibling->join == j ) {
sibling = sibling->prev;
}
return sibling; // (may = NULL)
}
/**
* Returns the last EntList where viable = match, searching backwards from
* this.
*/
EntList * EntList::lastWanted( MatchType match ) {
EntList * sibling = this;
while( sibling != NULL && sibling->viable != match ) {
sibling = sibling->prev;
}
return sibling; // (may = NULL)
}
/**
* Unmarks the node that was marked by this List. Normally called when
* undoing an OR choice to try out another.
*/
void SimpleList::unmarkAll( EntNode * ents ) {
EntNode * eptr = ents;
int comp = -1;
if( viable < MATCHSOME ) {
return;
}
while( eptr != NULL && ( comp = strcmp( eptr->name, name ) ) < 0 ) {
eptr = eptr->next;
}
// (We assume we have a match now since viable >= MATCHSOME.)
if( eptr->mark <= I_marked ) {
// Only unmark if we gave it the strongest mark:
eptr->setmark( NOMARK );
}
// Either way (whether or not another List's mark remains), we no longer
// marked:
I_marked = NOMARK;
}
/**
* Marks whichever node we can mark. We assume there is a match because
* this function is only called by a parent MultList if its child had a
* viable val of MATCHSOME. Return true if we mark a previously unmarked
* node; otherwise false.
*/
bool SimpleList::acceptChoice( EntNode * ents ) {
EntNode * eptr = ents;
int comp;
while( eptr != NULL ) {
if( ( comp = strcmp( name, eptr->name ) ) == 0 ) {
if( ! eptr->marked() ) {
eptr->setmark( ORMARK );
I_marked = ORMARK;
// Remember that we're the one who marked this. (Nec. in case
// we have to unmark later to try out another OR branch.)
return true;
}
return false; // we didn't mark
}
if( comp < 0 ) {
// We're beyond name in the ents list. No more checking to do.
return false;
}
eptr = eptr->next;
}
return false;
}