Fossil SCM
Refactored Th_ToXXX() to live on top of Th_TryXXX() to simplify some downstream code.
Commit
7554072246373e4b93120a8ca95e1e9584babeab
Parent
3b25f80edd84de7…
2 files changed
+44
-14
+2
M
src/th.c
+44
-14
| --- src/th.c | ||
| +++ src/th.c | ||
| @@ -2486,18 +2486,16 @@ | ||
| 2486 | 2486 | *pResult = sign<0 ? -v1 : v1; |
| 2487 | 2487 | return z - zBegin; |
| 2488 | 2488 | } |
| 2489 | 2489 | |
| 2490 | 2490 | /* |
| 2491 | -** Try to convert the string passed as arguments (z, n) to an integer. | |
| 2492 | -** If successful, store the result in *piOut and return TH_OK. | |
| 2493 | -** | |
| 2494 | -** If the string cannot be converted to an integer, return TH_ERROR. | |
| 2495 | -** If the interp argument is not NULL, leave an error message in the | |
| 2496 | -** interpreter result too. | |
| 2491 | +** Attempts to convert (zArg,nArg) to an integer. On success *piOut is | |
| 2492 | +** assigned to its value and TH_OK is returned, else piOut is not | |
| 2493 | +** modified and TH_ERROR is returned. Conversion errors are considered | |
| 2494 | +** non-fatal here, so interp's error state is not set. | |
| 2497 | 2495 | */ |
| 2498 | -int Th_ToInt(Th_Interp *interp, const char *z, int n, int *piOut){ | |
| 2496 | +int Th_TryInt(Th_Interp *interp, const char *z, int n, int *piOut){ | |
| 2499 | 2497 | int i = 0; |
| 2500 | 2498 | int iOut = 0; |
| 2501 | 2499 | |
| 2502 | 2500 | if( n<0 ){ |
| 2503 | 2501 | n = th_strlen(z); |
| @@ -2506,11 +2504,10 @@ | ||
| 2506 | 2504 | if( n>0 && (z[0]=='-' || z[0]=='+') ){ |
| 2507 | 2505 | i = 1; |
| 2508 | 2506 | } |
| 2509 | 2507 | for(; i<n; i++){ |
| 2510 | 2508 | if( !th_isdigit(z[i]) ){ |
| 2511 | - Th_ErrorMessage(interp, "expected integer, got: \"", z, n); | |
| 2512 | 2509 | return TH_ERROR; |
| 2513 | 2510 | } |
| 2514 | 2511 | iOut = iOut * 10 + (z[i] - 48); |
| 2515 | 2512 | } |
| 2516 | 2513 | |
| @@ -2519,10 +2516,45 @@ | ||
| 2519 | 2516 | } |
| 2520 | 2517 | |
| 2521 | 2518 | *piOut = iOut; |
| 2522 | 2519 | return TH_OK; |
| 2523 | 2520 | } |
| 2521 | + | |
| 2522 | +/* | |
| 2523 | +** Try to convert the string passed as arguments (z, n) to an integer. | |
| 2524 | +** If successful, store the result in *piOut and return TH_OK. | |
| 2525 | +** | |
| 2526 | +** If the string cannot be converted to an integer, return TH_ERROR. | |
| 2527 | +** If the interp argument is not NULL, leave an error message in the | |
| 2528 | +** interpreter result too. | |
| 2529 | +*/ | |
| 2530 | +int Th_ToInt(Th_Interp *interp, const char *z, int n, int *piOut){ | |
| 2531 | + const int rc = Th_TryInt(interp, z, n, piOut); | |
| 2532 | + if( TH_OK != rc ){ | |
| 2533 | + Th_ErrorMessage(interp, "expected integer, got: \"", z, n); | |
| 2534 | + } | |
| 2535 | + return rc; | |
| 2536 | +} | |
| 2537 | + | |
| 2538 | + | |
| 2539 | +/* | |
| 2540 | +** Functionally/semantically identical to Th_TryInt() but works on | |
| 2541 | +** doubles. | |
| 2542 | +*/ | |
| 2543 | +int Th_TryDouble( | |
| 2544 | + Th_Interp *interp, | |
| 2545 | + const char *z, | |
| 2546 | + int n, | |
| 2547 | + double *pfOut | |
| 2548 | +){ | |
| 2549 | + if( !sqlite3IsNumber((const char *)z, 0) ){ | |
| 2550 | + return TH_ERROR; | |
| 2551 | + }else{ | |
| 2552 | + sqlite3AtoF((const char *)z, pfOut); | |
| 2553 | + return TH_OK; | |
| 2554 | + } | |
| 2555 | +} | |
| 2524 | 2556 | |
| 2525 | 2557 | /* |
| 2526 | 2558 | ** Try to convert the string passed as arguments (z, n) to a double. |
| 2527 | 2559 | ** If successful, store the result in *pfOut and return TH_OK. |
| 2528 | 2560 | ** |
| @@ -2534,17 +2566,15 @@ | ||
| 2534 | 2566 | Th_Interp *interp, |
| 2535 | 2567 | const char *z, |
| 2536 | 2568 | int n, |
| 2537 | 2569 | double *pfOut |
| 2538 | 2570 | ){ |
| 2539 | - if( !sqlite3IsNumber((const char *)z, 0) ){ | |
| 2540 | - Th_ErrorMessage(interp, "expected number, got: \"", z, n); | |
| 2541 | - return TH_ERROR; | |
| 2571 | + const int rc = Th_TryDouble(interp, z, n, pfOut); | |
| 2572 | + if( TH_OK != rc ){ | |
| 2573 | + Th_ErrorMessage(interp, "expected number, got: \"", z, n); | |
| 2542 | 2574 | } |
| 2543 | - | |
| 2544 | - sqlite3AtoF((const char *)z, pfOut); | |
| 2545 | - return TH_OK; | |
| 2575 | + return rc; | |
| 2546 | 2576 | } |
| 2547 | 2577 | |
| 2548 | 2578 | /* |
| 2549 | 2579 | ** Set the result of the interpreter to the th1 representation of |
| 2550 | 2580 | ** the integer iVal and return TH_OK. |
| 2551 | 2581 |
| --- src/th.c | |
| +++ src/th.c | |
| @@ -2486,18 +2486,16 @@ | |
| 2486 | *pResult = sign<0 ? -v1 : v1; |
| 2487 | return z - zBegin; |
| 2488 | } |
| 2489 | |
| 2490 | /* |
| 2491 | ** Try to convert the string passed as arguments (z, n) to an integer. |
| 2492 | ** If successful, store the result in *piOut and return TH_OK. |
| 2493 | ** |
| 2494 | ** If the string cannot be converted to an integer, return TH_ERROR. |
| 2495 | ** If the interp argument is not NULL, leave an error message in the |
| 2496 | ** interpreter result too. |
| 2497 | */ |
| 2498 | int Th_ToInt(Th_Interp *interp, const char *z, int n, int *piOut){ |
| 2499 | int i = 0; |
| 2500 | int iOut = 0; |
| 2501 | |
| 2502 | if( n<0 ){ |
| 2503 | n = th_strlen(z); |
| @@ -2506,11 +2504,10 @@ | |
| 2506 | if( n>0 && (z[0]=='-' || z[0]=='+') ){ |
| 2507 | i = 1; |
| 2508 | } |
| 2509 | for(; i<n; i++){ |
| 2510 | if( !th_isdigit(z[i]) ){ |
| 2511 | Th_ErrorMessage(interp, "expected integer, got: \"", z, n); |
| 2512 | return TH_ERROR; |
| 2513 | } |
| 2514 | iOut = iOut * 10 + (z[i] - 48); |
| 2515 | } |
| 2516 | |
| @@ -2519,10 +2516,45 @@ | |
| 2519 | } |
| 2520 | |
| 2521 | *piOut = iOut; |
| 2522 | return TH_OK; |
| 2523 | } |
| 2524 | |
| 2525 | /* |
| 2526 | ** Try to convert the string passed as arguments (z, n) to a double. |
| 2527 | ** If successful, store the result in *pfOut and return TH_OK. |
| 2528 | ** |
| @@ -2534,17 +2566,15 @@ | |
| 2534 | Th_Interp *interp, |
| 2535 | const char *z, |
| 2536 | int n, |
| 2537 | double *pfOut |
| 2538 | ){ |
| 2539 | if( !sqlite3IsNumber((const char *)z, 0) ){ |
| 2540 | Th_ErrorMessage(interp, "expected number, got: \"", z, n); |
| 2541 | return TH_ERROR; |
| 2542 | } |
| 2543 | |
| 2544 | sqlite3AtoF((const char *)z, pfOut); |
| 2545 | return TH_OK; |
| 2546 | } |
| 2547 | |
| 2548 | /* |
| 2549 | ** Set the result of the interpreter to the th1 representation of |
| 2550 | ** the integer iVal and return TH_OK. |
| 2551 |
| --- src/th.c | |
| +++ src/th.c | |
| @@ -2486,18 +2486,16 @@ | |
| 2486 | *pResult = sign<0 ? -v1 : v1; |
| 2487 | return z - zBegin; |
| 2488 | } |
| 2489 | |
| 2490 | /* |
| 2491 | ** Attempts to convert (zArg,nArg) to an integer. On success *piOut is |
| 2492 | ** assigned to its value and TH_OK is returned, else piOut is not |
| 2493 | ** modified and TH_ERROR is returned. Conversion errors are considered |
| 2494 | ** non-fatal here, so interp's error state is not set. |
| 2495 | */ |
| 2496 | int Th_TryInt(Th_Interp *interp, const char *z, int n, int *piOut){ |
| 2497 | int i = 0; |
| 2498 | int iOut = 0; |
| 2499 | |
| 2500 | if( n<0 ){ |
| 2501 | n = th_strlen(z); |
| @@ -2506,11 +2504,10 @@ | |
| 2504 | if( n>0 && (z[0]=='-' || z[0]=='+') ){ |
| 2505 | i = 1; |
| 2506 | } |
| 2507 | for(; i<n; i++){ |
| 2508 | if( !th_isdigit(z[i]) ){ |
| 2509 | return TH_ERROR; |
| 2510 | } |
| 2511 | iOut = iOut * 10 + (z[i] - 48); |
| 2512 | } |
| 2513 | |
| @@ -2519,10 +2516,45 @@ | |
| 2516 | } |
| 2517 | |
| 2518 | *piOut = iOut; |
| 2519 | return TH_OK; |
| 2520 | } |
| 2521 | |
| 2522 | /* |
| 2523 | ** Try to convert the string passed as arguments (z, n) to an integer. |
| 2524 | ** If successful, store the result in *piOut and return TH_OK. |
| 2525 | ** |
| 2526 | ** If the string cannot be converted to an integer, return TH_ERROR. |
| 2527 | ** If the interp argument is not NULL, leave an error message in the |
| 2528 | ** interpreter result too. |
| 2529 | */ |
| 2530 | int Th_ToInt(Th_Interp *interp, const char *z, int n, int *piOut){ |
| 2531 | const int rc = Th_TryInt(interp, z, n, piOut); |
| 2532 | if( TH_OK != rc ){ |
| 2533 | Th_ErrorMessage(interp, "expected integer, got: \"", z, n); |
| 2534 | } |
| 2535 | return rc; |
| 2536 | } |
| 2537 | |
| 2538 | |
| 2539 | /* |
| 2540 | ** Functionally/semantically identical to Th_TryInt() but works on |
| 2541 | ** doubles. |
| 2542 | */ |
| 2543 | int Th_TryDouble( |
| 2544 | Th_Interp *interp, |
| 2545 | const char *z, |
| 2546 | int n, |
| 2547 | double *pfOut |
| 2548 | ){ |
| 2549 | if( !sqlite3IsNumber((const char *)z, 0) ){ |
| 2550 | return TH_ERROR; |
| 2551 | }else{ |
| 2552 | sqlite3AtoF((const char *)z, pfOut); |
| 2553 | return TH_OK; |
| 2554 | } |
| 2555 | } |
| 2556 | |
| 2557 | /* |
| 2558 | ** Try to convert the string passed as arguments (z, n) to a double. |
| 2559 | ** If successful, store the result in *pfOut and return TH_OK. |
| 2560 | ** |
| @@ -2534,17 +2566,15 @@ | |
| 2566 | Th_Interp *interp, |
| 2567 | const char *z, |
| 2568 | int n, |
| 2569 | double *pfOut |
| 2570 | ){ |
| 2571 | const int rc = Th_TryDouble(interp, z, n, pfOut); |
| 2572 | if( TH_OK != rc ){ |
| 2573 | Th_ErrorMessage(interp, "expected number, got: \"", z, n); |
| 2574 | } |
| 2575 | return rc; |
| 2576 | } |
| 2577 | |
| 2578 | /* |
| 2579 | ** Set the result of the interpreter to the th1 representation of |
| 2580 | ** the integer iVal and return TH_OK. |
| 2581 |
M
src/th.h
+2
| --- src/th.h | ||
| +++ src/th.h | ||
| @@ -167,10 +167,12 @@ | ||
| 167 | 167 | */ |
| 168 | 168 | int Th_ToInt(Th_Interp *, const char *, int, int *); |
| 169 | 169 | int Th_ToDouble(Th_Interp *, const char *, int, double *); |
| 170 | 170 | int Th_SetResultInt(Th_Interp *, int); |
| 171 | 171 | int Th_SetResultDouble(Th_Interp *, double); |
| 172 | +int Th_TryInt(Th_Interp *, const char * zArg, int nArg, int * piOut); | |
| 173 | +int Th_TryDouble(Th_Interp *, const char * zArg, int nArg, double * pfOut); | |
| 172 | 174 | |
| 173 | 175 | /* |
| 174 | 176 | ** Drop in replacements for the corresponding standard library functions. |
| 175 | 177 | */ |
| 176 | 178 | int th_strlen(const char *); |
| 177 | 179 |
| --- src/th.h | |
| +++ src/th.h | |
| @@ -167,10 +167,12 @@ | |
| 167 | */ |
| 168 | int Th_ToInt(Th_Interp *, const char *, int, int *); |
| 169 | int Th_ToDouble(Th_Interp *, const char *, int, double *); |
| 170 | int Th_SetResultInt(Th_Interp *, int); |
| 171 | int Th_SetResultDouble(Th_Interp *, double); |
| 172 | |
| 173 | /* |
| 174 | ** Drop in replacements for the corresponding standard library functions. |
| 175 | */ |
| 176 | int th_strlen(const char *); |
| 177 |
| --- src/th.h | |
| +++ src/th.h | |
| @@ -167,10 +167,12 @@ | |
| 167 | */ |
| 168 | int Th_ToInt(Th_Interp *, const char *, int, int *); |
| 169 | int Th_ToDouble(Th_Interp *, const char *, int, double *); |
| 170 | int Th_SetResultInt(Th_Interp *, int); |
| 171 | int Th_SetResultDouble(Th_Interp *, double); |
| 172 | int Th_TryInt(Th_Interp *, const char * zArg, int nArg, int * piOut); |
| 173 | int Th_TryDouble(Th_Interp *, const char * zArg, int nArg, double * pfOut); |
| 174 | |
| 175 | /* |
| 176 | ** Drop in replacements for the corresponding standard library functions. |
| 177 | */ |
| 178 | int th_strlen(const char *); |
| 179 |