]> git.ipfire.org Git - thirdparty/squid.git/blob - src/acl/BoolOps.cc
Merged from trunk r12948.
[thirdparty/squid.git] / src / acl / BoolOps.cc
1 #include "squid.h"
2 #include "acl/BoolOps.h"
3 #include "acl/Checklist.h"
4 #include "Debug.h"
5 #include "wordlist.h"
6
7 /* Acl::NotNode */
8
9 Acl::NotNode::NotNode(ACL *acl)
10 {
11 assert(acl);
12 name[0] = '!';
13 strncat(&name[1], acl->name, sizeof(name)-1-1);
14 add(acl);
15 }
16
17 void
18 Acl::NotNode::parse()
19 {
20 // Not implemented: by the time an upper level parser discovers
21 // an '!' operator, there is nothing left for us to parse.
22 assert(false);
23 }
24
25 int
26 Acl::NotNode::doMatch(ACLChecklist *checklist, Nodes::const_iterator start) const
27 {
28 assert(start == nodes.begin()); // we only have one node
29
30 if (checklist->matchChild(this, start, *start))
31 return 0; // converting match into mismatch
32
33 if (!checklist->keepMatching())
34 return -1; // suspend on async calls and stop on failures
35
36 return 1; // converting mismatch into match
37 }
38
39 char const *
40 Acl::NotNode::typeString() const
41 {
42 return "!";
43 }
44
45 ACL *
46 Acl::NotNode::clone() const
47 {
48 // Not implemented: we are not a named ACL type in squid.conf so nobody
49 // should try to create a NotNode instance by ACL type name (which is
50 // what clone() API is for -- it does not really clone anything).
51 assert(false);
52 return NULL;
53 }
54
55 wordlist*
56 Acl::NotNode::dump() const
57 {
58 wordlist *text = NULL;
59 wordlistAdd(&text, name);
60 return text;
61 }
62
63 /* Acl::AndNode */
64
65 char const *
66 Acl::AndNode::typeString() const
67 {
68 return "and";
69 }
70
71 ACL *
72 Acl::AndNode::clone() const
73 {
74 return new AndNode;
75 }
76
77 int
78 Acl::AndNode::doMatch(ACLChecklist *checklist, Nodes::const_iterator start) const
79 {
80 // find the first node that does not match
81 for (Nodes::const_iterator i = start; i != nodes.end(); ++i) {
82 if (!checklist->matchChild(this, i, *i))
83 return checklist->keepMatching() ? 0 : -1;
84 }
85
86 // one and not zero on empty because in math empty product equals identity
87 return 1; // no mismatches found (i.e., all kids matched)
88 }
89
90 void
91 Acl::AndNode::parse()
92 {
93 // Not implemented: AndNode cannot be configured directly. See Acl::AllOf.
94 assert(false);
95 }
96
97 /* Acl::OrNode */
98
99 char const *
100 Acl::OrNode::typeString() const
101 {
102 return "any-of";
103 }
104
105 ACL *
106 Acl::OrNode::clone() const
107 {
108 return new OrNode;
109 }
110
111 int
112 Acl::OrNode::doMatch(ACLChecklist *checklist, Nodes::const_iterator start) const
113 {
114 lastMatch_ = nodes.end();
115
116 // find the first node that matches, but stop if things go wrong
117 for (Nodes::const_iterator i = start; i != nodes.end(); ++i) {
118 if (checklist->matchChild(this, i, *i)) {
119 lastMatch_ = i;
120 return 1;
121 }
122
123 if (!checklist->keepMatching())
124 return -1; // suspend on async calls and stop on failures
125 }
126
127 // zero and not one on empty because in math empty sum equals zero
128 return 0; // all nodes mismatched
129 }
130
131 void
132 Acl::OrNode::parse()
133 {
134 // Not implemented: OrNode cannot be configured directly. See Acl::AnyOf.
135 assert(false);
136 }