summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsebres <sebres@users.sourceforge.net>2019-07-15 12:12:05 (GMT)
committersebres <sebres@users.sourceforge.net>2019-07-15 12:12:05 (GMT)
commitc587280d004ba2c60c5b1ce29dfecd3b6dc12e6d (patch)
tree62480d498b87837f4e1f9bc8f1b8aa8d7db7b236
parentcf0b861eb9fdb52c27d15aa46635608146226c6b (diff)
downloadtcl-c587280d004ba2c60c5b1ce29dfecd3b6dc12e6d.zip
tcl-c587280d004ba2c60c5b1ce29dfecd3b6dc12e6d.tar.gz
tcl-c587280d004ba2c60c5b1ce29dfecd3b6dc12e6d.tar.bz2
**interim** try simplify info-structure (replace yyHave... with flags)
-rw-r--r--generic/tclClock.c56
-rw-r--r--generic/tclDate.c60
-rw-r--r--generic/tclDate.h26
-rw-r--r--generic/tclGetDate.y46
4 files changed, 87 insertions, 101 deletions
diff --git a/generic/tclClock.c b/generic/tclClock.c
index 7f31411..14aaf2a 100644
--- a/generic/tclClock.c
+++ b/generic/tclClock.c
@@ -3794,14 +3794,14 @@ ClockValidDate(
}
/* first year (used later in hath / daysInPriorMonths) */
- if ((info->flags & (CLF_YEAR|CLF_ISO8601YEAR)) || yyHaveDate) {
+ if ((info->flags & (CLF_YEAR|CLF_ISO8601YEAR))) {
if ((info->flags & CLF_ISO8601YEAR)) {
if ( yydate.iso8601Year < dataPtr->validMinYear
|| yydate.iso8601Year > dataPtr->validMaxYear ) {
errMsg = "invalid iso year"; errCode = "iso year"; goto error;
}
}
- if ((info->flags & CLF_YEAR) || yyHaveDate) {
+ if (info->flags & CLF_YEAR) {
if ( yyYear < dataPtr->validMinYear
|| yyYear > dataPtr->validMaxYear ) {
errMsg = "invalid year"; errCode = "year"; goto error;
@@ -3817,14 +3817,14 @@ ClockValidDate(
}
}
/* and month (used later in hath) */
- if ((info->flags & CLF_MONTH) || yyHaveDate) {
+ if (info->flags & (CLF_MONTH|CLF_DATE)) {
info->flags |= CLF_MONTH;
if ( yyMonth < 1 || yyMonth > 12 ) {
errMsg = "invalid month"; errCode = "month"; goto error;
}
}
/* day of month */
- if ((info->flags & CLF_DAYOFMONTH) || (yyHaveDate || yyHaveDay)) {
+ if (info->flags & (CLF_DAYOFMONTH|CLF_DAYOFWEEK)) {
info->flags |= CLF_DAYOFMONTH;
if ( yyDay < 1 || yyDay > 31 ) {
errMsg = "invalid day"; errCode = "day"; goto error;
@@ -3837,7 +3837,7 @@ ClockValidDate(
}
}
}
- if ((info->flags & CLF_DAYOFYEAR)) {
+ if (info->flags & CLF_DAYOFYEAR) {
if ( yydate.dayOfYear < 1
|| yydate.dayOfYear > daysInPriorMonths[IsGregorianLeapYear(&yydate)][12] ) {
errMsg = "invalid day of year"; errCode = "day of year"; goto error;
@@ -3857,7 +3857,7 @@ ClockValidDate(
}
}
- if ((info->flags & CLF_TIME) || yyHaveTime) {
+ if (info->flags & CLF_TIME) {
/* hour */
if ( yyHour < 0 || yyHour > ((yyMeridian == MER24) ? 23 : 12) ) {
errMsg = "invalid time (hour)"; errCode = "hour"; goto error;
@@ -3884,7 +3884,7 @@ ClockValidDate(
/* time, regarding the modifications by the time-zone (looks for given time
* in between DST-time hole, so does not exist in this time-zone) */
- if (((info->flags & CLF_TIME) || yyHaveTime)) {
+ if (info->flags & CLF_TIME) {
/*
* we don't need to do the backwards time-conversion (UTC to local) and
* compare results, because the after conversion (local to UTC) we
@@ -3971,7 +3971,7 @@ ClockFreeScan(
* midnight.
*/
- if (yyHaveDate) {
+ if (info->flags & CLF_YEAR) {
if (yyYear < 100) {
if (yyYear >= dataPtr->yearOfCenturySwitch) {
yyYear -= 100;
@@ -3979,9 +3979,6 @@ ClockFreeScan(
yyYear += dataPtr->currentYearCentury;
}
yydate.era = CE;
- if (yyHaveTime == 0) {
- yyHaveTime = -1;
- }
info->flags |= CLF_ASSEMBLE_JULIANDAY|CLF_ASSEMBLE_SECONDS;
}
@@ -3990,7 +3987,7 @@ ClockFreeScan(
* zone indicator of +-hhmm and setup this time zone.
*/
- if (yyHaveZone) {
+ if (info->flags & CLF_ZONE) {
Tcl_Obj *tzObjStor = NULL;
int minEast = -yyTimezone;
int dstFlag = 1 - yyDSTmode;
@@ -4024,20 +4021,20 @@ ClockFreeScan(
* Assemble date, time, zone into seconds-from-epoch
*/
- if (yyHaveTime == -1) {
+ if ((info->flags & (CLF_TIME|CLF_HAVEDATE)) == CLF_HAVEDATE) {
yySecondOfDay = 0;
info->flags |= CLF_ASSEMBLE_SECONDS;
}
else
- if (yyHaveTime) {
+ if (info->flags & CLF_TIME) {
yySecondOfDay = ToSeconds(yyHour, yyMinutes,
yySeconds, yyMeridian);
info->flags |= CLF_ASSEMBLE_SECONDS;
}
else
- if ( (yyHaveDay && !yyHaveDate)
- || yyHaveOrdinalMonth
- || ( yyHaveRel
+ if ( (info->flags & (CLF_DAYOFWEEK|CLF_HAVEDATE)) == CLF_DAYOFWEEK
+ || (info->flags & CLF_ORDINALMONTH)
+ || ( (info->flags & CLF_RELCONV)
&& ( yyRelMonth != 0
|| yyRelDay != 0 ) )
) {
@@ -4090,7 +4087,7 @@ ClockCalcRelTime(
*/
repeat_rel:
- if (yyHaveRel) {
+ if (info->flags & CLF_RELCONV) {
/*
* Relative conversion normally possible in UTC time only, because
@@ -4162,14 +4159,14 @@ repeat_rel:
}
}
- yyHaveRel = 0;
+ info->flags &= ~CLF_RELCONV;
}
/*
* Do relative (ordinal) month
*/
- if (yyHaveOrdinalMonth) {
+ if (info->flags & CLF_ORDINALMONTH) {
int monthDiff;
/* if needed extract year, month, etc. again */
@@ -4195,12 +4192,10 @@ repeat_rel:
}
/* process it further via relative times */
- yyHaveRel++;
yyYear += yyMonthOrdinalIncr;
yyRelMonth += monthDiff;
- yyHaveOrdinalMonth = 0;
-
- info->flags |= CLF_ASSEMBLE_JULIANDAY|CLF_ASSEMBLE_SECONDS;
+ info->flags &= ~CLF_ORDINALMONTH;
+ info->flags |= CLF_RELCONV|CLF_ASSEMBLE_JULIANDAY|CLF_ASSEMBLE_SECONDS;
goto repeat_rel;
}
@@ -4209,12 +4204,11 @@ repeat_rel:
* Do relative weekday
*/
- if (yyHaveDay && !yyHaveDate) {
+ if ((info->flags & (CLF_DAYOFWEEK|CLF_HAVEDATE)) == CLF_DAYOFWEEK) {
/* restore scanned day of week */
- if (info->flags & CLF_DAYOFWEEK) {
- yyDayOfWeek = prevDayOfWeek;
- }
+ yyDayOfWeek = prevDayOfWeek;
+
/* if needed assemble julianDay now */
if (info->flags & CLF_ASSEMBLE_JULIANDAY) {
GetJulianDayFromEraYearMonthDay(&yydate, GREGORIAN_CHANGE_DATE);
@@ -4420,7 +4414,7 @@ ClockAddObjCmd(
* correct date info, because the date may be changed,
* so refresh it now */
- if ( yyHaveRel
+ if ( (info->flags & CLF_RELCONV)
&& ( unitIndex == CLC_ADD_WEEKDAYS
/* some months can be shorter as another */
|| yyRelMonth || yyRelDay
@@ -4435,7 +4429,7 @@ ClockAddObjCmd(
}
/* process increment by offset + unit */
- yyHaveRel++;
+ info->flags |= CLF_RELCONV;
switch (unitIndex) {
case CLC_ADD_YEARS:
yyRelMonth += offs * 12;
@@ -4472,7 +4466,7 @@ ClockAddObjCmd(
* Do relative times (if not yet already processed interim):
*/
- if (yyHaveRel) {
+ if (info->flags & CLF_RELCONV) {
if (ClockCalcRelTime(info, &opts) != TCL_OK) {
goto done;
}
diff --git a/generic/tclDate.c b/generic/tclDate.c
index 7badb1f..b0979cc 100644
--- a/generic/tclDate.c
+++ b/generic/tclDate.c
@@ -123,6 +123,13 @@
#define SECSPERDAY (24L * 60L * 60L)
#define IsLeapYear(x) ((x % 4 == 0) && (x % 100 != 0 || x % 400 == 0))
+#define yyIncrFlags(f) \
+ do { \
+ info->errFlags |= (info->flags & (f)); \
+ if (info->errFlags) { YYABORT; } \
+ info->flags |= (f); \
+ } while (0);
+
/*
* An entry in the lexical lookup table.
*/
@@ -551,13 +558,13 @@ static const yytype_uint8 yytranslate[] =
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
- 0, 160, 160, 161, 162, 165, 168, 171, 174, 177,
- 180, 183, 187, 192, 195, 201, 207, 215, 219, 223,
- 227, 231, 235, 241, 242, 245, 250, 255, 260, 265,
- 270, 277, 281, 286, 291, 296, 301, 305, 310, 314,
- 319, 326, 330, 336, 345, 353, 361, 370, 380, 394,
- 399, 402, 405, 408, 411, 414, 417, 422, 425, 430,
- 434, 438, 444, 447, 452, 470, 473
+ 0, 167, 167, 168, 169, 172, 175, 178, 181, 184,
+ 187, 190, 193, 196, 199, 205, 211, 219, 223, 227,
+ 231, 235, 239, 245, 246, 249, 253, 257, 261, 265,
+ 269, 275, 279, 284, 289, 294, 299, 303, 308, 312,
+ 317, 324, 328, 334, 343, 351, 359, 368, 378, 392,
+ 397, 400, 403, 406, 409, 412, 415, 420, 423, 428,
+ 432, 436, 442, 445, 450, 468, 471
};
#endif
@@ -1501,7 +1508,7 @@ yyreduce:
case 5:
{
- yyHaveTime++;
+ yyIncrFlags(CLF_TIME);
}
break;
@@ -1509,7 +1516,7 @@ yyreduce:
case 6:
{
- yyHaveZone++;
+ yyIncrFlags(CLF_ZONE);
}
break;
@@ -1517,7 +1524,7 @@ yyreduce:
case 7:
{
- yyHaveDate++;
+ yyIncrFlags(CLF_HAVEDATE);
}
break;
@@ -1525,7 +1532,7 @@ yyreduce:
case 8:
{
- yyHaveOrdinalMonth++;
+ yyIncrFlags(CLF_ORDINALMONTH);
}
break;
@@ -1533,7 +1540,7 @@ yyreduce:
case 9:
{
- yyHaveDay++;
+ yyIncrFlags(CLF_DAYOFWEEK);
}
break;
@@ -1541,7 +1548,7 @@ yyreduce:
case 10:
{
- yyHaveRel++;
+ yyIncrFlags(CLF_RELCONV);
}
break;
@@ -1549,8 +1556,7 @@ yyreduce:
case 11:
{
- yyHaveTime++;
- yyHaveDate++;
+ yyIncrFlags(CLF_TIME|CLF_HAVEDATE);
}
break;
@@ -1558,9 +1564,7 @@ yyreduce:
case 12:
{
- yyHaveTime++;
- yyHaveDate++;
- yyHaveRel++;
+ yyIncrFlags(CLF_TIME|CLF_HAVEDATE|CLF_RELCONV);
}
break;
@@ -1657,7 +1661,6 @@ yyreduce:
{
yyDayOrdinal = 1;
yyDayOfWeek = (yyvsp[0].Number);
- info->flags |= CLF_DAYOFWEEK;
}
break;
@@ -1667,7 +1670,6 @@ yyreduce:
{
yyDayOrdinal = 1;
yyDayOfWeek = (yyvsp[-1].Number);
- info->flags |= CLF_DAYOFWEEK;
}
break;
@@ -1677,7 +1679,6 @@ yyreduce:
{
yyDayOrdinal = (yyvsp[-1].Number);
yyDayOfWeek = (yyvsp[0].Number);
- info->flags |= CLF_DAYOFWEEK;
}
break;
@@ -1687,7 +1688,6 @@ yyreduce:
{
yyDayOrdinal = (yyvsp[-3].Number) * (yyvsp[-1].Number);
yyDayOfWeek = (yyvsp[0].Number);
- info->flags |= CLF_DAYOFWEEK;
}
break;
@@ -1697,7 +1697,6 @@ yyreduce:
{
yyDayOrdinal = (yyvsp[-2].Number) * (yyvsp[-1].Number);
yyDayOfWeek = (yyvsp[0].Number);
- info->flags |= CLF_DAYOFWEEK;
}
break;
@@ -1707,7 +1706,6 @@ yyreduce:
{
yyDayOrdinal = 2;
yyDayOfWeek = (yyvsp[0].Number);
- info->flags |= CLF_DAYOFWEEK;
}
break;
@@ -2031,10 +2029,10 @@ yyreduce:
case 64:
{
- if (yyHaveTime && yyHaveDate && !yyHaveRel) {
+ if ((info->flags & (CLF_TIME|CLF_HAVEDATE|CLF_RELCONV)) == (CLF_TIME|CLF_HAVEDATE)) {
yyYear = (yyvsp[0].Number);
} else {
- yyHaveTime++;
+ yyIncrFlags(CLF_TIME);
if (yyDigitCount <= 2) {
yyHour = (yyvsp[0].Number);
yyMinutes = 0;
@@ -2855,31 +2853,31 @@ TclClockFreeScan(
}
Tcl_DecrRefCount(info->messages);
- if (yyHaveDate > 1) {
+ if (info->errFlags & CLF_HAVEDATE) {
Tcl_SetObjResult(interp,
Tcl_NewStringObj("more than one date in string", -1));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "MULTIPLE", NULL);
return TCL_ERROR;
}
- if (yyHaveTime > 1) {
+ if (info->errFlags & CLF_TIME) {
Tcl_SetObjResult(interp,
Tcl_NewStringObj("more than one time of day in string", -1));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "MULTIPLE", NULL);
return TCL_ERROR;
}
- if (yyHaveZone > 1) {
+ if (info->errFlags & CLF_ZONE) {
Tcl_SetObjResult(interp,
Tcl_NewStringObj("more than one time zone in string", -1));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "MULTIPLE", NULL);
return TCL_ERROR;
}
- if (yyHaveDay > 1) {
+ if (info->errFlags & CLF_DAYOFWEEK) {
Tcl_SetObjResult(interp,
Tcl_NewStringObj("more than one weekday in string", -1));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "MULTIPLE", NULL);
return TCL_ERROR;
}
- if (yyHaveOrdinalMonth > 1) {
+ if (info->errFlags & CLF_ORDINALMONTH) {
Tcl_SetObjResult(interp,
Tcl_NewStringObj("more than one ordinal month in string", -1));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "MULTIPLE", NULL);
diff --git a/generic/tclDate.h b/generic/tclDate.h
index 568aef1..5616b13 100644
--- a/generic/tclDate.h
+++ b/generic/tclDate.h
@@ -37,6 +37,7 @@
#define CLF_LOCALSEC (1 << 2)
#define CLF_JULIANDAY (1 << 3)
#define CLF_TIME (1 << 4)
+#define CLF_ZONE (1 << 5)
#define CLF_CENTURY (1 << 6)
#define CLF_DAYOFMONTH (1 << 7)
#define CLF_DAYOFYEAR (1 << 8)
@@ -46,12 +47,19 @@
#define CLF_ISO8601YEAR (1 << 12)
#define CLF_ISO8601WEAK (1 << 13)
#define CLF_ISO8601CENTURY (1 << 14)
-#define CLF_SIGNED (1 << 15)
+
+#define CLF_SIGNED (1 << 16)
+
+/* extra flags used outside of scan/format-tokens too (int, not a short int) */
+#define CLF_RELCONV (1 << 17)
+#define CLF_ORDINALMONTH (1 << 18)
+
/* On demand (lazy) assemble flags */
#define CLF_ASSEMBLE_DATE (1 << 28) /* assemble year, month, etc. using julianDay */
#define CLF_ASSEMBLE_JULIANDAY (1 << 29) /* assemble julianDay using year, month, etc. */
#define CLF_ASSEMBLE_SECONDS (1 << 30) /* assemble localSeconds (and seconds at end) */
+#define CLF_HAVEDATE (CLF_DAYOFMONTH|CLF_MONTH|CLF_YEAR|CLF_ISO8601YEAR)
#define CLF_DATE (CLF_JULIANDAY | CLF_DAYOFMONTH | CLF_DAYOFYEAR | \
CLF_MONTH | CLF_YEAR | CLF_ISO8601YEAR | \
CLF_DAYOFWEEK | CLF_ISO8601WEAK)
@@ -185,28 +193,22 @@ typedef struct DateInfo {
TclDateFields date;
- int flags;
-
- int dateHaveDate;
+ int flags; /* Signals parts of date/time get found */
+ int errFlags; /* Signals error (part of date/time found twice) */
int dateMeridian;
- int dateHaveTime;
int dateTimezone;
int dateDSTmode;
- int dateHaveZone;
int dateRelMonth;
int dateRelDay;
int dateRelSeconds;
- int dateHaveRel;
int dateMonthOrdinalIncr;
int dateMonthOrdinal;
- int dateHaveOrdinalMonth;
int dateDayOrdinal;
- int dateHaveDay;
int *dateRelPointer;
@@ -235,12 +237,6 @@ typedef struct DateInfo {
#define yyDayOfWeek (info->date.dayOfWeek)
#define yyMonthOrdinalIncr (info->dateMonthOrdinalIncr)
#define yyMonthOrdinal (info->dateMonthOrdinal)
-#define yyHaveDate (info->dateHaveDate)
-#define yyHaveDay (info->dateHaveDay)
-#define yyHaveOrdinalMonth (info->dateHaveOrdinalMonth)
-#define yyHaveRel (info->dateHaveRel)
-#define yyHaveTime (info->dateHaveTime)
-#define yyHaveZone (info->dateHaveZone)
#define yyTimezone (info->dateTimezone)
#define yyMeridian (info->dateMeridian)
#define yyRelMonth (info->dateRelMonth)
diff --git a/generic/tclGetDate.y b/generic/tclGetDate.y
index 88432ec..cf1f674 100644
--- a/generic/tclGetDate.y
+++ b/generic/tclGetDate.y
@@ -75,6 +75,13 @@
#define SECSPERDAY (24L * 60L * 60L)
#define IsLeapYear(x) ((x % 4 == 0) && (x % 100 != 0 || x % 400 == 0))
+#define yyIncrFlags(f) \
+ do { \
+ info->errFlags |= (info->flags & (f)); \
+ if (info->errFlags) { YYABORT; } \
+ info->flags |= (f); \
+ } while (0);
+
/*
* An entry in the lexical lookup table.
*/
@@ -163,31 +170,28 @@ spec : /* NULL */
;
item : time {
- yyHaveTime++;
+ yyIncrFlags(CLF_TIME);
}
| zone {
- yyHaveZone++;
+ yyIncrFlags(CLF_ZONE);
}
| date {
- yyHaveDate++;
+ yyIncrFlags(CLF_HAVEDATE);
}
| ordMonth {
- yyHaveOrdinalMonth++;
+ yyIncrFlags(CLF_ORDINALMONTH);
}
| day {
- yyHaveDay++;
+ yyIncrFlags(CLF_DAYOFWEEK);
}
| relspec {
- yyHaveRel++;
+ yyIncrFlags(CLF_RELCONV);
}
| iso {
- yyHaveTime++;
- yyHaveDate++;
+ yyIncrFlags(CLF_TIME|CLF_HAVEDATE);
}
| trek {
- yyHaveTime++;
- yyHaveDate++;
- yyHaveRel++;
+ yyIncrFlags(CLF_TIME|CLF_HAVEDATE|CLF_RELCONV);
}
| number
;
@@ -245,32 +249,26 @@ comma : ','
day : tDAY {
yyDayOrdinal = 1;
yyDayOfWeek = $1;
- info->flags |= CLF_DAYOFWEEK;
}
| tDAY comma {
yyDayOrdinal = 1;
yyDayOfWeek = $1;
- info->flags |= CLF_DAYOFWEEK;
}
| tUNUMBER tDAY {
yyDayOrdinal = $1;
yyDayOfWeek = $2;
- info->flags |= CLF_DAYOFWEEK;
}
| sign SP tUNUMBER tDAY {
yyDayOrdinal = $1 * $3;
yyDayOfWeek = $4;
- info->flags |= CLF_DAYOFWEEK;
}
| sign tUNUMBER tDAY {
yyDayOrdinal = $1 * $2;
yyDayOfWeek = $3;
- info->flags |= CLF_DAYOFWEEK;
}
| tNEXT tDAY {
yyDayOrdinal = 2;
yyDayOfWeek = $2;
- info->flags |= CLF_DAYOFWEEK;
}
;
@@ -450,10 +448,10 @@ INTNUM : tUNUMBER {
;
number : INTNUM {
- if (yyHaveTime && yyHaveDate && !yyHaveRel) {
+ if ((info->flags & (CLF_TIME|CLF_HAVEDATE|CLF_RELCONV)) == (CLF_TIME|CLF_HAVEDATE)) {
yyYear = $1;
} else {
- yyHaveTime++;
+ yyIncrFlags(CLF_TIME);
if (yyDigitCount <= 2) {
yyHour = $1;
yyMinutes = 0;
@@ -1029,31 +1027,31 @@ TclClockFreeScan(
}
Tcl_DecrRefCount(info->messages);
- if (yyHaveDate > 1) {
+ if (info->errFlags & CLF_HAVEDATE) {
Tcl_SetObjResult(interp,
Tcl_NewStringObj("more than one date in string", -1));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "MULTIPLE", NULL);
return TCL_ERROR;
}
- if (yyHaveTime > 1) {
+ if (info->errFlags & CLF_TIME) {
Tcl_SetObjResult(interp,
Tcl_NewStringObj("more than one time of day in string", -1));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "MULTIPLE", NULL);
return TCL_ERROR;
}
- if (yyHaveZone > 1) {
+ if (info->errFlags & CLF_ZONE) {
Tcl_SetObjResult(interp,
Tcl_NewStringObj("more than one time zone in string", -1));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "MULTIPLE", NULL);
return TCL_ERROR;
}
- if (yyHaveDay > 1) {
+ if (info->errFlags & CLF_DAYOFWEEK) {
Tcl_SetObjResult(interp,
Tcl_NewStringObj("more than one weekday in string", -1));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "MULTIPLE", NULL);
return TCL_ERROR;
}
- if (yyHaveOrdinalMonth > 1) {
+ if (info->errFlags & CLF_ORDINALMONTH) {
Tcl_SetObjResult(interp,
Tcl_NewStringObj("more than one ordinal month in string", -1));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "MULTIPLE", NULL);