diff options
author | sebres <sebres@users.sourceforge.net> | 2024-03-24 16:54:40 (GMT) |
---|---|---|
committer | sebres <sebres@users.sourceforge.net> | 2024-03-24 16:54:40 (GMT) |
commit | 0fdf76249af5a8b1797254b1855ec46254701968 (patch) | |
tree | b33d47777132d79817bf3cc748ba30d7630717ba /generic | |
parent | fb4109fcf1747a450454d72242aea4216986e8a8 (diff) | |
download | tcl-0fdf76249af5a8b1797254b1855ec46254701968.zip tcl-0fdf76249af5a8b1797254b1855ec46254701968.tar.gz tcl-0fdf76249af5a8b1797254b1855ec46254701968.tar.bz2 |
review and more optimizations (cherry-pick from tclclockmod)
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tclClockFmt.c | 102 |
1 files changed, 71 insertions, 31 deletions
diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index 6ce478f..d59f424 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -56,6 +56,40 @@ static void ClockFrmScnFinalize(void *clientData); *---------------------------------------------------------------------- */ +static inline void +_str2int_no( + int *out, + const char *p, + const char *e, + int sign) +{ + /* assert(e <= p+10); */ + int val = 0; + /* overflow impossible for 10 digits ("9..9"), so no needs to check at all */ + while (p < e) { /* never overflows */ + val = val * 10 + (*p++ - '0'); + } + if (sign < 0) { val = -val; } + *out = val; +} + +static inline void +_str2wideInt_no( + Tcl_WideInt *out, + const char *p, + const char *e, + int sign) +{ + /* assert(e <= p+18); */ + Tcl_WideInt val = 0; + /* overflow impossible for 18 digits ("9..9"), so no needs to check at all */ + while (p < e) { /* never overflows */ + val = val * 10 + (*p++ - '0'); + } + if (sign < 0) { val = -val; } + *out = val; +} + /* int & Tcl_WideInt overflows may happens here (expected case) */ #if defined(__GNUC__) || defined(__GNUG__) # pragma GCC optimize("no-trapv") @@ -68,29 +102,27 @@ _str2int( const char *e, int sign) { - int val = 0, prev = 0; - const char *eNO = e; + int val = 0; /* overflow impossible for 10 digits ("9..9"), so no needs to check before */ - if (e-p > 10) { - eNO = p+10; + const char *eNO = p+10; + if (eNO > e) { + eNO = e; + } + while (p < eNO) { /* never overflows */ + val = val * 10 + (*p++ - '0'); } if (sign >= 0) { - while (p < eNO) { /* never overflows */ - val = val * 10 + (*p++ - '0'); - } while (p < e) { /* check for overflow */ - prev = val; + int prev = val; val = val * 10 + (*p++ - '0'); if (val / 10 < prev) { return TCL_ERROR; } } } else { - while (p < eNO) { /* never overflows */ - val = val * 10 - (*p++ - '0'); - } + val = -val; while (p < e) { /* check for overflow */ - prev = val; + int prev = val; val = val * 10 - (*p++ - '0'); if (val / 10 > prev) { return TCL_ERROR; @@ -108,29 +140,27 @@ _str2wideInt( const char *e, int sign) { - Tcl_WideInt val = 0, prev = 0; - const char *eNO = e; + register Tcl_WideInt val = 0; /* overflow impossible for 18 digits ("9..9"), so no needs to check before */ - if (e-p > 18) { - eNO = p+18; + const char *eNO = p+18; + if (eNO > e) { + eNO = e; + } + while (p < eNO) { /* never overflows */ + val = val * 10 + (*p++ - '0'); } if (sign >= 0) { - while (p < eNO) { /* never overflows */ - val = val * 10 + (*p++ - '0'); - } while (p < e) { /* check for overflow */ - prev = val; + Tcl_WideInt prev = val; val = val * 10 + (*p++ - '0'); if (val / 10 < prev) { return TCL_ERROR; } } } else { - while (p < eNO) { /* never overflows */ - val = val * 10 - (*p++ - '0'); - } + val = -val; while (p < e) { /* check for overflow */ - prev = val; + Tcl_WideInt prev = val; val = val * 10 - (*p++ - '0'); if (val / 10 > prev) { return TCL_ERROR; @@ -140,6 +170,7 @@ _str2wideInt( *out = val; return TCL_OK; } + int TclAtoWIe( Tcl_WideInt *out, @@ -150,7 +181,6 @@ TclAtoWIe( return _str2wideInt(out, p, e, sign); } - #if defined(__GNUC__) || defined(__GNUG__) # pragma GCC reset_options #endif @@ -2343,15 +2373,25 @@ ClockScan( if (map->offs) { p = yyInput; x = p + size; if (map->type == CTOKT_INT) { - if (_str2int((int *)(((char *)info) + map->offs), - p, x, sign) != TCL_OK) { - goto overflow; + if (size <= 10) { + _str2int_no((int *)(((char *)info) + map->offs), + p, x, sign); + } else { + if (_str2int((int *)(((char *)info) + map->offs), + p, x, sign) != TCL_OK) { + goto overflow; + } } p = x; } else { - if (_str2wideInt((Tcl_WideInt *)(((char *)info) + map->offs), - p, x, sign) != TCL_OK) { - goto overflow; + if (size <= 18) { + _str2wideInt_no((Tcl_WideInt *)(((char *)info) + map->offs), + p, x, sign); + } else { + if (_str2wideInt((Tcl_WideInt *)(((char *)info) + map->offs), + p, x, sign) != TCL_OK) { + goto overflow; + } } p = x; } |