00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "config.h"
00026
00027 static char rcsid[] not_used =
00028 {"$Id: ConstraintEvaluator.cc 16612 2007-06-04 22:08:57Z jimg $"
00029 };
00030
00031 #include "ConstraintEvaluator.h"
00032
00033 #include "ce_functions.h"
00034 #include "parser.h"
00035 #include "ce_parser.h"
00036 #include "debug.h"
00037
00038 using namespace libdap;
00039
00040 struct yy_buffer_state;
00041 yy_buffer_state *ce_expr_scan_string(const char *str);
00042 int ce_exprparse(void *arg);
00043
00044
00045 void ce_expr_switch_to_buffer(void *new_buffer);
00046 void ce_expr_delete_buffer(void * buffer);
00047 void *ce_expr_string(const char *yy_str);
00048
00049 ConstraintEvaluator::ConstraintEvaluator()
00050 {
00051 register_functions(*this);
00052 }
00053
00054 ConstraintEvaluator::~ConstraintEvaluator()
00055 {
00056
00057 for (Constants_iter j = constants.begin(); j != constants.end(); j++) {
00058 BaseType *btp = *j ;
00059 delete btp ; btp = 0;
00060 }
00061
00062 for (Clause_iter k = expr.begin(); k != expr.end(); k++) {
00063 Clause *cp = *k ;
00064 delete cp ; cp = 0;
00065 }
00066 }
00067
00069 ConstraintEvaluator::Clause_iter
00070 ConstraintEvaluator::clause_begin()
00071 {
00072 return expr.begin() ;
00073 }
00074
00077 ConstraintEvaluator::Clause_iter
00078 ConstraintEvaluator::clause_end()
00079 {
00080 return expr.end() ;
00081 }
00082
00085 bool
00086 ConstraintEvaluator::clause_value(Clause_iter &iter, DDS &dds,
00087 const string &dataset)
00088 {
00089 if (expr.empty())
00090 throw InternalErr(__FILE__, __LINE__,
00091 "There are no CE clauses for *this* DDS object.");
00092
00093 return (*iter)->value(dataset, dds);
00094 }
00095
00108 void
00109 ConstraintEvaluator::append_clause(int op, rvalue *arg1, rvalue_list *arg2)
00110 {
00111 Clause *clause = new Clause(op, arg1, arg2);
00112
00113 expr.push_back(clause);
00114 }
00115
00125 void
00126 ConstraintEvaluator::append_clause(bool_func func, rvalue_list *args)
00127 {
00128 Clause *clause = new Clause(func, args);
00129
00130 expr.push_back(clause);
00131 }
00132
00142 void
00143 ConstraintEvaluator::append_clause(btp_func func, rvalue_list *args)
00144 {
00145 Clause *clause = new Clause(func, args);
00146
00147 expr.push_back(clause);
00148 }
00149
00157 void
00158 ConstraintEvaluator::append_constant(BaseType *btp)
00159 {
00160 constants.push_back(btp);
00161 }
00162
00163 class func_name_is
00164 {
00165 private:
00166 const string d_name;
00167
00168 public:
00169 func_name_is(const string &name): d_name(name)
00170 {}
00171 bool operator()(const ConstraintEvaluator::function f)
00172 {
00173 return f.name == d_name;
00174 }
00175 };
00176
00196
00198 void
00199 ConstraintEvaluator::add_function(const string &name, bool_func f)
00200 {
00201 functions.remove_if(func_name_is(name));
00202 function func(name, f);
00203 functions.push_back(func);
00204 }
00205
00207 void
00208 ConstraintEvaluator::add_function(const string &name, btp_func f)
00209 {
00210 functions.remove_if(func_name_is(name));
00211 function func(name, f);
00212 functions.push_back(func);
00213 }
00214
00216 void
00217 ConstraintEvaluator::add_function(const string &name, proj_func f)
00218 {
00219 functions.remove_if(func_name_is(name));
00220 function func(name, f);
00221 functions.push_back(func);
00222 }
00223
00225 bool
00226 ConstraintEvaluator::find_function(const string &name, bool_func *f) const
00227 {
00228 if (functions.empty())
00229 return false;
00230
00231 for (Functions_citer i = functions.begin(); i != functions.end(); i++) {
00232 if (name == (*i).name && (*f = (*i).b_func)) {
00233 return true;
00234 }
00235 }
00236
00237 return false;
00238 }
00239
00241 bool
00242 ConstraintEvaluator::find_function(const string &name, btp_func *f) const
00243 {
00244 if (functions.empty())
00245 return false;
00246
00247 for (Functions_citer i = functions.begin(); i != functions.end(); i++) {
00248 if (name == (*i).name && (*f = (*i).bt_func)) {
00249 return true;
00250 }
00251 }
00252
00253 return false;
00254 }
00255
00257 bool
00258 ConstraintEvaluator::find_function(const string &name, proj_func *f) const
00259 {
00260 if (functions.empty())
00261 return false;
00262
00263 for (Functions_citer i = functions.begin(); i != functions.end(); i++)
00264 if (name == (*i).name && (*f = (*i).p_func)) {
00265 return true;
00266 }
00267
00268 return false;
00269 }
00271
00274 bool
00275 ConstraintEvaluator::functional_expression()
00276 {
00277 if (expr.empty())
00278 return false;
00279
00280 Clause *cp = expr[0] ;
00281 return cp->value_clause();
00282 }
00283
00285 BaseType *
00286 ConstraintEvaluator::eval_function(DDS &dds, const string &dataset)
00287 {
00288 if (expr.size() != 1)
00289 throw InternalErr(__FILE__, __LINE__,
00290 "The length of the list of CE clauses is not 1.");
00291
00292 Clause *cp = expr[0] ;
00293 BaseType *result;
00294 if (cp->value(dataset, dds, &result))
00295 return result;
00296 else
00297 return NULL;
00298 }
00299
00301 bool
00302 ConstraintEvaluator::boolean_expression()
00303 {
00304 if (expr.empty())
00305 return false;
00306
00307 bool boolean = true;
00308 for (Clause_iter i = expr.begin(); i != expr.end(); i++) {
00309 boolean = boolean && (*i)->boolean_clause();
00310 }
00311
00312 return boolean;
00313 }
00314
00315
00323 bool
00324 ConstraintEvaluator::eval_selection(DDS &dds, const string &dataset)
00325 {
00326 if (expr.empty()) {
00327 DBG(cerr << "No selection recorded" << endl);
00328 return true;
00329 }
00330
00331 DBG(cerr << "Eval selection" << endl);
00332
00333
00334
00335
00336
00337 bool result = true;
00338 for (Clause_iter i = expr.begin(); i != expr.end() && result; i++) {
00339
00340 if (!((*i)->boolean_clause()))
00341 throw InternalErr(__FILE__, __LINE__,
00342 "A selection expression must contain only boolean clauses.");
00343 result = result && (*i)->value(dataset, dds);
00344 }
00345
00346 return result;
00347 }
00348
00359 void
00360 ConstraintEvaluator::parse_constraint(const string &constraint, DDS &dds)
00361 {
00362 void *buffer = ce_expr_string(constraint.c_str());
00363 ce_expr_switch_to_buffer(buffer);
00364
00365 ce_parser_arg arg(this, &dds);
00366
00367
00368 ce_exprparse((void *)&arg);
00369
00370 ce_expr_delete_buffer(buffer);
00371 }