summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
Diffstat (limited to 'generic')
-rw-r--r--generic/tclClock.c80
-rw-r--r--generic/tclClockFmt.c4
-rw-r--r--generic/tclDate.h16
3 files changed, 80 insertions, 20 deletions
diff --git a/generic/tclClock.c b/generic/tclClock.c
index 1a5141b..a84300a 100644
--- a/generic/tclClock.c
+++ b/generic/tclClock.c
@@ -383,16 +383,52 @@ NormTimezoneObj(
/*
*----------------------------------------------------------------------
*/
+inline Tcl_Obj *
+ClockGetSystemLocale(
+ ClockClientData *dataPtr, /* Opaque pointer to literal pool, etc. */
+ Tcl_Interp *interp) /* Tcl interpreter */
+{
+ if (Tcl_EvalObjv(interp, 1, &dataPtr->literals[LIT_GETSYSTEMLOCALE], 0) != TCL_OK) {
+ return NULL;
+ }
+
+ return Tcl_GetObjResult(interp);
+}
+/*
+ *----------------------------------------------------------------------
+ */
+inline Tcl_Obj *
+ClockGetCurrentLocale(
+ ClockClientData *dataPtr, /* Client data containing literal pool */
+ Tcl_Interp *interp) /* Tcl interpreter */
+{
+ if (Tcl_EvalObjv(interp, 1, &dataPtr->literals[LIT_GETCURRENTLOCALE], 0) != TCL_OK) {
+ return NULL;
+ }
+
+ Tcl_SetObjRef(dataPtr->CurrentLocale, Tcl_GetObjResult(interp));
+ Tcl_UnsetObjRef(dataPtr->CurrentLocaleDict);
+
+ return dataPtr->CurrentLocale;
+}
+/*
+ *----------------------------------------------------------------------
+ */
static Tcl_Obj *
NormLocaleObj(
- ClockClientData *dataPtr, /* Client data containing literal pool */
+ ClockClientData *dataPtr, /* Client data containing literal pool */
+ Tcl_Interp *interp, /* Tcl interpreter */
Tcl_Obj *localeObj,
Tcl_Obj **mcDictObj)
{
const char *loc;
if ( localeObj == NULL || localeObj == dataPtr->CurrentLocale
- || localeObj == dataPtr->literals[LIT_C]
+ || localeObj == dataPtr->literals[LIT_C]
+ || localeObj == dataPtr->literals[LIT_CURRENT]
) {
+ if (dataPtr->CurrentLocale == NULL) {
+ ClockGetCurrentLocale(dataPtr, interp);
+ }
*mcDictObj = dataPtr->CurrentLocaleDict;
return dataPtr->CurrentLocale;
}
@@ -404,19 +440,23 @@ NormLocaleObj(
}
loc = TclGetString(localeObj);
- if (dataPtr->CurrentLocale != NULL &&
- (localeObj == dataPtr->CurrentLocale
- || strcmp(loc, TclGetString(dataPtr->CurrentLocale)) == 0
+ if ( dataPtr->CurrentLocale != NULL
+ && ( localeObj == dataPtr->CurrentLocale
+ || (localeObj->length == dataPtr->CurrentLocale->length
+ && strcmp(loc, TclGetString(dataPtr->CurrentLocale)) == 0
)
+ )
) {
*mcDictObj = dataPtr->CurrentLocaleDict;
localeObj = dataPtr->CurrentLocale;
}
else
- if (dataPtr->LastUsedLocale != NULL &&
- (localeObj == dataPtr->LastUsedLocale
- || strcmp(loc, TclGetString(dataPtr->LastUsedLocale)) == 0
+ if ( dataPtr->LastUsedLocale != NULL
+ && ( localeObj == dataPtr->LastUsedLocale
+ || (localeObj->length == dataPtr->LastUsedLocale->length
+ && strcmp(loc, TclGetString(dataPtr->LastUsedLocale)) == 0
)
+ )
) {
*mcDictObj = dataPtr->LastUsedLocaleDict;
Tcl_SetObjRef(dataPtr->LastUnnormUsedLocale, localeObj);
@@ -424,12 +464,28 @@ NormLocaleObj(
}
else
if (
- strcmp(loc, Literals[LIT_C]) == 0
+ (localeObj->length == 1 /* C */
+ && strncasecmp(loc, Literals[LIT_C], localeObj->length) == 0)
+ || (localeObj->length == 7 /* current */
+ && strncasecmp(loc, Literals[LIT_CURRENT], localeObj->length) == 0)
) {
+ if (dataPtr->CurrentLocale == NULL) {
+ ClockGetCurrentLocale(dataPtr, interp);
+ }
*mcDictObj = dataPtr->CurrentLocaleDict;
localeObj = dataPtr->CurrentLocale;
}
else
+ if (
+ (localeObj->length == 6 /* system */
+ && strncasecmp(loc, Literals[LIT_SYSTEM], localeObj->length) == 0)
+ ) {
+ Tcl_SetObjRef(dataPtr->LastUnnormUsedLocale, localeObj);
+ localeObj = ClockGetSystemLocale(dataPtr, interp);
+ Tcl_SetObjRef(dataPtr->LastUsedLocale, localeObj);
+ *mcDictObj = NULL;
+ }
+ else
{
*mcDictObj = NULL;
}
@@ -450,7 +506,7 @@ ClockMCDict(ClockFmtScnCmdArgs *opts)
/* if locale was not yet used */
if ( !(opts->flags & CLF_LOCALE_USED) ) {
- opts->localeObj = NormLocaleObj(opts->clientData,
+ opts->localeObj = NormLocaleObj(opts->clientData, opts->interp,
opts->localeObj, &opts->mcDictObj);
if (opts->localeObj == NULL) {
@@ -490,6 +546,8 @@ ClockMCDict(ClockFmtScnCmdArgs *opts)
}
if ( opts->localeObj == dataPtr->CurrentLocale ) {
Tcl_SetObjRef(dataPtr->CurrentLocaleDict, opts->mcDictObj);
+ } else if ( opts->localeObj == dataPtr->LastUsedLocale ) {
+ Tcl_SetObjRef(dataPtr->LastUsedLocaleDict, opts->mcDictObj);
} else {
Tcl_SetObjRef(dataPtr->LastUsedLocale, opts->localeObj);
Tcl_UnsetObjRef(dataPtr->LastUnnormUsedLocale);
@@ -2717,7 +2775,7 @@ _ClockParseFmtScnArgs(
if ((saw & (1 << CLOCK_FORMAT_GMT))
&& (saw & (1 << CLOCK_FORMAT_TIMEZONE))) {
- Tcl_SetObjResult(interp, litPtr[LIT_CANNOT_USE_GMT_AND_TIMEZONE]);
+ Tcl_SetResult(interp, "cannot use -gmt and -timezone in same call", TCL_STATIC);
Tcl_SetErrorCode(interp, "CLOCK", "gmtWithTimezone", NULL);
return TCL_ERROR;
}
diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c
index f965a17..5d3dcaf 100644
--- a/generic/tclClockFmt.c
+++ b/generic/tclClockFmt.c
@@ -1199,7 +1199,9 @@ ClockLocalizeFormat(
clean:
Tcl_UnsetObjRef(keyObj);
- Tcl_ResetResult(opts->interp);
+ if (valObj) {
+ Tcl_ResetResult(opts->interp);
+ }
}
return (opts->formatObj = valObj);
diff --git a/generic/tclDate.h b/generic/tclDate.h
index fc922cb..e78d4f8 100644
--- a/generic/tclDate.h
+++ b/generic/tclDate.h
@@ -58,9 +58,8 @@
typedef enum ClockLiteral {
LIT__NIL,
LIT__DEFAULT_FORMAT,
- LIT_BCE, LIT_C,
- LIT_CANNOT_USE_GMT_AND_TIMEZONE,
- LIT_CE,
+ LIT_SYSTEM, LIT_CURRENT,
+ LIT_BCE, LIT_C, LIT_CE,
LIT_DAYOFMONTH, LIT_DAYOFWEEK, LIT_DAYOFYEAR,
LIT_ERA, LIT_GMT, LIT_GREGORIAN,
LIT_INTEGER_VALUE_TOO_LARGE,
@@ -72,7 +71,8 @@ typedef enum ClockLiteral {
LIT_TZDATA,
LIT_GETSYSTEMTIMEZONE,
LIT_SETUPTIMEZONE,
- LIT_MCGET, LIT_TCL_CLOCK,
+ LIT_MCGET,
+ LIT_GETSYSTEMLOCALE, LIT_GETCURRENTLOCALE,
LIT_LOCALIZE_FORMAT,
LIT__END
} ClockLiteral;
@@ -80,9 +80,8 @@ typedef enum ClockLiteral {
#define CLOCK_LITERAL_ARRAY(litarr) static const char *const litarr[] = { \
"", \
"%a %b %d %H:%M:%S %Z %Y", \
- "BCE", "C", \
- "cannot use -gmt and -timezone in same call", \
- "CE", \
+ "system", "current", \
+ "BCE", "C", "CE", \
"dayOfMonth", "dayOfWeek", "dayOfYear", \
"era", ":GMT", "gregorian", \
"integer value too large to represent", \
@@ -94,7 +93,8 @@ typedef enum ClockLiteral {
"::tcl::clock::TZData", \
"::tcl::clock::GetSystemTimeZone", \
"::tcl::clock::SetupTimeZone", \
- "::tcl::clock::mcget", "::tcl::clock", \
+ "::tcl::clock::mcget", \
+ "::tcl::clock::GetSystemLocale", "::tcl::clock::mclocale", \
"::tcl::clock::LocalizeFormat" \
}