Skip to content

Commit eee424d

Browse files
committed
merge 8.7 (clock compat repair)
2 parents ff0d91b + 6c80da1 commit eee424d

File tree

2 files changed

+54
-20
lines changed

2 files changed

+54
-20
lines changed

generic/tclClockFmt.c

+40-20
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ TCL_DECLARE_MUTEX(ClockFmtMutex); /* Serializes access to common format list. */
2828
static void ClockFmtScnStorageDelete(ClockFmtScnStorage *fss);
2929
static void ClockFrmScnFinalize(void *);
3030

31+
#ifndef TCL_CLOCK_FULL_COMPAT
32+
#define TCL_CLOCK_FULL_COMPAT 1
33+
#endif
34+
3135
/*
3236
* Derivation of tclStringHashKeyType with another allocEntryProc
3337
*/
@@ -1019,7 +1023,8 @@ static const char *
10191023
FindTokenBegin(
10201024
const char *p,
10211025
const char *end,
1022-
ClockScanToken *tok)
1026+
ClockScanToken *tok,
1027+
int flags)
10231028
{
10241029
if (p < end) {
10251030
char c;
@@ -1028,23 +1033,35 @@ FindTokenBegin(
10281033
switch (tok->map->type) {
10291034
case CTOKT_INT:
10301035
case CTOKT_WIDE:
1031-
/* should match at least one digit */
1032-
while (!isdigit(UCHAR(*p)) && (p = Tcl_UtfNext(p)) < end) {}
1036+
if (!(flags & CLF_STRICT)) {
1037+
/* should match at least one digit or space */
1038+
while (!isdigit(UCHAR(*p)) && !isspace(UCHAR(*p)) &&
1039+
(p = Tcl_UtfNext(p)) < end) {}
1040+
} else {
1041+
/* should match at least one digit */
1042+
while (!isdigit(UCHAR(*p)) && (p = Tcl_UtfNext(p)) < end) {}
1043+
}
10331044
return p;
10341045

10351046
case CTOKT_WORD:
10361047
c = *(tok->tokWord.start);
1037-
/* should match at least to the first char of this word */
1038-
while (*p != c && (p = Tcl_UtfNext(p)) < end) {}
1039-
return p;
1048+
goto findChar;
10401049

10411050
case CTOKT_SPACE:
10421051
while (!isspace(UCHAR(*p)) && (p = Tcl_UtfNext(p)) < end) {}
10431052
return p;
10441053

10451054
case CTOKT_CHAR:
10461055
c = *((char *)tok->map->data);
1047-
while (*p != c && (p = Tcl_UtfNext(p)) < end) {}
1056+
findChar:
1057+
if (!(flags & CLF_STRICT)) {
1058+
/* should match the char or space */
1059+
while (*p != c && !isspace(UCHAR(*p)) &&
1060+
(p = Tcl_UtfNext(p)) < end) {}
1061+
} else {
1062+
/* should match the char */
1063+
while (*p != c && (p = Tcl_UtfNext(p)) < end) {}
1064+
}
10481065
return p;
10491066
}
10501067
}
@@ -1069,6 +1086,7 @@ FindTokenBegin(
10691086

10701087
static void
10711088
DetermineGreedySearchLen(
1089+
ClockFmtScnCmdArgs *opts,
10721090
DateInfo *info,
10731091
ClockScanToken *tok,
10741092
int *minLenPtr,
@@ -1083,7 +1101,8 @@ DetermineGreedySearchLen(
10831101
if ((tok + 1)->map) {
10841102
end -= tok->endDistance + yySpaceCount;
10851103
/* find position of next known token */
1086-
p = FindTokenBegin(p, end, tok + 1);
1104+
p = FindTokenBegin(p, end, tok + 1,
1105+
TCL_CLOCK_FULL_COMPAT ? opts->flags : CLF_STRICT);
10871106
if (p < end) {
10881107
minLen = p - yyInput;
10891108
}
@@ -1134,7 +1153,8 @@ DetermineGreedySearchLen(
11341153

11351154
/* try to find laTok between [lookAhMin, lookAhMax] */
11361155
while (minLen < maxLen) {
1137-
const char *f = FindTokenBegin(p, end, laTok);
1156+
const char *f = FindTokenBegin(p, end, laTok,
1157+
TCL_CLOCK_FULL_COMPAT ? opts->flags : CLF_STRICT);
11381158
/* if found (not below lookAhMax) */
11391159
if (f < end) {
11401160
break;
@@ -1518,7 +1538,7 @@ ClockScnToken_Month_Proc(
15181538
int minLen, maxLen;
15191539
TclStrIdxTree *idxTree;
15201540

1521-
DetermineGreedySearchLen(info, tok, &minLen, &maxLen);
1541+
DetermineGreedySearchLen(opts, info, tok, &minLen, &maxLen);
15221542

15231543
/* get or create tree in msgcat dict */
15241544

@@ -1550,7 +1570,7 @@ ClockScnToken_DayOfWeek_Proc(
15501570
char curTok = *tok->tokWord.start;
15511571
TclStrIdxTree *idxTree;
15521572

1553-
DetermineGreedySearchLen(info, tok, &minLen, &maxLen);
1573+
DetermineGreedySearchLen(opts, info, tok, &minLen, &maxLen);
15541574

15551575
/* %u %w %Ou %Ow */
15561576
if (curTok != 'a' && curTok != 'A'
@@ -1621,7 +1641,7 @@ ClockScnToken_amPmInd_Proc(
16211641
int minLen, maxLen;
16221642
Tcl_Obj *amPmObj[2];
16231643

1624-
DetermineGreedySearchLen(info, tok, &minLen, &maxLen);
1644+
DetermineGreedySearchLen(opts, info, tok, &minLen, &maxLen);
16251645

16261646
amPmObj[0] = ClockMCGet(opts, MCLIT_AM);
16271647
amPmObj[1] = ClockMCGet(opts, MCLIT_PM);
@@ -1656,7 +1676,7 @@ ClockScnToken_LocaleERA_Proc(
16561676
int minLen, maxLen;
16571677
Tcl_Obj *eraObj[6];
16581678

1659-
DetermineGreedySearchLen(info, tok, &minLen, &maxLen);
1679+
DetermineGreedySearchLen(opts, info, tok, &minLen, &maxLen);
16601680

16611681
eraObj[0] = ClockMCGet(opts, MCLIT_BCE);
16621682
eraObj[1] = ClockMCGet(opts, MCLIT_CE);
@@ -1693,7 +1713,7 @@ ClockScnToken_LocaleListMatcher_Proc(
16931713
int minLen, maxLen;
16941714
TclStrIdxTree *idxTree;
16951715

1696-
DetermineGreedySearchLen(info, tok, &minLen, &maxLen);
1716+
DetermineGreedySearchLen(opts, info, tok, &minLen, &maxLen);
16971717

16981718
/* get or create tree in msgcat dict */
16991719

@@ -1716,7 +1736,7 @@ ClockScnToken_LocaleListMatcher_Proc(
17161736

17171737
static int
17181738
ClockScnToken_JDN_Proc(
1719-
TCL_UNUSED(ClockFmtScnCmdArgs *),
1739+
ClockFmtScnCmdArgs *opts,
17201740
DateInfo *info,
17211741
ClockScanToken *tok)
17221742
{
@@ -1725,7 +1745,7 @@ ClockScnToken_JDN_Proc(
17251745
Tcl_WideInt intJD;
17261746
int fractJD = 0, fractJDDiv = 1;
17271747

1728-
DetermineGreedySearchLen(info, tok, &minLen, &maxLen);
1748+
DetermineGreedySearchLen(opts, info, tok, &minLen, &maxLen);
17291749

17301750
end = yyInput + maxLen;
17311751

@@ -1796,7 +1816,7 @@ ClockScnToken_TimeZone_Proc(
17961816
const char *p = yyInput;
17971817
Tcl_Obj *tzObjStor = NULL;
17981818

1799-
DetermineGreedySearchLen(info, tok, &minLen, &maxLen);
1819+
DetermineGreedySearchLen(opts, info, tok, &minLen, &maxLen);
18001820

18011821
/* numeric timezone */
18021822
if (*p == '+' || *p == '-') {
@@ -1879,7 +1899,7 @@ ClockScnToken_TimeZone_Proc(
18791899

18801900
static int
18811901
ClockScnToken_StarDate_Proc(
1882-
TCL_UNUSED(ClockFmtScnCmdArgs *),
1902+
ClockFmtScnCmdArgs *opts,
18831903
DateInfo *info,
18841904
ClockScanToken *tok)
18851905
{
@@ -1888,7 +1908,7 @@ ClockScnToken_StarDate_Proc(
18881908
int year, fractYear, fractDayDiv, fractDay;
18891909
static const char *stardatePref = "stardate ";
18901910

1891-
DetermineGreedySearchLen(info, tok, &minLen, &maxLen);
1911+
DetermineGreedySearchLen(opts, info, tok, &minLen, &maxLen);
18921912

18931913
end = yyInput + maxLen;
18941914

@@ -2436,7 +2456,7 @@ ClockScan(
24362456
}
24372457
}
24382458

2439-
DetermineGreedySearchLen(info, tok, &minLen, &size);
2459+
DetermineGreedySearchLen(opts, info, tok, &minLen, &size);
24402460

24412461
if (size < map->minSize) {
24422462
/* missing input -> error */

tests/clock.test

+14
Original file line numberDiff line numberDiff line change
@@ -37032,12 +37032,26 @@ test clock-44.1 {regression test - time zone name containing hyphen } \
3703237032
}
3703337033
} \
3703437034
-result {12:34:56-0500}
37035+
3703537036
test clock-44.2 {regression test - time zone containing only two digits} \
3703637037
-body {
3703737038
clock scan 1985-04-12T10:15:30+04 -format %Y-%m-%dT%H:%M:%S%Z
3703837039
} \
3703937040
-result 482134530
3704037041

37042+
test clock-44.3 {regression test - spaces between some scan tokens are optional (TCL_CLOCK_FULL_COMPAT, no-strict only)} \
37043+
-body {
37044+
list [clock scan {9 Apr 2024} -format {%d %b%Y} -gmt 1] \
37045+
[clock scan {Tue, 9 Apr 2024 00:00:00 +0000} -format {%a, %d %b%Y %H:%M:%S %Z} -gmt 1]
37046+
} \
37047+
-result {1712620800 1712620800}
37048+
test clock-44.4 {regression test - spaces between all scan tokens are optional (TCL_CLOCK_FULL_COMPAT, no-strict only)} \
37049+
-body {
37050+
list [clock scan {9 Apr 2024} -format {%d%b%Y} -gmt 1] \
37051+
[clock scan {Tue, 9 Apr 2024 00:00:00 +0000} -format {%a,%d%b%Y%H:%M:%S%Z} -gmt 1]
37052+
} \
37053+
-result {1712620800 1712620800}
37054+
3704137055
test clock-45.1 {compat: scan regression on spaces (multiple spaces in format)} \
3704237056
-body {
3704337057
list \

0 commit comments

Comments
 (0)