summaryrefslogtreecommitdiffstats
path: root/generic/tclClock.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclClock.c')
-rw-r--r--generic/tclClock.c1225
1 files changed, 739 insertions, 486 deletions
diff --git a/generic/tclClock.c b/generic/tclClock.c
index 6189a5a..15f29e5 100644
--- a/generic/tclClock.c
+++ b/generic/tclClock.c
@@ -7,12 +7,10 @@
*
* Copyright 1991-1995 Karl Lehenbauer and Mark Diekhans.
* Copyright (c) 1995 Sun Microsystems, Inc.
- * Copyright (c) 2004 by Kevin B. Kenny. All rights reserved.
+ * Copyright (c) 2004 by Kevin B. Kenny. All rights reserved.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
- *
- * RCS: @(#) $Id: tclClock.c,v 1.50 2005/12/13 22:43:17 kennykb Exp $
*/
#include "tclInt.h"
@@ -21,7 +19,7 @@
* Windows has mktime. The configurators do not check.
*/
-#ifdef __WIN32__
+#ifdef _WIN32
#define HAVE_MKTIME 1
#endif
@@ -32,13 +30,13 @@
#define JULIAN_DAY_POSIX_EPOCH 2440588
#define SECONDS_PER_DAY 86400
#define JULIAN_SEC_POSIX_EPOCH (((Tcl_WideInt) JULIAN_DAY_POSIX_EPOCH) \
- * SECONDS_PER_DAY)
-#define FOUR_CENTURIES 146097 /* days */
+ * SECONDS_PER_DAY)
+#define FOUR_CENTURIES 146097 /* days */
#define JDAY_1_JAN_1_CE_JULIAN 1721424
#define JDAY_1_JAN_1_CE_GREGORIAN 1721426
-#define ONE_CENTURY_GREGORIAN 36524 /* days */
-#define FOUR_YEARS 1461 /* days */
-#define ONE_YEAR 365 /* days */
+#define ONE_CENTURY_GREGORIAN 36524 /* days */
+#define FOUR_YEARS 1461 /* days */
+#define ONE_YEAR 365 /* days */
/*
* Table of the days in each month, leap and common years
@@ -58,24 +56,34 @@ static const int daysInPriorMonths[2][13] = {
*/
typedef enum ClockLiteral {
- LIT_BCE, LIT_CE,
- LIT_DAYOFMONTH, LIT_DAYOFWEEK, LIT_DAYOFYEAR,
- LIT_ERA, LIT_GREGORIAN,
+ LIT__NIL,
+ LIT__DEFAULT_FORMAT,
+ LIT_BCE, LIT_C,
+ LIT_CANNOT_USE_GMT_AND_TIMEZONE,
+ LIT_CE,
+ LIT_DAYOFMONTH, LIT_DAYOFWEEK, LIT_DAYOFYEAR,
+ LIT_ERA, LIT_GMT, LIT_GREGORIAN,
+ LIT_INTEGER_VALUE_TOO_LARGE,
LIT_ISO8601WEEK, LIT_ISO8601YEAR,
LIT_JULIANDAY, LIT_LOCALSECONDS,
LIT_MONTH,
- LIT_SECONDS, LIT_TZNAME, LIT_TZOFFSET,
+ LIT_SECONDS, LIT_TZNAME, LIT_TZOFFSET,
LIT_YEAR,
LIT__END
} ClockLiteral;
static const char *const literals[] = {
- "BCE", "CE",
- "dayOfMonth", "dayOfWeek", "dayOfYear",
- "era", "gregorian",
+ "",
+ "%a %b %d %H:%M:%S %Z %Y",
+ "BCE", "C",
+ "cannot use -gmt and -timezone in same call",
+ "CE",
+ "dayOfMonth", "dayOfWeek", "dayOfYear",
+ "era", ":GMT", "gregorian",
+ "integer value too large to represent",
"iso8601Week", "iso8601Year",
"julianDay", "localSeconds",
"month",
- "seconds", "tzName", "tzOffset",
+ "seconds", "tzName", "tzOffset",
"year"
};
@@ -84,8 +92,8 @@ static const char *const literals[] = {
*/
typedef struct ClockClientData {
- int refCount; /* Number of live references */
- Tcl_Obj** literals; /* Pool of object literals */
+ int refCount; /* Number of live references. */
+ Tcl_Obj **literals; /* Pool of object literals. */
} ClockClientData;
/*
@@ -93,13 +101,13 @@ typedef struct ClockClientData {
*/
typedef struct TclDateFields {
- Tcl_WideInt seconds; /* Time expressed in seconds from the
- * Posix epoch */
+ Tcl_WideInt seconds; /* Time expressed in seconds from the Posix
+ * epoch */
Tcl_WideInt localSeconds; /* Local time expressed in nominal seconds
* from the Posix epoch */
int tzOffset; /* Time zone offset in seconds east of
* Greenwich */
- Tcl_Obj* tzName; /* Time zone name */
+ Tcl_Obj *tzName; /* Time zone name */
int julianDay; /* Julian Day Number in local time zone */
enum {BCE=1, CE=0} era; /* Era */
int gregorian; /* Flag == 1 if the date is Gregorian */
@@ -110,9 +118,8 @@ typedef struct TclDateFields {
int iso8601Year; /* ISO8601 week-based year */
int iso8601Week; /* ISO8601 week number */
int dayOfWeek; /* Day of the week */
-
} TclDateFields;
-static CONST char* eras[] = { "CE", "BCE", NULL };
+static const char *const eras[] = { "CE", "BCE", NULL };
/*
* Thread specific data block holding a 'struct tm' for the 'gmtime' and
@@ -132,68 +139,99 @@ TCL_DECLARE_MUTEX(clockMutex)
* Function prototypes for local procedures in this file:
*/
-static int ConvertUTCToLocal(Tcl_Interp*,
- TclDateFields*, Tcl_Obj*, int);
-static int ConvertUTCToLocalUsingTable(Tcl_Interp*,
- TclDateFields*, int, Tcl_Obj *CONST[]);
-static int ConvertUTCToLocalUsingC(Tcl_Interp*,
- TclDateFields*, int);
-static int ConvertLocalToUTC(Tcl_Interp*,
- TclDateFields*, Tcl_Obj*, int);
-static int ConvertLocalToUTCUsingTable(Tcl_Interp*,
- TclDateFields*, int, Tcl_Obj *CONST[]);
-static int ConvertLocalToUTCUsingC(Tcl_Interp*,
- TclDateFields*, int);
-static Tcl_Obj* LookupLastTransition(Tcl_Interp*, Tcl_WideInt,
- int, Tcl_Obj *CONST *);
-static void GetYearWeekDay(TclDateFields*, int);
-static void GetGregorianEraYearDay(TclDateFields*, int);
-static void GetMonthDay(TclDateFields*);
-static void GetJulianDayFromEraYearWeekDay(TclDateFields*, int);
-static void GetJulianDayFromEraYearMonthDay(TclDateFields*, int);
-static int IsGregorianLeapYear(TclDateFields*);
+static int ConvertUTCToLocal(Tcl_Interp *,
+ TclDateFields *, Tcl_Obj *, int);
+static int ConvertUTCToLocalUsingTable(Tcl_Interp *,
+ TclDateFields *, int, Tcl_Obj *const[]);
+static int ConvertUTCToLocalUsingC(Tcl_Interp *,
+ TclDateFields *, int);
+static int ConvertLocalToUTC(Tcl_Interp *,
+ TclDateFields *, Tcl_Obj *, int);
+static int ConvertLocalToUTCUsingTable(Tcl_Interp *,
+ TclDateFields *, int, Tcl_Obj *const[]);
+static int ConvertLocalToUTCUsingC(Tcl_Interp *,
+ TclDateFields *, int);
+static Tcl_Obj * LookupLastTransition(Tcl_Interp *, Tcl_WideInt,
+ int, Tcl_Obj *const *);
+static void GetYearWeekDay(TclDateFields *, int);
+static void GetGregorianEraYearDay(TclDateFields *, int);
+static void GetMonthDay(TclDateFields *);
+static void GetJulianDayFromEraYearWeekDay(TclDateFields *, int);
+static void GetJulianDayFromEraYearMonthDay(TclDateFields *, int);
+static int IsGregorianLeapYear(TclDateFields *);
static int WeekdayOnOrBefore(int, int);
static int ClockClicksObjCmd(
ClientData clientData, Tcl_Interp *interp,
- int objc, Tcl_Obj *CONST objv[]);
+ int objc, Tcl_Obj *const objv[]);
static int ClockConvertlocaltoutcObjCmd(
ClientData clientData, Tcl_Interp *interp,
- int objc, Tcl_Obj *CONST objv[]);
+ int objc, Tcl_Obj *const objv[]);
static int ClockGetdatefieldsObjCmd(
ClientData clientData, Tcl_Interp *interp,
- int objc, Tcl_Obj *CONST objv[]);
+ int objc, Tcl_Obj *const objv[]);
static int ClockGetjuliandayfromerayearmonthdayObjCmd(
ClientData clientData, Tcl_Interp *interp,
- int objc, Tcl_Obj *CONST objv[]);
+ int objc, Tcl_Obj *const objv[]);
static int ClockGetjuliandayfromerayearweekdayObjCmd(
ClientData clientData, Tcl_Interp *interp,
- int objc, Tcl_Obj *CONST objv[]);
+ int objc, Tcl_Obj *const objv[]);
static int ClockGetenvObjCmd(
ClientData clientData, Tcl_Interp *interp,
- int objc, Tcl_Obj *CONST objv[]);
+ int objc, Tcl_Obj *const objv[]);
static int ClockMicrosecondsObjCmd(
ClientData clientData, Tcl_Interp *interp,
- int objc, Tcl_Obj *CONST objv[]);
+ int objc, Tcl_Obj *const objv[]);
static int ClockMillisecondsObjCmd(
ClientData clientData, Tcl_Interp *interp,
- int objc, Tcl_Obj *CONST objv[]);
+ int objc, Tcl_Obj *const objv[]);
+static int ClockParseformatargsObjCmd(
+ ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
static int ClockSecondsObjCmd(
ClientData clientData, Tcl_Interp *interp,
- int objc, Tcl_Obj *CONST objv[]);
-static struct tm * ThreadSafeLocalTime(CONST time_t *);
+ int objc, Tcl_Obj *const objv[]);
+static struct tm * ThreadSafeLocalTime(const time_t *);
static void TzsetIfNecessary(void);
static void ClockDeleteCmdProc(ClientData);
+/*
+ * Structure containing description of "native" clock commands to create.
+ */
+
+struct ClockCommand {
+ const char *name; /* The tail of the command name. The full name
+ * is "::tcl::clock::<name>". When NULL marks
+ * the end of the table. */
+ Tcl_ObjCmdProc *objCmdProc; /* Function that implements the command. This
+ * will always have the ClockClientData sent
+ * to it, but may well ignore this data. */
+};
+
+static const struct ClockCommand clockCommands[] = {
+ { "clicks", ClockClicksObjCmd },
+ { "getenv", ClockGetenvObjCmd },
+ { "microseconds", ClockMicrosecondsObjCmd },
+ { "milliseconds", ClockMillisecondsObjCmd },
+ { "seconds", ClockSecondsObjCmd },
+ { "Oldscan", TclClockOldscanObjCmd },
+ { "ConvertLocalToUTC", ClockConvertlocaltoutcObjCmd },
+ { "GetDateFields", ClockGetdatefieldsObjCmd },
+ { "GetJulianDayFromEraYearMonthDay",
+ ClockGetjuliandayfromerayearmonthdayObjCmd },
+ { "GetJulianDayFromEraYearWeekDay",
+ ClockGetjuliandayfromerayearweekdayObjCmd },
+ { "ParseFormatArgs", ClockParseformatargsObjCmd },
+ { NULL, NULL }
+};
/*
*----------------------------------------------------------------------
*
* TclClockInit --
*
- * Registers the 'clock' subcommands with the Tcl interpreter
- * and initializes its client data (which consists mostly of
- * constant Tcl_Obj's that it is too much trouble to keep
- * recreating).
+ * Registers the 'clock' subcommands with the Tcl interpreter and
+ * initializes its client data (which consists mostly of constant
+ * Tcl_Obj's that it is too much trouble to keep recreating).
*
* Results:
* None.
@@ -206,58 +244,48 @@ static void ClockDeleteCmdProc(ClientData);
void
TclClockInit(
- Tcl_Interp* interp /* Tcl interpreter */
-) {
+ Tcl_Interp *interp) /* Tcl interpreter */
+{
+ const struct ClockCommand *clockCmdPtr;
+ char cmdName[50]; /* Buffer large enough to hold the string
+ *::tcl::clock::GetJulianDayFromEraYearMonthDay
+ * plus a terminating NUL. */
+ ClockClientData *data;
int i;
- /* Create the client data */
+ /*
+ * Safe interps get [::clock] as alias to a master, so do not need their
+ * own copies of the support routines.
+ */
+
+ if (Tcl_IsSafe(interp)) {
+ return;
+ }
- ClockClientData *data =
- (ClockClientData*) ckalloc(sizeof(ClockClientData));
- data->refCount = 0;
-
/*
- * Create the literal pool
+ * Create the client data, which is a refcounted literal pool.
*/
- data->literals = (Tcl_Obj**) ckalloc(LIT__END * sizeof(Tcl_Obj*));
+
+ data = ckalloc(sizeof(ClockClientData));
+ data->refCount = 0;
+ data->literals = ckalloc(LIT__END * sizeof(Tcl_Obj*));
for (i = 0; i < LIT__END; ++i) {
data->literals[i] = Tcl_NewStringObj(literals[i], -1);
Tcl_IncrRefCount(data->literals[i]);
}
- /* Install the commands */
-
- Tcl_CreateObjCommand(interp, "::tcl::clock::clicks",
- ClockClicksObjCmd, (ClientData) NULL, NULL);
- Tcl_CreateObjCommand(interp, "::tcl::clock::getenv",
- ClockGetenvObjCmd, (ClientData) NULL, NULL);
- Tcl_CreateObjCommand(interp, "::tcl::clock::microseconds",
- ClockMicrosecondsObjCmd, (ClientData) NULL, NULL);
- Tcl_CreateObjCommand(interp, "::tcl::clock::milliseconds",
- ClockMillisecondsObjCmd, (ClientData) NULL, NULL);
- Tcl_CreateObjCommand(interp, "::tcl::clock::seconds",
- ClockSecondsObjCmd, (ClientData) NULL, NULL);
- Tcl_CreateObjCommand(interp, "::tcl::clock::Oldscan",
- TclClockOldscanObjCmd, (ClientData) NULL, NULL);
- Tcl_CreateObjCommand(interp, "::tcl::clock::ConvertLocalToUTC",
- ClockConvertlocaltoutcObjCmd, (ClientData) data,
- ClockDeleteCmdProc);
- ++data->refCount;
- Tcl_CreateObjCommand(interp, "::tcl::clock::GetDateFields",
- ClockGetdatefieldsObjCmd,(ClientData) data,
- ClockDeleteCmdProc);
- ++data->refCount;
- Tcl_CreateObjCommand(interp,
- "::tcl::clock::GetJulianDayFromEraYearMonthDay",
- ClockGetjuliandayfromerayearmonthdayObjCmd,(ClientData) data,
- ClockDeleteCmdProc);
- ++data->refCount;
- Tcl_CreateObjCommand(interp,
- "::tcl::clock::GetJulianDayFromEraYearWeekDay",
- ClockGetjuliandayfromerayearweekdayObjCmd,(ClientData) data,
- ClockDeleteCmdProc);
- ++data->refCount;
+ /*
+ * Install the commands.
+ */
+#define TCL_CLOCK_PREFIX_LEN 14 /* == strlen("::tcl::clock::") */
+ memcpy(cmdName, "::tcl::clock::", TCL_CLOCK_PREFIX_LEN);
+ for (clockCmdPtr=clockCommands ; clockCmdPtr->name!=NULL ; clockCmdPtr++) {
+ strcpy(cmdName + TCL_CLOCK_PREFIX_LEN, clockCmdPtr->name);
+ data->refCount++;
+ Tcl_CreateObjCommand(interp, cmdName, clockCmdPtr->objCmdProc, data,
+ ClockDeleteCmdProc);
+ }
}
/*
@@ -265,8 +293,8 @@ TclClockInit(
*
* ClockConvertlocaltoutcObjCmd --
*
- * Tcl command that converts a UTC time to a local time by
- * whatever means is available.
+ * Tcl command that converts a UTC time to a local time by whatever means
+ * is available.
*
* Usage:
* ::tcl::clock::ConvertUTCToLocal dictionary tzdata changeover
@@ -281,7 +309,7 @@ TclClockInit(
*
* Side effects:
* On success, sets the interpreter result to the given dictionary
- * augmented with a 'seconds' field giving the UTC time. On failure,
+ * augmented with a 'seconds' field giving the UTC time. On failure,
* leaves an error message in the interpreter result.
*
*----------------------------------------------------------------------
@@ -289,39 +317,48 @@ TclClockInit(
static int
ClockConvertlocaltoutcObjCmd(
- ClientData clientData, /* Client data */
- Tcl_Interp* interp, /* Tcl interpreter */
+ ClientData clientData, /* Client data */
+ Tcl_Interp *interp, /* Tcl interpreter */
int objc, /* Parameter count */
- Tcl_Obj *CONST * objv /* Parameter vector */
-) {
- ClockClientData* data = (ClockClientData*) clientData;
- Tcl_Obj* CONST * literals = data->literals;
- Tcl_Obj* secondsObj;
- Tcl_Obj* dict;
+ Tcl_Obj *const *objv) /* Parameter vector */
+{
+ ClockClientData *data = clientData;
+ Tcl_Obj *const *literals = data->literals;
+ Tcl_Obj *secondsObj;
+ Tcl_Obj *dict;
int changeover;
TclDateFields fields;
int created = 0;
int status;
- /* Check params and convert time */
+ /*
+ * Check params and convert time.
+ */
if (objc != 4) {
Tcl_WrongNumArgs(interp, 1, objv, "dict tzdata changeover");
return TCL_ERROR;
}
dict = objv[1];
- if ((Tcl_DictObjGet(interp, dict, literals[LIT_LOCALSECONDS], &secondsObj)
- != TCL_OK)
- || (Tcl_GetWideIntFromObj(interp, secondsObj, &(fields.localSeconds))
- != TCL_OK)
- || (Tcl_GetIntFromObj(interp, objv[3], &changeover) != TCL_OK)
+ if (Tcl_DictObjGet(interp, dict, literals[LIT_LOCALSECONDS],
+ &secondsObj)!= TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (secondsObj == NULL) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("key \"localseconds\" not "
+ "found in dictionary", -1));
+ return TCL_ERROR;
+ }
+ if ((Tcl_GetWideIntFromObj(interp, secondsObj,
+ &fields.localSeconds) != TCL_OK)
+ || (TclGetIntFromObj(interp, objv[3], &changeover) != TCL_OK)
|| ConvertLocalToUTC(interp, &fields, objv[2], changeover)) {
return TCL_ERROR;
}
- /*
- * Copy-on-write; set the 'seconds' field in the dictionary and
- * place the modified dictionary in the interpreter result.
+ /*
+ * Copy-on-write; set the 'seconds' field in the dictionary and place the
+ * modified dictionary in the interpreter result.
*/
if (Tcl_IsShared(dict)) {
@@ -330,7 +367,7 @@ ClockConvertlocaltoutcObjCmd(
Tcl_IncrRefCount(dict);
}
status = Tcl_DictObjPut(interp, dict, literals[LIT_SECONDS],
- Tcl_NewWideIntObj(fields.seconds));
+ Tcl_NewWideIntObj(fields.seconds));
if (status == TCL_OK) {
Tcl_SetObjResult(interp, dict);
}
@@ -345,24 +382,24 @@ ClockConvertlocaltoutcObjCmd(
*
* ClockGetdatefieldsObjCmd --
*
- * Tcl command that determines the values that [clock format] will
- * use in formatting a date, and populates a dictionary with them.
+ * Tcl command that determines the values that [clock format] will use in
+ * formatting a date, and populates a dictionary with them.
*
* Usage:
* ::tcl::clock::GetDateFields seconds tzdata changeover
*
* Parameters:
* seconds - Time expressed in seconds from the Posix epoch.
- * tzdata - Time zone data of the time zone in which time is to
- * be expressed.
+ * tzdata - Time zone data of the time zone in which time is to be
+ * expressed.
* changeover - Julian Day Number at which the current locale adopted
* the Gregorian calendar
*
* Results:
* Returns a dictonary populated with the fields:
* seconds - Seconds from the Posix epoch
- * localSeconds - Nominal seconds from the Posix epoch in
- * the local time zone.
+ * localSeconds - Nominal seconds from the Posix epoch in the
+ * local time zone.
* tzOffset - Time zone offset in seconds east of Greenwich
* tzName - Time zone name
* julianDay - Julian Day Number in the local time zone
@@ -373,74 +410,91 @@ ClockConvertlocaltoutcObjCmd(
int
ClockGetdatefieldsObjCmd(
ClientData clientData, /* Opaque pointer to literal pool, etc. */
- Tcl_Interp* interp, /* Tcl interpreter */
+ Tcl_Interp *interp, /* Tcl interpreter */
int objc, /* Parameter count */
- Tcl_Obj *CONST *objv /* Parameter vector */
-) {
+ Tcl_Obj *const *objv) /* Parameter vector */
+{
TclDateFields fields;
- Tcl_Obj* dict;
- ClockClientData* data = (ClockClientData*) clientData;
- Tcl_Obj* CONST * literals = data->literals;
+ Tcl_Obj *dict;
+ ClockClientData *data = clientData;
+ Tcl_Obj *const *literals = data->literals;
int changeover;
- /* Check params */
+ /*
+ * Check params.
+ */
if (objc != 4) {
Tcl_WrongNumArgs(interp, 1, objv, "seconds tzdata changeover");
return TCL_ERROR;
}
- if (Tcl_GetWideIntFromObj(interp, objv[1], &(fields.seconds)) != TCL_OK
- || Tcl_GetIntFromObj(interp, objv[3], &changeover) != TCL_OK) {
+ if (Tcl_GetWideIntFromObj(interp, objv[1], &fields.seconds) != TCL_OK
+ || TclGetIntFromObj(interp, objv[3], &changeover) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * fields.seconds could be an unsigned number that overflowed. Make sure
+ * that it isn't.
+ */
+
+ if (objv[1]->typePtr == &tclBignumType) {
+ Tcl_SetObjResult(interp, literals[LIT_INTEGER_VALUE_TOO_LARGE]);
return TCL_ERROR;
}
- /* Convert UTC time to local */
+ /*
+ * Convert UTC time to local.
+ */
if (ConvertUTCToLocal(interp, &fields, objv[2], changeover) != TCL_OK) {
return TCL_ERROR;
}
- /* Extract Julian day */
+ /*
+ * Extract Julian day.
+ */
fields.julianDay = (int) ((fields.localSeconds + JULIAN_SEC_POSIX_EPOCH)
- / SECONDS_PER_DAY);
+ / SECONDS_PER_DAY);
- /* Convert to Julian or Gregorian calendar */
+ /*
+ * Convert to Julian or Gregorian calendar.
+ */
GetGregorianEraYearDay(&fields, changeover);
GetMonthDay(&fields);
GetYearWeekDay(&fields, changeover);
dict = Tcl_NewDictObj();
- Tcl_DictObjPut((Tcl_Interp*) NULL, dict, literals[LIT_LOCALSECONDS],
- Tcl_NewWideIntObj(fields.localSeconds));
- Tcl_DictObjPut((Tcl_Interp*) NULL, dict, literals[LIT_SECONDS],
- Tcl_NewWideIntObj(fields.seconds));
- Tcl_DictObjPut((Tcl_Interp*) NULL, dict, literals[LIT_TZNAME],
- fields.tzName);
+ Tcl_DictObjPut(NULL, dict, literals[LIT_LOCALSECONDS],
+ Tcl_NewWideIntObj(fields.localSeconds));
+ Tcl_DictObjPut(NULL, dict, literals[LIT_SECONDS],
+ Tcl_NewWideIntObj(fields.seconds));
+ Tcl_DictObjPut(NULL, dict, literals[LIT_TZNAME], fields.tzName);
Tcl_DecrRefCount(fields.tzName);
- Tcl_DictObjPut((Tcl_Interp*) NULL, dict, literals[LIT_TZOFFSET],
- Tcl_NewIntObj(fields.tzOffset));
- Tcl_DictObjPut((Tcl_Interp*) NULL, dict, literals[LIT_JULIANDAY],
- Tcl_NewIntObj(fields.julianDay));
- Tcl_DictObjPut((Tcl_Interp*) NULL, dict, literals[LIT_GREGORIAN],
- Tcl_NewIntObj(fields.gregorian));
- Tcl_DictObjPut((Tcl_Interp*) NULL, dict, literals[LIT_ERA],
- literals[fields.era ? LIT_BCE : LIT_CE]);
- Tcl_DictObjPut((Tcl_Interp*) NULL, dict, literals[LIT_YEAR],
- Tcl_NewIntObj(fields.year));
- Tcl_DictObjPut((Tcl_Interp*) NULL, dict, literals[LIT_DAYOFYEAR],
- Tcl_NewIntObj(fields.dayOfYear));
- Tcl_DictObjPut((Tcl_Interp*) NULL, dict, literals[LIT_MONTH],
- Tcl_NewIntObj(fields.month));
- Tcl_DictObjPut((Tcl_Interp*) NULL, dict, literals[LIT_DAYOFMONTH],
- Tcl_NewIntObj(fields.dayOfMonth));
- Tcl_DictObjPut((Tcl_Interp*) NULL, dict, literals[LIT_ISO8601YEAR],
- Tcl_NewIntObj(fields.iso8601Year));
- Tcl_DictObjPut((Tcl_Interp*) NULL, dict, literals[LIT_ISO8601WEEK],
- Tcl_NewIntObj(fields.iso8601Week));
- Tcl_DictObjPut((Tcl_Interp*) NULL, dict, literals[LIT_DAYOFWEEK],
- Tcl_NewIntObj(fields.dayOfWeek));
+ Tcl_DictObjPut(NULL, dict, literals[LIT_TZOFFSET],
+ Tcl_NewIntObj(fields.tzOffset));
+ Tcl_DictObjPut(NULL, dict, literals[LIT_JULIANDAY],
+ Tcl_NewIntObj(fields.julianDay));
+ Tcl_DictObjPut(NULL, dict, literals[LIT_GREGORIAN],
+ Tcl_NewIntObj(fields.gregorian));
+ Tcl_DictObjPut(NULL, dict, literals[LIT_ERA],
+ literals[fields.era ? LIT_BCE : LIT_CE]);
+ Tcl_DictObjPut(NULL, dict, literals[LIT_YEAR],
+ Tcl_NewIntObj(fields.year));
+ Tcl_DictObjPut(NULL, dict, literals[LIT_DAYOFYEAR],
+ Tcl_NewIntObj(fields.dayOfYear));
+ Tcl_DictObjPut(NULL, dict, literals[LIT_MONTH],
+ Tcl_NewIntObj(fields.month));
+ Tcl_DictObjPut(NULL, dict, literals[LIT_DAYOFMONTH],
+ Tcl_NewIntObj(fields.dayOfMonth));
+ Tcl_DictObjPut(NULL, dict, literals[LIT_ISO8601YEAR],
+ Tcl_NewIntObj(fields.iso8601Year));
+ Tcl_DictObjPut(NULL, dict, literals[LIT_ISO8601WEEK],
+ Tcl_NewIntObj(fields.iso8601Week));
+ Tcl_DictObjPut(NULL, dict, literals[LIT_DAYOFWEEK],
+ Tcl_NewIntObj(fields.dayOfWeek));
Tcl_SetObjResult(interp, dict);
return TCL_OK;
@@ -451,8 +505,8 @@ ClockGetdatefieldsObjCmd(
*
* ClockGetjuliandayfromerayearmonthdayObjCmd --
*
- * Tcl command that converts a time from era-year-month-day to
- * a Julian Day Number.
+ * Tcl command that converts a time from era-year-month-day to a Julian
+ * Day Number.
*
* Parameters:
* dict - Dictionary that contains 'era', 'year', 'month' and
@@ -468,23 +522,25 @@ ClockGetdatefieldsObjCmd(
*/
static int
-ClockGetjuliandayfromerayearmonthdayObjCmd (
+ClockGetjuliandayfromerayearmonthdayObjCmd(
ClientData clientData, /* Opaque pointer to literal pool, etc. */
- Tcl_Interp* interp, /* Tcl interpreter */
+ Tcl_Interp *interp, /* Tcl interpreter */
int objc, /* Parameter count */
- Tcl_Obj *CONST *objv /* Parameter vector */
-) {
+ Tcl_Obj *const *objv) /* Parameter vector */
+{
TclDateFields fields;
- Tcl_Obj* dict;
- ClockClientData* data = (ClockClientData*) clientData;
- Tcl_Obj* CONST * literals = data->literals;
- Tcl_Obj* fieldPtr;
+ Tcl_Obj *dict;
+ ClockClientData *data = clientData;
+ Tcl_Obj *const *literals = data->literals;
+ Tcl_Obj *fieldPtr;
int changeover;
int copied = 0;
int status;
int era = 0;
- /* Check params */
+ /*
+ * Check params.
+ */
if (objc != 3) {
Tcl_WrongNumArgs(interp, 1, objv, "dict changeover");
@@ -492,27 +548,34 @@ ClockGetjuliandayfromerayearmonthdayObjCmd (
}
dict = objv[1];
if (Tcl_DictObjGet(interp, dict, literals[LIT_ERA], &fieldPtr) != TCL_OK
- || Tcl_GetIndexFromObj(interp, fieldPtr, eras, "era", TCL_EXACT,
- &era) != TCL_OK
- || Tcl_DictObjGet(interp, dict, literals[LIT_YEAR],
- &fieldPtr) != TCL_OK
- || Tcl_GetIntFromObj(interp, fieldPtr, &(fields.year)) != TCL_OK
- || Tcl_DictObjGet(interp, dict, literals[LIT_MONTH],
- &fieldPtr) != TCL_OK
- || Tcl_GetIntFromObj(interp, fieldPtr, &(fields.month)) != TCL_OK
- || Tcl_DictObjGet(interp, dict, literals[LIT_DAYOFMONTH],
- &fieldPtr) != TCL_OK
- || Tcl_GetIntFromObj(interp, fieldPtr, &(fields.dayOfMonth)) != TCL_OK
- || Tcl_GetIntFromObj(interp, objv[2], &changeover) != TCL_OK) {
+ || fieldPtr == NULL
+ || Tcl_GetIndexFromObj(interp, fieldPtr, eras, "era", TCL_EXACT,
+ &era) != TCL_OK
+ || Tcl_DictObjGet(interp, dict, literals[LIT_YEAR], &fieldPtr) != TCL_OK
+ || fieldPtr == NULL
+ || TclGetIntFromObj(interp, fieldPtr, &fields.year) != TCL_OK
+ || Tcl_DictObjGet(interp, dict, literals[LIT_MONTH], &fieldPtr) != TCL_OK
+ || fieldPtr == NULL
+ || TclGetIntFromObj(interp, fieldPtr, &fields.month) != TCL_OK
+ || Tcl_DictObjGet(interp, dict, literals[LIT_DAYOFMONTH], &fieldPtr) != TCL_OK
+ || fieldPtr == NULL
+ || TclGetIntFromObj(interp, fieldPtr, &fields.dayOfMonth)!=TCL_OK
+ || TclGetIntFromObj(interp, objv[2], &changeover) != TCL_OK) {
+ if (fieldPtr == NULL)
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("expected key(s) not found in dictionary", -1));
return TCL_ERROR;
}
fields.era = era;
- /* Get Julian day */
+ /*
+ * Get Julian day.
+ */
GetJulianDayFromEraYearMonthDay(&fields, changeover);
- /* Store Julian day in the dictionary - copy on write */
+ /*
+ * Store Julian day in the dictionary - copy on write.
+ */
if (Tcl_IsShared(dict)) {
dict = Tcl_DuplicateObj(dict);
@@ -520,7 +583,7 @@ ClockGetjuliandayfromerayearmonthdayObjCmd (
copied = 1;
}
status = Tcl_DictObjPut(interp, dict, literals[LIT_JULIANDAY],
- Tcl_NewIntObj(fields.julianDay));
+ Tcl_NewIntObj(fields.julianDay));
if (status == TCL_OK) {
Tcl_SetObjResult(interp, dict);
}
@@ -528,47 +591,49 @@ ClockGetjuliandayfromerayearmonthdayObjCmd (
Tcl_DecrRefCount(dict);
}
return status;
-}
+}
/*
*----------------------------------------------------------------------
*
* ClockGetjuliandayfromerayearweekdayObjCmd --
*
- * Tcl command that converts a time from the ISO calendar to
- * a Julian Day Number.
+ * Tcl command that converts a time from the ISO calendar to a Julian Day
+ * Number.
*
* Parameters:
- * dict - Dictionary that contains 'era', 'iso8601Year', 'iso8601Week'
+ * dict - Dictionary that contains 'era', 'iso8601Year', 'iso8601Week'
* and 'dayOfWeek' keys.
* changeover - Julian Day of changeover to the Gregorian calendar
*
* Results:
* Result is either TCL_OK, with the interpreter result being the
- * dictionary augmented with a 'julianDay' key, or TCL_ERROR,
- * with the result being an error message.
+ * dictionary augmented with a 'julianDay' key, or TCL_ERROR, with the
+ * result being an error message.
*
*----------------------------------------------------------------------
*/
static int
-ClockGetjuliandayfromerayearweekdayObjCmd (
+ClockGetjuliandayfromerayearweekdayObjCmd(
ClientData clientData, /* Opaque pointer to literal pool, etc. */
- Tcl_Interp* interp, /* Tcl interpreter */
+ Tcl_Interp *interp, /* Tcl interpreter */
int objc, /* Parameter count */
- Tcl_Obj *CONST *objv /* Parameter vector */
-) {
+ Tcl_Obj *const *objv) /* Parameter vector */
+{
TclDateFields fields;
- Tcl_Obj* dict;
- ClockClientData* data = (ClockClientData*) clientData;
- Tcl_Obj* CONST * literals = data->literals;
- Tcl_Obj* fieldPtr;
+ Tcl_Obj *dict;
+ ClockClientData *data = clientData;
+ Tcl_Obj *const *literals = data->literals;
+ Tcl_Obj *fieldPtr;
int changeover;
int copied = 0;
int status;
int era = 0;
- /* Check params */
+ /*
+ * Check params.
+ */
if (objc != 3) {
Tcl_WrongNumArgs(interp, 1, objv, "dict changeover");
@@ -576,27 +641,34 @@ ClockGetjuliandayfromerayearweekdayObjCmd (
}
dict = objv[1];
if (Tcl_DictObjGet(interp, dict, literals[LIT_ERA], &fieldPtr) != TCL_OK
- || Tcl_GetIndexFromObj(interp, fieldPtr, eras, "era", TCL_EXACT,
- &era) != TCL_OK
- || Tcl_DictObjGet(interp, dict, literals[LIT_ISO8601YEAR],
- &fieldPtr) != TCL_OK
- || Tcl_GetIntFromObj(interp, fieldPtr, &(fields.iso8601Year)) != TCL_OK
- || Tcl_DictObjGet(interp, dict, literals[LIT_ISO8601WEEK],
- &fieldPtr) != TCL_OK
- || Tcl_GetIntFromObj(interp, fieldPtr, &(fields.iso8601Week)) != TCL_OK
- || Tcl_DictObjGet(interp, dict, literals[LIT_DAYOFWEEK],
- &fieldPtr) != TCL_OK
- || Tcl_GetIntFromObj(interp, fieldPtr, &(fields.dayOfWeek)) != TCL_OK
- || Tcl_GetIntFromObj(interp, objv[2], &changeover) != TCL_OK) {
+ || fieldPtr == NULL
+ || Tcl_GetIndexFromObj(interp, fieldPtr, eras, "era", TCL_EXACT,
+ &era) != TCL_OK
+ || Tcl_DictObjGet(interp, dict, literals[LIT_ISO8601YEAR], &fieldPtr) != TCL_OK
+ || fieldPtr == NULL
+ || TclGetIntFromObj(interp, fieldPtr, &(fields.iso8601Year)) != TCL_OK
+ || Tcl_DictObjGet(interp, dict, literals[LIT_ISO8601WEEK], &fieldPtr) != TCL_OK
+ || fieldPtr == NULL
+ || TclGetIntFromObj(interp, fieldPtr, &(fields.iso8601Week)) != TCL_OK
+ || Tcl_DictObjGet(interp, dict, literals[LIT_DAYOFWEEK], &fieldPtr) != TCL_OK
+ || fieldPtr == NULL
+ || TclGetIntFromObj(interp, fieldPtr, &(fields.dayOfWeek)) != TCL_OK
+ || TclGetIntFromObj(interp, objv[2], &changeover) != TCL_OK) {
+ if (fieldPtr == NULL)
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("expected key(s) not found in dictionary", -1));
return TCL_ERROR;
}
fields.era = era;
- /* Get Julian day */
+ /*
+ * Get Julian day.
+ */
GetJulianDayFromEraYearWeekDay(&fields, changeover);
- /* Store Julian day in the dictionary - copy on write */
+ /*
+ * Store Julian day in the dictionary - copy on write.
+ */
if (Tcl_IsShared(dict)) {
dict = Tcl_DuplicateObj(dict);
@@ -604,7 +676,7 @@ ClockGetjuliandayfromerayearweekdayObjCmd (
copied = 1;
}
status = Tcl_DictObjPut(interp, dict, literals[LIT_JULIANDAY],
- Tcl_NewIntObj(fields.julianDay));
+ Tcl_NewIntObj(fields.julianDay));
if (status == TCL_OK) {
Tcl_SetObjResult(interp, dict);
}
@@ -612,43 +684,45 @@ ClockGetjuliandayfromerayearweekdayObjCmd (
Tcl_DecrRefCount(dict);
}
return status;
-}
+}
/*
*----------------------------------------------------------------------
*
* ConvertLocalToUTC --
*
- * Converts a time (in a TclDateFields structure) from the
- * local wall clock to UTC.
+ * Converts a time (in a TclDateFields structure) from the local wall
+ * clock to UTC.
*
* Results:
* Returns a standard Tcl result.
*
* Side effects:
- * Populates the 'seconds' field if successful; stores an error
- * message in the interpreter result on failure.
+ * Populates the 'seconds' field if successful; stores an error message
+ * in the interpreter result on failure.
*
*----------------------------------------------------------------------
*/
static int
ConvertLocalToUTC(
- Tcl_Interp* interp, /* Tcl interpreter */
- TclDateFields* fields, /* Fields of the time */
- Tcl_Obj* tzdata, /* Time zone data */
- int changeover /* Julian Day of the Gregorian transition */
-) {
+ Tcl_Interp *interp, /* Tcl interpreter */
+ TclDateFields *fields, /* Fields of the time */
+ Tcl_Obj *tzdata, /* Time zone data */
+ int changeover) /* Julian Day of the Gregorian transition */
+{
int rowc; /* Number of rows in tzdata */
- Tcl_Obj** rowv; /* Pointers to the rows */
+ Tcl_Obj **rowv; /* Pointers to the rows */
- /* unpack the tz data */
+ /*
+ * Unpack the tz data.
+ */
- if (Tcl_ListObjGetElements(interp, tzdata, &rowc, &rowv) != TCL_OK) {
+ if (TclListObjGetElements(interp, tzdata, &rowc, &rowv) != TCL_OK) {
return TCL_ERROR;
}
- /*
+ /*
* Special case: If the time zone is :localtime, the tzdata will be empty.
* Use 'mktime' to convert the time to local
*/
@@ -665,41 +739,42 @@ ConvertLocalToUTC(
*
* ConvertLocalToUTCUsingTable --
*
- * Converts a time (in a TclDateFields structure) from local time
- * in a given time zone to UTC.
+ * Converts a time (in a TclDateFields structure) from local time in a
+ * given time zone to UTC.
*
* Results:
* Returns a standard Tcl result.
*
* Side effects:
- * Stores an error message in the interpreter if an error occurs;
- * if successful, stores the 'seconds' field in 'fields.
+ * Stores an error message in the interpreter if an error occurs; if
+ * successful, stores the 'seconds' field in 'fields.
*
*----------------------------------------------------------------------
*/
+
static int
ConvertLocalToUTCUsingTable(
- Tcl_Interp* interp, /* Tcl interpreter */
- TclDateFields* fields, /* Time to convert, with 'seconds' filled in */
+ Tcl_Interp *interp, /* Tcl interpreter */
+ TclDateFields *fields, /* Time to convert, with 'seconds' filled in */
int rowc, /* Number of points at which time changes */
- Tcl_Obj *CONST rowv[] /* Points at which time changes */
-) {
- Tcl_Obj* row;
+ Tcl_Obj *const rowv[]) /* Points at which time changes */
+{
+ Tcl_Obj *row;
int cellc;
- Tcl_Obj** cellv;
+ Tcl_Obj **cellv;
int have[8];
int nHave = 0;
int i;
int found;
/*
- * Perform an initial lookup assuming that local == UTC, and locate
- * the last time conversion prior to that time. Get the offset from
- * that row, and look up again. Continue until we find an offset
- * that we found before. This definition, rather than "the same offset"
- * ensures that we don't enter an endless loop, as would otherwise happen
- * when trying to convert a non-existent time such as 02:30 during
- * the US Spring Daylight Saving Time transition.
+ * Perform an initial lookup assuming that local == UTC, and locate the
+ * last time conversion prior to that time. Get the offset from that row,
+ * and look up again. Continue until we find an offset that we found
+ * before. This definition, rather than "the same offset" ensures that we
+ * don't enter an endless loop, as would otherwise happen when trying to
+ * convert a non-existent time such as 02:30 during the US Spring Daylight
+ * Saving Time transition.
*/
found = 0;
@@ -708,9 +783,10 @@ ConvertLocalToUTCUsingTable(
while (!found) {
row = LookupLastTransition(interp, fields->seconds, rowc, rowv);
if ((row == NULL)
- || (Tcl_ListObjGetElements(interp, row, &cellc, &cellv) != TCL_OK)
- || (Tcl_GetIntFromObj(interp, cellv[1], &(fields->tzOffset))
- != TCL_OK)) {
+ || TclListObjGetElements(interp, row, &cellc,
+ &cellv) != TCL_OK
+ || TclGetIntFromObj(interp, cellv[1],
+ &fields->tzOffset) != TCL_OK) {
return TCL_ERROR;
}
found = 0;
@@ -718,14 +794,13 @@ ConvertLocalToUTCUsingTable(
if (have[i] == fields->tzOffset) {
found = 1;
break;
- }
+ }
}
if (!found) {
if (nHave == 8) {
Tcl_Panic("loop in ConvertLocalToUTCUsingTable");
}
- have[nHave] = fields->tzOffset;
- ++nHave;
+ have[nHave++] = fields->tzOffset;
}
fields->seconds = fields->localSeconds - fields->tzOffset;
}
@@ -739,45 +814,51 @@ ConvertLocalToUTCUsingTable(
*
* ConvertLocalToUTCUsingC --
*
- * Converts a time from local wall clock to UTC when the local
- * time zone cannot be determined. Uses 'mktime' to do the job.
+ * Converts a time from local wall clock to UTC when the local time zone
+ * cannot be determined. Uses 'mktime' to do the job.
*
* Results:
* Returns a standard Tcl result.
*
* Side effects:
- * Stores an error message in the interpreter if an error occurs;
- * if successful, stores the 'seconds' field in 'fields.
+ * Stores an error message in the interpreter if an error occurs; if
+ * successful, stores the 'seconds' field in 'fields.
*
*----------------------------------------------------------------------
*/
static int
ConvertLocalToUTCUsingC(
- Tcl_Interp* interp, /* Tcl interpreter */
- TclDateFields* fields, /* Time to convert, with 'seconds' filled in */
- int changeover /* Julian Day of the Gregorian transition */
-) {
+ Tcl_Interp *interp, /* Tcl interpreter */
+ TclDateFields *fields, /* Time to convert, with 'seconds' filled in */
+ int changeover) /* Julian Day of the Gregorian transition */
+{
struct tm timeVal;
int localErrno;
int secondOfDay;
+ Tcl_WideInt jsec;
- /* Convert the given time to a date */
+ /*
+ * Convert the given time to a date.
+ */
- fields->julianDay = (int) ((fields->localSeconds + JULIAN_SEC_POSIX_EPOCH)
- / SECONDS_PER_DAY);
+ jsec = fields->localSeconds + JULIAN_SEC_POSIX_EPOCH;
+ fields->julianDay = (int) (jsec / SECONDS_PER_DAY);
+ secondOfDay = (int)(jsec % SECONDS_PER_DAY);
+ if (secondOfDay < 0) {
+ secondOfDay += SECONDS_PER_DAY;
+ fields->julianDay--;
+ }
GetGregorianEraYearDay(fields, changeover);
GetMonthDay(fields);
-
- /* Convert the date/time to a 'struct tm' */
+
+ /*
+ * Convert the date/time to a 'struct tm'.
+ */
timeVal.tm_year = fields->year - 1900;
timeVal.tm_mon = fields->month - 1;
timeVal.tm_mday = fields->dayOfMonth;
- secondOfDay = (int)(fields->localSeconds % SECONDS_PER_DAY);
- if (secondOfDay < 0) {
- secondOfDay += SECONDS_PER_DAY;
- }
timeVal.tm_hour = (secondOfDay / 3600) % 24;
timeVal.tm_min = (secondOfDay / 60) % 60;
timeVal.tm_sec = secondOfDay % 60;
@@ -785,9 +866,9 @@ ConvertLocalToUTCUsingC(
timeVal.tm_wday = -1;
timeVal.tm_yday = -1;
- /*
- * Get local time. It is rumored that mktime is not thread safe
- * on some platforms, so seize a mutex before attempting this.
+ /*
+ * Get local time. It is rumored that mktime is not thread safe on some
+ * platforms, so seize a mutex before attempting this.
*/
TzsetIfNecessary();
@@ -797,13 +878,14 @@ ConvertLocalToUTCUsingC(
localErrno = errno;
Tcl_MutexUnlock(&clockMutex);
- /* If conversion fails, report an error */
+ /*
+ * If conversion fails, report an error.
+ */
if (localErrno != 0
- || (fields->seconds == -1 && timeVal.tm_yday == -1)) {
- Tcl_SetObjResult(interp,
- Tcl_NewStringObj( "time value too large/small to "
- "represent", -1));
+ || (fields->seconds == -1 && timeVal.tm_yday == -1)) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "time value too large/small to represent", -1));
return TCL_ERROR;
}
return TCL_OK;
@@ -814,8 +896,7 @@ ConvertLocalToUTCUsingC(
*
* ConvertUTCToLocal --
*
- * Converts a time (in a TclDateFields structure) from UTC to
- * local time.
+ * Converts a time (in a TclDateFields structure) from UTC to local time.
*
* Results:
* Returns a standard Tcl result.
@@ -828,21 +909,23 @@ ConvertLocalToUTCUsingC(
static int
ConvertUTCToLocal(
- Tcl_Interp* interp, /* Tcl interpreter */
- TclDateFields* fields, /* Fields of the time */
- Tcl_Obj* tzdata, /* Time zone data */
- int changeover /* Julian Day of the Gregorian transition */
-) {
+ Tcl_Interp *interp, /* Tcl interpreter */
+ TclDateFields *fields, /* Fields of the time */
+ Tcl_Obj *tzdata, /* Time zone data */
+ int changeover) /* Julian Day of the Gregorian transition */
+{
int rowc; /* Number of rows in tzdata */
- Tcl_Obj** rowv; /* Pointers to the rows */
+ Tcl_Obj **rowv; /* Pointers to the rows */
- /* unpack the tz data */
+ /*
+ * Unpack the tz data.
+ */
- if (Tcl_ListObjGetElements(interp, tzdata, &rowc, &rowv) != TCL_OK) {
+ if (TclListObjGetElements(interp, tzdata, &rowc, &rowv) != TCL_OK) {
return TCL_ERROR;
}
- /*
+ /*
* Special case: If the time zone is :localtime, the tzdata will be empty.
* Use 'localtime' to convert the time to local
*/
@@ -852,7 +935,6 @@ ConvertUTCToLocal(
} else {
return ConvertUTCToLocalUsingTable(interp, fields, rowc, rowv);
}
-
}
/*
@@ -867,36 +949,38 @@ ConvertUTCToLocal(
*
* Side effects:
* On success, fills fields->tzName, fields->tzOffset and
- * fields->localSeconds. On failure, places an error message in
- * the interpreter result.
+ * fields->localSeconds. On failure, places an error message in the
+ * interpreter result.
*
*----------------------------------------------------------------------
*/
static int
ConvertUTCToLocalUsingTable(
- Tcl_Interp* interp, /* Tcl interpreter */
- TclDateFields* fields, /* Fields of the date */
+ Tcl_Interp *interp, /* Tcl interpreter */
+ TclDateFields *fields, /* Fields of the date */
int rowc, /* Number of rows in the conversion table
* (>= 1) */
- Tcl_Obj *CONST rowv[] /* Rows of the conversion table */
-) {
-
- Tcl_Obj* row; /* Row containing the current information */
- int cellc; /* Count of cells in the row (must be 4) */
- Tcl_Obj** cellv; /* Pointers to the cells */
+ Tcl_Obj *const rowv[]) /* Rows of the conversion table */
+{
+ Tcl_Obj *row; /* Row containing the current information */
+ int cellc; /* Count of cells in the row (must be 4) */
+ Tcl_Obj **cellv; /* Pointers to the cells */
- /* Look up the nearest transition time */
+ /*
+ * Look up the nearest transition time.
+ */
row = LookupLastTransition(interp, fields->seconds, rowc, rowv);
- if (row == NULL
- || (Tcl_ListObjGetElements(interp, row, &cellc, &cellv) != TCL_OK)
- || (Tcl_GetIntFromObj(interp, cellv[1], &(fields->tzOffset))
- != TCL_OK)) {
+ if (row == NULL ||
+ TclListObjGetElements(interp, row, &cellc, &cellv) != TCL_OK ||
+ TclGetIntFromObj(interp, cellv[1], &fields->tzOffset) != TCL_OK) {
return TCL_ERROR;
}
- /* Convert the time */
+ /*
+ * Convert the time.
+ */
fields->tzName = cellv[3];
Tcl_IncrRefCount(fields->tzName);
@@ -909,53 +993,55 @@ ConvertUTCToLocalUsingTable(
*
* ConvertUTCToLocalUsingC --
*
- * Converts UTC to localtime in cases where the local time zone is
- * not determinable, using the C 'localtime' function to do it.
+ * Converts UTC to localtime in cases where the local time zone is not
+ * determinable, using the C 'localtime' function to do it.
*
* Results:
* Returns a standard Tcl result.
*
* Side effects:
* On success, fills fields->tzName, fields->tzOffset and
- * fields->localSeconds. On failure, places an error message in
- * the interpreter result.
+ * fields->localSeconds. On failure, places an error message in the
+ * interpreter result.
*
*----------------------------------------------------------------------
*/
-
+
static int
ConvertUTCToLocalUsingC(
- Tcl_Interp* interp, /* Tcl interpreter */
- TclDateFields* fields, /* Time to convert, with 'seconds' filled in */
- int changeover /* Julian Day of the Gregorian transition */
-) {
-
+ Tcl_Interp *interp, /* Tcl interpreter */
+ TclDateFields *fields, /* Time to convert, with 'seconds' filled in */
+ int changeover) /* Julian Day of the Gregorian transition */
+{
time_t tock;
- struct tm* timeVal; /* Time after conversion */
+ struct tm *timeVal; /* Time after conversion */
int diff; /* Time zone diff local-Greenwich */
char buffer[8]; /* Buffer for time zone name */
- /* Use 'localtime' to determine local year, month, day, time of day. */
+ /*
+ * Use 'localtime' to determine local year, month, day, time of day.
+ */
tock = (time_t) fields->seconds;
if ((Tcl_WideInt) tock != fields->seconds) {
- Tcl_AppendResult(interp,
- "number too large to represent as a Posix time",
- NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "number too large to represent as a Posix time", -1));
Tcl_SetErrorCode(interp, "CLOCK", "argTooLarge", NULL);
return TCL_ERROR;
}
TzsetIfNecessary();
timeVal = ThreadSafeLocalTime(&tock);
if (timeVal == NULL) {
- Tcl_AppendResult(interp,
- "localtime failed (clock value may be too ",
- "large/small to represent)", NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "localtime failed (clock value may be too "
+ "large/small to represent)", -1));
Tcl_SetErrorCode(interp, "CLOCK", "localtimeFailed", NULL);
return TCL_ERROR;
}
- /* Fill in the date in 'fields' and use it to derive Julian Day */
+ /*
+ * Fill in the date in 'fields' and use it to derive Julian Day.
+ */
fields->era = CE;
fields->year = timeVal->tm_year + 1900;
@@ -963,14 +1049,17 @@ ConvertUTCToLocalUsingC(
fields->dayOfMonth = timeVal->tm_mday;
GetJulianDayFromEraYearMonthDay(fields, changeover);
- /* Convert that value to seconds */
-
+ /*
+ * Convert that value to seconds.
+ */
+
fields->localSeconds = (((fields->julianDay * (Tcl_WideInt) 24
- + timeVal->tm_hour) * 60
- + timeVal->tm_min) * 60
- + timeVal->tm_sec) - JULIAN_SEC_POSIX_EPOCH;
-
- /* Determine a time zone offset and name; just use +hhmm for the name */
+ + timeVal->tm_hour) * 60 + timeVal->tm_min) * 60
+ + timeVal->tm_sec) - JULIAN_SEC_POSIX_EPOCH;
+
+ /*
+ * Determine a time zone offset and name; just use +hhmm for the name.
+ */
diff = (int) (fields->localSeconds - fields->seconds);
fields->tzOffset = diff;
@@ -997,8 +1086,8 @@ ConvertUTCToLocalUsingC(
*
* LookupLastTransition --
*
- * Given a UTC time and a tzdata array, looks up the last
- * transition on or before the given time.
+ * Given a UTC time and a tzdata array, looks up the last transition on
+ * or before the given time.
*
* Results:
* Returns a pointer to the row, or NULL if an error occurs.
@@ -1006,33 +1095,37 @@ ConvertUTCToLocalUsingC(
*----------------------------------------------------------------------
*/
-static Tcl_Obj*
+static Tcl_Obj *
LookupLastTransition(
- Tcl_Interp* interp, /* Interpreter for error messages */
+ Tcl_Interp *interp, /* Interpreter for error messages */
Tcl_WideInt tick, /* Time from the epoch */
int rowc, /* Number of rows of tzdata */
- Tcl_Obj *CONST * rowv) /* Rows in tzdata */
+ Tcl_Obj *const *rowv) /* Rows in tzdata */
{
int l;
int u;
- Tcl_Obj* compObj;
+ Tcl_Obj *compObj;
Tcl_WideInt compVal;
- /* Examine the first row to make sure we're in bounds */
+ /*
+ * Examine the first row to make sure we're in bounds.
+ */
if (Tcl_ListObjIndex(interp, rowv[0], 0, &compObj) != TCL_OK
- || Tcl_GetWideIntFromObj(interp, compObj, &compVal) != TCL_OK) {
+ || Tcl_GetWideIntFromObj(interp, compObj, &compVal) != TCL_OK) {
return NULL;
}
- /*
- * Bizarre case - first row doesn't begin at MIN_WIDE_INT.
- * Return it anyway.
+
+ /*
+ * Bizarre case - first row doesn't begin at MIN_WIDE_INT. Return it
+ * anyway.
*/
+
if (tick < compVal) {
return rowv[0];
}
- /*
+ /*
* Binary-search to find the transition.
*/
@@ -1040,8 +1133,9 @@ LookupLastTransition(
u = rowc-1;
while (l < u) {
int m = (l + u + 1) / 2;
- if (Tcl_ListObjIndex(interp, rowv[m], 0, &compObj) != TCL_OK
- || Tcl_GetWideIntFromObj(interp, compObj, &compVal) != TCL_OK) {
+
+ if (Tcl_ListObjIndex(interp, rowv[m], 0, &compObj) != TCL_OK ||
+ Tcl_GetWideIntFromObj(interp, compObj, &compVal) != TCL_OK) {
return NULL;
}
if (tick >= compVal) {
@@ -1051,7 +1145,6 @@ LookupLastTransition(
}
}
return rowv[l];
-
}
/*
@@ -1059,30 +1152,30 @@ LookupLastTransition(
*
* GetYearWeekDay --
*
- * Given a date with Julian Calendar Day, compute the year, week,
- * and day in the ISO8601 calendar.
+ * Given a date with Julian Calendar Day, compute the year, week, and day
+ * in the ISO8601 calendar.
*
* Results:
* None.
*
* Side effects:
- * Stores 'iso8601Year', 'iso8601Week' and 'dayOfWeek' in
- * the date fields.
+ * Stores 'iso8601Year', 'iso8601Week' and 'dayOfWeek' in the date
+ * fields.
*
*----------------------------------------------------------------------
*/
static void
GetYearWeekDay(
- TclDateFields* fields, /* Date to convert, must have 'julianDay' */
- int changeover /* Julian Day Number of the Gregorian
+ TclDateFields *fields, /* Date to convert, must have 'julianDay' */
+ int changeover) /* Julian Day Number of the Gregorian
* transition */
-) {
+{
TclDateFields temp;
int dayOfFiscalYear;
- /*
- * Find the given date, minus three days, plus one year. That date's
+ /*
+ * Find the given date, minus three days, plus one year. That date's
* iso8601 year is an upper bound on the ISO8601 year of the given date.
*/
@@ -1097,10 +1190,10 @@ GetYearWeekDay(
temp.dayOfWeek = 1;
GetJulianDayFromEraYearWeekDay(&temp, changeover);
- /*
- * temp.julianDay is now the start of an ISO8601 year, either the
- * one corresponding to the given date, or the one after. If we guessed
- * high, move one year earlier
+ /*
+ * temp.julianDay is now the start of an ISO8601 year, either the one
+ * corresponding to the given date, or the one after. If we guessed high,
+ * move one year earlier
*/
if (fields->julianDay < temp.julianDay) {
@@ -1126,10 +1219,9 @@ GetYearWeekDay(
*
* GetGregorianEraYearDay --
*
- * Given a Julian Day Number, extracts the year and day of the
- * year and puts them into TclDateFields, along with the era
- * (BCE or CE) and a flag indicating whether the date is Gregorian
- * or Julian.
+ * Given a Julian Day Number, extracts the year and day of the year and
+ * puts them into TclDateFields, along with the era (BCE or CE) and a
+ * flag indicating whether the date is Gregorian or Julian.
*
* Results:
* None.
@@ -1142,29 +1234,34 @@ GetYearWeekDay(
static void
GetGregorianEraYearDay(
- TclDateFields* fields, /* Date fields containing 'julianDay' */
- int changeover /* Gregorian transition date */
-) {
+ TclDateFields *fields, /* Date fields containing 'julianDay' */
+ int changeover) /* Gregorian transition date */
+{
int jday = fields->julianDay;
int day;
int year;
int n;
if (jday >= changeover) {
-
- /* Gregorian calendar */
+ /*
+ * Gregorian calendar.
+ */
fields->gregorian = 1;
year = 1;
- /*
+ /*
* n = Number of 400-year cycles since 1 January, 1 CE in the
- * proleptic Gregorian calendar. day = remaining days.
+ * proleptic Gregorian calendar. day = remaining days.
*/
day = jday - JDAY_1_JAN_1_CE_GREGORIAN;
n = day / FOUR_CENTURIES;
day %= FOUR_CENTURIES;
+ if (day < 0) {
+ day += FOUR_CENTURIES;
+ n--;
+ }
year += 400 * n;
/*
@@ -1175,42 +1272,57 @@ GetGregorianEraYearDay(
n = day / ONE_CENTURY_GREGORIAN;
day %= ONE_CENTURY_GREGORIAN;
if (n > 3) {
- /* 31 December in the last year of a 400-year cycle */
+ /*
+ * 31 December in the last year of a 400-year cycle.
+ */
+
n = 3;
day += ONE_CENTURY_GREGORIAN;
}
year += 100 * n;
-
} else {
-
- /* Julian calendar */
+ /*
+ * Julian calendar.
+ */
fields->gregorian = 0;
year = 1;
day = jday - JDAY_1_JAN_1_CE_JULIAN;
-
}
- /* n = number of 4-year cycles; days = remaining days */
+ /*
+ * n = number of 4-year cycles; days = remaining days.
+ */
n = day / FOUR_YEARS;
- day %= 1461;
+ day %= FOUR_YEARS;
+ if (day < 0) {
+ day += FOUR_YEARS;
+ n--;
+ }
year += 4 * n;
- /* n = number of years; days = remaining days */
+ /*
+ * n = number of years; days = remaining days.
+ */
n = day / ONE_YEAR;
day %= ONE_YEAR;
if (n > 3) {
- /* 31 December of a leap year */
+ /*
+ * 31 December of a leap year.
+ */
+
n = 3;
day += 365;
}
year += n;
- /* store era/year/day back into fields */
+ /*
+ * store era/year/day back into fields.
+ */
- if (year < 0) {
+ if (year <= 0) {
fields->era = BCE;
fields->year = 1 - year;
} else {
@@ -1218,7 +1330,6 @@ GetGregorianEraYearDay(
fields->year = year;
}
fields->dayOfYear = day + 1;
-
}
/*
@@ -1239,11 +1350,12 @@ GetGregorianEraYearDay(
static void
GetMonthDay(
- TclDateFields* fields /* Date to convert */
-) {
+ TclDateFields *fields) /* Date to convert */
+{
int day = fields->dayOfYear;
int month;
- const int* h = hath[IsGregorianLeapYear(fields)];
+ const int *h = hath[IsGregorianLeapYear(fields)];
+
for (month = 0; month < 12 && day > h[month]; ++month) {
day -= h[month];
}
@@ -1256,8 +1368,8 @@ GetMonthDay(
*
* GetJulianDayFromEraYearWeekDay --
*
- * Given a TclDateFields structure containing era, ISO8601 year,
- * ISO8601 week, and day of week, computes the Julian Day Number.
+ * Given a TclDateFields structure containing era, ISO8601 year, ISO8601
+ * week, and day of week, computes the Julian Day Number.
*
* Results:
* None.
@@ -1270,32 +1382,36 @@ GetMonthDay(
static void
GetJulianDayFromEraYearWeekDay(
- TclDateFields* fields, /* Date to convert */
- int changeover /* Julian Day Number of the
- * Gregorian transition */
-) {
-
- int firstMonday; /* Julian day number of week 1, day 1
- * in the given year */
+ TclDateFields *fields, /* Date to convert */
+ int changeover) /* Julian Day Number of the Gregorian
+ * transition */
+{
+ int firstMonday; /* Julian day number of week 1, day 1 in the
+ * given year */
+ TclDateFields firstWeek;
- /* Find January 4 in the ISO8601 year, which will always be in week 1 */
+ /*
+ * Find January 4 in the ISO8601 year, which will always be in week 1.
+ */
- TclDateFields firstWeek;
firstWeek.era = fields->era;
firstWeek.year = fields->iso8601Year;
firstWeek.month = 1;
firstWeek.dayOfMonth = 4;
GetJulianDayFromEraYearMonthDay(&firstWeek, changeover);
- /* Find Monday of week 1. */
+ /*
+ * Find Monday of week 1.
+ */
firstMonday = WeekdayOnOrBefore(1, firstWeek.julianDay);
- /* Advance to the given week and day */
+ /*
+ * Advance to the given week and day.
+ */
fields->julianDay = firstMonday + 7 * (fields->iso8601Week - 1)
- + fields->dayOfWeek - 1;
-
+ + fields->dayOfWeek - 1;
}
/*
@@ -1303,8 +1419,8 @@ GetJulianDayFromEraYearWeekDay(
*
* GetJulianDayFromEraYearMonthDay --
*
- * Given era, year, month, and dayOfMonth (in TclDateFields), and
- * the Gregorian transition date, computes the Julian Day Number.
+ * Given era, year, month, and dayOfMonth (in TclDateFields), and the
+ * Gregorian transition date, computes the Julian Day Number.
*
* Results:
* None.
@@ -1317,12 +1433,10 @@ GetJulianDayFromEraYearWeekDay(
static void
GetJulianDayFromEraYearMonthDay(
- TclDateFields* fields, /* Date to convert */
- int changeover /* Gregorian transition date as a Julian Day */
-) {
- int year; int ym1;
- int month; int mm1;
- int q; int r;
+ TclDateFields *fields, /* Date to convert */
+ int changeover) /* Gregorian transition date as a Julian Day */
+{
+ int year, ym1, month, mm1, q, r, ym1o4, ym1o100, ym1o400;
if (fields->era == BCE) {
year = 1 - fields->year;
@@ -1330,7 +1444,9 @@ GetJulianDayFromEraYearMonthDay(
year = fields->year;
}
- /* Reduce month modulo 12 */
+ /*
+ * Reduce month modulo 12.
+ */
month = fields->month;
mm1 = month - 1;
@@ -1343,8 +1459,10 @@ GetJulianDayFromEraYearMonthDay(
year += q;
month = r + 1;
ym1 = year - 1;
-
- /* Adjust the year after reducing the month */
+
+ /*
+ * Adjust the year after reducing the month.
+ */
fields->gregorian = 1;
if (year < 1) {
@@ -1355,30 +1473,43 @@ GetJulianDayFromEraYearMonthDay(
fields->year = year;
}
- /* Try an initial conversion in the Gregorian calendar */
+ /*
+ * Try an initial conversion in the Gregorian calendar.
+ */
+ ym1o4 = ym1 / 4;
+ if (ym1 % 4 < 0) {
+ ym1o4--;
+ }
+ ym1o100 = ym1 / 100;
+ if (ym1 % 100 < 0) {
+ ym1o100--;
+ }
+ ym1o400 = ym1 / 400;
+ if (ym1 % 400 < 0) {
+ ym1o400--;
+ }
fields->julianDay = JDAY_1_JAN_1_CE_GREGORIAN - 1
- + fields->dayOfMonth
- + daysInPriorMonths[IsGregorianLeapYear(fields)][month - 1]
- + (ONE_YEAR * ym1)
- + (ym1 / 4)
- - (ym1 / 100)
- + (ym1 / 400);
-
- /*
- * If the resulting date is before the Gregorian changeover, convert
- * in the Julian calendar instead.
+ + fields->dayOfMonth
+ + daysInPriorMonths[IsGregorianLeapYear(fields)][month - 1]
+ + (ONE_YEAR * ym1)
+ + ym1o4
+ - ym1o100
+ + ym1o400;
+
+ /*
+ * If the resulting date is before the Gregorian changeover, convert in
+ * the Julian calendar instead.
*/
if (fields->julianDay < changeover) {
fields->gregorian = 0;
fields->julianDay = JDAY_1_JAN_1_CE_JULIAN - 1
- + fields->dayOfMonth
- + daysInPriorMonths[year%4 == 0][month - 1]
- + (365 * ym1)
- + (ym1 / 4);
+ + fields->dayOfMonth
+ + daysInPriorMonths[year%4 == 0][month - 1]
+ + (365 * ym1)
+ + ym1o4;
}
-
}
/*
@@ -1386,8 +1517,8 @@ GetJulianDayFromEraYearMonthDay(
*
* IsGregorianLeapYear --
*
- * Tests whether a given year is a leap year, in either Julian
- * or Gregorian calendar.
+ * Tests whether a given year is a leap year, in either Julian or
+ * Gregorian calendar.
*
* Results:
* Returns 1 for a leap year, 0 otherwise.
@@ -1397,9 +1528,10 @@ GetJulianDayFromEraYearMonthDay(
static int
IsGregorianLeapYear(
- TclDateFields* fields /* Date to test */
-) {
+ TclDateFields *fields) /* Date to test */
+{
int year;
+
if (fields->era == BCE) {
year = 1 - fields->year;
} else {
@@ -1423,8 +1555,8 @@ IsGregorianLeapYear(
*
* WeekdayOnOrBefore --
*
- * Finds the Julian Day Number of a given day of the week that
- * falls on or before a given date, expressed as Julian Day Number.
+ * Finds the Julian Day Number of a given day of the week that falls on
+ * or before a given date, expressed as Julian Day Number.
*
* Results:
* Returns the Julian Day Number
@@ -1435,9 +1567,12 @@ IsGregorianLeapYear(
static int
WeekdayOnOrBefore(
int dayOfWeek, /* Day of week; Sunday == 0 or 7 */
- int julianDay /* Reference date */
-) {
+ int julianDay) /* Reference date */
+{
int k = (dayOfWeek + 6) % 7;
+ if (k < 0) {
+ k += 7;
+ }
return julianDay - ((julianDay - k) % 7);
}
@@ -1455,10 +1590,9 @@ WeekdayOnOrBefore(
* NAME - Name of the environment variable desired
*
* Results:
- * Returns a standard Tcl result. Returns an error if the
- * variable does not exist, with a message left in the interpreter.
- * Returns TCL_OK and the value of the variable if the variable
- * does exist,
+ * Returns a standard Tcl result. Returns an error if the variable does
+ * not exist, with a message left in the interpreter. Returns TCL_OK and
+ * the value of the variable if the variable does exist,
*
*----------------------------------------------------------------------
*/
@@ -1466,19 +1600,18 @@ WeekdayOnOrBefore(
int
ClockGetenvObjCmd(
ClientData clientData,
- Tcl_Interp* interp,
+ Tcl_Interp *interp,
int objc,
- Tcl_Obj *CONST objv[])
+ Tcl_Obj *const objv[])
{
-
- CONST char* varName;
- CONST char* varValue;
+ const char *varName;
+ const char *varValue;
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "name");
return TCL_ERROR;
}
- varName = Tcl_GetStringFromObj(objv[1], NULL);
+ varName = TclGetString(objv[1]);
varValue = getenv(varName);
if (varValue == NULL) {
varValue = "";
@@ -1506,15 +1639,14 @@ ClockGetenvObjCmd(
static struct tm *
ThreadSafeLocalTime(
- CONST time_t *timePtr) /* Pointer to the number of seconds since the
+ const time_t *timePtr) /* Pointer to the number of seconds since the
* local system's epoch */
{
/*
* Get a thread-local buffer to hold the returned time.
*/
- struct tm *tmPtr = (struct tm *)
- Tcl_GetThreadData(&tmKey, (int) sizeof(struct tm));
+ struct tm *tmPtr = Tcl_GetThreadData(&tmKey, (int) sizeof(struct tm));
#ifdef HAVE_LOCALTIME_R
localtime_r(timePtr, tmPtr);
#else
@@ -1525,10 +1657,9 @@ ThreadSafeLocalTime(
if (sysTmPtr == NULL) {
Tcl_MutexUnlock(&clockMutex);
return NULL;
- } else {
- memcpy((VOID *) tmPtr, (VOID *) localtime(timePtr), sizeof(struct tm));
- Tcl_MutexUnlock(&clockMutex);
}
+ memcpy(tmPtr, localtime(timePtr), sizeof(struct tm));
+ Tcl_MutexUnlock(&clockMutex);
#endif
return tmPtr;
}
@@ -1554,50 +1685,53 @@ ThreadSafeLocalTime(
int
ClockClicksObjCmd(
ClientData clientData, /* Client data is unused */
- Tcl_Interp* interp, /* Tcl interpreter */
+ Tcl_Interp *interp, /* Tcl interpreter */
int objc, /* Parameter count */
- Tcl_Obj* CONST* objv) /* Parameter values */
+ Tcl_Obj *const *objv) /* Parameter values */
{
- static CONST char *clicksSwitches[] = {
+ static const char *const clicksSwitches[] = {
"-milliseconds", "-microseconds", NULL
};
enum ClicksSwitch {
- CLICKS_MILLIS, CLICKS_MICROS, CLICKS_NATIVE
+ CLICKS_MILLIS, CLICKS_MICROS, CLICKS_NATIVE
};
int index = CLICKS_NATIVE;
Tcl_Time now;
+ Tcl_WideInt clicks = 0;
switch (objc) {
case 1:
break;
case 2:
- if (Tcl_GetIndexFromObj(interp, objv[1], clicksSwitches, "option", 0,
+ if (Tcl_GetIndexFromObj(interp, objv[1], clicksSwitches, "switch", 0,
&index) != TCL_OK) {
return TCL_ERROR;
}
break;
default:
- Tcl_WrongNumArgs(interp, 1, objv, "?option?");
+ Tcl_WrongNumArgs(interp, 1, objv, "?-switch?");
return TCL_ERROR;
}
switch (index) {
case CLICKS_MILLIS:
Tcl_GetTime(&now);
- Tcl_SetObjResult(interp, Tcl_NewWideIntObj( (Tcl_WideInt)
- now.sec * 1000 + now.usec / 1000 ) );
+ clicks = (Tcl_WideInt) now.sec * 1000 + now.usec / 1000;
break;
case CLICKS_NATIVE:
- Tcl_SetObjResult(interp, Tcl_NewWideIntObj( (Tcl_WideInt)
- TclpGetClicks()));
+#ifdef TCL_WIDE_CLICKS
+ clicks = TclpGetWideClicks();
+#else
+ clicks = (Tcl_WideInt) TclpGetClicks();
+#endif
break;
case CLICKS_MICROS:
Tcl_GetTime(&now);
- Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
- ((Tcl_WideInt) now.sec * 1000000) + now.usec));
+ clicks = ((Tcl_WideInt) now.sec * 1000000) + now.usec;
break;
}
+ Tcl_SetObjResult(interp, Tcl_NewWideIntObj(clicks));
return TCL_OK;
}
@@ -1622,9 +1756,9 @@ ClockClicksObjCmd(
int
ClockMillisecondsObjCmd(
ClientData clientData, /* Client data is unused */
- Tcl_Interp* interp, /* Tcl interpreter */
+ Tcl_Interp *interp, /* Tcl interpreter */
int objc, /* Parameter count */
- Tcl_Obj* CONST* objv) /* Parameter values */
+ Tcl_Obj *const *objv) /* Parameter values */
{
Tcl_Time now;
@@ -1633,7 +1767,7 @@ ClockMillisecondsObjCmd(
return TCL_ERROR;
}
Tcl_GetTime(&now);
- Tcl_SetObjResult(interp, Tcl_NewWideIntObj( (Tcl_WideInt)
+ Tcl_SetObjResult(interp, Tcl_NewWideIntObj((Tcl_WideInt)
now.sec * 1000 + now.usec / 1000));
return TCL_OK;
}
@@ -1659,9 +1793,9 @@ ClockMillisecondsObjCmd(
int
ClockMicrosecondsObjCmd(
ClientData clientData, /* Client data is unused */
- Tcl_Interp* interp, /* Tcl interpreter */
+ Tcl_Interp *interp, /* Tcl interpreter */
int objc, /* Parameter count */
- Tcl_Obj* CONST* objv) /* Parameter values */
+ Tcl_Obj *const *objv) /* Parameter values */
{
Tcl_Time now;
@@ -1675,6 +1809,124 @@ ClockMicrosecondsObjCmd(
return TCL_OK;
}
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * ClockParseformatargsObjCmd --
+ *
+ * Parses the arguments for [clock format].
+ *
+ * Results:
+ * Returns a standard Tcl result, whose value is a four-element list
+ * comprising the time format, the locale, and the timezone.
+ *
+ * This function exists because the loop that parses the [clock format]
+ * options is a known performance "hot spot", and is implemented in an effort
+ * to speed that particular code up.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+ClockParseformatargsObjCmd(
+ ClientData clientData, /* Client data containing literal pool */
+ Tcl_Interp *interp, /* Tcl interpreter */
+ int objc, /* Parameter count */
+ Tcl_Obj *const objv[]) /* Parameter vector */
+{
+ ClockClientData *dataPtr = clientData;
+ Tcl_Obj **litPtr = dataPtr->literals;
+ Tcl_Obj *results[3]; /* Format, locale and timezone */
+#define formatObj results[0]
+#define localeObj results[1]
+#define timezoneObj results[2]
+ int gmtFlag = 0;
+ static const char *const options[] = { /* Command line options expected */
+ "-format", "-gmt", "-locale",
+ "-timezone", NULL };
+ enum optionInd {
+ CLOCK_FORMAT_FORMAT, CLOCK_FORMAT_GMT, CLOCK_FORMAT_LOCALE,
+ CLOCK_FORMAT_TIMEZONE
+ };
+ int optionIndex; /* Index of an option. */
+ int saw = 0; /* Flag == 1 if option was seen already. */
+ Tcl_WideInt clockVal; /* Clock value - just used to parse. */
+ int i;
+
+ /*
+ * Args consist of a time followed by keyword-value pairs.
+ */
+
+ if (objc < 2 || (objc % 2) != 0) {
+ Tcl_WrongNumArgs(interp, 0, objv,
+ "clock format clockval ?-format string? "
+ "?-gmt boolean? ?-locale LOCALE? ?-timezone ZONE?");
+ Tcl_SetErrorCode(interp, "CLOCK", "wrongNumArgs", NULL);
+ return TCL_ERROR;
+ }
+
+ /*
+ * Extract values for the keywords.
+ */
+
+ formatObj = litPtr[LIT__DEFAULT_FORMAT];
+ localeObj = litPtr[LIT_C];
+ timezoneObj = litPtr[LIT__NIL];
+ for (i = 2; i < objc; i+=2) {
+ if (Tcl_GetIndexFromObj(interp, objv[i], options, "switch", 0,
+ &optionIndex) != TCL_OK) {
+ Tcl_SetErrorCode(interp, "CLOCK", "badSwitch",
+ Tcl_GetString(objv[i]), NULL);
+ return TCL_ERROR;
+ }
+ switch (optionIndex) {
+ case CLOCK_FORMAT_FORMAT:
+ formatObj = objv[i+1];
+ break;
+ case CLOCK_FORMAT_GMT:
+ if (Tcl_GetBooleanFromObj(interp, objv[i+1], &gmtFlag) != TCL_OK){
+ return TCL_ERROR;
+ }
+ break;
+ case CLOCK_FORMAT_LOCALE:
+ localeObj = objv[i+1];
+ break;
+ case CLOCK_FORMAT_TIMEZONE:
+ timezoneObj = objv[i+1];
+ break;
+ }
+ saw |= 1 << optionIndex;
+ }
+
+ /*
+ * Check options.
+ */
+
+ if (Tcl_GetWideIntFromObj(interp, objv[1], &clockVal) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if ((saw & (1 << CLOCK_FORMAT_GMT))
+ && (saw & (1 << CLOCK_FORMAT_TIMEZONE))) {
+ Tcl_SetObjResult(interp, litPtr[LIT_CANNOT_USE_GMT_AND_TIMEZONE]);
+ Tcl_SetErrorCode(interp, "CLOCK", "gmtWithTimezone", NULL);
+ return TCL_ERROR;
+ }
+ if (gmtFlag) {
+ timezoneObj = litPtr[LIT_GMT];
+ }
+
+ /*
+ * Return options as a list.
+ */
+
+ Tcl_SetObjResult(interp, Tcl_NewListObj(3, results));
+ return TCL_OK;
+
+#undef timezoneObj
+#undef localeObj
+#undef formatObj
+}
+
/*----------------------------------------------------------------------
*
* ClockSecondsObjCmd -
@@ -1696,9 +1948,9 @@ ClockMicrosecondsObjCmd(
int
ClockSecondsObjCmd(
ClientData clientData, /* Client data is unused */
- Tcl_Interp* interp, /* Tcl interpreter */
+ Tcl_Interp *interp, /* Tcl interpreter */
int objc, /* Parameter count */
- Tcl_Obj* CONST* objv) /* Parameter values */
+ Tcl_Obj *const *objv) /* Parameter values */
{
Tcl_Time now;
@@ -1731,9 +1983,9 @@ ClockSecondsObjCmd(
static void
TzsetIfNecessary(void)
{
- static char* tzWas = NULL; /* Previous value of TZ, protected by
+ static char *tzWas = NULL; /* Previous value of TZ, protected by
* clockMutex. */
- CONST char* tzIsNow; /* Current value of TZ */
+ const char *tzIsNow; /* Current value of TZ */
Tcl_MutexLock(&clockMutex);
tzIsNow = getenv("TZ");
@@ -1767,18 +2019,19 @@ TzsetIfNecessary(void)
*/
static void
-ClockDeleteCmdProc(ClientData clientData)
- /* Opaque pointer to the client data */
+ClockDeleteCmdProc(
+ ClientData clientData) /* Opaque pointer to the client data */
{
- ClockClientData *data = (ClockClientData*) clientData;
+ ClockClientData *data = clientData;
int i;
- --(data->refCount);
+
+ data->refCount--;
if (data->refCount == 0) {
for (i = 0; i < LIT__END; ++i) {
Tcl_DecrRefCount(data->literals[i]);
}
- ckfree((char*) (data->literals));
- ckfree((char*) data);
+ ckfree(data->literals);
+ ckfree(data);
}
}