| 1 |
/* |
|---|
| 2 |
www.sourceforge.net/projects/tinyxpath |
|---|
| 3 |
Copyright (c) 2002-2004 Yves Berquin (yvesb@users.sourceforge.net) |
|---|
| 4 |
|
|---|
| 5 |
This software is provided 'as-is', without any express or implied |
|---|
| 6 |
warranty. In no event will the authors be held liable for any |
|---|
| 7 |
damages arising from the use of this software. |
|---|
| 8 |
|
|---|
| 9 |
Permission is granted to anyone to use this software for any |
|---|
| 10 |
purpose, including commercial applications, and to alter it and |
|---|
| 11 |
redistribute it freely, subject to the following restrictions: |
|---|
| 12 |
|
|---|
| 13 |
1. The origin of this software must not be misrepresented; you must |
|---|
| 14 |
not claim that you wrote the original software. If you use this |
|---|
| 15 |
software in a product, an acknowledgment in the product documentation |
|---|
| 16 |
would be appreciated but is not required. |
|---|
| 17 |
|
|---|
| 18 |
2. Altered source versions must be plainly marked as such, and |
|---|
| 19 |
must not be misrepresented as being the original software. |
|---|
| 20 |
|
|---|
| 21 |
3. This notice may not be removed or altered from any source |
|---|
| 22 |
distribution. |
|---|
| 23 |
*/ |
|---|
| 24 |
|
|---|
| 25 |
/** |
|---|
| 26 |
\file xpath_stack.h |
|---|
| 27 |
\author Yves Berquin |
|---|
| 28 |
*/ |
|---|
| 29 |
module xpath.xpath_stack; |
|---|
| 30 |
private { |
|---|
| 31 |
import xpath.xpath_stream; |
|---|
| 32 |
import xpath.xpath_expression; |
|---|
| 33 |
import xpath.xpath_processor; |
|---|
| 34 |
import xpath.node_set; |
|---|
| 35 |
debug import std.stdio; |
|---|
| 36 |
|
|---|
| 37 |
|
|---|
| 38 |
class result_and_next |
|---|
| 39 |
{ |
|---|
| 40 |
private expression_result myE; |
|---|
| 41 |
public { |
|---|
| 42 |
/// Constructor |
|---|
| 43 |
this (expression_result er_in, result_and_next rnp_in_next) |
|---|
| 44 |
{ |
|---|
| 45 |
myE = er_in; |
|---|
| 46 |
rnp_next = rnp_in_next; |
|---|
| 47 |
} |
|---|
| 48 |
/// Return next element |
|---|
| 49 |
result_and_next rnp_get_next () |
|---|
| 50 |
{ |
|---|
| 51 |
return rnp_next; |
|---|
| 52 |
} |
|---|
| 53 |
} |
|---|
| 54 |
debug { |
|---|
| 55 |
void v_dump() |
|---|
| 56 |
{ |
|---|
| 57 |
myE.v_dump(); |
|---|
| 58 |
} |
|---|
| 59 |
} |
|---|
| 60 |
protected { |
|---|
| 61 |
/// Next element in the stack |
|---|
| 62 |
result_and_next rnp_next; |
|---|
| 63 |
} |
|---|
| 64 |
}; |
|---|
| 65 |
|
|---|
| 66 |
} |
|---|
| 67 |
public |
|---|
| 68 |
{ |
|---|
| 69 |
|
|---|
| 70 |
|
|---|
| 71 |
|
|---|
| 72 |
/// The XPath execution stack |
|---|
| 73 |
/// \n All elements are result_and_next elements |
|---|
| 74 |
class xpath_stack |
|---|
| 75 |
{ |
|---|
| 76 |
public : |
|---|
| 77 |
debug |
|---|
| 78 |
void v_dump () |
|---|
| 79 |
{ |
|---|
| 80 |
result_and_next rnp_ptr; |
|---|
| 81 |
|
|---|
| 82 |
writefln("--- stack start (%d elem) ---", u_size); |
|---|
| 83 |
rnp_ptr = rnp_first; |
|---|
| 84 |
while (rnp_ptr) |
|---|
| 85 |
{ |
|---|
| 86 |
rnp_ptr.v_dump (); |
|---|
| 87 |
rnp_ptr = rnp_ptr.rnp_get_next (); |
|---|
| 88 |
} |
|---|
| 89 |
writefln("--- stack end ---"); |
|---|
| 90 |
} |
|---|
| 91 |
|
|---|
| 92 |
|
|---|
| 93 |
this() { rnp_first = null; u_size = 0; } |
|---|
| 94 |
~ this() { while (rnp_first) v_pop_one(); } |
|---|
| 95 |
void v_push (expression_result er_res) |
|---|
| 96 |
{ |
|---|
| 97 |
result_and_next rnp_new; |
|---|
| 98 |
|
|---|
| 99 |
rnp_new = new result_and_next (er_res, rnp_first); |
|---|
| 100 |
rnp_first = rnp_new; |
|---|
| 101 |
u_size++; |
|---|
| 102 |
} |
|---|
| 103 |
|
|---|
| 104 |
void v_push_int (int i_elem, char[] cp_comment = "") |
|---|
| 105 |
{ |
|---|
| 106 |
expression_result er_res = new expression_result; |
|---|
| 107 |
er_res . v_set_int (i_elem); |
|---|
| 108 |
if (cp_comment) |
|---|
| 109 |
er_res . v_set_comment (cp_comment); |
|---|
| 110 |
v_push (er_res); |
|---|
| 111 |
} |
|---|
| 112 |
|
|---|
| 113 |
void v_push_bool (bool o_in) |
|---|
| 114 |
{ |
|---|
| 115 |
expression_result er_res = new expression_result; |
|---|
| 116 |
er_res . v_set_bool (o_in); |
|---|
| 117 |
v_push (er_res); |
|---|
| 118 |
} |
|---|
| 119 |
|
|---|
| 120 |
void v_push_string (char[] S_in) |
|---|
| 121 |
{ |
|---|
| 122 |
expression_result er_res = new expression_result(); |
|---|
| 123 |
er_res . v_set_string (S_in); |
|---|
| 124 |
v_push (er_res); |
|---|
| 125 |
} |
|---|
| 126 |
|
|---|
| 127 |
void v_push_double (double d_elem) |
|---|
| 128 |
{ |
|---|
| 129 |
expression_result er_res = new expression_result; |
|---|
| 130 |
er_res . v_set_double (d_elem); |
|---|
| 131 |
v_push (er_res); |
|---|
| 132 |
} |
|---|
| 133 |
|
|---|
| 134 |
void v_push_node_set (node_set nsp_ptr) |
|---|
| 135 |
{ |
|---|
| 136 |
expression_result er_res = new expression_result; |
|---|
| 137 |
er_res . v_set_node_set (nsp_ptr); |
|---|
| 138 |
v_push (er_res); |
|---|
| 139 |
} |
|---|
| 140 |
|
|---|
| 141 |
|
|---|
| 142 |
expression_result erp_top () |
|---|
| 143 |
{ |
|---|
| 144 |
if (! rnp_first) |
|---|
| 145 |
throw new execution_error (34); |
|---|
| 146 |
return rnp_first.myE; |
|---|
| 147 |
} |
|---|
| 148 |
|
|---|
| 149 |
int i_top_int () |
|---|
| 150 |
{ |
|---|
| 151 |
int i_res; |
|---|
| 152 |
|
|---|
| 153 |
i_res = erp_top () . i_get_int (); |
|---|
| 154 |
return i_res; |
|---|
| 155 |
} |
|---|
| 156 |
|
|---|
| 157 |
|
|---|
| 158 |
void v_pop (uint u_nb = 1) |
|---|
| 159 |
{ |
|---|
| 160 |
uint u_elem; |
|---|
| 161 |
|
|---|
| 162 |
for (u_elem = 0; u_elem < u_nb; u_elem++) |
|---|
| 163 |
v_pop_one (); |
|---|
| 164 |
} |
|---|
| 165 |
|
|---|
| 166 |
int i_pop_int () |
|---|
| 167 |
{ |
|---|
| 168 |
int i_res; |
|---|
| 169 |
|
|---|
| 170 |
i_res = erp_top().i_get_int (); |
|---|
| 171 |
v_pop (); |
|---|
| 172 |
return i_res; |
|---|
| 173 |
} |
|---|
| 174 |
|
|---|
| 175 |
char[] S_pop_string () |
|---|
| 176 |
{ |
|---|
| 177 |
char[] S_res; |
|---|
| 178 |
|
|---|
| 179 |
S_res = erp_top () . S_get_string (); |
|---|
| 180 |
v_pop (); |
|---|
| 181 |
return S_res; |
|---|
| 182 |
} |
|---|
| 183 |
|
|---|
| 184 |
bool o_pop_bool () |
|---|
| 185 |
{ |
|---|
| 186 |
bool o_res; |
|---|
| 187 |
|
|---|
| 188 |
o_res = erp_top ().o_get_bool (); |
|---|
| 189 |
v_pop (); |
|---|
| 190 |
return o_res; |
|---|
| 191 |
} |
|---|
| 192 |
node_set ns_pop_node_set () |
|---|
| 193 |
{ |
|---|
| 194 |
node_set ns_ret; |
|---|
| 195 |
|
|---|
| 196 |
ns_ret = erp_top () . nsp_get_node_set (); |
|---|
| 197 |
v_pop (); |
|---|
| 198 |
return ns_ret; |
|---|
| 199 |
} |
|---|
| 200 |
|
|---|
| 201 |
/// Return the stack's size |
|---|
| 202 |
uint u_get_size () {return u_size;} |
|---|
| 203 |
expression_result erp_previous (uint u_nb) |
|---|
| 204 |
{ |
|---|
| 205 |
result_and_next rnp_current; |
|---|
| 206 |
uint u_prev; |
|---|
| 207 |
|
|---|
| 208 |
assert (u_nb <= u_size); |
|---|
| 209 |
rnp_current = rnp_first; |
|---|
| 210 |
for (u_prev = 0; u_prev < u_nb; u_prev++) |
|---|
| 211 |
{ |
|---|
| 212 |
assert (rnp_current); |
|---|
| 213 |
rnp_current = rnp_current . rnp_get_next (); |
|---|
| 214 |
} |
|---|
| 215 |
return rnp_current.myE; |
|---|
| 216 |
} |
|---|
| 217 |
|
|---|
| 218 |
|
|---|
| 219 |
protected : |
|---|
| 220 |
/// First element in the stack |
|---|
| 221 |
result_and_next rnp_first; |
|---|
| 222 |
/// Stack size |
|---|
| 223 |
uint u_size; |
|---|
| 224 |
void v_pop_one () |
|---|
| 225 |
{ |
|---|
| 226 |
result_and_next rnp_old; |
|---|
| 227 |
|
|---|
| 228 |
if (! u_size) |
|---|
| 229 |
throw new execution_error (35); |
|---|
| 230 |
if (! rnp_first) |
|---|
| 231 |
throw new execution_error (36); |
|---|
| 232 |
rnp_old = rnp_first; |
|---|
| 233 |
rnp_first = rnp_first.rnp_get_next; |
|---|
| 234 |
delete rnp_old; |
|---|
| 235 |
u_size--; |
|---|
| 236 |
} |
|---|
| 237 |
|
|---|
| 238 |
} ; |
|---|
| 239 |
|
|---|
| 240 |
} |
|---|