summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generic/tclClock.c268
-rw-r--r--generic/tclClockFmt.c178
-rw-r--r--generic/tclDate.h116
-rw-r--r--generic/tclStrIdxTree.c2
4 files changed, 306 insertions, 258 deletions
diff --git a/generic/tclClock.c b/generic/tclClock.c
index 5c428d2..722aba7 100644
--- a/generic/tclClock.c
+++ b/generic/tclClock.c
@@ -76,7 +76,7 @@ static int ConvertUTCToLocalUsingTable(Tcl_Interp *,
Tcl_WideInt *rangesVal);
static int ConvertUTCToLocalUsingC(Tcl_Interp *,
TclDateFields *, int);
-static int ConvertLocalToUTC(void *clientData, Tcl_Interp *,
+static int ConvertLocalToUTC(ClockClientData *, Tcl_Interp *,
TclDateFields *, Tcl_Obj *timezoneObj, int);
static int ConvertLocalToUTCUsingTable(Tcl_Interp *,
TclDateFields *, int, Tcl_Obj *const[],
@@ -91,7 +91,7 @@ static void GetMonthDay(TclDateFields *);
static Tcl_WideInt WeekdayOnOrBefore(int, Tcl_WideInt);
static Tcl_ObjCmdProc ClockClicksObjCmd;
static Tcl_ObjCmdProc ClockConvertlocaltoutcObjCmd;
-static int ClockGetDateFields(void *clientData,
+static int ClockGetDateFields(ClockClientData *,
Tcl_Interp *interp, TclDateFields *fields,
Tcl_Obj *timezoneObj, int changeover);
static Tcl_ObjCmdProc ClockGetdatefieldsObjCmd;
@@ -197,7 +197,8 @@ TclClockInit(
data->refCount = 0;
data->literals = (Tcl_Obj **) ckalloc(LIT__END * sizeof(Tcl_Obj*));
for (i = 0; i < LIT__END; ++i) {
- TclInitObjRef(data->literals[i], Tcl_NewStringObj(Literals[i], -1));
+ TclInitObjRef(data->literals[i], Tcl_NewStringObj(
+ Literals[i], TCL_AUTO_LENGTH));
}
data->mcLiterals = NULL;
data->mcLitIdxs = NULL;
@@ -374,19 +375,20 @@ ClockDeleteCmdProc(
*
* Used to store previously used/cached time zone (makes it reusable).
*
- * This enables faster switch between time zones (e. g. to convert from one to another).
+ * This enables faster switch between time zones (e. g. to convert from
+ * one to another).
*
* Results:
* None.
*
*----------------------------------------------------------------------
*/
-
static inline void
SavePrevTimezoneObj(
ClockClientData *dataPtr) /* Client data containing literal pool */
{
Tcl_Obj *timezoneObj = dataPtr->lastSetupTimeZone;
+
if (timezoneObj && timezoneObj != dataPtr->prevSetupTimeZone) {
TclSetObjRef(dataPtr->prevSetupTimeZoneUnnorm, dataPtr->lastSetupTimeZoneUnnorm);
TclSetObjRef(dataPtr->prevSetupTimeZone, timezoneObj);
@@ -686,19 +688,20 @@ Tcl_Obj *
ClockMCDict(
ClockFmtScnCmdArgs *opts)
{
- ClockClientData *dataPtr = (ClockClientData *)opts->clientData;
+ ClockClientData *dataPtr = opts->dataPtr;
/* if dict not yet retrieved */
if (opts->mcDictObj == NULL) {
/* if locale was not yet used */
if (!(opts->flags & CLF_LOCALE_USED)) {
- opts->localeObj = NormLocaleObj((ClockClientData *) opts->clientData, opts->interp,
+ opts->localeObj = NormLocaleObj(dataPtr, opts->interp,
opts->localeObj, &opts->mcDictObj);
if (opts->localeObj == NULL) {
Tcl_SetObjResult(opts->interp, Tcl_NewStringObj(
- "locale not specified and no default locale set", -1));
+ "locale not specified and no default locale set",
+ TCL_AUTO_LENGTH));
Tcl_SetErrorCode(opts->interp, "CLOCK", "badOption", (char *)NULL);
return NULL;
}
@@ -711,8 +714,8 @@ ClockMCDict(
dataPtr->mcLiterals = (Tcl_Obj **)
ckalloc(MCLIT__END * sizeof(Tcl_Obj*));
for (i = 0; i < MCLIT__END; ++i) {
- TclInitObjRef(dataPtr->mcLiterals[i],
- Tcl_NewStringObj(MsgCtLiterals[i], -1));
+ TclInitObjRef(dataPtr->mcLiterals[i], Tcl_NewStringObj(
+ MsgCtLiterals[i], TCL_AUTO_LENGTH));
}
}
}
@@ -795,7 +798,6 @@ ClockMCGet(
ClockFmtScnCmdArgs *opts,
int mcKey)
{
- ClockClientData *dataPtr = (ClockClientData *)opts->clientData;
Tcl_Obj *valObj = NULL;
if (opts->mcDictObj == NULL) {
@@ -806,8 +808,7 @@ ClockMCGet(
}
Tcl_DictObjGet(opts->interp, opts->mcDictObj,
- dataPtr->mcLiterals[mcKey], &valObj);
-
+ opts->dataPtr->mcLiterals[mcKey], &valObj);
return valObj; /* or NULL in obscure case if Tcl_DictObjGet failed */
}
@@ -831,7 +832,7 @@ ClockMCGetIdx(
ClockFmtScnCmdArgs *opts,
int mcKey)
{
- ClockClientData *dataPtr = (ClockClientData *)opts->clientData;
+ ClockClientData *dataPtr = opts->dataPtr;
Tcl_Obj *valObj = NULL;
if (opts->mcDictObj == NULL) {
@@ -874,7 +875,7 @@ ClockMCSetIdx(
int mcKey,
Tcl_Obj *valObj)
{
- ClockClientData *dataPtr = (ClockClientData *)opts->clientData;
+ ClockClientData *dataPtr = opts->dataPtr;
if (opts->mcDictObj == NULL) {
ClockMCDict(opts);
@@ -890,7 +891,7 @@ ClockMCSetIdx(
dataPtr->mcLitIdxs = (Tcl_Obj **) ckalloc(MCLIT__END * sizeof(Tcl_Obj*));
for (i = 0; i < MCLIT__END; ++i) {
TclInitObjRef(dataPtr->mcLitIdxs[i],
- Tcl_NewStringObj(MsgCtLitIdxs[i], -1));
+ Tcl_NewStringObj(MsgCtLitIdxs[i], TCL_AUTO_LENGTH));
}
}
@@ -909,7 +910,7 @@ TimezoneLoaded(
/* mark GMT zone loaded */
if (dataPtr->gmtSetupTimeZone == NULL) {
TclSetObjRef(dataPtr->gmtSetupTimeZone,
- dataPtr->literals[LIT_GMT]);
+ dataPtr->literals[LIT_GMT]);
}
TclSetObjRef(dataPtr->gmtSetupTimeZoneUnnorm, tzUnnormObj);
return;
@@ -1175,11 +1176,10 @@ ClockConfigureObjCmd(
static inline Tcl_Obj *
ClockGetTZData(
- void *clientData, /* Opaque pointer to literal pool, etc. */
+ ClockClientData *dataPtr, /* Opaque pointer to literal pool, etc. */
Tcl_Interp *interp, /* Tcl interpreter */
Tcl_Obj *timezoneObj) /* Name of the timezone */
{
- ClockClientData *dataPtr = (ClockClientData *)clientData;
Tcl_Obj *ret, **out = NULL;
/* if cached (if already setup this one) */
@@ -1245,11 +1245,9 @@ ClockGetTZData(
static Tcl_Obj *
ClockGetSystemTimeZone(
- void *clientData, /* Opaque pointer to literal pool, etc. */
+ ClockClientData *dataPtr, /* Pointer to literal pool, etc. */
Tcl_Interp *interp) /* Tcl interpreter */
{
- ClockClientData *dataPtr = (ClockClientData *)clientData;
-
/* if known (cached and same epoch) - return now */
if (dataPtr->systemTimeZone != NULL
&& dataPtr->lastTZEpoch == TzsetIfNecessary()) {
@@ -1284,11 +1282,10 @@ ClockGetSystemTimeZone(
Tcl_Obj *
ClockSetupTimeZone(
- void *clientData, /* Opaque pointer to literal pool, etc. */
+ ClockClientData *dataPtr, /* Pointer to literal pool, etc. */
Tcl_Interp *interp, /* Tcl interpreter */
Tcl_Obj *timezoneObj)
{
- ClockClientData *dataPtr = (ClockClientData *)clientData;
int loaded;
Tcl_Obj *callargs[2];
@@ -1401,12 +1398,12 @@ ClockFormatNumericTimeZone(
static int
ClockConvertlocaltoutcObjCmd(
- void *clientData, /* Client data */
+ void *clientData, /* Literal table */
Tcl_Interp *interp, /* Tcl interpreter */
int objc, /* Parameter count */
Tcl_Obj *const *objv) /* Parameter vector */
{
- ClockClientData *data = (ClockClientData *)clientData;
+ ClockClientData *dataPtr = (ClockClientData *)clientData;
Tcl_Obj *secondsObj;
Tcl_Obj *dict;
int changeover;
@@ -1424,18 +1421,18 @@ ClockConvertlocaltoutcObjCmd(
return TCL_ERROR;
}
dict = objv[1];
- if (Tcl_DictObjGet(interp, dict, data->literals[LIT_LOCALSECONDS],
+ if (Tcl_DictObjGet(interp, dict, dataPtr->literals[LIT_LOCALSECONDS],
&secondsObj)!= TCL_OK) {
return TCL_ERROR;
}
if (secondsObj == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("key \"localseconds\" not "
- "found in dictionary", -1));
+ "found in dictionary", TCL_AUTO_LENGTH));
return TCL_ERROR;
}
if ((TclGetWideIntFromObj(interp, secondsObj, &fields.localSeconds) != TCL_OK)
|| (TclGetIntFromObj(interp, objv[3], &changeover) != TCL_OK)
- || ConvertLocalToUTC(clientData, interp, &fields, objv[2], changeover)) {
+ || ConvertLocalToUTC(dataPtr, interp, &fields, objv[2], changeover)) {
return TCL_ERROR;
}
@@ -1449,7 +1446,7 @@ ClockConvertlocaltoutcObjCmd(
created = 1;
Tcl_IncrRefCount(dict);
}
- status = Tcl_DictObjPut(interp, dict, data->literals[LIT_SECONDS],
+ status = Tcl_DictObjPut(interp, dict, dataPtr->literals[LIT_SECONDS],
Tcl_NewWideIntObj(fields.seconds));
if (status == TCL_OK) {
Tcl_SetObjResult(interp, dict);
@@ -1498,8 +1495,8 @@ ClockGetdatefieldsObjCmd(
{
TclDateFields fields;
Tcl_Obj *dict;
- ClockClientData *data = (ClockClientData *)clientData;
- Tcl_Obj *const *lit = data->literals;
+ ClockClientData *dataPtr = (ClockClientData *)clientData;
+ Tcl_Obj *const *lit = dataPtr->literals;
int changeover;
fields.tzName = NULL;
@@ -1529,7 +1526,7 @@ ClockGetdatefieldsObjCmd(
/* Extract fields */
- if (ClockGetDateFields(clientData, interp, &fields, objv[2],
+ if (ClockGetDateFields(dataPtr, interp, &fields, objv[2],
changeover) != TCL_OK) {
return TCL_ERROR;
}
@@ -1588,7 +1585,7 @@ ClockGetdatefieldsObjCmd(
int
ClockGetDateFields(
- void *clientData, /* Client data of the interpreter */
+ ClockClientData *dataPtr, /* Literal pool, etc. */
Tcl_Interp *interp, /* Tcl interpreter */
TclDateFields *fields, /* Pointer to result fields, where
* fields->seconds contains date to extract */
@@ -1599,7 +1596,7 @@ ClockGetDateFields(
* Convert UTC time to local.
*/
- if (ConvertUTCToLocal(clientData, interp, fields, timezoneObj,
+ if (ConvertUTCToLocal(dataPtr, interp, fields, timezoneObj,
changeover) != TCL_OK) {
return TCL_ERROR;
}
@@ -1609,7 +1606,7 @@ ClockGetDateFields(
*/
ClockExtractJDAndSODFromSeconds(fields->julianDay, fields->secondOfDay,
- fields->localSeconds);
+ fields->localSeconds);
/*
* Convert to Julian or Gregorian calendar.
@@ -1657,7 +1654,7 @@ FetchEraField(
}
if (value == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "expected key(s) not found in dictionary", -1));
+ "expected key(s) not found in dictionary", TCL_AUTO_LENGTH));
return TCL_ERROR;
}
return Tcl_GetIndexFromObj(interp, value, eras, "era", TCL_EXACT, storePtr);
@@ -1677,7 +1674,7 @@ FetchIntField(
}
if (value == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "expected key(s) not found in dictionary", -1));
+ "expected key(s) not found in dictionary", TCL_AUTO_LENGTH));
return TCL_ERROR;
}
return TclGetIntFromObj(interp, value, storePtr);
@@ -1854,13 +1851,12 @@ ClockGetjuliandayfromerayearweekdayObjCmd(
static int
ConvertLocalToUTC(
- void *clientData, /* Client data of the interpreter */
+ ClockClientData *dataPtr, /* Literal pool, etc. */
Tcl_Interp *interp, /* Tcl interpreter */
TclDateFields *fields, /* Fields of the time */
Tcl_Obj *timezoneObj, /* Time zone */
int changeover) /* Julian Day of the Gregorian transition */
{
- ClockClientData *dataPtr = (ClockClientData *)clientData;
Tcl_Obj *tzdata; /* Time zone data */
Tcl_Size rowc; /* Number of rows in tzdata */
Tcl_Obj **rowv; /* Pointers to the rows */
@@ -1905,7 +1901,7 @@ ConvertLocalToUTC(
* Unpack the tz data.
*/
- tzdata = ClockGetTZData(clientData, interp, timezoneObj);
+ tzdata = ClockGetTZData(dataPtr, interp, timezoneObj);
if (tzdata == NULL) {
return TCL_ERROR;
}
@@ -2123,7 +2119,7 @@ ConvertLocalToUTCUsingC(
if (localErrno != 0
|| (fields->seconds == -1 && timeVal.tm_yday == -1)) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "time value too large/small to represent", -1));
+ "time value too large/small to represent", TCL_AUTO_LENGTH));
return TCL_ERROR;
}
return TCL_OK;
@@ -2147,13 +2143,12 @@ ConvertLocalToUTCUsingC(
int
ConvertUTCToLocal(
- void *clientData, /* Client data of the interpreter */
+ ClockClientData *dataPtr, /* Literal pool, etc. */
Tcl_Interp *interp, /* Tcl interpreter */
TclDateFields *fields, /* Fields of the time */
Tcl_Obj *timezoneObj, /* Time zone */
int changeover) /* Julian Day of the Gregorian transition */
{
- ClockClientData *dataPtr = (ClockClientData *)clientData;
Tcl_Obj *tzdata; /* Time zone data */
Tcl_Size rowc; /* Number of rows in tzdata */
Tcl_Obj **rowv; /* Pointers to the rows */
@@ -2166,7 +2161,7 @@ ConvertUTCToLocal(
if (dataPtr->gmtTZName == NULL) {
Tcl_Obj *tzName;
- tzdata = ClockGetTZData(clientData, interp, timezoneObj);
+ tzdata = ClockGetTZData(dataPtr, interp, timezoneObj);
if (TclListObjGetElements(interp, tzdata, &rowc, &rowv) != TCL_OK
|| Tcl_ListObjIndex(interp, rowv[0], 3, &tzName) != TCL_OK) {
return TCL_ERROR;
@@ -2201,7 +2196,7 @@ ConvertUTCToLocal(
* Unpack the tz data.
*/
- tzdata = ClockGetTZData(clientData, interp, timezoneObj);
+ tzdata = ClockGetTZData(dataPtr, interp, timezoneObj);
if (tzdata == NULL) {
return TCL_ERROR;
}
@@ -2346,7 +2341,7 @@ ConvertUTCToLocalUsingC(
tock = (time_t) fields->seconds;
if ((Tcl_WideInt) tock != fields->seconds) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "number too large to represent as a Posix time", -1));
+ "number too large to represent as a Posix time", TCL_AUTO_LENGTH));
Tcl_SetErrorCode(interp, "CLOCK", "argTooLarge", (char *)NULL);
return TCL_ERROR;
}
@@ -2355,7 +2350,7 @@ ConvertUTCToLocalUsingC(
if (timeVal == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"localtime failed (clock value may be too "
- "large/small to represent)", -1));
+ "large/small to represent)", TCL_AUTO_LENGTH));
Tcl_SetErrorCode(interp, "CLOCK", "localtimeFailed", (char *)NULL);
return TCL_ERROR;
}
@@ -3049,7 +3044,8 @@ ClockGetenvObjCmd(
varName = TclGetString(objv[1]);
varValue = getenv(varName);
if (varValue != NULL) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(varValue, -1));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ varValue, TCL_AUTO_LENGTH));
}
#endif
return TCL_OK;
@@ -3243,12 +3239,12 @@ ClockMicrosecondsObjCmd(
static inline void
ClockInitFmtScnArgs(
- void *clientData,
+ ClockClientData *dataPtr,
Tcl_Interp *interp,
ClockFmtScnCmdArgs *opts)
{
memset(opts, 0, sizeof(*opts));
- opts->clientData = clientData;
+ opts->dataPtr = dataPtr;
opts->interp = interp;
}
@@ -3270,22 +3266,24 @@ ClockInitFmtScnArgs(
*-----------------------------------------------------------------------------
*/
-#define CLC_FMT_ARGS (0)
-#define CLC_SCN_ARGS (1 << 0)
-#define CLC_ADD_ARGS (1 << 1)
+typedef enum ClockOperation {
+ CLC_OP_FMT = 0, /* Doing [clock format] */
+ CLC_OP_SCN, /* Doing [clock scan] */
+ CLC_OP_ADD /* Doing [clock add] */
+} ClockOperation;
static int
ClockParseFmtScnArgs(
ClockFmtScnCmdArgs *opts, /* Result vector: format, locale, timezone... */
- TclDateFields *date, /* Extracted date-time corresponding base
+ TclDateFields *date, /* Extracted date-time corresponding base
* (by scan or add) resp. clockval (by format) */
int objc, /* Parameter count */
Tcl_Obj *const objv[], /* Parameter vector */
- int flags, /* Flags, differentiates between format, scan, add */
+ ClockOperation operation, /* What operation are we doing: format, scan, add */
const char *syntax) /* Syntax of the current command */
{
Tcl_Interp *interp = opts->interp;
- ClockClientData *dataPtr = (ClockClientData *)opts->clientData;
+ ClockClientData *dataPtr = opts->dataPtr;
int gmtFlag = 0;
static const char *const options[] = {
"-base", "-format", "-gmt", "-locale", "-timezone", "-validate", NULL
@@ -3299,13 +3297,13 @@ ClockParseFmtScnArgs(
int i, baseIdx;
Tcl_WideInt baseVal; /* Base time, expressed in seconds from the Epoch */
- if (flags & CLC_SCN_ARGS) {
+ if (operation == CLC_OP_SCN) {
/* default flags (from configure) */
- opts->flags |= dataPtr->defFlags & (CLF_VALIDATE);
+ opts->flags |= dataPtr->defFlags & CLF_VALIDATE;
} else {
/* clock value (as current base) */
opts->baseObj = objv[(baseIdx = 1)];
- saw |= (1 << CLC_ARGS_BASE);
+ saw |= 1 << CLC_ARGS_BASE;
}
/*
@@ -3314,7 +3312,7 @@ ClockParseFmtScnArgs(
for (i = 2; i < objc; i+=2) {
/* bypass integers (offsets) by "clock add" */
- if (flags & CLC_ADD_ARGS) {
+ if (operation == CLC_OP_ADD) {
Tcl_WideInt num;
if (TclGetWideIntFromObj(NULL, objv[i], &num) == TCL_OK) {
@@ -3328,8 +3326,7 @@ ClockParseFmtScnArgs(
}
/* if already specified */
if (saw & (1 << optionIndex)) {
- if (!(flags & CLC_SCN_ARGS)
- && optionIndex == CLC_ARGS_BASE) {
+ if (operation != CLC_OP_SCN && optionIndex == CLC_ARGS_BASE) {
goto badOptionMsg;
}
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
@@ -3339,7 +3336,7 @@ ClockParseFmtScnArgs(
}
switch (optionIndex) {
case CLC_ARGS_FORMAT:
- if (flags & CLC_ADD_ARGS) {
+ if (operation == CLC_OP_ADD) {
goto badOptionMsg;
}
opts->formatObj = objv[i + 1];
@@ -3359,7 +3356,7 @@ ClockParseFmtScnArgs(
opts->baseObj = objv[(baseIdx = i + 1)];
break;
case CLC_ARGS_VALIDATE:
- if (!(flags & CLC_SCN_ARGS)) {
+ if (operation != CLC_OP_SCN) {
goto badOptionMsg;
} else {
int val;
@@ -3375,7 +3372,7 @@ ClockParseFmtScnArgs(
}
break;
}
- saw |= (1 << optionIndex);
+ saw |= 1 << optionIndex;
}
/*
@@ -3384,7 +3381,8 @@ ClockParseFmtScnArgs(
if ((saw & (1 << CLC_ARGS_GMT))
&& (saw & (1 << CLC_ARGS_TIMEZONE))) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot use -gmt and -timezone in same call", -1));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "cannot use -gmt and -timezone in same call", TCL_AUTO_LENGTH));
Tcl_SetErrorCode(interp, "CLOCK", "gmtWithTimezone", (char *)NULL);
return TCL_ERROR;
}
@@ -3394,7 +3392,7 @@ ClockParseFmtScnArgs(
|| TclGetString(opts->timezoneObj) == NULL
|| opts->timezoneObj->length == 0) {
/* If time zone not specified use system time zone */
- opts->timezoneObj = ClockGetSystemTimeZone(opts->clientData, interp);
+ opts->timezoneObj = ClockGetSystemTimeZone(dataPtr, interp);
if (opts->timezoneObj == NULL) {
return TCL_ERROR;
}
@@ -3402,7 +3400,7 @@ ClockParseFmtScnArgs(
/* Setup timezone (normalize object if needed and load TZ on demand) */
- opts->timezoneObj = ClockSetupTimeZone(opts->clientData, interp, opts->timezoneObj);
+ opts->timezoneObj = ClockSetupTimeZone(dataPtr, interp, opts->timezoneObj);
if (opts->timezoneObj == NULL) {
return TCL_ERROR;
}
@@ -3413,7 +3411,7 @@ ClockParseFmtScnArgs(
Tcl_Obj *baseObj = opts->baseObj;
/* bypass integer recognition if looks like option "-now" */
- if ((baseObj->bytes && baseObj->length == 4 && *(baseObj->bytes + 1) == 'n')
+ if ((baseObj->bytes && baseObj->length == 4 && baseObj->bytes[1] == 'n')
|| TclGetWideIntFromObj(NULL, baseObj, &baseVal) != TCL_OK) {
/* we accept "-now" as current date-time */
static const char *const nowOpts[] = {
@@ -3471,7 +3469,7 @@ ClockParseFmtScnArgs(
} else {
/* extact fields from base */
date->seconds = baseVal;
- if (ClockGetDateFields(opts->clientData, interp, date, opts->timezoneObj,
+ if (ClockGetDateFields(dataPtr, interp, date, opts->timezoneObj,
GREGORIAN_CHANGE_DATE) != TCL_OK) {
/* TODO - GREGORIAN_CHANGE_DATE should be locale-dependent */
return TCL_ERROR;
@@ -3522,7 +3520,6 @@ ClockFormatObjCmd(
Tcl_Obj *const objv[]) /* Parameter values */
{
ClockClientData *dataPtr = (ClockClientData *)clientData;
-
static const char *syntax = "clock format clockval|-now "
"?-format string? "
"?-gmt boolean? "
@@ -3544,9 +3541,9 @@ ClockFormatObjCmd(
* Extract values for the keywords.
*/
- ClockInitFmtScnArgs(clientData, interp, &opts);
+ ClockInitFmtScnArgs(dataPtr, interp, &opts);
ret = ClockParseFmtScnArgs(&opts, &dateFmt.date, objc, objv,
- CLC_FMT_ARGS, "-format, -gmt, -locale, or -timezone");
+ CLC_OP_FMT, "-format, -gmt, -locale, or -timezone");
if (ret != TCL_OK) {
goto done;
}
@@ -3591,6 +3588,7 @@ ClockScanObjCmd(
int objc, /* Parameter count */
Tcl_Obj *const objv[]) /* Parameter values */
{
+ ClockClientData *dataPtr = (ClockClientData *)clientData;
static const char *syntax = "clock scan string "
"?-base seconds? "
"?-format string? "
@@ -3614,9 +3612,9 @@ ClockScanObjCmd(
* Extract values for the keywords.
*/
- ClockInitFmtScnArgs(clientData, interp, &opts);
+ ClockInitFmtScnArgs(dataPtr, interp, &opts);
ret = ClockParseFmtScnArgs(&opts, &yy.date, objc, objv,
- CLC_SCN_ARGS, "-base, -format, -gmt, -locale, -timezone or -validate");
+ CLC_OP_SCN, "-base, -format, -gmt, -locale, -timezone or -validate");
if (ret != TCL_OK) {
goto done;
}
@@ -3632,7 +3630,7 @@ ClockScanObjCmd(
* it's not localized. */
if (opts.localeObj != NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "legacy [clock scan] does not support -locale", -1));
+ "legacy [clock scan] does not support -locale", TCL_AUTO_LENGTH));
Tcl_SetErrorCode(interp, "CLOCK", "flagWithLegacyFormat", (char *)NULL);
ret = TCL_ERROR;
goto done;
@@ -3722,13 +3720,11 @@ ClockScanCommit(
/* some overflow checks */
if (info->flags & CLF_JULIANDAY) {
- ClockClientData *dataPtr = (ClockClientData *)opts->clientData;
-
double curJDN = (double)yydate.julianDay
+ ((double)yySecondOfDay - SECONDS_PER_DAY/2) / SECONDS_PER_DAY;
- if (curJDN > dataPtr->maxJDN) {
+ if (curJDN > opts->dataPtr->maxJDN) {
Tcl_SetObjResult(opts->interp, Tcl_NewStringObj(
- "requested date too large to represent", -1));
+ "requested date too large to represent", TCL_AUTO_LENGTH));
Tcl_SetErrorCode(opts->interp, "CLOCK", "dateTooLarge", (char *)NULL);
return TCL_ERROR;
}
@@ -3736,15 +3732,15 @@ ClockScanCommit(
/* Local seconds to UTC (stored in yydate.seconds) */
- if (info->flags & (CLF_ASSEMBLE_SECONDS)) {
+ if (info->flags & CLF_ASSEMBLE_SECONDS) {
yydate.localSeconds =
-210866803200LL
+ (SECONDS_PER_DAY * yydate.julianDay)
+ (yySecondOfDay % SECONDS_PER_DAY);
}
- if (info->flags & (CLF_ASSEMBLE_SECONDS|CLF_LOCALSEC)) {
- if (ConvertLocalToUTC(opts->clientData, opts->interp, &yydate,
+ if (info->flags & (CLF_ASSEMBLE_SECONDS | CLF_LOCALSEC)) {
+ if (ConvertLocalToUTC(opts->dataPtr, opts->interp, &yydate,
opts->timezoneObj, GREGORIAN_CHANGE_DATE) != TCL_OK) {
return TCL_ERROR;
}
@@ -3780,7 +3776,7 @@ ClockValidDate(
const char *errMsg = "", *errCode = "";
TclDateFields temp;
int tempCpyFlg = 0;
- ClockClientData *dataPtr = (ClockClientData *)opts->clientData;
+ ClockClientData *dataPtr = opts->dataPtr;
#if 0
printf("yyMonth %d, yyDay %d, yyDayOfYear %d, yyHour %d, yyMinutes %d, yySeconds %d, "
@@ -3796,7 +3792,7 @@ ClockValidDate(
opts->flags &= ~CLF_VALIDATE_S1; /* stage 1 is done */
/* first year (used later in hath / daysInPriorMonths) */
- if ((info->flags & (CLF_YEAR|CLF_ISO8601YEAR))) {
+ if ((info->flags & (CLF_YEAR | CLF_ISO8601YEAR))) {
if ((info->flags & CLF_ISO8601YEAR)) {
if (yydate.iso8601Year < dataPtr->validMinYear
|| yydate.iso8601Year > dataPtr->validMaxYear) {
@@ -3815,8 +3811,8 @@ ClockValidDate(
} else if ((info->flags & CLF_ISO8601YEAR)) {
yyYear = yydate.iso8601Year; /* used to recognize leap */
}
- if ((info->flags & (CLF_ISO8601YEAR|CLF_YEAR))
- == (CLF_ISO8601YEAR|CLF_YEAR)) {
+ if ((info->flags & (CLF_ISO8601YEAR | CLF_YEAR))
+ == (CLF_ISO8601YEAR | CLF_YEAR)) {
if (yyYear != yydate.iso8601Year) {
errMsg = "ambiguous year";
errCode = "year";
@@ -3966,8 +3962,7 @@ ClockFreeScan(
ClockFmtScnCmdArgs *opts) /* Command options */
{
Tcl_Interp *interp = opts->interp;
- ClockClientData *dataPtr = (ClockClientData *)opts->clientData;
-
+ ClockClientData *dataPtr = opts->dataPtr;
int ret = TCL_ERROR;
/*
@@ -3981,12 +3976,9 @@ ClockFreeScan(
yyInput = TclGetString(strObj);
if (TclClockFreeScan(interp, info) != TCL_OK) {
- Tcl_Obj *msg;
-
- TclNewObj(msg);
- Tcl_AppendPrintfToObj(msg, "unable to convert date-time string \"%s\": %s",
- TclGetString(strObj), Tcl_GetString(Tcl_GetObjResult(interp)));
- Tcl_SetObjResult(interp, msg);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unable to convert date-time string \"%s\": %s",
+ TclGetString(strObj), Tcl_GetString(Tcl_GetObjResult(interp))));
goto done;
}
@@ -4054,14 +4046,13 @@ ClockFreeScan(
* Assemble date, time, zone into seconds-from-epoch
*/
- if ((info->flags & (CLF_TIME|CLF_HAVEDATE)) == CLF_HAVEDATE) {
+ if ((info->flags & (CLF_TIME | CLF_HAVEDATE)) == CLF_HAVEDATE) {
yySecondOfDay = 0;
info->flags |= CLF_ASSEMBLE_SECONDS;
} else if (info->flags & CLF_TIME) {
- yySecondOfDay = ToSeconds(yyHour, yyMinutes,
- yySeconds, yyMeridian);
+ yySecondOfDay = ToSeconds(yyHour, yyMinutes, yySeconds, yyMeridian);
info->flags |= CLF_ASSEMBLE_SECONDS;
- } else if ((info->flags & (CLF_DAYOFWEEK|CLF_HAVEDATE)) == CLF_DAYOFWEEK
+ } else if ((info->flags & (CLF_DAYOFWEEK | CLF_HAVEDATE)) == CLF_DAYOFWEEK
|| (info->flags & CLF_ORDINALMONTH)
|| ((info->flags & CLF_RELCONV)
&& (yyRelMonth != 0 || yyRelDay != 0))) {
@@ -4147,7 +4138,7 @@ ClockCalcRelTime(
}
/* on demand (lazy) assemble julianDay using new year, month, etc. */
- info->flags |= CLF_ASSEMBLE_JULIANDAY|CLF_ASSEMBLE_SECONDS;
+ info->flags |= CLF_ASSEMBLE_JULIANDAY | CLF_ASSEMBLE_SECONDS;
yyRelMonth = 0;
}
@@ -4395,9 +4386,9 @@ ClockAddObjCmd(
* Extract values for the keywords.
*/
- ClockInitFmtScnArgs(clientData, interp, &opts);
+ ClockInitFmtScnArgs(dataPtr, interp, &opts);
ret = ClockParseFmtScnArgs(&opts, &yy.date, objc, objv,
- CLC_ADD_ARGS, "-gmt, -locale, or -timezone");
+ CLC_OP_ADD, "-gmt, -locale, or -timezone");
if (ret != TCL_OK) {
goto done;
}
@@ -4405,7 +4396,9 @@ ClockAddObjCmd(
/* time together as seconds of the day */
yySecondOfDay = yySeconds = yydate.localSeconds % SECONDS_PER_DAY;
/* seconds are in localSeconds (relative base date), so reset time here */
- yyHour = 0; yyMinutes = 0; yyMeridian = MER24;
+ yyHour = 0;
+ yyMinutes = 0;
+ yyMeridian = MER24;
ret = TCL_ERROR;
@@ -4642,58 +4635,69 @@ ClockSafeCatchCmd(
#define wcscmp strcmp
#define wcscpy strcpy
#endif
+#define TZ_INIT_MARKER ((WCHAR *) INT2PTR(-1))
static size_t
TzsetIfNecessary(void)
{
- static WCHAR* tzWas = (WCHAR *)INT2PTR(-1); /* Previous value of TZ, protected by
- * clockMutex. */
- static long tzLastRefresh = 0; /* Used for latency before next refresh */
- static size_t tzWasEpoch = 0; /* Epoch, signals that TZ changed */
- static size_t tzEnvEpoch = 0; /* Last env epoch, for faster signaling,
- that TZ changed via TCL */
- const WCHAR *tzIsNow; /* Current value of TZ */
+ typedef struct ClockTzStatic {
+ WCHAR *was; /* Previous value of TZ. */
+ long lastRefresh; /* Used for latency before next refresh. */
+ size_t epoch; /* Epoch, signals that TZ changed. */
+ size_t envEpoch; /* Last env epoch, for faster signaling,
+ * that TZ changed via TCL */
+ } ClockTzStatic;
+ static ClockTzStatic tz = { /* Global timezone info; protected by
+ * clockMutex.*/
+ TZ_INIT_MARKER, 0, 0, 0
+ };
+ const WCHAR *tzNow; /* Current value of TZ. */
+ Tcl_Time now; /* Current time. */
+ size_t epoch; /* The tz.epoch that the TZ was read at. */
/*
* Prevent performance regression on some platforms by resolving of system time zone:
* small latency for check whether environment was changed (once per second)
* no latency if environment was changed with tcl-env (compare both epoch values)
*/
- Tcl_Time now;
+
Tcl_GetTime(&now);
- if (now.sec == tzLastRefresh && tzEnvEpoch == TclEnvEpoch) {
- return tzWasEpoch;
+ if (now.sec == tz.lastRefresh && tz.envEpoch == TclEnvEpoch) {
+ return tz.epoch;
}
- tzEnvEpoch = TclEnvEpoch;
- tzLastRefresh = now.sec;
+ tz.envEpoch = TclEnvEpoch;
+ tz.lastRefresh = now.sec;
/* check in lock */
Tcl_MutexLock(&clockMutex);
- tzIsNow = getenv("TCL_TZ");
- if (tzIsNow == NULL) {
- tzIsNow = getenv("TZ");
+ tzNow = getenv("TCL_TZ");
+ if (tzNow == NULL) {
+ tzNow = getenv("TZ");
}
- if (tzIsNow != NULL && (tzWas == NULL || tzWas == (WCHAR *)INT2PTR(-1)
- || wcscmp(tzIsNow, tzWas) != 0)) {
+ if (tzNow != NULL && (tz.was == NULL || tz.was == TZ_INIT_MARKER
+ || wcscmp(tzNow, tz.was) != 0)) {
tzset();
- if (tzWas != NULL && tzWas != (WCHAR *)INT2PTR(-1)) {
- ckfree(tzWas);
+ if (tz.was != NULL && tz.was != TZ_INIT_MARKER) {
+ ckfree(tz.was);
}
- tzWas = (WCHAR *)ckalloc(sizeof(WCHAR) * (wcslen(tzIsNow) + 1));
- wcscpy(tzWas, tzIsNow);
- tzWasEpoch++;
- } else if (tzIsNow == NULL && tzWas != NULL) {
+ tz.was = (WCHAR *)
+ ckalloc(sizeof(WCHAR) * (wcslen(tzNow) + 1));
+ wcscpy(tz.was, tzNow);
+ epoch = ++tz.epoch;
+ } else if (tzNow == NULL && tz.was != NULL) {
tzset();
- if (tzWas != (WCHAR *)INT2PTR(-1)) {
- ckfree(tzWas);
+ if (tz.was != TZ_INIT_MARKER) {
+ ckfree(tz.was);
}
- tzWas = NULL;
- tzWasEpoch++;
+ tz.was = NULL;
+ epoch = ++tz.epoch;
+ } else {
+ epoch = tz.epoch;
}
Tcl_MutexUnlock(&clockMutex);
- return tzWasEpoch;
+ return epoch;
}
/*
diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c
index 06684a6..cbb935d 100644
--- a/generic/tclClockFmt.c
+++ b/generic/tclClockFmt.c
@@ -33,6 +33,11 @@ static void ClockFrmScnFinalize(void *);
*/
static Tcl_HashKeyType ClockFmtScnStorageHashKeyType;
+
+#define IntFieldAt(info, offset) \
+ ((int *) (((char *) (info)) + (offset)))
+#define WideFieldAt(info, offset) \
+ ((Tcl_WideInt *) (((char *) (info)) + (offset)))
/*
* Clock scan and format facilities.
@@ -41,7 +46,7 @@ static Tcl_HashKeyType ClockFmtScnStorageHashKeyType;
/*
*----------------------------------------------------------------------
*
- * _str2int -- , _str2wideInt --
+ * Clock_str2int, Clock_str2wideInt --
*
* Fast inline-convertion of string to signed int or wide int by given
* start/end.
@@ -57,7 +62,7 @@ static Tcl_HashKeyType ClockFmtScnStorageHashKeyType;
*/
static inline void
-_str2int_no(
+Clock_str2int_no(
int *out,
const char *p,
const char *e,
@@ -65,8 +70,9 @@ _str2int_no(
{
/* 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 */
+ while (p < e) { /* never overflows */
val = val * 10 + (*p++ - '0');
}
if (sign < 0) {
@@ -76,7 +82,7 @@ _str2int_no(
}
static inline void
-_str2wideInt_no(
+Clock_str2wideInt_no(
Tcl_WideInt *out,
const char *p,
const char *e,
@@ -84,8 +90,9 @@ _str2wideInt_no(
{
/* 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 */
+ while (p < e) { /* never overflows */
val = val * 10 + (*p++ - '0');
}
if (sign < 0) {
@@ -100,7 +107,7 @@ _str2wideInt_no(
#endif
static inline int
-_str2int(
+Clock_str2int(
int *out,
const char *p,
const char *e,
@@ -109,6 +116,7 @@ _str2int(
int val = 0;
/* overflow impossible for 10 digits ("9..9"), so no needs to check before */
const char *eNO = p + 10;
+
if (eNO > e) {
eNO = e;
}
@@ -118,6 +126,7 @@ _str2int(
if (sign >= 0) {
while (p < e) { /* check for overflow */
int prev = val;
+
val = val * 10 + (*p++ - '0');
if (val / 10 < prev) {
return TCL_ERROR;
@@ -127,6 +136,7 @@ _str2int(
val = -val;
while (p < e) { /* check for overflow */
int prev = val;
+
val = val * 10 - (*p++ - '0');
if (val / 10 > prev) {
return TCL_ERROR;
@@ -138,7 +148,7 @@ _str2int(
}
static inline int
-_str2wideInt(
+Clock_str2wideInt(
Tcl_WideInt *out,
const char *p,
const char *e,
@@ -147,6 +157,7 @@ _str2wideInt(
Tcl_WideInt val = 0;
/* overflow impossible for 18 digits ("9..9"), so no needs to check before */
const char *eNO = p + 18;
+
if (eNO > e) {
eNO = e;
}
@@ -156,6 +167,7 @@ _str2wideInt(
if (sign >= 0) {
while (p < e) { /* check for overflow */
Tcl_WideInt prev = val;
+
val = val * 10 + (*p++ - '0');
if (val / 10 < prev) {
return TCL_ERROR;
@@ -165,6 +177,7 @@ _str2wideInt(
val = -val;
while (p < e) { /* check for overflow */
Tcl_WideInt prev = val;
+
val = val * 10 - (*p++ - '0');
if (val / 10 > prev) {
return TCL_ERROR;
@@ -182,7 +195,7 @@ TclAtoWIe(
const char *e,
int sign)
{
- return _str2wideInt(out, p, e, sign);
+ return Clock_str2wideInt(out, p, e, sign);
}
#if defined(__GNUC__) || defined(__GNUG__)
@@ -192,7 +205,7 @@ TclAtoWIe(
/*
*----------------------------------------------------------------------
*
- * _itoaw -- , _witoaw --
+ * Clock_itoaw, Clock_witoaw --
*
* Fast inline-convertion of signed int or wide int to string, using
* given padding with specified padchar and width (or without padding).
@@ -206,14 +219,16 @@ TclAtoWIe(
*/
static inline char *
-_itoaw(
+Clock_itoaw(
char *buf,
int val,
char padchar,
unsigned short width)
{
char *p;
- static int wrange[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
+ static const int wrange[] = {
+ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000
+ };
/* positive integer */
@@ -226,7 +241,8 @@ _itoaw(
p = buf + width;
*p-- = '\0';
do {
- char c = (val % 10);
+ char c = val % 10;
+
val /= 10;
*p-- = '0' + c;
} while (val > 0);
@@ -254,13 +270,15 @@ _itoaw(
/* differentiate platforms with -1 % 10 == 1 and -1 % 10 == -1 */
if (-1 % 10 == -1) {
do {
- char c = (val % 10);
+ char c = val % 10;
+
val /= 10;
*p-- = '0' - c;
} while (val < 0);
} else {
do {
- char c = (val % 10);
+ char c = val % 10;
+
val /= 10;
*p-- = '0' + c;
} while (val < 0);
@@ -287,18 +305,20 @@ TclItoAw(
char padchar,
unsigned short width)
{
- return _itoaw(buf, val, padchar, width);
+ return Clock_itoaw(buf, val, padchar, width);
}
static inline char *
-_witoaw(
+Clock_witoaw(
char *buf,
Tcl_WideInt val,
char padchar,
unsigned short width)
{
char *p;
- static int wrange[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
+ static const int wrange[] = {
+ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000
+ };
/* positive integer */
@@ -306,6 +326,7 @@ _witoaw(
/* check resp. recalculate width */
if (val >= 10000000000LL) {
Tcl_WideInt val2 = val / 10000000000LL;
+
while (width <= 9 && val2 >= wrange[width]) {
width++;
}
@@ -340,6 +361,7 @@ _witoaw(
width--;
if (val <= -10000000000LL) {
Tcl_WideInt val2 = val / 10000000000LL;
+
while (width <= 9 && val2 <= -wrange[width]) {
width++;
}
@@ -356,13 +378,15 @@ _witoaw(
/* differentiate platforms with -1 % 10 == 1 and -1 % 10 == -1 */
if (-1 % 10 == -1) {
do {
- char c = (val % 10);
+ char c = val % 10;
+
val /= 10;
*p-- = '0' - c;
} while (val < 0);
} else {
do {
- char c = (val % 10);
+ char c = val % 10;
+
val /= 10;
*p-- = '0' + c;
} while (val < 0);
@@ -903,7 +927,7 @@ Tcl_Obj *
ClockLocalizeFormat(
ClockFmtScnCmdArgs *opts)
{
- ClockClientData *dataPtr = (ClockClientData *)opts->clientData;
+ ClockClientData *dataPtr = opts->dataPtr;
Tcl_Obj *valObj = NULL, *keyObj;
keyObj = ClockFrmObjGetLocFmtKey(opts->interp, opts->formatObj);
@@ -1051,8 +1075,8 @@ DetermineGreedySearchLen(
{
int minLen = tok->map->minSize;
int maxLen;
- const char *p = yyInput + minLen,
- *end = info->dateEnd;
+ const char *p = yyInput + minLen;
+ const char *end = info->dateEnd;
/* if still tokens available, try to correct minimum length */
if ((tok + 1)->map) {
@@ -1558,7 +1582,7 @@ ClockScnToken_DayOfWeek_Proc(
}
if (val > 7) {
Tcl_SetObjResult(opts->interp, Tcl_NewStringObj(
- "day of week is greater than 7", -1));
+ "day of week is greater than 7", TCL_AUTO_LENGTH));
Tcl_SetErrorCode(opts->interp, "CLOCK", "badDayOfWeek", (char *)NULL);
return TCL_ERROR;
}
@@ -1625,7 +1649,7 @@ ClockScnToken_LocaleERA_Proc(
DateInfo *info,
ClockScanToken *tok)
{
- ClockClientData *dataPtr = (ClockClientData *)opts->clientData;
+ ClockClientData *dataPtr = opts->dataPtr;
int ret, val;
int minLen, maxLen;
@@ -1683,7 +1707,7 @@ ClockScnToken_LocaleListMatcher_Proc(
}
if (tok->map->offs > 0) {
- *(int *)(((char *)info) + tok->map->offs) = --val;
+ *IntFieldAt(info, tok->map->offs) = --val;
}
return TCL_OK;
@@ -1712,7 +1736,7 @@ ClockScnToken_JDN_Proc(
while (p < end && isdigit(UCHAR(*p))) {
p++;
}
- if (_str2wideInt(&intJD, s, p, (*yyInput != '-' ? 1 : -1)) != TCL_OK) {
+ if (Clock_str2wideInt(&intJD, s, p, (*yyInput != '-' ? 1 : -1)) != TCL_OK) {
return TCL_RETURN;
}
yyInput = p;
@@ -1730,7 +1754,7 @@ ClockScnToken_JDN_Proc(
fractJDDiv *= 10;
p++;
}
- if (_str2int(&fractJD, s, p, 1) != TCL_OK) {
+ if (Clock_str2int(&fractJD, s, p, 1) != TCL_OK) {
return TCL_RETURN;
}
yyInput = p;
@@ -1742,7 +1766,7 @@ ClockScnToken_JDN_Proc(
*/
fractJD = (int)tok->map->offs /* 0 for calendar or 43200 for astro JD */
- + (int)((Tcl_WideInt)SECONDS_PER_DAY * fractJD / fractJDDiv);
+ + (int)((Tcl_WideInt)SECONDS_PER_DAY * fractJD / fractJDDiv);
if (fractJD > SECONDS_PER_DAY) {
fractJD %= SECONDS_PER_DAY;
intJD += 1;
@@ -1840,7 +1864,7 @@ ClockScnToken_TimeZone_Proc(
/* try to apply new time zone */
Tcl_IncrRefCount(tzObjStor);
- opts->timezoneObj = ClockSetupTimeZone(opts->clientData, opts->interp,
+ opts->timezoneObj = ClockSetupTimeZone(opts->dataPtr, opts->interp,
tzObjStor);
Tcl_DecrRefCount(tzObjStor);
@@ -1890,8 +1914,8 @@ ClockScnToken_StarDate_Proc(
if (p >= end || p - s < 4) {
return TCL_RETURN;
}
- if (_str2int(&year, s, p - 3, 1) != TCL_OK
- || _str2int(&fractYear, p - 3, p, 1) != TCL_OK) {
+ if (Clock_str2int(&year, s, p - 3, 1) != TCL_OK
+ || Clock_str2int(&fractYear, p - 3, p, 1) != TCL_OK) {
return TCL_RETURN;
}
if (*p++ != '.') {
@@ -1903,7 +1927,7 @@ ClockScnToken_StarDate_Proc(
fractDayDiv *= 10;
p++;
}
- if (_str2int(&fractDay, s, p, 1) != TCL_OK) {
+ if (Clock_str2int(&fractDay, s, p, 1) != TCL_OK) {
return TCL_RETURN;
}
yyInput = p;
@@ -1934,6 +1958,10 @@ ClockScnToken_StarDate_Proc(
return TCL_OK;
}
+/*
+ * Descriptors for the various fields in [clock scan].
+ */
+
static const char *ScnSTokenMapIndex = "dmbyYHMSpJjCgGVazUsntQ";
static const ClockScanTokenMap ScnSTokenMap[] = {
/* %d %e */
@@ -2142,7 +2170,7 @@ ClockGetOrParseScanFormat(
fss->scnSpaceCount = 0;
scnTok = tok = (ClockScanToken *) ckalloc(sizeof(*tok) * fss->scnTokC);
- memset(tok, 0, sizeof(*(tok)));
+ memset(tok, 0, sizeof(*tok));
tokCnt = 1;
while (p < e) {
switch (*p) {
@@ -2249,10 +2277,11 @@ ClockGetOrParseScanFormat(
tokCnt++;
continue;
}
-word_tok:
+ word_tok:
{
ClockScanToken *wordTok = tok;
- if (tok > scnTok && (tok-1)->map == &ScnWordTokenMap) {
+
+ if (tok > scnTok && (tok - 1)->map == &ScnWordTokenMap) {
wordTok = tok - 1;
}
/* new word token */
@@ -2275,7 +2304,7 @@ word_tok:
/* calculate end distance value for each tokens */
if (tok > scnTok) {
unsigned endDist = 0;
- ClockScanToken *prevTok = tok-1;
+ ClockScanToken *prevTok = tok - 1;
while (prevTok >= scnTok) {
prevTok->endDistance = endDist;
@@ -2316,7 +2345,7 @@ ClockScan(
Tcl_Obj *strObj, /* String containing the time to scan */
ClockFmtScnCmdArgs *opts) /* Command options */
{
- ClockClientData *dataPtr = (ClockClientData *)opts->clientData;
+ ClockClientData *dataPtr = opts->dataPtr;
ClockFmtScnStorage *fss;
ClockScanToken *tok;
const ClockScanTokenMap *map;
@@ -2421,24 +2450,20 @@ ClockScan(
x = p + size;
if (map->type == CTOKT_INT) {
if (size <= 10) {
- _str2int_no((int *)(((char *)info) + map->offs),
+ Clock_str2int_no(IntFieldAt(info, map->offs),
p, x, sign);
- } else {
- if (_str2int((int *)(((char *)info) + map->offs),
- p, x, sign) != TCL_OK) {
- goto overflow;
- }
+ } else if (Clock_str2int(
+ IntFieldAt(info, map->offs), p, x, sign) != TCL_OK) {
+ goto overflow;
}
p = x;
} else {
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;
- }
+ Clock_str2wideInt_no(
+ WideFieldAt(info, map->offs), p, x, sign);
+ } else if (Clock_str2wideInt(
+ WideFieldAt(info, map->offs), p, x, sign) != TCL_OK) {
+ goto overflow;
}
p = x;
}
@@ -2651,14 +2676,14 @@ ClockScan(
overflow:
Tcl_SetObjResult(opts->interp, Tcl_NewStringObj(
- "integer value too large to represent", -1));
+ "integer value too large to represent", TCL_AUTO_LENGTH));
Tcl_SetErrorCode(opts->interp, "CLOCK", "dateTooLarge", (char *)NULL);
goto done;
not_match:
#if 1
Tcl_SetObjResult(opts->interp, Tcl_NewStringObj(
- "input string does not match supplied format", -1));
+ "input string does not match supplied format", TCL_AUTO_LENGTH));
#else
/* to debug where exactly scan breaks */
Tcl_SetObjResult(opts->interp, Tcl_ObjPrintf(
@@ -2772,9 +2797,9 @@ ClockFmtToken_StarDate_Proc(
}
memcpy(dateFmt->output, "Stardate ", 9);
dateFmt->output += 9;
- dateFmt->output = _itoaw(dateFmt->output,
+ dateFmt->output = Clock_itoaw(dateFmt->output,
dateFmt->date.year - RODDENBERRY, '0', 2);
- dateFmt->output = _itoaw(dateFmt->output,
+ dateFmt->output = Clock_itoaw(dateFmt->output,
fractYear, '0', 3);
*dateFmt->output++ = '.';
/* be sure positive after decimal point (note: clock-value can be negative) */
@@ -2782,7 +2807,7 @@ ClockFmtToken_StarDate_Proc(
if (v < 0) {
v = 10 + v;
}
- dateFmt->output = _itoaw(dateFmt->output, v, '0', 1);
+ dateFmt->output = Clock_itoaw(dateFmt->output, v, '0', 1);
return TCL_OK;
}
static int
@@ -2837,7 +2862,7 @@ ClockFmtToken_JDN_Proc(
if (FrmResultAllocate(dateFmt, 21) != TCL_OK) {
return TCL_ERROR;
}
- dateFmt->output = _witoaw(dateFmt->output, intJD, '0', 1);
+ dateFmt->output = Clock_witoaw(dateFmt->output, intJD, '0', 1);
/* simplest cases .0 and .5 */
if (!fractJD || fractJD == (SECONDS_PER_DAY / 2)) {
/* point + 0 or 5 */
@@ -2863,11 +2888,11 @@ ClockFmtToken_JDN_Proc(
return TCL_ERROR;
}
*dateFmt->output++ = '.';
- p = _itoaw(dateFmt->output, fractJD, '0', JDN_MAX_PRECISION);
+ p = Clock_itoaw(dateFmt->output, fractJD, '0', JDN_MAX_PRECISION);
/* remove trailing zero's */
dateFmt->output++;
- while (p > dateFmt->output && *(p-1) == '0') {
+ while (p > dateFmt->output && p[-1] == '0') {
p--;
}
*p = '\0';
@@ -2894,12 +2919,12 @@ ClockFmtToken_TimeZone_Proc(
return TCL_ERROR;
}
*dateFmt->output++ = sign;
- dateFmt->output = _itoaw(dateFmt->output, z / 3600, '0', 2);
+ dateFmt->output = Clock_itoaw(dateFmt->output, z / 3600, '0', 2);
z %= 3600;
- dateFmt->output = _itoaw(dateFmt->output, z / 60, '0', 2);
+ dateFmt->output = Clock_itoaw(dateFmt->output, z / 60, '0', 2);
z %= 60;
if (z != 0) {
- dateFmt->output = _itoaw(dateFmt->output, z, '0', 2);
+ dateFmt->output = Clock_itoaw(dateFmt->output, z, '0', 2);
}
} else {
Tcl_Obj * objPtr;
@@ -2907,7 +2932,7 @@ ClockFmtToken_TimeZone_Proc(
Tcl_Size len;
/* convert seconds to local seconds to obtain tzName object */
- if (ConvertUTCToLocal(opts->clientData, opts->interp,
+ if (ConvertUTCToLocal(opts->dataPtr, opts->interp,
&dateFmt->date, opts->timezoneObj,
GREGORIAN_CHANGE_DATE) != TCL_OK) {
return TCL_ERROR;
@@ -2986,12 +3011,10 @@ ClockFmtToken_LocaleERAYear_Proc(
}
if (*tok->tokWord.start == 'C') { /* %EC */
*val = dateFmt->date.year / 100;
- dateFmt->output = _itoaw(dateFmt->output,
- *val, '0', 2);
+ dateFmt->output = Clock_itoaw(dateFmt->output, *val, '0', 2);
} else { /* %Ey */
*val = dateFmt->date.year % 100;
- dateFmt->output = _itoaw(dateFmt->output,
- *val, '0', 2);
+ dateFmt->output = Clock_itoaw(dateFmt->output, *val, '0', 2);
}
} else {
Tcl_Obj *objPtr;
@@ -3027,8 +3050,7 @@ ClockFmtToken_LocaleERAYear_Proc(
if (FrmResultAllocate(dateFmt, 11) != TCL_OK) {
return TCL_ERROR;
}
- dateFmt->output = _itoaw(dateFmt->output,
- *val, '0', 2);
+ dateFmt->output = Clock_itoaw(dateFmt->output, *val, '0', 2);
return TCL_OK;
}
}
@@ -3042,6 +3064,10 @@ ClockFmtToken_LocaleERAYear_Proc(
return TCL_OK;
}
+/*
+ * Descriptors for the various fields in [clock format].
+ */
+
static const char *FmtSTokenMapIndex =
"demNbByYCHMSIklpaAuwUVzgGjJsntQ";
static const ClockFormatTokenMap FmtSTokenMap[] = {
@@ -3219,7 +3245,7 @@ ClockGetOrParseFmtFormat(
fss->fmtTokC = EstimateTokenCount(p, e);
fmtTok = tok = (ClockFormatToken *) ckalloc(sizeof(*tok) * fss->fmtTokC);
- memset(tok, 0, sizeof(*(tok)));
+ memset(tok, 0, sizeof(*tok));
tokCnt = 1;
while (p < e) {
switch (*p) {
@@ -3293,8 +3319,8 @@ ClockGetOrParseFmtFormat(
word_tok: {
ClockFormatToken *wordTok = tok;
- if (tok > fmtTok && (tok-1)->map == &FmtWordTokenMap) {
- wordTok = tok-1;
+ if (tok > fmtTok && (tok - 1)->map == &FmtWordTokenMap) {
+ wordTok = tok - 1;
}
if (wordTok == tok) {
wordTok->tokWord.start = p;
@@ -3368,7 +3394,7 @@ ClockFormat(
map = tok->map;
switch (map->type) {
case CTOKT_INT: {
- int val = (int)*(int *)(((char *)dateFmt) + map->offs);
+ int val = *IntFieldAt(dateFmt, map->offs);
if (map->fmtproc == NULL) {
if (map->flags & CLFMT_DECR) {
@@ -3397,13 +3423,15 @@ ClockFormat(
goto error;
}
if (map->width) {
- dateFmt->output = _itoaw(dateFmt->output, val, *map->tostr, map->width);
+ dateFmt->output = Clock_itoaw(
+ dateFmt->output, val, *map->tostr, map->width);
} else {
dateFmt->output += sprintf(dateFmt->output, map->tostr, val);
}
} else {
const char *s;
Tcl_Obj * mcObj = ClockMCGet(opts, PTR2INT(map->data) /* mcKey */);
+
if (mcObj == NULL) {
goto error;
}
@@ -3421,13 +3449,13 @@ ClockFormat(
break;
}
case CTOKT_WIDE: {
- Tcl_WideInt val = *(Tcl_WideInt *)(((char *)dateFmt) + map->offs);
+ Tcl_WideInt val = *WideFieldAt(dateFmt, map->offs);
if (FrmResultAllocate(dateFmt, 21) != TCL_OK) {
goto error;
}
if (map->width) {
- dateFmt->output = _witoaw(dateFmt->output, val, *map->tostr, map->width);
+ dateFmt->output = Clock_witoaw(dateFmt->output, val, *map->tostr, map->width);
} else {
dateFmt->output += sprintf(dateFmt->output, map->tostr, val);
}
diff --git a/generic/tclDate.h b/generic/tclDate.h
index 8b71827..60e07ab 100644
--- a/generic/tclDate.h
+++ b/generic/tclDate.h
@@ -31,42 +31,51 @@
#define RODDENBERRY 1946 /* Another epoch (Hi, Jeff!) */
+enum DateInfoFlags {
+ CLF_OPTIONAL = 1 << 0, /* token is non mandatory */
+ CLF_POSIXSEC = 1 << 1,
+ CLF_LOCALSEC = 1 << 2,
+ CLF_JULIANDAY = 1 << 3,
+ CLF_TIME = 1 << 4,
+ CLF_ZONE = 1 << 5,
+ CLF_CENTURY = 1 << 6,
+ CLF_DAYOFMONTH = 1 << 7,
+ CLF_DAYOFYEAR = 1 << 8,
+ CLF_MONTH = 1 << 9,
+ CLF_YEAR = 1 << 10,
+ CLF_DAYOFWEEK = 1 << 11,
+ CLF_ISO8601YEAR = 1 << 12,
+ CLF_ISO8601WEAK = 1 << 13,
+ CLF_ISO8601CENTURY = 1 << 14,
+
+ CLF_SIGNED = 1 << 15,
+
+ /* Compounds */
+
+ CLF_HAVEDATE = (CLF_DAYOFMONTH | CLF_MONTH | CLF_YEAR),
+ CLF_DATE = (CLF_JULIANDAY | CLF_DAYOFMONTH | CLF_DAYOFYEAR
+ | CLF_MONTH | CLF_YEAR | CLF_ISO8601YEAR
+ | CLF_DAYOFWEEK | CLF_ISO8601WEAK),
+
+ /*
+ * Extra flags used outside of scan/format-tokens too (int, not a short).
+ */
+
+ CLF_RELCONV = 1 << 17,
+ CLF_ORDINALMONTH = 1 << 18,
+
+ /* On demand (lazy) assemble flags */
+
+ CLF_ASSEMBLE_DATE = 1 << 28,/* assemble year, month, etc. using julianDay */
+ CLF_ASSEMBLE_JULIANDAY = 1 << 29,
+ /* assemble julianDay using year, month, etc. */
+ CLF_ASSEMBLE_SECONDS = 1 << 30
+ /* assemble localSeconds (and seconds at end) */
+};
-#define CLF_OPTIONAL (1 << 0) /* token is non mandatory */
-#define CLF_POSIXSEC (1 << 1)
-#define CLF_LOCALSEC (1 << 2)
-#define CLF_JULIANDAY (1 << 3)
-#define CLF_TIME (1 << 4)
-#define CLF_ZONE (1 << 5)
-#define CLF_CENTURY (1 << 6)
-#define CLF_DAYOFMONTH (1 << 7)
-#define CLF_DAYOFYEAR (1 << 8)
-#define CLF_MONTH (1 << 9)
-#define CLF_YEAR (1 << 10)
-#define CLF_DAYOFWEEK (1 << 11)
-#define CLF_ISO8601YEAR (1 << 12)
-#define CLF_ISO8601WEAK (1 << 13)
-#define CLF_ISO8601CENTURY (1 << 14)
-
-#define CLF_SIGNED (1 << 15)
-
-/* extra flags used outside of scan/format-tokens too (int, not a short int) */
-#define CLF_RELCONV (1 << 17)
-#define CLF_ORDINALMONTH (1 << 18)
-
-/* On demand (lazy) assemble flags */
-#define CLF_ASSEMBLE_DATE (1 << 28) /* assemble year, month, etc. using julianDay */
-#define CLF_ASSEMBLE_JULIANDAY (1 << 29) /* assemble julianDay using year, month, etc. */
-#define CLF_ASSEMBLE_SECONDS (1 << 30) /* assemble localSeconds (and seconds at end) */
-
-#define CLF_HAVEDATE (CLF_DAYOFMONTH|CLF_MONTH|CLF_YEAR)
-#define CLF_DATE (CLF_JULIANDAY | CLF_DAYOFMONTH | CLF_DAYOFYEAR | \
- CLF_MONTH | CLF_YEAR | CLF_ISO8601YEAR | \
- CLF_DAYOFWEEK | CLF_ISO8601WEAK)
-
-#define TCL_MIN_SECONDS -0x00F0000000000000LL
-#define TCL_MAX_SECONDS 0x00F0000000000000LL
-#define TCL_INV_SECONDS (TCL_MIN_SECONDS-1)
+#define TCL_MIN_SECONDS -0x00F0000000000000LL
+#define TCL_MAX_SECONDS 0x00F0000000000000LL
+#define TCL_INV_SECONDS (TCL_MIN_SECONDS - 1)
/*
* Enumeration of the string literals used in [clock]
@@ -148,10 +157,11 @@ typedef enum ClockMsgCtLiteral {
* Structure containing the fields used in [clock format] and [clock scan]
*/
-#define CLF_CTZ (1 << 4)
+enum TclDateFieldsFlags {
+ CLF_CTZ = (1 << 4)
+};
typedef struct TclDateFields {
-
/* Cacheable fields: */
Tcl_WideInt seconds; /* Time expressed in seconds from the Posix
@@ -270,15 +280,19 @@ ClockInitDateInfo(
* Structure containing the command arguments supplied to [clock format] and [clock scan]
*/
-#define CLF_VALIDATE_S1 (1 << 0)
-#define CLF_VALIDATE_S2 (1 << 1)
-#define CLF_VALIDATE (CLF_VALIDATE_S1|CLF_VALIDATE_S2)
-#define CLF_EXTENDED (1 << 4)
-#define CLF_STRICT (1 << 8)
-#define CLF_LOCALE_USED (1 << 15)
+enum ClockFmtScnCmdArgsFlags {
+ CLF_VALIDATE_S1 = (1 << 0),
+ CLF_VALIDATE_S2 = (1 << 1),
+ CLF_VALIDATE = (CLF_VALIDATE_S1|CLF_VALIDATE_S2),
+ CLF_EXTENDED = (1 << 4),
+ CLF_STRICT = (1 << 8),
+ CLF_LOCALE_USED = (1 << 15)
+};
+
+typedef struct ClockClientData ClockClientData;
typedef struct ClockFmtScnCmdArgs {
- void *clientData; /* Opaque pointer to literal pool, etc. */
+ ClockClientData *dataPtr; /* Pointer to literal pool, etc. */
Tcl_Interp *interp; /* Tcl interpreter */
Tcl_Obj *formatObj; /* Format */
Tcl_Obj *localeObj; /* Name of the locale where the time will be expressed. */
@@ -422,10 +436,12 @@ typedef struct DateFormat {
Tcl_Obj *localeEra;
} DateFormat;
-#define CLFMT_INCR (1 << 3)
-#define CLFMT_DECR (1 << 4)
-#define CLFMT_CALC (1 << 5)
-#define CLFMT_LOCALE_INDX (1 << 8)
+enum ClockFormatTokenMapFlags {
+ CLFMT_INCR = (1 << 3),
+ CLFMT_DECR = (1 << 4),
+ CLFMT_CALC = (1 << 5),
+ CLFMT_LOCALE_INDX = (1 << 8)
+};
typedef struct ClockFormatToken ClockFormatToken;
@@ -513,7 +529,7 @@ MODULE_SCOPE void GetJulianDayFromEraYearMonthDay(
TclDateFields *fields, int changeover);
MODULE_SCOPE void GetJulianDayFromEraYearDay(
TclDateFields *fields, int changeover);
-MODULE_SCOPE int ConvertUTCToLocal(void *clientData, Tcl_Interp *,
+MODULE_SCOPE int ConvertUTCToLocal(ClockClientData *dataPtr, Tcl_Interp *,
TclDateFields *, Tcl_Obj *timezoneObj, int);
MODULE_SCOPE Tcl_Obj * LookupLastTransition(Tcl_Interp *, Tcl_WideInt,
Tcl_Size, Tcl_Obj *const *, Tcl_WideInt *rangesVal);
@@ -521,7 +537,7 @@ MODULE_SCOPE int TclClockFreeScan(Tcl_Interp *interp, DateInfo *info);
/* tclClock.c module declarations */
-MODULE_SCOPE Tcl_Obj * ClockSetupTimeZone(void *clientData,
+MODULE_SCOPE Tcl_Obj * ClockSetupTimeZone(ClockClientData *dataPtr,
Tcl_Interp *interp, Tcl_Obj *timezoneObj);
MODULE_SCOPE Tcl_Obj * ClockMCDict(ClockFmtScnCmdArgs *opts);
MODULE_SCOPE Tcl_Obj * ClockMCGet(ClockFmtScnCmdArgs *opts, int mcKey);
diff --git a/generic/tclStrIdxTree.c b/generic/tclStrIdxTree.c
index a1c83a9..533f73d 100644
--- a/generic/tclStrIdxTree.c
+++ b/generic/tclStrIdxTree.c
@@ -462,7 +462,7 @@ TclStrIdxTreePrint(
Tcl_Obj *obj[2];
const char *s;
- TclInitObjRef(obj[0], Tcl_NewStringObj("::puts", -1));
+ TclInitObjRef(obj[0], Tcl_NewStringObj("::puts", TCL_AUTO_LENGTH));
while (tree != NULL) {
s = TclGetString(tree->key) + offs;
TclInitObjRef(obj[1], Tcl_ObjPrintf("%*s%.*s\t:%d",