@@ -28,6 +28,10 @@ TCL_DECLARE_MUTEX(ClockFmtMutex); /* Serializes access to common format list. */
28
28
static void ClockFmtScnStorageDelete (ClockFmtScnStorage * fss );
29
29
static void ClockFrmScnFinalize (void * );
30
30
31
+ #ifndef TCL_CLOCK_FULL_COMPAT
32
+ #define TCL_CLOCK_FULL_COMPAT 1
33
+ #endif
34
+
31
35
/*
32
36
* Derivation of tclStringHashKeyType with another allocEntryProc
33
37
*/
@@ -1019,7 +1023,8 @@ static const char *
1019
1023
FindTokenBegin (
1020
1024
const char * p ,
1021
1025
const char * end ,
1022
- ClockScanToken * tok )
1026
+ ClockScanToken * tok ,
1027
+ int flags )
1023
1028
{
1024
1029
if (p < end ) {
1025
1030
char c ;
@@ -1028,23 +1033,35 @@ FindTokenBegin(
1028
1033
switch (tok -> map -> type ) {
1029
1034
case CTOKT_INT :
1030
1035
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
+ }
1033
1044
return p ;
1034
1045
1035
1046
case CTOKT_WORD :
1036
1047
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 ;
1040
1049
1041
1050
case CTOKT_SPACE :
1042
1051
while (!isspace (UCHAR (* p )) && (p = Tcl_UtfNext (p )) < end ) {}
1043
1052
return p ;
1044
1053
1045
1054
case CTOKT_CHAR :
1046
1055
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
+ }
1048
1065
return p ;
1049
1066
}
1050
1067
}
@@ -1069,6 +1086,7 @@ FindTokenBegin(
1069
1086
1070
1087
static void
1071
1088
DetermineGreedySearchLen (
1089
+ ClockFmtScnCmdArgs * opts ,
1072
1090
DateInfo * info ,
1073
1091
ClockScanToken * tok ,
1074
1092
int * minLenPtr ,
@@ -1083,7 +1101,8 @@ DetermineGreedySearchLen(
1083
1101
if ((tok + 1 )-> map ) {
1084
1102
end -= tok -> endDistance + yySpaceCount ;
1085
1103
/* 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 );
1087
1106
if (p < end ) {
1088
1107
minLen = p - yyInput ;
1089
1108
}
@@ -1134,7 +1153,8 @@ DetermineGreedySearchLen(
1134
1153
1135
1154
/* try to find laTok between [lookAhMin, lookAhMax] */
1136
1155
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 );
1138
1158
/* if found (not below lookAhMax) */
1139
1159
if (f < end ) {
1140
1160
break ;
@@ -1518,7 +1538,7 @@ ClockScnToken_Month_Proc(
1518
1538
int minLen , maxLen ;
1519
1539
TclStrIdxTree * idxTree ;
1520
1540
1521
- DetermineGreedySearchLen (info , tok , & minLen , & maxLen );
1541
+ DetermineGreedySearchLen (opts , info , tok , & minLen , & maxLen );
1522
1542
1523
1543
/* get or create tree in msgcat dict */
1524
1544
@@ -1550,7 +1570,7 @@ ClockScnToken_DayOfWeek_Proc(
1550
1570
char curTok = * tok -> tokWord .start ;
1551
1571
TclStrIdxTree * idxTree ;
1552
1572
1553
- DetermineGreedySearchLen (info , tok , & minLen , & maxLen );
1573
+ DetermineGreedySearchLen (opts , info , tok , & minLen , & maxLen );
1554
1574
1555
1575
/* %u %w %Ou %Ow */
1556
1576
if (curTok != 'a' && curTok != 'A'
@@ -1621,7 +1641,7 @@ ClockScnToken_amPmInd_Proc(
1621
1641
int minLen , maxLen ;
1622
1642
Tcl_Obj * amPmObj [2 ];
1623
1643
1624
- DetermineGreedySearchLen (info , tok , & minLen , & maxLen );
1644
+ DetermineGreedySearchLen (opts , info , tok , & minLen , & maxLen );
1625
1645
1626
1646
amPmObj [0 ] = ClockMCGet (opts , MCLIT_AM );
1627
1647
amPmObj [1 ] = ClockMCGet (opts , MCLIT_PM );
@@ -1656,7 +1676,7 @@ ClockScnToken_LocaleERA_Proc(
1656
1676
int minLen , maxLen ;
1657
1677
Tcl_Obj * eraObj [6 ];
1658
1678
1659
- DetermineGreedySearchLen (info , tok , & minLen , & maxLen );
1679
+ DetermineGreedySearchLen (opts , info , tok , & minLen , & maxLen );
1660
1680
1661
1681
eraObj [0 ] = ClockMCGet (opts , MCLIT_BCE );
1662
1682
eraObj [1 ] = ClockMCGet (opts , MCLIT_CE );
@@ -1693,7 +1713,7 @@ ClockScnToken_LocaleListMatcher_Proc(
1693
1713
int minLen , maxLen ;
1694
1714
TclStrIdxTree * idxTree ;
1695
1715
1696
- DetermineGreedySearchLen (info , tok , & minLen , & maxLen );
1716
+ DetermineGreedySearchLen (opts , info , tok , & minLen , & maxLen );
1697
1717
1698
1718
/* get or create tree in msgcat dict */
1699
1719
@@ -1716,7 +1736,7 @@ ClockScnToken_LocaleListMatcher_Proc(
1716
1736
1717
1737
static int
1718
1738
ClockScnToken_JDN_Proc (
1719
- TCL_UNUSED ( ClockFmtScnCmdArgs * ) ,
1739
+ ClockFmtScnCmdArgs * opts ,
1720
1740
DateInfo * info ,
1721
1741
ClockScanToken * tok )
1722
1742
{
@@ -1725,7 +1745,7 @@ ClockScnToken_JDN_Proc(
1725
1745
Tcl_WideInt intJD ;
1726
1746
int fractJD = 0 , fractJDDiv = 1 ;
1727
1747
1728
- DetermineGreedySearchLen (info , tok , & minLen , & maxLen );
1748
+ DetermineGreedySearchLen (opts , info , tok , & minLen , & maxLen );
1729
1749
1730
1750
end = yyInput + maxLen ;
1731
1751
@@ -1796,7 +1816,7 @@ ClockScnToken_TimeZone_Proc(
1796
1816
const char * p = yyInput ;
1797
1817
Tcl_Obj * tzObjStor = NULL ;
1798
1818
1799
- DetermineGreedySearchLen (info , tok , & minLen , & maxLen );
1819
+ DetermineGreedySearchLen (opts , info , tok , & minLen , & maxLen );
1800
1820
1801
1821
/* numeric timezone */
1802
1822
if (* p == '+' || * p == '-' ) {
@@ -1879,7 +1899,7 @@ ClockScnToken_TimeZone_Proc(
1879
1899
1880
1900
static int
1881
1901
ClockScnToken_StarDate_Proc (
1882
- TCL_UNUSED ( ClockFmtScnCmdArgs * ) ,
1902
+ ClockFmtScnCmdArgs * opts ,
1883
1903
DateInfo * info ,
1884
1904
ClockScanToken * tok )
1885
1905
{
@@ -1888,7 +1908,7 @@ ClockScnToken_StarDate_Proc(
1888
1908
int year , fractYear , fractDayDiv , fractDay ;
1889
1909
static const char * stardatePref = "stardate " ;
1890
1910
1891
- DetermineGreedySearchLen (info , tok , & minLen , & maxLen );
1911
+ DetermineGreedySearchLen (opts , info , tok , & minLen , & maxLen );
1892
1912
1893
1913
end = yyInput + maxLen ;
1894
1914
@@ -2436,7 +2456,7 @@ ClockScan(
2436
2456
}
2437
2457
}
2438
2458
2439
- DetermineGreedySearchLen (info , tok , & minLen , & size );
2459
+ DetermineGreedySearchLen (opts , info , tok , & minLen , & size );
2440
2460
2441
2461
if (size < map -> minSize ) {
2442
2462
/* missing input -> error */
0 commit comments