|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// -*- mode: c++; c-basic-offset:4 -*-
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// This file is part of libdap, A C++ implementation of the OPeNDAP Data
|
|
Packit |
a4aae4 |
// Access Protocol.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Copyright (c) 2002,2003 OPeNDAP, Inc.
|
|
Packit |
a4aae4 |
// Author: James Gallagher <jgallagher@opendap.org>
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// This library is free software; you can redistribute it and/or
|
|
Packit |
a4aae4 |
// modify it under the terms of the GNU Lesser General Public
|
|
Packit |
a4aae4 |
// License as published by the Free Software Foundation; either
|
|
Packit |
a4aae4 |
// version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// This library is distributed in the hope that it will be useful,
|
|
Packit |
a4aae4 |
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
a4aae4 |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
a4aae4 |
// Lesser General Public License for more details.
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// You should have received a copy of the GNU Lesser General Public
|
|
Packit |
a4aae4 |
// License along with this library; if not, write to the Free Software
|
|
Packit |
a4aae4 |
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// (c) COPYRIGHT URI/MIT 1996-1999
|
|
Packit |
a4aae4 |
// Please read the full copyright statement in the file COPYRIGHT_URI.
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// Authors:
|
|
Packit |
a4aae4 |
// jhrg,jimg James Gallagher <jgallagher@gso.uri.edu>
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// This file contains mfuncs defined for struct rvalue (see expr.h) that
|
|
Packit |
a4aae4 |
// *cannot* be included in that struct's declaration because their
|
|
Packit |
a4aae4 |
// definitions must follow *both* rvalue's and func_rvalue's declarations.
|
|
Packit |
a4aae4 |
// jhrg 3/4/96
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include "config.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include <cassert>
|
|
Packit |
a4aae4 |
#include <iostream>
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include "BaseType.h"
|
|
Packit |
a4aae4 |
#include "expr.h"
|
|
Packit |
a4aae4 |
#include "RValue.h"
|
|
Packit |
a4aae4 |
#include "DDS.h"
|
|
Packit |
a4aae4 |
#include "dods-limits.h"
|
|
Packit |
a4aae4 |
#include "util.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
using namespace std;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
namespace libdap {
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
rvalue_list *
|
|
Packit |
a4aae4 |
make_rvalue_list(rvalue *rv)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
assert(rv);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
rvalue_list *rvals = new rvalue_list;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return append_rvalue_list(rvals, rv);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Given a rvalue_list pointer RVALS and a value pointer VAL, make a variable
|
|
Packit |
a4aae4 |
// to hold VAL and append that variable to the list RVALS.
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// Returns: A pointer to the updated rvalue_list.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
rvalue_list *
|
|
Packit |
a4aae4 |
append_rvalue_list(rvalue_list *rvals, rvalue *rv)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
rvals->push_back(rv);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return rvals;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** Build an argument list suitable for calling a \c btp_func,
|
|
Packit |
a4aae4 |
\c bool_func, and so on. Since this takes an rvalue_list and
|
|
Packit |
a4aae4 |
not an rvalue, it is a function rather than a class
|
|
Packit |
a4aae4 |
member.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
This function performs a common task but does not fit within the RValue
|
|
Packit |
a4aae4 |
class well. It is used by Clause and ce_expr.y.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@param args A list of RValue objects
|
|
Packit |
a4aae4 |
@param dds Use this DDS when evaluating functions */
|
|
Packit |
a4aae4 |
BaseType **
|
|
Packit |
a4aae4 |
build_btp_args(rvalue_list *args, DDS &dds)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
int argc = 0;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (args)
|
|
Packit |
a4aae4 |
argc = args->size();
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Sanitize allocation size
|
|
Packit |
a4aae4 |
if (!size_ok(sizeof(BaseType*), argc + 1))
|
|
Packit |
a4aae4 |
throw Error(malformed_expr, string("Malformed argument list (")
|
|
Packit |
a4aae4 |
+ long_to_string(argc) + string(")."));
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Add space for a null terminator
|
|
Packit |
a4aae4 |
BaseType **argv = new BaseType*[argc + 1];
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
int index = 0;
|
|
Packit |
a4aae4 |
if (argv && argc) {
|
|
Packit |
a4aae4 |
for (rvalue::Args_iter i = args->begin(); i != args->end() && index
|
|
Packit |
a4aae4 |
< argc + 1; ++i)
|
|
Packit |
a4aae4 |
argv[index++] = (*i)->bvalue(dds);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
argv[index] = 0; // Add the null terminator.
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
if (index != argc) {
|
|
Packit |
a4aae4 |
delete[] argv;
|
|
Packit |
a4aae4 |
throw InternalErr(__FILE__, __LINE__, "index out of range.");
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
#if 0
|
|
Packit |
a4aae4 |
argv[index] = 0; // Add the null terminator.
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
return argv;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
rvalue::rvalue(BaseType *bt): d_value(bt), d_func(0), d_args(0)
|
|
Packit |
a4aae4 |
{}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
rvalue::rvalue(btp_func f, vector<rvalue *> *a) : d_value(0), d_func(f), d_args(a)
|
|
Packit |
a4aae4 |
{}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
rvalue::rvalue(): d_value(0), d_func(0), d_args(0)
|
|
Packit |
a4aae4 |
{}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
rvalue::~rvalue()
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
// Deleting the BaseType pointers in value and args is a bad idea since
|
|
Packit |
a4aae4 |
// those might be variables in the dataset. The DDS dtor will take care
|
|
Packit |
a4aae4 |
// of deleting them. The constants wrapped in BaseType objects should be
|
|
Packit |
a4aae4 |
// pushed on the list of CE-allocated temp objects which the CE frees.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// ADB: the d_args vector still needs to be deleted
|
|
Packit |
a4aae4 |
if (d_args != 0) {
|
|
Packit |
a4aae4 |
for (std::vector<rvalue *>::iterator iter = d_args->begin(); iter != d_args->end(); ++iter) {
|
|
Packit |
a4aae4 |
delete *iter;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
delete d_args;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
string
|
|
Packit |
a4aae4 |
rvalue::value_name()
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
assert(d_value);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return d_value->name();
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** Return the BaseType * for a given rvalue. If
|
|
Packit |
a4aae4 |
the rvalue is a func_rvalue, evaluates the func_rvalue and returns the
|
|
Packit |
a4aae4 |
result. The functions referenced by func_rvalues must encapsulate their
|
|
Packit |
a4aae4 |
return values in BaseType *s.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@param dds The dds to pass to a function.
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
BaseType *
|
|
Packit |
a4aae4 |
rvalue::bvalue(DDS &dds)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if (d_value) { // i.e., if this RValue is a BaseType
|
|
Packit |
a4aae4 |
return d_value;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else if (d_func) {
|
|
Packit |
a4aae4 |
// If func is true, then args must be set. See the constructor.
|
|
Packit |
a4aae4 |
// 12/23/04 jhrg
|
|
Packit |
a4aae4 |
BaseType **argv = build_btp_args(d_args, dds);
|
|
Packit |
a4aae4 |
BaseType *ret_val;
|
|
Packit |
a4aae4 |
(*d_func)(d_args->size(), argv, dds, &ret_val);
|
|
Packit |
a4aae4 |
delete[] argv;
|
|
Packit |
a4aae4 |
return ret_val;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else {
|
|
Packit |
a4aae4 |
return 0;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
} // namespace libdap
|
|
Packit |
a4aae4 |
|