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
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "config.h"
00037
00038 static char rcsid[] not_used =
00039 { "$Id: parser-util.cc 22373 2010-03-23 18:02:57Z jimg $"
00040 };
00041
00042 #include <cerrno>
00043 #include <cassert>
00044 #include <cstring>
00045 #include <cmath>
00046 #include <cstdlib>
00047
00048 #include <iostream>
00049 #include <sstream>
00050
00051
00052
00053 #ifdef WIN32
00054 #include <limits>
00055 double w32strtod(const char *, char **);
00056 #endif
00057
00058 #include "debug.h"
00059 #include "parser.h"
00060 #include "dods-limits.h"
00061 #include "util.h"
00062
00063 using std::cerr;
00064 using std::endl;
00065
00066 #ifdef WIN32
00067
00068
00069
00070
00071
00072 double w32strtod(const char *val, char **ptr)
00073 {
00074
00075 string *sval = new string(val);
00076 string *snan = new string("NaN");
00077
00078
00079
00080 if (stricmp(sval->c_str(), snan->c_str()) != 0)
00081 return (strtod(val, ptr));
00082
00083
00084
00085 *ptr = (char *) val + strlen(val);
00086 return (std::numeric_limits < double >::quiet_NaN());
00087 }
00088 #endif
00089
00090 namespace libdap {
00091
00092
00093 void
00094 parse_error(parser_arg * arg, const char *msg, const int line_num,
00095 const char *context)
00096 {
00097
00098
00099
00100 assert(arg);
00101 assert(msg);
00102
00103 arg->set_status(FALSE);
00104
00105 string oss = "";
00106
00107 if (line_num != 0) {
00108 oss += "Error parsing the text on line ";
00109 append_long_to_string(line_num, 10, oss);
00110 }
00111 else {
00112 oss += "Parse error.";
00113 }
00114
00115 if (context)
00116 oss += (string) " at or near: " + context + (string) "\n" + msg
00117 + (string) "\n";
00118 else
00119 oss += (string) "\n" + msg + (string) "\n";
00120
00121 arg->set_error(new Error(unknown_error, oss));
00122 }
00123
00124 void
00125 parse_error(const char *msg, const int line_num, const char *context)
00126 {
00127
00128
00129
00130 assert(msg);
00131
00132 string oss = "";
00133
00134 if (line_num != 0) {
00135 oss += "Error parsing the text on line ";
00136 append_long_to_string(line_num, 10, oss);
00137 }
00138 else {
00139 oss += "Parse error.";
00140 }
00141
00142 if (context)
00143 oss += (string) " at or near: " + context + (string) "\n" + msg
00144 + (string) "\n";
00145 else
00146 oss += (string) "\n" + msg + (string) "\n";
00147
00148 throw Error(oss);
00149 }
00150
00151
00152
00153 void
00154 parse_error(const string & msg, const int line_num, const char *context)
00155 {
00156 parse_error(msg.c_str(), line_num, context);
00157 }
00158
00159 void save_str(char *dst, const char *src, const int line_num)
00160 {
00161 if (strlen(src) >= ID_MAX)
00162 parse_error(string("The word `") + string(src)
00163 + string("' is too long (it should be no longer than ")
00164 + long_to_string(ID_MAX) + string(")."), line_num);
00165
00166 strncpy(dst, src, ID_MAX);
00167 dst[ID_MAX - 1] = '\0';
00168 }
00169
00170 void save_str(string & dst, const char *src, const int)
00171 {
00172 dst = src;
00173 }
00174
00175 bool is_keyword(string id, const string & keyword)
00176 {
00177 downcase(id);
00178 id = prune_spaces(id);
00179 DBG(cerr << "is_keyword: " << keyword << " = " << id << endl);
00180 return id == keyword;
00181 }
00182
00183 int check_byte(const char *val)
00184 {
00185 char *ptr;
00186 long v = strtol(val, &ptr, 0);
00187
00188 if ((v == 0 && val == ptr) || *ptr != '\0') {
00189 return FALSE;
00190 }
00191
00192 DBG(cerr << "v: " << v << endl);
00193
00194
00195
00196
00197
00198
00199 if ((v < 0 && v < DODS_SCHAR_MIN)
00200 || (v > 0 && static_cast < unsigned long >(v) > DODS_UCHAR_MAX))
00201 return FALSE;
00202
00203 return TRUE;
00204 }
00205
00206
00207
00208
00209 int check_int16(const char *val)
00210 {
00211 char *ptr;
00212 long v = strtol(val, &ptr, 0);
00213
00214 if ((v == 0 && val == ptr) || *ptr != '\0') {
00215 return FALSE;
00216 }
00217
00218 if (v > DODS_SHRT_MAX || v < DODS_SHRT_MIN) {
00219 return FALSE;
00220 }
00221
00222 return TRUE;
00223 }
00224
00225 int check_uint16(const char *val)
00226 {
00227 char *ptr;
00228 unsigned long v = strtol(val, &ptr, 0);
00229
00230 if ((v == 0 && val == ptr) || *ptr != '\0') {
00231 return FALSE;
00232 }
00233
00234 if (v > DODS_USHRT_MAX) {
00235 return FALSE;
00236 }
00237
00238 return TRUE;
00239 }
00240
00241 int check_int32(const char *val)
00242 {
00243 char *ptr;
00244 errno = 0;
00245 long v = strtol(val, &ptr, 0);
00246
00247
00248 if ((v == 0 && val == ptr) || *ptr != '\0') {
00249 return FALSE;
00250 }
00251
00252
00253
00254
00255 if (errno == ERANGE) {
00256 return FALSE;
00257 }
00258
00259
00260
00261 else if (v > DODS_INT_MAX || v < DODS_INT_MIN) {
00262 return FALSE;
00263 }
00264 else {
00265 return TRUE;
00266 }
00267 }
00268
00269 int check_uint32(const char *val)
00270 {
00271
00272
00273 const char* c = val;
00274 while (c && isspace(*c)) {
00275 c++;
00276 }
00277 if (c && (*c == '-')) {
00278 return FALSE;
00279 }
00280
00281 char *ptr;
00282 errno = 0;
00283 unsigned long v = strtoul(val, &ptr, 0);
00284
00285 if ((v == 0 && val == ptr) || *ptr != '\0') {
00286 return FALSE;
00287 }
00288
00289
00290
00291
00292 if (errno == ERANGE) {
00293 return FALSE;
00294 }
00295
00296 else if (v > DODS_UINT_MAX) {
00297 return FALSE;
00298 }
00299 else {
00300 return TRUE;
00301 }
00302 }
00303
00304
00305
00306
00307
00308 int check_float32(const char *val)
00309 {
00310 char *ptr;
00311 errno = 0;
00312
00313
00314 #ifdef WIN32
00315 double v = w32strtod(val, &ptr);
00316 #else
00317 double v = strtod(val, &ptr);
00318 #endif
00319
00320 DBG(cerr << "v: " << v << ", ptr: " << ptr
00321 << ", errno: " << errno << ", val==ptr: " << (val == ptr) << endl);
00322
00323 if (errno == ERANGE || (v == 0.0 && val == ptr) || *ptr != '\0')
00324 return FALSE;
00325 #if 0
00326 if ((v == 0.0 && (val == ptr || errno == HUGE_VAL || errno == ERANGE))
00327 || *ptr != '\0') {
00328 return FALSE;
00329 }
00330 #endif
00331
00332 DBG(cerr << "fabs(" << val << ") = " << fabs(v) << endl);
00333 double abs_val = fabs(v);
00334 if (abs_val > DODS_FLT_MAX
00335 || (abs_val != 0.0 && abs_val < DODS_FLT_MIN))
00336 return FALSE;
00337
00338 return TRUE;
00339 }
00340
00341 int check_float64(const char *val)
00342 {
00343 DBG(cerr << "val: " << val << endl);
00344 char *ptr;
00345 errno = 0;
00346
00347 #ifdef WIN32
00348 double v = w32strtod(val, &ptr);
00349 #else
00350 double v = strtod(val, &ptr);
00351 #endif
00352
00353 DBG(cerr << "v: " << v << ", ptr: " << ptr
00354 << ", errno: " << errno << ", val==ptr: " << (val == ptr) << endl);
00355
00356
00357 if (errno == ERANGE || (v == 0.0 && val == ptr) || *ptr != '\0')
00358 return FALSE;
00359 #if 0
00360 if ((v == 0.0 && (val == ptr || errno == HUGE_VAL || errno == ERANGE))
00361 || *ptr != '\0') {
00362 return FALSE;
00363 }
00364 #endif
00365 DBG(cerr << "fabs(" << val << ") = " << fabs(v) << endl);
00366 double abs_val = fabs(v);
00367 if (abs_val > DODS_DBL_MAX
00368 || (abs_val != 0.0 && abs_val < DODS_DBL_MIN))
00369 return FALSE;
00370
00371 return TRUE;
00372 }
00373
00374
00375
00376
00377
00378 int check_url(const char *)
00379 {
00380 return TRUE;
00381 }
00382
00383 }