summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2023-06-03 19:51:21 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2023-06-03 19:51:21 (GMT)
commita7e21b7c564f60937d36bef38d68da14d57997fa (patch)
treebe118b0074fe1b8ac46a3c729579824c145d0e80
parenta5297cf7c36358be626614b3363cc68a4d05c4ac (diff)
parent73ff912a1fd8edfb65a5b594ebecfc531eef79fc (diff)
downloadtcl-a7e21b7c564f60937d36bef38d68da14d57997fa.zip
tcl-a7e21b7c564f60937d36bef38d68da14d57997fa.tar.gz
tcl-a7e21b7c564f60937d36bef38d68da14d57997fa.tar.bz2
Fix [af3ebc5fafe0097c]: clock scan and clock add bugs in error cases / with abbreviated options
-rw-r--r--library/clock.tcl135
-rw-r--r--tests/clock.test18
2 files changed, 88 insertions, 65 deletions
diff --git a/library/clock.tcl b/library/clock.tcl
index abe6c81..b9bbc2c 100644
--- a/library/clock.tcl
+++ b/library/clock.tcl
@@ -310,28 +310,28 @@ proc ::tcl::clock::Initialize {} {
{-43200 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Pacific/Kwajalein
{-39600 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Pacific/Midway
{-36000 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Pacific/Honolulu
- {-32400 0 3600 0 11 0 1 2 0 0 0 0 3 0 2 2 0 0 0} :America/Anchorage
- {-28800 0 3600 0 11 0 1 2 0 0 0 0 3 0 2 2 0 0 0} :America/Los_Angeles
- {-28800 0 3600 0 10 0 5 2 0 0 0 0 4 0 1 2 0 0 0} :America/Tijuana
- {-25200 0 3600 0 11 0 1 2 0 0 0 0 3 0 2 2 0 0 0} :America/Denver
- {-25200 0 3600 0 10 0 5 2 0 0 0 0 4 0 1 2 0 0 0} :America/Chihuahua
+ {-32400 0 3600 0 11 0 1 2 0 0 0 0 3 0 2 2 0 0 0} :America/Anchorage
+ {-28800 0 3600 0 11 0 1 2 0 0 0 0 3 0 2 2 0 0 0} :America/Los_Angeles
+ {-28800 0 3600 0 10 0 5 2 0 0 0 0 4 0 1 2 0 0 0} :America/Tijuana
+ {-25200 0 3600 0 11 0 1 2 0 0 0 0 3 0 2 2 0 0 0} :America/Denver
+ {-25200 0 3600 0 10 0 5 2 0 0 0 0 4 0 1 2 0 0 0} :America/Chihuahua
{-25200 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :America/Phoenix
{-21600 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :America/Regina
{-21600 0 3600 0 11 0 1 2 0 0 0 0 3 0 2 2 0 0 0} :America/Chicago
- {-21600 0 3600 0 10 0 5 2 0 0 0 0 4 0 1 2 0 0 0} :America/Mexico_City
+ {-21600 0 3600 0 10 0 5 2 0 0 0 0 4 0 1 2 0 0 0} :America/Mexico_City
{-18000 0 3600 0 11 0 1 2 0 0 0 0 3 0 2 2 0 0 0} :America/New_York
{-18000 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :America/Indianapolis
{-14400 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :America/Caracas
- {-14400 0 3600 0 3 6 2 23 59 59 999 0 10 6 2 23 59 59 999}
+ {-14400 0 3600 0 3 6 2 23 59 59 999 0 10 6 2 23 59 59 999}
:America/Santiago
- {-14400 0 3600 0 2 0 5 2 0 0 0 0 11 0 1 2 0 0 0} :America/Manaus
- {-14400 0 3600 0 11 0 1 2 0 0 0 0 3 0 2 2 0 0 0} :America/Halifax
+ {-14400 0 3600 0 2 0 5 2 0 0 0 0 11 0 1 2 0 0 0} :America/Manaus
+ {-14400 0 3600 0 11 0 1 2 0 0 0 0 3 0 2 2 0 0 0} :America/Halifax
{-12600 0 3600 0 10 0 5 2 0 0 0 0 4 0 1 2 0 0 0} :America/St_Johns
{-10800 0 3600 0 2 0 2 2 0 0 0 0 10 0 3 2 0 0 0} :America/Sao_Paulo
{-10800 0 3600 0 10 0 5 2 0 0 0 0 4 0 1 2 0 0 0} :America/Godthab
{-10800 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :America/Buenos_Aires
- {-10800 0 3600 0 2 0 5 2 0 0 0 0 11 0 1 2 0 0 0} :America/Bahia
- {-10800 0 3600 0 3 0 2 2 0 0 0 0 10 0 1 2 0 0 0} :America/Montevideo
+ {-10800 0 3600 0 2 0 5 2 0 0 0 0 11 0 1 2 0 0 0} :America/Bahia
+ {-10800 0 3600 0 3 0 2 2 0 0 0 0 10 0 1 2 0 0 0} :America/Montevideo
{-7200 0 3600 0 9 0 5 2 0 0 0 0 3 0 5 2 0 0 0} :America/Noronha
{-3600 0 3600 0 10 0 5 3 0 0 0 0 3 0 5 2 0 0 0} :Atlantic/Azores
{-3600 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Atlantic/Cape_Verde
@@ -339,22 +339,22 @@ proc ::tcl::clock::Initialize {} {
{0 0 3600 0 10 0 5 2 0 0 0 0 3 0 5 1 0 0 0} :Europe/London
{3600 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Africa/Kinshasa
{3600 0 3600 0 10 0 5 3 0 0 0 0 3 0 5 2 0 0 0} :CET
- {7200 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Africa/Harare
- {7200 0 3600 0 9 4 5 23 59 59 0 0 4 4 5 23 59 59 0}
+ {7200 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Africa/Harare
+ {7200 0 3600 0 9 4 5 23 59 59 0 0 4 4 5 23 59 59 0}
:Africa/Cairo
{7200 0 3600 0 10 0 5 4 0 0 0 0 3 0 5 3 0 0 0} :Europe/Helsinki
- {7200 0 3600 0 9 0 3 2 0 0 0 0 3 5 5 2 0 0 0} :Asia/Jerusalem
+ {7200 0 3600 0 9 0 3 2 0 0 0 0 3 5 5 2 0 0 0} :Asia/Jerusalem
{7200 0 3600 0 9 0 5 1 0 0 0 0 3 0 5 0 0 0 0} :Europe/Bucharest
{7200 0 3600 0 10 0 5 3 0 0 0 0 3 0 5 2 0 0 0} :Europe/Athens
- {7200 0 3600 0 9 5 5 1 0 0 0 0 3 4 5 0 0 0 0} :Asia/Amman
- {7200 0 3600 0 10 6 5 23 59 59 999 0 3 0 5 0 0 0 0}
+ {7200 0 3600 0 9 5 5 1 0 0 0 0 3 4 5 0 0 0 0} :Asia/Amman
+ {7200 0 3600 0 10 6 5 23 59 59 999 0 3 0 5 0 0 0 0}
:Asia/Beirut
- {7200 0 -3600 0 4 0 1 2 0 0 0 0 9 0 1 2 0 0 0} :Africa/Windhoek
+ {7200 0 -3600 0 4 0 1 2 0 0 0 0 9 0 1 2 0 0 0} :Africa/Windhoek
{10800 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Asia/Riyadh
{10800 0 3600 0 10 0 1 4 0 0 0 0 4 0 1 3 0 0 0} :Asia/Baghdad
{10800 0 3600 0 10 0 5 3 0 0 0 0 3 0 5 2 0 0 0} :Europe/Moscow
{12600 0 3600 0 9 2 4 2 0 0 0 0 3 0 1 2 0 0 0} :Asia/Tehran
- {14400 0 3600 0 10 0 5 5 0 0 0 0 3 0 5 4 0 0 0} :Asia/Baku
+ {14400 0 3600 0 10 0 5 5 0 0 0 0 3 0 5 4 0 0 0} :Asia/Baku
{14400 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Asia/Muscat
{14400 0 3600 0 10 0 5 3 0 0 0 0 3 0 5 2 0 0 0} :Asia/Tbilisi
{16200 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} :Asia/Kabul
@@ -584,8 +584,8 @@ proc ::tcl::clock::Initialize {} {
jst +0900 \
kst +0900 \
cast +0930 \
- jdt +1000 \
- kdt +1000 \
+ jdt +1000 \
+ kdt +1000 \
cadt +1030 \
east +1000 \
eadt +1030 \
@@ -1158,8 +1158,8 @@ proc ::tcl::clock::ParseClockFormatFormat2 {format locale procName} {
}
proc $procName {clockval timezone} "
- $preFormatCode
- return \[::format [list $formatString] $substituents\]
+ $preFormatCode
+ return \[::format [list $formatString] $substituents\]
"
# puts [list $procName [info args $procName] [info body $procName]]
@@ -1173,7 +1173,7 @@ proc ::tcl::clock::ParseClockFormatFormat2 {format locale procName} {
#
# Inputs a count of seconds since the Posix Epoch as a time of day.
#
-# The 'clock format' command scans times of day on input. Refer to the user
+# The 'clock scan' command scans times of day on input. Refer to the user
# documentation to see what it does.
#
#----------------------------------------------------------------------
@@ -1189,10 +1189,10 @@ proc ::tcl::clock::scan { args } {
return -code error \
-errorcode [list CLOCK wrongNumArgs] \
"wrong \# args: should be\
- \"$cmdName string\
- ?-base seconds?\
- ?-format string? ?-gmt boolean?\
- ?-locale LOCALE? ?-timezone ZONE?\""
+ \"$cmdName string\
+ ?-base seconds?\
+ ?-format string? ?-gmt boolean?\
+ ?-locale LOCALE? ?-timezone ZONE?\""
}
# Set defaults
@@ -1207,28 +1207,31 @@ proc ::tcl::clock::scan { args } {
# Pick up command line options.
foreach { flag value } [lreplace $args 0 0] {
- set saw($flag) {}
switch -exact -- $flag {
-b - -ba - -bas - -base {
set base $value
}
-f - -fo - -for - -form - -forma - -format {
+ set saw(-format) {}
set format $value
}
-g - -gm - -gmt {
+ set saw(-gmt) {}
set gmt $value
}
-l - -lo - -loc - -loca - -local - -locale {
+ set saw(-locale) {}
set locale [string tolower $value]
}
-t - -ti - -tim - -time - -timez - -timezo - -timezon - -timezone {
+ set saw(-timezone) {}
set timezone $value
}
default {
return -code error \
-errorcode [list CLOCK badOption $flag] \
"bad option \"$flag\",\
- must be -base, -format, -gmt, -locale or -timezone"
+ must be -base, -format, -gmt, -locale or -timezone"
}
}
}
@@ -1975,7 +1978,7 @@ proc ::tcl::clock::ParseClockScanFormat {formatString locale} {
# being processed - they're always absolute
if { ![dict exists $fieldSet seconds]
- && ![dict exists $fieldSet starDate] } {
+ && ![dict exists $fieldSet starDate] } {
append procBody {
if { [dict get $date julianDay] > 5373484 } {
return -code error -errorcode [list CLOCK dateTooLarge] \
@@ -2379,8 +2382,8 @@ proc ::tcl::clock::LoadWindowsDateTimeFormats { locale } {
M %N
yyyy %Y
yy %y
- y %y
- gg {}
+ y %y
+ gg {}
} $unquoted]
if { $quoted eq {} } {
set quote '
@@ -2409,8 +2412,8 @@ proc ::tcl::clock::LoadWindowsDateTimeFormats { locale } {
M %N
yyyy %Y
yy %y
- y %y
- gg {}
+ y %y
+ gg {}
} $unquoted]
if { $quoted eq {} } {
set quote '
@@ -2989,19 +2992,19 @@ proc ::tcl::clock::GetSystemTimeZone {} {
} elseif {[set result [getenv TZ]] ne {}} {
set timezone $result
} else {
- # Cache the time zone only if it was detected by one of the
- # expensive methods.
- if { [info exists CachedSystemTimeZone] } {
- set timezone $CachedSystemTimeZone
- } elseif { $::tcl_platform(platform) eq {windows} } {
- set timezone [GuessWindowsTimeZone]
- } elseif { [file exists /etc/localtime]
- && ![catch {ReadZoneinfoFile \
- Tcl/Localtime /etc/localtime}] } {
- set timezone :Tcl/Localtime
- } else {
- set timezone :localtime
- }
+ # Cache the time zone only if it was detected by one of the
+ # expensive methods.
+ if { [info exists CachedSystemTimeZone] } {
+ set timezone $CachedSystemTimeZone
+ } elseif { $::tcl_platform(platform) eq {windows} } {
+ set timezone [GuessWindowsTimeZone]
+ } elseif { [file exists /etc/localtime]
+ && ![catch {ReadZoneinfoFile \
+ Tcl/Localtime /etc/localtime}] } {
+ set timezone :Tcl/Localtime
+ } else {
+ set timezone :localtime
+ }
set CachedSystemTimeZone $timezone
}
if { ![dict exists $TimeZoneBad $timezone] } {
@@ -3608,7 +3611,7 @@ proc ::tcl::clock::ParsePosixTimeZone { tz } {
# 4 - Standard time zone offset, minutes
: ([[:digit:]]{1,2})
(?:
- # 5 - Standard time zone offset, seconds
+ # 5 - Standard time zone offset, seconds
: ([[:digit:]]{1,2} )
)?
)?
@@ -3616,7 +3619,7 @@ proc ::tcl::clock::ParsePosixTimeZone { tz } {
# 6 - DST time zone name
([[:alpha:]]+ | <[-+[:alnum:]]+>)
(?:
- (?:
+ (?:
# 7 - DST time zone offset, signum
([-+]?)
# 8 - DST time zone offset, hours
@@ -3625,17 +3628,17 @@ proc ::tcl::clock::ParsePosixTimeZone { tz } {
# 9 - DST time zone offset, minutes
: ([[:digit:]]{1,2})
(?:
- # 10 - DST time zone offset, seconds
+ # 10 - DST time zone offset, seconds
: ([[:digit:]]{1,2})
)?
)?
)?
- (?:
+ (?:
,
(?:
# 11 - Optional J in n and Jn form 12 - Day of year
- ( J ? ) ( [[:digit:]]+ )
- | M
+ ( J ? ) ( [[:digit:]]+ )
+ | M
# 13 - Month number 14 - Week of month 15 - Day of week
( [[:digit:]] + )
[.] ( [[:digit:]] + )
@@ -3644,7 +3647,7 @@ proc ::tcl::clock::ParsePosixTimeZone { tz } {
(?:
# 16 - Start time of DST - hours
/ ( [[:digit:]]{1,2} )
- (?:
+ (?:
# 17 - Start time of DST - minutes
: ( [[:digit:]]{1,2} )
(?:
@@ -3656,8 +3659,8 @@ proc ::tcl::clock::ParsePosixTimeZone { tz } {
,
(?:
# 19 - Optional J in n and Jn form 20 - Day of year
- ( J ? ) ( [[:digit:]]+ )
- | M
+ ( J ? ) ( [[:digit:]]+ )
+ | M
# 21 - Month number 22 - Week of month 23 - Day of week
( [[:digit:]] + )
[.] ( [[:digit:]] + )
@@ -3666,7 +3669,7 @@ proc ::tcl::clock::ParsePosixTimeZone { tz } {
(?:
# 24 - End time of DST - hours
/ ( [[:digit:]]{1,2} )
- (?:
+ (?:
# 25 - End time of DST - minutes
: ( [[:digit:]]{1,2} )
(?:
@@ -3675,9 +3678,9 @@ proc ::tcl::clock::ParsePosixTimeZone { tz } {
)?
)?
)?
- )?
+ )?
)?
- )?
+ )?
$
} $tz -> x(stdName) x(stdSignum) x(stdHours) x(stdMinutes) x(stdSeconds) \
x(dstName) x(dstSignum) x(dstHours) x(dstMinutes) x(dstSeconds) \
@@ -4243,8 +4246,8 @@ proc ::tcl::clock::add { clockval args } {
return -code error \
-errorcode [list CLOCK wrongNumArgs] \
"wrong \# args: should be\
- \"$cmdName clockval ?number units?...\
- ?-gmt boolean? ?-locale LOCALE? ?-timezone ZONE?\""
+ \"$cmdName clockval ?number units?...\
+ ?-gmt boolean? ?-locale LOCALE? ?-timezone ZONE?\""
}
if { [catch { expr {wide($clockval)} } result] } {
return -code error $result
@@ -4261,6 +4264,7 @@ proc ::tcl::clock::add { clockval args } {
} else {
switch -exact -- $a {
-g - -gm - -gmt {
+ set saw(-gmt) {}
set gmt $b
}
-l - -lo - -loc - -loca - -local - -locale {
@@ -4268,12 +4272,13 @@ proc ::tcl::clock::add { clockval args } {
}
-t - -ti - -tim - -time - -timez - -timezo - -timezon -
-timezone {
+ set saw(-timezone) {}
set timezone $b
}
default {
throw [list CLOCK badOption $a] \
"bad option \"$a\",\
- must be -gmt, -locale or -timezone"
+ must be -gmt, -locale or -timezone"
}
}
}
@@ -4338,7 +4343,7 @@ proc ::tcl::clock::add { clockval args } {
default {
throw [list CLOCK badUnit $unit] \
"unknown unit \"$unit\", must be \
- years, months, weeks, days, hours, minutes or seconds"
+ years, months, weeks, days, hours, minutes or seconds"
}
}
}
@@ -4498,10 +4503,10 @@ proc ::tcl::clock::ChangeCurrentLocale {args} {
variable TimeZoneBad
foreach p [info procs [namespace current]::scanproc'*'current] {
- rename $p {}
+ rename $p {}
}
foreach p [info procs [namespace current]::formatproc'*'current] {
- rename $p {}
+ rename $p {}
}
catch {array unset FormatProc *'current}
diff --git a/tests/clock.test b/tests/clock.test
index c30fea3..5ac70a6 100644
--- a/tests/clock.test
+++ b/tests/clock.test
@@ -36772,6 +36772,15 @@ test clock-57.1 {clock scan - abbreviated options} {
clock scan 1970-01-01 -f %Y-%m-%d -g true
} 0
+test clock-57.2 {clock scan - not -gmt and -timezone in the same call} {
+ catch {clock scan 1970-01-01 -format %Y-%m-%d -gmt true -timezone :Europe/Berlin}
+} 1
+
+# Bug af3ebc5fafe009
+test clock-57.3 {clock scan - not -g and -timezone in the same call} {
+ catch {clock scan 1970-01-01 -format %Y-%m-%d -gmt true -timezone :Europe/Berlin}
+} 1
+
test clock-58.1 {clock l10n - Japanese localisation} {*}{
-setup {
proc backslashify { string } {
@@ -36984,6 +36993,15 @@ test clock-65.1 {clock add, bad option [Bug 2481670]} {*}{
-result {bad option "-foo"*}
}
+test clock-65.2 {clock add with both -timezone and -gmt} {*}{
+ -body {
+ clock add 0 1 year -timezone :CET -gmt true
+ }
+ -match glob
+ -returnCodes error
+ -result {cannot use -gmt and -timezone in same call}
+}
+
test clock-66.1 {clock scan, no date, never-before-seen timezone} {*}{
-setup {
::tcl::clock::ClearCaches