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