Skip to content

Commit

Permalink
simplifying info-structure, usage of flags etc (normalizing in order …
Browse files Browse the repository at this point in the history
…to use same flags as by formatted scan instead of members like yyHave...);

(additionally allocates info->messages object on demand, if free scan fails)
  • Loading branch information
sebres committed Jul 15, 2019
1 parent a31ae8b commit 49664e3
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 101 deletions.
4 changes: 1 addition & 3 deletions generic/tclClock.c
Original file line number Diff line number Diff line change
Expand Up @@ -3817,15 +3817,13 @@ ClockValidDate(
}
}
/* and month (used later in hath) */
if (info->flags & (CLF_MONTH|CLF_DATE)) {
info->flags |= CLF_MONTH;
if (info->flags & CLF_MONTH) {
if ( yyMonth < 1 || yyMonth > 12 ) {
errMsg = "invalid month"; errCode = "month"; goto error;
}
}
/* day of month */
if (info->flags & (CLF_DAYOFMONTH|CLF_DAYOFWEEK)) {
info->flags |= CLF_DAYOFMONTH;
if ( yyDay < 1 || yyDay > 31 ) {
errMsg = "invalid day"; errCode = "day"; goto error;
}
Expand Down
90 changes: 39 additions & 51 deletions generic/tclDate.c
Original file line number Diff line number Diff line change
Expand Up @@ -559,12 +559,12 @@ static const yytype_uint8 yytranslate[] =
static const yytype_uint16 yyrline[] =
{
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
187, 190, 193, 197, 200, 206, 212, 220, 224, 228,
232, 236, 240, 246, 247, 250, 254, 258, 262, 266,
270, 276, 280, 285, 290, 295, 300, 304, 309, 313,
318, 325, 329, 335, 344, 352, 360, 369, 379, 393,
398, 401, 404, 407, 410, 413, 416, 421, 424, 429,
433, 437, 443, 446, 451, 469, 472
};
#endif

Expand Down Expand Up @@ -1548,7 +1548,7 @@ YYLTYPE yylloc = yyloc_default;
case 10:

{
yyIncrFlags(CLF_RELCONV);
info->flags |= CLF_RELCONV;
}

break;
Expand All @@ -1564,7 +1564,8 @@ YYLTYPE yylloc = yyloc_default;
case 12:

{
yyIncrFlags(CLF_TIME|CLF_HAVEDATE|CLF_RELCONV);
yyIncrFlags(CLF_TIME|CLF_HAVEDATE);
info->flags |= CLF_RELCONV;
}

break;
Expand Down Expand Up @@ -2524,6 +2525,9 @@ TclDateerror(
const char *s)
{
Tcl_Obj* t;
if (!infoPtr->messages) {
infoPtr->messages = Tcl_NewObj();
}
Tcl_AppendToObj(infoPtr->messages, infoPtr->separatrix, -1);
Tcl_AppendToObj(infoPtr->messages, s, -1);
Tcl_AppendToObj(infoPtr->messages, " (characters ", -1);
Expand Down Expand Up @@ -2821,9 +2825,7 @@ TclClockFreeScan(

yyDSTmode = DSTmaybe;

info->messages = Tcl_NewObj();
info->separatrix = "";
Tcl_IncrRefCount(info->messages);

info->dateStart = yyInput;

Expand All @@ -2833,58 +2835,44 @@ TclClockFreeScan(
/* parse */
status = yyparse(info);
if (status == 1) {
Tcl_SetObjResult(interp, info->messages);
Tcl_DecrRefCount(info->messages);
Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "PARSE", NULL);
return TCL_ERROR;
const char *msg = NULL;
if (info->errFlags & CLF_HAVEDATE) {
msg = "more than one date in string";
} else if (info->errFlags & CLF_TIME) {
msg = "more than one time of day in string";
} else if (info->errFlags & CLF_ZONE) {
msg = "more than one time zone in string";
} else if (info->errFlags & CLF_DAYOFWEEK) {
msg = "more than one weekday in string";
} else if (info->errFlags & CLF_ORDINALMONTH) {
msg = "more than one ordinal month in string";
}
if (msg) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(msg, -1));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "MULTIPLE", NULL);
} else {
Tcl_SetObjResult(interp,
info->messages ? info->messages : Tcl_NewObj());
info->messages = NULL;
Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "PARSE", NULL);
}
status = TCL_ERROR;
} else if (status == 2) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("memory exhausted", -1));
Tcl_DecrRefCount(info->messages);
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
return TCL_ERROR;
status = TCL_ERROR;
} else if (status != 0) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("Unknown status returned "
"from date parser. Please "
"report this error as a "
"bug in Tcl.", -1));
Tcl_DecrRefCount(info->messages);
Tcl_SetErrorCode(interp, "TCL", "BUG", NULL);
return TCL_ERROR;
status = TCL_ERROR;
}
Tcl_DecrRefCount(info->messages);

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 (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 (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 (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 (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);
return TCL_ERROR;
if (info->messages) {
Tcl_DecrRefCount(info->messages);
}

return TCL_OK;
return status;
}

/*
Expand Down
4 changes: 2 additions & 2 deletions generic/tclDate.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
#define CLF_ISO8601WEAK (1 << 13)
#define CLF_ISO8601CENTURY (1 << 14)

#define CLF_SIGNED (1 << 16)
#define CLF_SIGNED (1 << 15)

/* extra flags used outside of scan/format-tokens too (int, not a short int) */
#define CLF_RELCONV (1 << 17)
Expand All @@ -59,7 +59,7 @@
#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_HAVEDATE (CLF_DAYOFMONTH|CLF_MONTH|CLF_YEAR)
#define CLF_DATE (CLF_JULIANDAY | CLF_DAYOFMONTH | CLF_DAYOFYEAR | \
CLF_MONTH | CLF_YEAR | CLF_ISO8601YEAR | \
CLF_DAYOFWEEK | CLF_ISO8601WEAK)
Expand Down
78 changes: 33 additions & 45 deletions generic/tclGetDate.y
Original file line number Diff line number Diff line change
Expand Up @@ -185,13 +185,14 @@ item : time {
yyIncrFlags(CLF_DAYOFWEEK);
}
| relspec {
yyIncrFlags(CLF_RELCONV);
info->flags |= CLF_RELCONV;
}
| iso {
yyIncrFlags(CLF_TIME|CLF_HAVEDATE);
}
| trek {
yyIncrFlags(CLF_TIME|CLF_HAVEDATE|CLF_RELCONV);
yyIncrFlags(CLF_TIME|CLF_HAVEDATE);
info->flags |= CLF_RELCONV;
}
| number
;
Expand Down Expand Up @@ -698,6 +699,9 @@ TclDateerror(
const char *s)
{
Tcl_Obj* t;
if (!infoPtr->messages) {
infoPtr->messages = Tcl_NewObj();
}
Tcl_AppendToObj(infoPtr->messages, infoPtr->separatrix, -1);
Tcl_AppendToObj(infoPtr->messages, s, -1);
Tcl_AppendToObj(infoPtr->messages, " (characters ", -1);
Expand Down Expand Up @@ -995,9 +999,7 @@ TclClockFreeScan(

yyDSTmode = DSTmaybe;

info->messages = Tcl_NewObj();
info->separatrix = "";
Tcl_IncrRefCount(info->messages);

info->dateStart = yyInput;

Expand All @@ -1007,58 +1009,44 @@ TclClockFreeScan(
/* parse */
status = yyparse(info);
if (status == 1) {
Tcl_SetObjResult(interp, info->messages);
Tcl_DecrRefCount(info->messages);
Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "PARSE", NULL);
return TCL_ERROR;
const char *msg = NULL;
if (info->errFlags & CLF_HAVEDATE) {
msg = "more than one date in string";
} else if (info->errFlags & CLF_TIME) {
msg = "more than one time of day in string";
} else if (info->errFlags & CLF_ZONE) {
msg = "more than one time zone in string";
} else if (info->errFlags & CLF_DAYOFWEEK) {
msg = "more than one weekday in string";
} else if (info->errFlags & CLF_ORDINALMONTH) {
msg = "more than one ordinal month in string";
}
if (msg) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(msg, -1));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "MULTIPLE", NULL);
} else {
Tcl_SetObjResult(interp,
info->messages ? info->messages : Tcl_NewObj());
info->messages = NULL;
Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "PARSE", NULL);
}
status = TCL_ERROR;
} else if (status == 2) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("memory exhausted", -1));
Tcl_DecrRefCount(info->messages);
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
return TCL_ERROR;
status = TCL_ERROR;
} else if (status != 0) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("Unknown status returned "
"from date parser. Please "
"report this error as a "
"bug in Tcl.", -1));
Tcl_DecrRefCount(info->messages);
Tcl_SetErrorCode(interp, "TCL", "BUG", NULL);
return TCL_ERROR;
status = TCL_ERROR;
}
Tcl_DecrRefCount(info->messages);

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 (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 (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 (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 (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);
return TCL_ERROR;
if (info->messages) {
Tcl_DecrRefCount(info->messages);
}

return TCL_OK;
return status;
}

/*
Expand Down

0 comments on commit 49664e3

Please sign in to comment.