Differences From Artifact [4a0c5c902820e390]:
- File
jim.c
-
2010-10-15 01:02:50
- part of checkin
[626463d4ea]
on branch trunk
- Clean up the indentation mess
Use 'indent'. Not perfect, but at least consistent.
Signed-off-by: Steve Bennett <steveb@workware.net.au> (user: steveb@workware.net.au
-
2010-10-15 01:02:50
- part of checkin
[626463d4ea]
on branch trunk
- Clean up the indentation mess
To Artifact [8dded17273791ce5]:
- File
jim.c
-
2010-10-15 01:02:50
- part of checkin
[6faeca70b7]
on branch trunk
- Add 'string is' to Jim
Also, double parsing now allows trailing white space
Signed-off-by: Steve Bennett <steveb@workware.net.au> (user: steveb@workware.net.au
-
2010-10-15 01:02:50
- part of checkin
[6faeca70b7]
on branch trunk
- Add 'string is' to Jim
88 88 static void JimSetFailedEnumResult(Jim_Interp *interp, const char *arg, const char *badtype,
89 89 const char *prefix, const char *const *tablePtr, const char *name);
90 90 static void JimDeleteLocalProcs(Jim_Interp *interp);
91 91 static int JimCallProcedure(Jim_Interp *interp, Jim_Cmd *cmd, const char *filename, int linenr,
92 92 int argc, Jim_Obj *const *argv);
93 93 static int JimEvalObjVector(Jim_Interp *interp, int objc, Jim_Obj *const *objv,
94 94 const char *filename, int linenr);
95 +static int JimGetWideNoErr(Jim_Interp *interp, Jim_Obj *objPtr, jim_wide * widePtr);
95 96
96 97 static const Jim_HashTableType JimVariablesHashTableType;
97 98
98 99 const char *tt_name(int type);
99 100
100 101 /* -----------------------------------------------------------------------------
101 102 * Utility functions
................................................................................
308 309 int Jim_WideToString(char *buf, jim_wide wideValue)
309 310 {
310 311 const char *fmt = "%" JIM_WIDE_MODIFIER;
311 312
312 313 return sprintf(buf, fmt, wideValue);
313 314 }
314 315
315 -int Jim_StringToWide(const char *str, jim_wide * widePtr, int base)
316 +/**
317 + * After an strtol()/strtod()-like conversion,
318 + * check whether something was converted and that
319 + * the only thing left is white space.
320 + *
321 + * Returns JIM_OK or JIM_ERR.
322 + */
323 +static int JimCheckConversion(const char *str, const char *endptr)
316 324 {
317 - char *endptr;
325 + if (str[0] == '\0' || str == endptr) {
326 + return JIM_ERR;
327 + }
318 328
319 - *widePtr = strtoull(str, &endptr, base);
320 -
321 - if ((str[0] == '\0') || (str == endptr))
322 - return JIM_ERR;
323 329 if (endptr[0] != '\0') {
324 330 while (*endptr) {
325 331 if (!isspace(*endptr)) {
326 332 return JIM_ERR;
327 333 }
328 334 endptr++;
329 335 }
330 336 }
331 337 return JIM_OK;
332 338 }
339 +
340 +int Jim_StringToWide(const char *str, jim_wide * widePtr, int base)
341 +{
342 + char *endptr;
343 +
344 + *widePtr = strtoull(str, &endptr, base);
345 +
346 + return JimCheckConversion(str, endptr);
347 +}
333 348
334 349 int Jim_DoubleToString(char *buf, double doubleValue)
335 350 {
336 351 int len;
337 352
338 353 len = sprintf(buf, "%.12g", doubleValue);
339 354
................................................................................
356 371
357 372 return len + 2;
358 373 }
359 374
360 375 int Jim_StringToDouble(const char *str, double *doublePtr)
361 376 {
362 377 char *endptr;
378 +
379 + /* Callers can check for underflow via ERANGE */
380 + errno = 0;
363 381
364 382 *doublePtr = strtod(str, &endptr);
365 - if (str[0] == '\0' || endptr[0] != '\0' || (str == endptr)) {
366 - return JIM_ERR;
367 - }
368 - return JIM_OK;
383 +
384 + return JimCheckConversion(str, endptr);
369 385 }
370 386
371 387 static jim_wide JimPowWide(jim_wide b, jim_wide e)
372 388 {
373 389 jim_wide i, res = 1;
374 390
375 391 if ((b == 0 && e != 0) || (e < 0))
................................................................................
2251 2267
2252 2268 buf = Jim_StrDup(strObjPtr->bytes);
2253 2269 trim_right(buf, trimchars);
2254 2270
2255 2271 return Jim_NewStringObjNoAlloc(interp, buf, -1);
2256 2272 }
2257 2273
2274 +
2275 +static int JimStringIs(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *strClass, int strict)
2276 +{
2277 + static const char *strclassnames[] = {
2278 + "integer", "alpha", "alnum", "ascii", "digit",
2279 + "double", "lower", "upper", "space", "xdigit",
2280 + "control", "print", "graph", "punct",
2281 + NULL
2282 + };
2283 + enum {
2284 + STR_IS_INTEGER, STR_IS_ALPHA, STR_IS_ALNUM, STR_IS_ASCII, STR_IS_DIGIT,
2285 + STR_IS_DOUBLE, STR_IS_LOWER, STR_IS_UPPER, STR_IS_SPACE, STR_IS_XDIGIT,
2286 + STR_IS_CONTROL, STR_IS_PRINT, STR_IS_GRAPH, STR_IS_PUNCT
2287 + };
2288 + int strclass;
2289 + int len;
2290 + int i;
2291 + const char *str;
2292 + int (*isclassfunc)(int c) = NULL;
2293 +
2294 + if (Jim_GetEnum(interp, strClass, strclassnames, &strclass, "class", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) {
2295 + return JIM_ERR;
2296 + }
2297 +
2298 + str = Jim_GetString(strObjPtr, &len);
2299 + if (len == 0) {
2300 + Jim_SetResultInt(interp, !strict);
2301 + return JIM_OK;
2302 + }
2303 +
2304 + switch (strclass) {
2305 + case STR_IS_INTEGER:
2306 + {
2307 + jim_wide w;
2308 + Jim_SetResultInt(interp, JimGetWideNoErr(interp, strObjPtr, &w) == JIM_OK);
2309 + return JIM_OK;
2310 + }
2311 +
2312 + case STR_IS_DOUBLE:
2313 + {
2314 + double d;
2315 + Jim_SetResultInt(interp, Jim_GetDouble(interp, strObjPtr, &d) == JIM_OK && errno != ERANGE);
2316 + return JIM_OK;
2317 + }
2318 +
2319 + case STR_IS_ALPHA: isclassfunc = isalpha; break;
2320 + case STR_IS_ALNUM: isclassfunc = isalnum; break;
2321 + case STR_IS_ASCII: isclassfunc = isascii; break;
2322 + case STR_IS_DIGIT: isclassfunc = isdigit; break;
2323 + case STR_IS_LOWER: isclassfunc = islower; break;
2324 + case STR_IS_UPPER: isclassfunc = isupper; break;
2325 + case STR_IS_SPACE: isclassfunc = isspace; break;
2326 + case STR_IS_XDIGIT: isclassfunc = isxdigit; break;
2327 + case STR_IS_CONTROL: isclassfunc = iscntrl; break;
2328 + case STR_IS_PRINT: isclassfunc = isprint; break;
2329 + case STR_IS_GRAPH: isclassfunc = isgraph; break;
2330 + case STR_IS_PUNCT: isclassfunc = ispunct; break;
2331 + }
2332 +
2333 + for (i = 0; i < len; i++) {
2334 + if (!isclassfunc(str[i])) {
2335 + Jim_SetResultInt(interp, 0);
2336 + return JIM_OK;
2337 + }
2338 + }
2339 + Jim_SetResultInt(interp, 1);
2340 + return JIM_OK;
2341 +}
2342 +
2258 2343 /* This is the core of the [format] command.
2259 2344 * TODO: Lots of things work - via a hack
2260 2345 * However, no format item can be >= JIM_MAX_FMT
2261 2346 */
2262 2347 #define JIM_MAX_FMT 2048
2263 2348 static Jim_Obj *Jim_FormatString_Inner(Jim_Interp *interp, Jim_Obj *fmtObjPtr,
2264 2349 int objc, Jim_Obj *const *objv, char *sprintf_buf)
................................................................................
12114 12199 /* [string] */
12115 12200 static int Jim_StringCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
12116 12201 {
12117 12202 int len;
12118 12203 int opt_case = 1;
12119 12204 int option;
12120 12205 static const char *options[] = {
12121 - "length", "compare", "match", "equal", "range", "map",
12206 + "length", "compare", "match", "equal", "is", "range", "map",
12122 12207 "repeat", "reverse", "index", "first", "last",
12123 12208 "trim", "trimleft", "trimright", "tolower", "toupper", NULL
12124 12209 };
12125 12210 enum
12126 12211 {
12127 - OPT_LENGTH, OPT_COMPARE, OPT_MATCH, OPT_EQUAL, OPT_RANGE, OPT_MAP,
12212 + OPT_LENGTH, OPT_COMPARE, OPT_MATCH, OPT_EQUAL, OPT_IS, OPT_RANGE, OPT_MAP,
12128 12213 OPT_REPEAT, OPT_REVERSE, OPT_INDEX, OPT_FIRST, OPT_LAST,
12129 12214 OPT_TRIM, OPT_TRIMLEFT, OPT_TRIMRIGHT, OPT_TOLOWER, OPT_TOUPPER
12130 12215 };
12131 12216 static const char *nocase_options[] = {
12132 12217 "-nocase", NULL
12133 12218 };
12134 12219
................................................................................
12345 12430 if (option == OPT_TOLOWER) {
12346 12431 Jim_SetResult(interp, JimStringToLower(interp, argv[2]));
12347 12432 }
12348 12433 else {
12349 12434 Jim_SetResult(interp, JimStringToUpper(interp, argv[2]));
12350 12435 }
12351 12436 return JIM_OK;
12437 +
12438 + case OPT_IS:
12439 + if (argc == 4 || (argc == 5 && Jim_CompareStringImmediate(interp, argv[3], "-strict"))) {
12440 + return JimStringIs(interp, argv[argc - 1], argv[2], argc == 5);
12441 + }
12442 + Jim_WrongNumArgs(interp, 2, argv, "class ?-strict? str");
12443 + return JIM_ERR;
12352 12444 }
12353 12445 return JIM_OK;
12354 12446 }
12355 12447
12356 12448 /* [time] */
12357 12449 static int Jim_TimeCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
12358 12450 {