31#include "d4_ce_parser.tab.hh"
42#define PREVENT_XXS_VIA_CE 1
43#if NDEBUG && !PREVENT_XXS_VIA_CE
44#error("Never release libdap with PREVENT_XXS_VIA_CE turned off")
54 d_dmr->set_ce_empty(
true);
58 std::istringstream iss(expr);
63 parser.set_debug_level(1);
64 parser.set_debug_stream(std::cerr);
67 return parser.parse() == 0;
76[[noreturn]]
void D4ConstraintEvaluator::throw_not_found(
const string & ,
const string & ) {
79 string(
"The constraint expression referenced a variable that was not found in the dataset."));
81 throw Error(
no_such_variable, d_expr +
": The variable " +
id +
" was not found in the dataset (" + ident +
").");
85[[noreturn]]
void D4ConstraintEvaluator::throw_not_array(
const string & ,
const string & ) {
88 string(
"The constraint expression referenced an Array that was not found in the dataset."));
90 throw Error(
no_such_variable, d_expr +
": The variable '" +
id +
"' is not an Array variable (" + ident +
").");
94void D4ConstraintEvaluator::search_for_and_mark_arrays(
BaseType *btp) {
95 DBG(cerr <<
"Entering D4ConstraintEvaluator::search_for_and_mark_arrays...(" << btp->name() <<
")" << endl);
97 if (!btp->is_constructor_type())
98 throw InternalErr(__FILE__, __LINE__,
99 "D4ConstraintEvaluator::search_for_and_mark_arrays(): Expected a Constructor type.");
101 auto ctor =
static_cast<Constructor *
>(btp);
102 for (
auto var : ctor->variables()) {
103 switch (var->type()) {
105 DBG(cerr <<
"Found an array: " << (*i)->name() << endl);
106 mark_array_variable(var);
110 DBG(cerr <<
"Found a ctor: " << (*i)->name() << endl);
111 search_for_and_mark_arrays(var);
130 throw InternalErr(__FILE__, __LINE__,
131 "D4ConstraintEvaluator::mark_variable(): Expected a non-null BaseType pointer.");
133 DBG(cerr <<
"In D4ConstraintEvaluator::mark_variable... (" << btp->name() <<
"; " << btp->type_name() <<
")"
136 btp->set_send_p(
true);
139 mark_array_variable(btp);
143 if (btp->is_constructor_type()) {
144 search_for_and_mark_arrays(btp);
145 }
else if (btp->type() ==
dods_array_c && btp->var() && btp->var()->is_constructor_type()) {
146 search_for_and_mark_arrays(btp->var());
150 BaseType *parent = btp->get_parent();
152 parent->BaseType::set_send_p(
true);
153 parent = parent->get_parent();
159static bool array_uses_shared_dimension(
Array *map,
const D4Dimension *source_dim) {
160 for (
auto d = map->dim_begin(), e = map->dim_end(); d != e; ++d) {
161 if (source_dim->name() == (*d).name)
185 throw InternalErr(__FILE__, __LINE__,
"D4ConstraintEvaluator::mark_array_variable(): Expected an Array type.");
187 auto *a =
static_cast<Array *
>(btp);
192 if (d_indexes.empty()) {
193 for (
auto d = a->dim_begin(), de = a->dim_end(); d != de; ++d) {
194 D4Dimension *dim = a->dimension_D4dim(d);
196 a->add_constraint(d, dim);
201 if (d_indexes.size() != a->dimensions())
202 throw Error(
malformed_expr,
"The index constraint for '" + btp->name() +
"' does not match its rank.");
204 auto d = a->dim_begin();
205 for (
auto const &index : d_indexes) {
206 if (d == a->dim_end())
207 throw Error(
malformed_expr,
"The index constraint for '" + btp->name() +
"' does not match its rank.");
209 if (index.stride > (a->dimension_stop_ll(d,
false) - a->dimension_start_ll(d,
false)) + 1)
211 "For '" + btp->name() +
212 "', the index stride value is greater than the number of elements in the Array");
213 if (!index.rest && index.stop > (a->dimension_stop_ll(d,
false) - a->dimension_start_ll(d,
false)) + 1)
215 "For '" + btp->name() +
216 "', the index stop value is greater than the number of elements in the Array");
218 D4Dimension *dim = a->dimension_D4dim(d);
225 if (dim && index.empty) {
229 a->add_constraint(d, dim);
236 use_explicit_projection(a, d, index);
255 auto root =
dynamic_cast<D4Group *
>(a->get_ancestor());
257 throw InternalErr(__FILE__, __LINE__,
"Expected a valid ancestor Group.");
259 for (
auto m = a->maps()->map_begin(), e = a->maps()->map_end(); m != e; ++m) {
262 auto *map = (*m)->array(root);
263 if (dim && array_uses_shared_dimension(map, dim)) {
264 D4Map *map_to_be_removed = *m;
265 a->maps()->remove_map(map_to_be_removed);
266 delete map_to_be_removed;
280 const D4ConstraintEvaluator::index &index) {
282 a->add_constraint_ll(dim_iter, index.start, index.stride, index.rest ? -1 : index.stop);
293 if (!a->maps()->empty()) {
296 int map_size = a->maps()->size();
297 for (
int map_index = 0; map_index < map_size; map_index++) {
298 array_map_remover(a, a->dimension_D4dim(dim_iter));
311D4Dimension *D4ConstraintEvaluator::slice_dimension(
const std::string &
id,
const index &i) {
314 if ((uint64_t)i.stride > dim->size())
316 "For '" +
id +
"', the index stride value is greater than the size of the dimension");
317 if (!i.rest && ((uint64_t)i.stop > dim->size() - 1))
318 throw Error(
malformed_expr,
"For '" +
id +
"', the index stop value is greater than the size of the dimension");
320 dim->set_constraint(i.start, i.stride, i.rest ? dim->size() - 1 : i.stop);
325D4ConstraintEvaluator::index D4ConstraintEvaluator::make_index(
const std::string &i) {
327 return {v, 1, v,
false,
false ,
""};
330D4ConstraintEvaluator::index D4ConstraintEvaluator::make_index(
const std::string &i,
const std::string &s,
331 const std::string &e) {
335 throw Error(
malformed_expr,
string(
"The start value of an array index is past the stop value."));
337 return {initial,
get_int64(s.c_str()), end,
false,
false ,
""};
340D4ConstraintEvaluator::index D4ConstraintEvaluator::make_index(
const std::string &i, int64_t s,
const std::string &e) {
344 throw Error(
malformed_expr,
string(
"The start value of an array index is past the stop value."));
346 return {initial, s, end,
false,
false ,
""};
349D4ConstraintEvaluator::index D4ConstraintEvaluator::make_index(
const std::string &i,
const std::string &s) {
353D4ConstraintEvaluator::index D4ConstraintEvaluator::make_index(
const std::string &i, int64_t s) {
354 return {
get_int64(i.c_str()), s, 0,
true,
false ,
""};
357static string expr_msg(
const std::string &op,
const std::string &arg1,
const std::string &arg2) {
358 return "(" + arg1 +
" " + op +
" " + arg2 +
").";
379 DBGN(cerr <<
"Entering " << __PRETTY_FUNCTION__ << endl <<
"op: " << op << endl);
420void D4ConstraintEvaluator::add_filter_clause(
const std::string &op,
const std::string &arg1,
421 const std::string &arg2)
const {
422 DBG(cerr <<
"Entering: " << __PRETTY_FUNCTION__ << endl);
425 auto s =
dynamic_cast<D4Sequence *
>(top_basetype());
427 throw Error(
malformed_expr,
"When a filter expression is used, it must be bound to a Sequence variable: " +
428 expr_msg(op, arg1, arg2));
430 DBG(cerr <<
"s->name(): " << s->name() << endl);
433 BaseType *a1 = s->var(arg1);
434 BaseType *a2 = s->var(arg2);
435 DBG(cerr <<
"a1: " << a1 <<
", a2: " << a2 << endl);
439 "One of the arguments in a filter expression must be a constant: " + expr_msg(op, arg1, arg2));
441 throw Error(
malformed_expr,
"One of the arguments in a filter expression must be a variable in a Sequence: " +
442 expr_msg(op, arg1, arg2));
446 s->clauses().add_clause(
new D4FilterClause(get_op_code(op),
new D4RValue(a1),
D4RValueFactory(arg2)));
448 s->clauses().add_clause(
new D4FilterClause(get_op_code(op),
D4RValueFactory(arg1),
new D4RValue(a2)));
458string &D4ConstraintEvaluator::remove_quotes(
string &s) {
459 if (*s.begin() ==
'\"' && *(s.end() - 1) ==
'\"') {
461 s.erase(s.end() - 1);
475#if PREVENT_XXS_VIA_CE
476 oss <<
"Constraint expression parse error: " << m << ends;
478 oss << l <<
": " << m << ends;
#define malformed_expr
(400)
#define no_such_variable
(400)
A multidimensional array of identical data types.
std::vector< dimension >::iterator Dim_iter
The basic data type for the DODS DAP types.
bool parse(const std::string &expr)
static void error(const libdap::location &l, const std::string &m)
bool trace_parsing() const
D4Dimension * find_dim(const string &path)
Find the dimension using a path. Using the DAP4 name syntax, lookup a dimension. The dimension must b...
A class for error processing.
A class for software fault reporting.
long long get_int64(const char *val)
top level DAP object to house generic methods
D4RValue * D4RValueFactory(std::string cpps)
Build an appropriate RValue.