Skip to content

Commit

Permalink
restore backwards compatibility (see clock-44.3) - spaces between tok…
Browse files Browse the repository at this point in the history
…ens are optional, repaired greedy search (minLen), which finds a space besides of start of next token now; it is also more consistent than old engine now (covered by clock-44.4)
  • Loading branch information
sebres committed Apr 17, 2024
1 parent b02f578 commit 192ea54
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 18 deletions.
51 changes: 34 additions & 17 deletions generic/tclClockFmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ TCL_DECLARE_MUTEX(ClockFmtMutex); /* Serializes access to common format list. */

static void ClockFmtScnStorageDelete(ClockFmtScnStorage *fss);

#ifndef TCL_CLOCK_FULL_COMPAT
#define TCL_CLOCK_FULL_COMPAT 1
#endif

/*
* Clock scan and format facilities.
*/
Expand Down Expand Up @@ -984,33 +988,42 @@ static const char *
FindTokenBegin(
register const char *p,
register const char *end,
ClockScanToken *tok)
ClockScanToken *tok,
int flags)
{
char c;
if (p < end) {
/* next token a known token type */
switch (tok->map->type) {
case CTOKT_INT:
case CTOKT_WIDE:
/* should match at least one digit */
while (!isdigit(UCHAR(*p)) && (p = Tcl_UtfNext(p)) < end) {};
if (!(flags & CLF_STRICT)) {
/* should match at least one digit or space */
while (!isdigit(UCHAR(*p)) && !isspace(UCHAR(*p)) &&
(p = Tcl_UtfNext(p)) < end) {}
} else {
/* should match at least one digit */
while (!isdigit(UCHAR(*p)) && (p = Tcl_UtfNext(p)) < end) {}
}
return p;
break;
case CTOKT_WORD:
c = *(tok->tokWord.start);
/* should match at least to the first char of this word */
while (*p != c && (p = Tcl_UtfNext(p)) < end) {};
return p;
break;
goto findChar;
case CTOKT_SPACE:
while (!isspace(UCHAR(*p)) && (p = Tcl_UtfNext(p)) < end) {};
return p;
break;
case CTOKT_CHAR:
c = *((char *)tok->map->data);
while (*p != c && (p = Tcl_UtfNext(p)) < end) {};
findChar:
if (!(flags & CLF_STRICT)) {
/* should match the char or space */
while (*p != c && !isspace(UCHAR(*p)) &&
(p = Tcl_UtfNext(p)) < end) {}
} else {
/* should match the char */
while (*p != c && (p = Tcl_UtfNext(p)) < end) {}
}
return p;
break;
}
}
return p;
Expand All @@ -1033,9 +1046,12 @@ FindTokenBegin(
*/

static void
DetermineGreedySearchLen(ClockFmtScnCmdArgs *opts,
DateInfo *info, ClockScanToken *tok,
int *minLenPtr, int *maxLenPtr)
DetermineGreedySearchLen(
ClockFmtScnCmdArgs *opts,
DateInfo *info,
ClockScanToken *tok,
int *minLenPtr,
int *maxLenPtr)
{
register int minLen = tok->map->minSize;
register int maxLen;
Expand All @@ -1046,7 +1062,8 @@ DetermineGreedySearchLen(ClockFmtScnCmdArgs *opts,
if ((tok+1)->map) {
end -= tok->endDistance + yySpaceCount;
/* find position of next known token */
p = FindTokenBegin(p, end, tok+1);
p = FindTokenBegin(p, end, tok+1,
TCL_CLOCK_FULL_COMPAT ? opts->flags : CLF_STRICT);
if (p < end) {
minLen = p - yyInput;
}
Expand Down Expand Up @@ -1089,10 +1106,10 @@ DetermineGreedySearchLen(ClockFmtScnCmdArgs *opts,
}
p += tok->lookAhMin;
if (laTok->map && p < end) {
const char *f;
/* try to find laTok between [lookAhMin, lookAhMax] */
while (minLen < maxLen) {
f = FindTokenBegin(p, end, laTok);
const char *f = FindTokenBegin(p, end, laTok,
TCL_CLOCK_FULL_COMPAT ? opts->flags : CLF_STRICT);
/* if found (not below lookAhMax) */
if (f < end) {
break;
Expand Down
8 changes: 7 additions & 1 deletion tests/clock.test
Original file line number Diff line number Diff line change
Expand Up @@ -37022,12 +37022,18 @@ test clock-44.2 {regression test - time zone containing only two digits} \
} \
-result 482134530

test clock-44.3 {regression test - spaces between some scan tokens are optional} \
test clock-44.3 {regression test - spaces between some scan tokens are optional (TCL_CLOCK_FULL_COMPAT, no-strict only)} \
-body {
list [clock scan {9 Apr 2024} -format {%d %b%Y} -gmt 1] \
[clock scan {Tue, 9 Apr 2024 00:00:00 +0000} -format {%a, %d %b%Y %H:%M:%S %Z} -gmt 1]
} \
-result {1712620800 1712620800}
test clock-44.4 {regression test - spaces between all scan tokens are optional (TCL_CLOCK_FULL_COMPAT, no-strict only)} \
-body {
list [clock scan {9 Apr 2024} -format {%d%b%Y} -gmt 1] \
[clock scan {Tue, 9 Apr 2024 00:00:00 +0000} -format {%a,%d%b%Y%H:%M:%S%Z} -gmt 1]
} \
-result {1712620800 1712620800}

test clock-45.1 {compat: scan regression on spaces (multiple spaces in format)} \
-body {
Expand Down

0 comments on commit 192ea54

Please sign in to comment.