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