diff options
author | sebres <sebres@users.sourceforge.net> | 2024-03-12 02:05:58 (GMT) |
---|---|---|
committer | sebres <sebres@users.sourceforge.net> | 2024-03-12 02:05:58 (GMT) |
commit | bbb594048998c37ffff17a30ac1ababd1be5c9bf (patch) | |
tree | 318aef73b9c9ecb2df948ee255fd5693b2f03fa3 /generic | |
parent | 8be2c4bdbc2d3f24ea0670b493d2f637aae11441 (diff) | |
parent | 1310cb5ded14e54448035cf0df34fc46782aaa47 (diff) | |
download | tcl-bbb594048998c37ffff17a30ac1ababd1be5c9bf.zip tcl-bbb594048998c37ffff17a30ac1ababd1be5c9bf.tar.gz tcl-bbb594048998c37ffff17a30ac1ababd1be5c9bf.tar.bz2 |
merge sebres-8-6-clock-speedup-cr2
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tclClock.c | 85 | ||||
-rw-r--r-- | generic/tclClockFmt.c | 9 | ||||
-rw-r--r-- | generic/tclDate.c | 4 | ||||
-rw-r--r-- | generic/tclDate.h | 20 | ||||
-rw-r--r-- | generic/tclGetDate.y | 4 |
5 files changed, 78 insertions, 44 deletions
diff --git a/generic/tclClock.c b/generic/tclClock.c index 1c91578..107d4e5 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -1350,20 +1350,20 @@ ClockSetupTimeZone( Tcl_Obj * ClockFormatNumericTimeZone(int z) { - char sign = '+'; - int h, m; + char buf[12+1], *p; + if ( z < 0 ) { z = -z; - sign = '-'; + *buf = '-'; + } else { + *buf = '+'; } - h = z / 3600; - z %= 3600; - m = z / 60; - z %= 60; + TclItoAw(buf+1, z / 3600, '0', 2); z %= 3600; + p = TclItoAw(buf+3, z / 60, '0', 2); z %= 60; if (z != 0) { - return Tcl_ObjPrintf("%c%02d%02d%02d", sign, h, m, z); + p = TclItoAw(buf+5, z, '0', 2); } - return Tcl_ObjPrintf("%c%02d%02d", sign, h, m); + return Tcl_NewStringObj(buf, p - buf); } /* @@ -2219,6 +2219,9 @@ ConvertUTCToLocal( return TCL_ERROR; } + /* signal we need to revalidate TZ epoch next time fields gets used. */ + fields->flags |= CLF_CTZ; + /* we cannot cache (ranges unknown yet) */ } else { Tcl_WideInt rangesVal[2]; @@ -2228,6 +2231,9 @@ ConvertUTCToLocal( return TCL_ERROR; } + /* converted using table (TZ isn't :localtime) */ + fields->flags &= ~CLF_CTZ; + /* Cache the last conversion */ if (ltzoc != NULL) { /* slot was found above */ /* timezoneObj and changeover are the same */ @@ -2330,7 +2336,7 @@ ConvertUTCToLocalUsingC( time_t tock; struct tm *timeVal; /* Time after conversion */ int diff; /* Time zone diff local-Greenwich */ - char buffer[16]; /* Buffer for time zone name */ + char buffer[16], *p; /* Buffer for time zone name */ /* * Use 'localtime' to determine local year, month, day, time of day. @@ -2383,14 +2389,12 @@ ConvertUTCToLocalUsingC( } else { *buffer = '+'; } - snprintf(buffer+1, sizeof(buffer) - 1, "%02d", diff / 3600); - diff %= 3600; - snprintf(buffer+3, sizeof(buffer) - 3, "%02d", diff / 60); - diff %= 60; - if (diff > 0) { - snprintf(buffer+5, sizeof(buffer) - 5, "%02d", diff); + TclItoAw(buffer+1, diff / 3600, '0', 2); diff %= 3600; + p = TclItoAw(buffer+3, diff / 60, '0', 2); diff %= 60; + if (diff != 0) { + p = TclItoAw(buffer+5, diff, '0', 2); } - Tcl_SetObjRef(fields->tzName, Tcl_NewStringObj(buffer, -1)); + Tcl_SetObjRef(fields->tzName, Tcl_NewStringObj(buffer, p - buffer)); return TCL_OK; } @@ -3462,7 +3466,10 @@ baseNow: /* check base fields already cached (by TZ, last-second cache) */ if ( dataPtr->lastBase.timezoneObj == opts->timezoneObj - && dataPtr->lastBase.date.seconds == baseVal) { + && dataPtr->lastBase.date.seconds == baseVal + && (!(dataPtr->lastBase.date.flags & CLF_CTZ) + || dataPtr->lastTZEpoch == TzsetIfNecessary()) + ) { memcpy(date, &dataPtr->lastBase.date, ClockCacheableDateFieldsSize); } else { /* extact fields from base */ @@ -3986,16 +3993,23 @@ ClockFreeScan( */ if (info->flags & CLF_ZONE) { - Tcl_Obj *tzObjStor = NULL; - int minEast = -yyTimezone; - int dstFlag = 1 - yyDSTmode; - tzObjStor = ClockFormatNumericTimeZone( - 60 * minEast + 3600 * dstFlag); - Tcl_IncrRefCount(tzObjStor); - - opts->timezoneObj = ClockSetupTimeZone(dataPtr, interp, tzObjStor); - - Tcl_DecrRefCount(tzObjStor); + if (yyTimezone || !yyDSTmode) { + /* Real time zone from numeric zone */ + Tcl_Obj *tzObjStor = NULL; + int minEast = -yyTimezone; + int dstFlag = 1 - yyDSTmode; + tzObjStor = ClockFormatNumericTimeZone( + 60 * minEast + 3600 * dstFlag); + Tcl_IncrRefCount(tzObjStor); + + opts->timezoneObj = ClockSetupTimeZone(dataPtr, interp, tzObjStor); + + Tcl_DecrRefCount(tzObjStor); + } else { + /* simplest case - GMT / UTC */ + opts->timezoneObj = ClockSetupTimeZone(dataPtr, interp, + dataPtr->literals[LIT_GMT]); + } if (opts->timezoneObj == NULL) { goto done; } @@ -4147,7 +4161,7 @@ repeat_rel: /* relative time (seconds), if exceeds current date, do the day conversion and * leave rest of the increment in yyRelSeconds to add it hereafter in UTC seconds */ if (yyRelSeconds) { - int newSecs = yySecondOfDay + yyRelSeconds; + Tcl_WideInt newSecs = yySecondOfDay + yyRelSeconds; /* if seconds increment outside of current date, increment day */ if (newSecs / SECONDS_PER_DAY != yySecondOfDay / SECONDS_PER_DAY) { @@ -4392,19 +4406,22 @@ ClockAddObjCmd( */ for (i = 2; i < objc; i+=2) { - /* bypass not integers (options, allready processed above) */ + /* bypass not integers (options, allready processed above in ClockParseFmtScnArgs) */ if (TclGetWideIntFromObj(NULL, objv[i], &offs) != TCL_OK) { continue; } - if (objv[i]->typePtr == &tclBignumType) { - Tcl_SetObjResult(interp, dataPtr->literals[LIT_INTEGER_VALUE_TOO_LARGE]); - goto done; - } /* get unit */ if (Tcl_GetIndexFromObj(interp, objv[i+1], units, "unit", 0, &unitIndex) != TCL_OK) { goto done; } + if (objv[i]->typePtr == &tclBignumType + || offs > (unitIndex < CLC_ADD_HOURS ? 0x7fffffff : TCL_MAX_SECONDS) + || offs < (unitIndex < CLC_ADD_HOURS ? -0x7fffffff : TCL_MIN_SECONDS) + ) { + Tcl_SetObjResult(interp, dataPtr->literals[LIT_INTEGER_VALUE_TOO_LARGE]); + goto done; + } /* nothing to do if zero quantity */ if (!offs) { diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index f79a863..edb74ae 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -197,6 +197,15 @@ _itoaw( return buf + width; } +char * +TclItoAw( + char *buf, + int val, + char padchar, + unsigned short int width) +{ + return _itoaw(buf, val, padchar, width); +} static inline char * _witoaw( diff --git a/generic/tclDate.c b/generic/tclDate.c index f4be5b6..1614bb0 100644 --- a/generic/tclDate.c +++ b/generic/tclDate.c @@ -139,7 +139,7 @@ typedef struct _TABLE { const char *name; int type; - long value; + Tcl_WideInt value; } TABLE; /* @@ -221,7 +221,7 @@ extern int TclDatedebug; union YYSTYPE { - long Number; + Tcl_WideInt Number; enum _MERIDIAN Meridian; diff --git a/generic/tclDate.h b/generic/tclDate.h index 5033018..3544dee 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -148,6 +148,8 @@ typedef enum ClockMsgCtLiteral { * Structure containing the fields used in [clock format] and [clock scan] */ +#define CLF_CTZ (1 << 4) + typedef struct TclDateFields { /* Cacheable fields: */ @@ -170,8 +172,10 @@ typedef struct TclDateFields { int dayOfWeek; /* Day of the week */ int hour; /* Hours of day (in-between time only calculation) */ int minutes; /* Minutes of hour (in-between time only calculation) */ - int secondOfMin; /* Seconds of minute (in-between time only calculation) */ - int secondOfDay; /* Seconds of day (in-between time only calculation) */ + Tcl_WideInt secondOfMin; /* Seconds of minute (in-between time only calculation) */ + Tcl_WideInt secondOfDay; /* Seconds of day (in-between time only calculation) */ + + int flags; /* 0 or CLF_CTZ */ /* Non cacheable fields: */ @@ -209,16 +213,16 @@ typedef struct DateInfo { int dateTimezone; int dateDSTmode; - int dateRelMonth; - int dateRelDay; - int dateRelSeconds; + Tcl_WideInt dateRelMonth; + Tcl_WideInt dateRelDay; + Tcl_WideInt dateRelSeconds; int dateMonthOrdinalIncr; int dateMonthOrdinal; int dateDayOrdinal; - int *dateRelPointer; + Tcl_WideInt *dateRelPointer; int dateSpaceCount; int dateDigitCount; @@ -538,6 +542,10 @@ MODULE_SCOPE int ClockMCSetIdx(ClockFmtScnCmdArgs *opts, int mcKey, /* tclClockFmt.c module declarations */ + +MODULE_SCOPE char * + TclItoAw(char *buf, int val, char padchar, unsigned short int width); + MODULE_SCOPE Tcl_Obj* ClockFrmObjGetLocFmtKey(Tcl_Interp *interp, Tcl_Obj *objPtr); diff --git a/generic/tclGetDate.y b/generic/tclGetDate.y index 270a3a8..0bf16e8 100644 --- a/generic/tclGetDate.y +++ b/generic/tclGetDate.y @@ -89,7 +89,7 @@ typedef struct _TABLE { const char *name; int type; - long value; + Tcl_WideInt value; } TABLE; /* @@ -103,7 +103,7 @@ typedef enum _DSTMODE { %} %union { - long Number; + Tcl_WideInt Number; enum _MERIDIAN Meridian; } |