1 2 // -*- mode: c++; c-basic-offset:4 -*- 3 4 // This file is part of libdap, A C++ implementation of the OPeNDAP Data 5 // Access Protocol. 6 7 // Copyright (c) 2002,2003 OPeNDAP, Inc. 8 // Author: James Gallagher <jgallagher@opendap.org> 9 // 10 // This library is free software; you can redistribute it and/or 11 // modify it under the terms of the GNU Lesser General Public 12 // License as published by the Free Software Foundation; either 13 // version 2.1 of the License, or (at your option) any later version. 14 // 15 // This library is distributed in the hope that it will be useful, 16 // but WITHOUT ANY WARRANTY; without even the implied warranty of 17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 // Lesser General Public License for more details. 19 // 20 // You should have received a copy of the GNU Lesser General Public 21 // License along with this library; if not, write to the Free Software 22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 23 // 24 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112. 25 26 // (c) COPYRIGHT URI/MIT 1995-1999 27 // Please read the full copyright statement in the file COPYRIGHT_URI. 28 // 29 // Authors: 30 // jhrg,jimg James Gallagher <jgallagher@gso.uri.edu> 31 32 // Types for the expr parser. 33 // 34 // 11/4/95 jhrg 35 36 #ifndef _expr_h 37 #define _expr_h 38 39 #include <string> 40 #include <vector> 41 42 #include "Type.h" 43 #include "parser-util.h" 44 #include "Error.h" 45 46 namespace libdap 47 { 48 49 class BaseType; 50 class DDS; 51 class ConstraintEvaluator; 52 53 // VALUE is used to return constant values from the scanner to the parser. 54 // Constants are packaged in BaseType *s for evaluation by the parser. 55 // 56 // I changed this to simplify support of natural axes subsetting. Since 'value' 57 // was only being used for the string* return, I added a string* filed to ce_exprlval 58 // and moved 'value' out of it. This meant that I can use non-trivial ctors for 59 // value without breaking the rules for c++ unions. Those ctors make it easier to 60 // build value instances without errors. jhrg 2/10/20 61 62 typedef struct value { 63 bool is_range_value; // true if this is part of a natural axes projection 64 Type type; // Type is an enum defined in Type.h 65 union { 66 unsigned int ui; 67 int i; 68 double f; 69 std::string *s; 70 } v; 71 72 /** 73 * @brief build an instance by divining the type. 74 * @param token 75 */ build_instancevalue76 void build_instance(const std::string &token) { 77 if (check_int32(token.c_str(), v.i)) { 78 type = dods_int32_c; 79 #if 0 80 v.i = atoi(token.c_str()); 81 #endif 82 } 83 else if (check_uint32(token.c_str(), v.ui)) { 84 type = dods_uint32_c; 85 #if 0 86 v.ui = atoi(token.c_str()); 87 #endif 88 } 89 else if (check_float64(token.c_str(), v.f)) { 90 type = dods_float64_c; 91 #if 0 92 v.f = atof(token.c_str()); 93 #endif 94 } 95 else { 96 type = dods_str_c; 97 v.s = new std::string(token); 98 } 99 } 100 101 /** 102 * @brief Build an instance given the type 103 * @param token 104 */ build_typed_instancevalue105 void build_typed_instance(const std::string &token) { 106 switch (type) { 107 case dods_uint32_c: 108 v.ui = get_uint32(token.c_str()); 109 break; 110 case dods_int32_c: 111 v.i = get_int32(token.c_str()); 112 break; 113 case dods_float64_c: 114 v.ui = get_float64(token.c_str()); 115 break; 116 case dods_str_c: 117 v.s = new std::string(token); 118 break; 119 default: 120 throw Error("Expected an int32, unsigned int32, float64 or string token."); 121 } 122 } 123 124 // By default, value instances are int32s with values of 0 and the range_value 125 // property is set to false. valuevalue126 value() : is_range_value(false), type(dods_int32_c) { v.i = 0; } 127 128 // set a value is_range_valuevalue129 value(const std::string &token, bool rv = false, Type t = dods_null_c) : is_range_value(rv), type(t) { 130 if (type == dods_null_c) 131 build_instance(token); 132 else 133 build_typed_instance(token); 134 } 135 is_range_valuevalue136 value(int val, bool rv = false, Type t = dods_null_c) : is_range_value(rv), type(t) { 137 switch (type) { 138 case dods_uint32_c: 139 v.ui = val; 140 break; 141 case dods_int32_c: 142 v.i = val; 143 break; 144 default: 145 throw Error("Expected an int32 or unsigned int32 token."); 146 } 147 } 148 is_range_valuevalue149 value(unsigned int val, bool rv = false, Type t = dods_null_c) : is_range_value(rv), type(t) { 150 switch (type) { 151 case dods_uint32_c: 152 v.ui = val; 153 break; 154 default: 155 throw Error("Expected an unsigned int32 token."); 156 } 157 } 158 159 } value; 160 161 // Syntactic sugar for `pointer to function returning boolean' (bool_func) 162 // and `pointer to function returning BaseType *' (btp_func). Both function 163 // types take four arguments, an integer (argc), a vector of BaseType *s 164 // (argv), the DDS for the dataset for which these function is being 165 // evaluated (analogous to the ENVP in UNIX) and a pointer for the function's 166 // return value. ARGC is the length of ARGV. 167 168 typedef void (*bool_func)(int argc, BaseType *argv[], DDS &dds, bool *result); 169 typedef void (*btp_func)(int argc, BaseType *argv[], DDS &dds, BaseType **btpp); 170 171 // Projection function: A function that appears in the projection part of the 172 // CE and is executed for its side-effect. Usually adds a new variable to 173 // the DDS. These are run _during the parse_ so their side-effects can be used 174 // by subsequent parts of the CE. 175 176 typedef void (*proj_func)(int argc, BaseType *argv[], DDS &dds, ConstraintEvaluator &ce); 177 178 // INT_LIST and INT_LIST_LIST are used by the parser to store the array 179 // indexes. 180 181 // To add the new feature of 'to the end' in an array projection (denoted using 182 // star), I used the value -1 for an index. This makes do difference here. jhrg 183 // 12/20/12 184 185 // By using 'value' and not integers, the slices can use floats which is a better fit 186 // for lat and lon values. jhrg 4/18/19 187 // I used a vector of pointers to dim_slice because pointers have trivial copy ctors and 188 // these types are using by the CE parsers in a union. Unions in C++ require trivial copy 189 // ctors. jhrg 2/5/20 190 typedef std::vector<value> dim_slice; 191 typedef std::vector<dim_slice *> slices; 192 193 } // namespace libdap 194 195 #endif /* _expr_h */ 196