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 18315 2008-03-03 20:14:44Z 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 long v = strtol(val, &ptr, 0);
00243
00244 if ((v == 0 && val == ptr) || *ptr != '\0') {
00245 return FALSE;
00246 }
00247
00248 if (v > DODS_INT_MAX || v < DODS_INT_MIN) {
00249 return FALSE;
00250 }
00251
00252 return TRUE;
00253 }
00254
00255 int check_uint32(const char *val)
00256 {
00257 char *ptr;
00258 unsigned long v = strtol(val, &ptr, 0);
00259
00260 if ((v == 0 && val == ptr) || *ptr != '\0') {
00261 return FALSE;
00262 }
00263
00264 return TRUE;
00265 }
00266
00267
00268
00269
00270
00271 int check_float32(const char *val)
00272 {
00273 char *ptr;
00274 errno = 0;
00275
00276
00277 #ifdef WIN32
00278 double v = w32strtod(val, &ptr);
00279 #else
00280 double v = strtod(val, &ptr);
00281 #endif
00282
00283 DBG(cerr << "v: " << v << ", ptr: " << ptr
00284 << ", errno: " << errno << ", val==ptr: " << (val == ptr) << endl);
00285 if ((v == 0.0 && (val == ptr || errno == HUGE_VAL || errno == ERANGE))
00286 || *ptr != '\0') {
00287 return FALSE;
00288 }
00289
00290 DBG(cerr << "fabs(" << val << ") = " << fabs(v) << endl);
00291 double abs_val = fabs(v);
00292 if (abs_val > DODS_FLT_MAX
00293 || (abs_val != 0.0 && abs_val < DODS_FLT_MIN))
00294 return FALSE;
00295
00296 return TRUE;
00297 }
00298
00299 int check_float64(const char *val)
00300 {
00301 DBG(cerr << "val: " << val << endl);
00302 char *ptr;
00303 errno = 0;
00304
00305 #ifdef WIN32
00306 double v = w32strtod(val, &ptr);
00307 #else
00308 double v = strtod(val, &ptr);
00309 #endif
00310
00311 DBG(cerr << "v: " << v << ", ptr: " << ptr
00312 << ", errno: " << errno << ", val==ptr: " << (val == ptr) << endl);
00313
00314 if ((v == 0.0 && (val == ptr || errno == HUGE_VAL || errno == ERANGE))
00315 || *ptr != '\0') {
00316 return FALSE;
00317 }
00318
00319 DBG(cerr << "fabs(" << val << ") = " << fabs(v) << endl);
00320 double abs_val = fabs(v);
00321 if (abs_val > DODS_DBL_MAX
00322 || (abs_val != 0.0 && abs_val < DODS_DBL_MIN))
00323 return FALSE;
00324
00325 return TRUE;
00326 }
00327
00328
00329
00330
00331
00332 int check_url(const char *)
00333 {
00334 return TRUE;
00335 }
00336
00337 }