[PROPOSED] Remove old Y2K code
The circa-1996 runtime tests to catch potential Y2K problems are no longer worth the maintenance hassle, as the Y2K transition was done many years ago. * Makefile, NEWS: Mention this. * strftime.c (YEAR_2000_NAME, IN_NONE, IN_SOME, IN_THIS, IN_ALL): Remove. All uses removed. (strftime): Do not warn about Y2K problems. (_fmt): Omit last (warning) arg; all uses changed. --- Makefile | 3 --- NEWS | 2 ++ strftime.c | 71 ++++++++++++-------------------------------------------------- 3 files changed, 15 insertions(+), 61 deletions(-) diff --git a/Makefile b/Makefile index 07f4f77..65915ea 100644 --- a/Makefile +++ b/Makefile @@ -162,9 +162,6 @@ LDLIBS= # than what POSIX specifies, assuming local time is UT. # For example, N is 252460800 on AmigaOS. # -Dlocale_t=XXX if your system uses XXX instead of locale_t -# -DNO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU=1 -# if you do not want run time warnings about formats that may cause -# year 2000 grief # -Dssize_t=long on hosts like MS-Windows that lack ssize_t # -DTHREAD_SAFE to make localtime.c thread-safe, as POSIX requires; # not needed by the main-program tz code, which is single-threaded. diff --git a/NEWS b/NEWS index 2c86e90..40285bf 100644 --- a/NEWS +++ b/NEWS @@ -81,6 +81,8 @@ Unreleased, experimental changes other two variables as optional. Also, USG_COMPAT is now 1 or 0: if not defined, the code attempts to guess it from other macros. + Y2K runtime checks have been removed, as Y2K was years ago. + Several minor changes have been made to the code to make it a bit easier to port to MS-Windows and Solaris. (Thanks to Kees Dekker for reporting the problems.) diff --git a/strftime.c b/strftime.c index 173ff8b..9df4176 100644 --- a/strftime.c +++ b/strftime.c @@ -101,19 +101,9 @@ static const struct lc_time_T C_time_locale = { static char * _add(const char *, char *, const char *); static char * _conv(int, const char *, char *, const char *); -static char * _fmt(const char *, const struct tm *, char *, const char *, - int *); +static char * _fmt(const char *, const struct tm *, char *, const char *); static char * _yconv(int, int, bool, bool, char *, char const *); -#ifndef YEAR_2000_NAME -#define YEAR_2000_NAME "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS" -#endif /* !defined YEAR_2000_NAME */ - -#define IN_NONE 0 -#define IN_SOME 1 -#define IN_THIS 2 -#define IN_ALL 3 - #if HAVE_STRFTIME_L size_t strftime_l(char *s, size_t maxsize, char const *format, struct tm const *t, @@ -128,24 +118,9 @@ size_t strftime(char *s, size_t maxsize, const char *format, const struct tm *t) { char * p; - int warn; tzset(); - warn = IN_NONE; - p = _fmt(format, t, s, s + maxsize, &warn); -#ifndef NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU - if (warn != IN_NONE && getenv(YEAR_2000_NAME) != NULL) { - fprintf(stderr, "\n"); - fprintf(stderr, "strftime format \"%s\" ", format); - fprintf(stderr, "yields only two digits of years in "); - if (warn == IN_SOME) - fprintf(stderr, "some locales"); - else if (warn == IN_THIS) - fprintf(stderr, "the current locale"); - else fprintf(stderr, "all locales"); - fprintf(stderr, "\n"); - } -#endif /* !defined NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU */ + p = _fmt(format, t, s, s + maxsize); if (p == s + maxsize) return 0; *p = '\0'; @@ -153,8 +128,7 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *t) } static char * -_fmt(const char *format, const struct tm *t, char *pt, - const char *ptlim, int *warnp) +_fmt(const char *format, const struct tm *t, char *pt, const char *ptlim) { for ( ; *format; ++format) { if (*format == '%') { @@ -200,18 +174,10 @@ label: true, false, pt, ptlim); continue; case 'c': - { - int warn2 = IN_SOME; - - pt = _fmt(Locale->c_fmt, t, pt, ptlim, &warn2); - if (warn2 == IN_ALL) - warn2 = IN_THIS; - if (warn2 > *warnp) - *warnp = warn2; - } + pt = _fmt(Locale->c_fmt, t, pt, ptlim); continue; case 'D': - pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp); + pt = _fmt("%m/%d/%y", t, pt, ptlim); continue; case 'd': pt = _conv(t->tm_mday, "%02d", pt, ptlim); @@ -232,7 +198,7 @@ label: pt = _conv(t->tm_mday, "%2d", pt, ptlim); continue; case 'F': - pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp); + pt = _fmt("%Y-%m-%d", t, pt, ptlim); continue; case 'H': pt = _conv(t->tm_hour, "%02d", pt, ptlim); @@ -296,10 +262,10 @@ label: pt, ptlim); continue; case 'R': - pt = _fmt("%H:%M", t, pt, ptlim, warnp); + pt = _fmt("%H:%M", t, pt, ptlim); continue; case 'r': - pt = _fmt("%I:%M:%S %p", t, pt, ptlim, warnp); + pt = _fmt("%I:%M:%S %p", t, pt, ptlim); continue; case 'S': pt = _conv(t->tm_sec, "%02d", pt, ptlim); @@ -322,7 +288,7 @@ label: } continue; case 'T': - pt = _fmt("%H:%M:%S", t, pt, ptlim, warnp); + pt = _fmt("%H:%M:%S", t, pt, ptlim); continue; case 't': pt = _add("\t", pt, ptlim); @@ -424,7 +390,6 @@ label: pt = _conv(w, "%02d", pt, ptlim); else if (*format == 'g') { - *warnp = IN_ALL; pt = _yconv(year, base, false, true, pt, ptlim); @@ -439,7 +404,7 @@ label: ** "date as dd-bbb-YYYY" ** (ado, 1993-05-24) */ - pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp); + pt = _fmt("%e-%b-%Y", t, pt, ptlim); continue; case 'W': pt = _conv((t->tm_yday + DAYSPERWEEK - @@ -452,21 +417,12 @@ label: pt = _conv(t->tm_wday, "%d", pt, ptlim); continue; case 'X': - pt = _fmt(Locale->X_fmt, t, pt, ptlim, warnp); + pt = _fmt(Locale->X_fmt, t, pt, ptlim); continue; case 'x': - { - int warn2 = IN_SOME; - - pt = _fmt(Locale->x_fmt, t, pt, ptlim, &warn2); - if (warn2 == IN_ALL) - warn2 = IN_THIS; - if (warn2 > *warnp) - *warnp = warn2; - } + pt = _fmt(Locale->x_fmt, t, pt, ptlim); continue; case 'y': - *warnp = IN_ALL; pt = _yconv(t->tm_year, TM_YEAR_BASE, false, true, pt, ptlim); @@ -559,8 +515,7 @@ label: #endif continue; case '+': - pt = _fmt(Locale->date_fmt, t, pt, ptlim, - warnp); + pt = _fmt(Locale->date_fmt, t, pt, ptlim); continue; case '%': /* -- 2.9.4
On 2017-06-12 17:30, Paul Eggert wrote:
The circa-1996 runtime tests to catch potential Y2K problems are no longer worth the maintenance hassle, as the Y2K transition was done many years ago. * Makefile, NEWS: Mention this. * strftime.c (YEAR_2000_NAME, IN_NONE, IN_SOME, IN_THIS, IN_ALL): Remove. All uses removed. (strftime): Do not warn about Y2K problems. (_fmt): Omit last (warning) arg; all uses changed.
Please reconsider removing this, and change it if necessary to DEPRECATE_TWO_DIGIT_YEARS, as the lessons have not been learned, and that nasty habit has persisted and spread, with more programs generating two digit years and months and days, resulting in confusion on ~.4 of the dates in each year, and ~.666 of the last 18 years, unless you happen to know the project's rules or program's locale (if they even support locales) with certainty. Personally I would like to see any use of %y dropped, declared UB, or at least unspecified behaviour, with the options of treating it as %Y, or deletion of the source file containing it, unless suppressed by a directive such as #pragma BONEHEAD_SINCE_EPOCH, when it should have been deprecated! -- Take care. Thanks, Brian Inglis, Calgary, Alberta, Canada
On 06/12/2017 09:06 PM, Brian Inglis wrote:
Please reconsider removing this, and change it if necessary to DEPRECATE_TWO_DIGIT_YEARS, as the lessons have not been learned
Perhaps you're right, I was too hasty. I brought back that code under the name you suggested, by installing the attached.
On 2017-06-12 23:59, Paul Eggert wrote:
On 06/12/2017 09:06 PM, Brian Inglis wrote:
Please reconsider removing this, and change it if necessary to DEPRECATE_TWO_DIGIT_YEARS, as the lessons have not been learned
Perhaps you're right, I was too hasty. I brought back that code under the name you suggested, by installing the attached.
Thank you, and developers 70-80 years from now will thank you! Between now and then, I hope to get the "date formatting" printf examples removed from: http://pubs.opengroup.org/onlinepubs/9699919799/functions/fprintf.html#tag_1... which are examples of what not to do, as it causes future problems, when you have specialized, localized facilities available, better suited to do those jobs, like strftime(3), gettext(3), catgets(3), and friends. -- Take care. Thanks, Brian Inglis, Calgary, Alberta, Canada
On Monday, June 12 2017, "Paul Eggert" wrote to "Brian.Inglis@SystematicSw.ab.ca, Time zone mailing list" saying:
Perhaps you're right, I was too hasty. I brought back that code under the name you suggested, by installing the attached.
+ Y2K runtime checks are no longer enabled by default. Add + -DDEPRECATE_TWO_DIGIT_YEARS to CFLAGS to enable them, instead of + adding -DNO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU + to disable them. (New name suggested by Brian Inglis.) +
Since DEPRECATE_TWO_DIGIT_YEARS is used in an if statement, shouldn't this be -DDEPRECATE_TWO_DIGIT_YEARS=true ? Otherwise it expands to if ( && warn != IN_NONE ... which obviously won't compile. -- Jonathan Lennox lennox@cs.columbia.edu
On Jun 13, 2017, at 2:17 PM, Jonathan Lennox <lennox@cs.columbia.edu> wrote:
On Monday, June 12 2017, "Paul Eggert" wrote to "Brian.Inglis@SystematicSw.ab.ca, Time zone mailing list" saying:
Perhaps you're right, I was too hasty. I brought back that code under the name you suggested, by installing the attached.
+ Y2K runtime checks are no longer enabled by default. Add + -DDEPRECATE_TWO_DIGIT_YEARS to CFLAGS to enable them, instead of + adding -DNO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU + to disable them. (New name suggested by Brian Inglis.) +
Since DEPRECATE_TWO_DIGIT_YEARS is used in an if statement, shouldn't this be -DDEPRECATE_TWO_DIGIT_YEARS=true ? Otherwise it expands to if ( && warn != IN_NONE ...
which obviously won't compile.
Not so, because -DFOO is equivalent to -DFOO=1 . paul
On 13/06/17 20:47, Paul.Koning@dell.com wrote:
On Jun 13, 2017, at 2:17 PM, Jonathan Lennox <lennox@cs.columbia.edu> wrote:
On Monday, June 12 2017, "Paul Eggert" wrote to "Brian.Inglis@SystematicSw.ab.ca, Time zone mailing list" saying:
Perhaps you're right, I was too hasty. I brought back that code under the name you suggested, by installing the attached.
+ Y2K runtime checks are no longer enabled by default. Add + -DDEPRECATE_TWO_DIGIT_YEARS to CFLAGS to enable them, instead of + adding -DNO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU + to disable them. (New name suggested by Brian Inglis.) +
Since DEPRECATE_TWO_DIGIT_YEARS is used in an if statement, shouldn't this be -DDEPRECATE_TWO_DIGIT_YEARS=true ? Otherwise it expands to if ( && warn != IN_NONE ...
which obviously won't compile.
Not so, because -DFOO is equivalent to -DFOO=1 .
Yes, although technically this is compiler (or precompiler) behavior, not part of any C standard (since it only concerns the language). The comments for the '-D' options in Makefile mostly seem to follow the style of omitting the default '=1' (as it assumes POSIX style C compiler options are being used), except for the cases where '=1' is one of two or more documented values (for example, in the comments for 'HAVE_TZNAME'). Perhaps a note could be added to the comments in the Makefile to make it clear that it is assuming that '-DFOO' is equivalent to '-DFOO=1', and that '-DFOO=bar' defines a macro with the given replacement, although I guess anyone porting the Makefile and compiler options ought to have a passing acquaintance with POSIX conventions. -- -=( Ian Abbott @ MEV Ltd. E-mail: <abbotti@mev.co.uk> )=- -=( Web: http://www.mev.co.uk/ )=-
Jonathan Lennox said:
Since DEPRECATE_TWO_DIGIT_YEARS is used in an if statement, shouldn't this be -DDEPRECATE_TWO_DIGIT_YEARS=true ? Otherwise it expands to if ( && warn != IN_NONE ...
which obviously won't compile.
Better is to have, in the code: #ifdef DEPRECATE_TWO_DIGIT_YEARS #undef DEPRECATE_TWO_DIGIT_YEARS #define DEPRECATE_TWO_DIGIT_YEARS true #else #define DEPRECATE_TWO_DIGIT_YEARS false #endif so that it can't be misdefined. -- Clive D.W. Feather | If you lie to the compiler, Email: clive@davros.org | it will get its revenge. Web: http://www.davros.org | - Henry Spencer Mobile: +44 7973 377646
Clive D.W. Feather wrote:
#ifdef DEPRECATE_TWO_DIGIT_YEARS #undef DEPRECATE_TWO_DIGIT_YEARS #define DEPRECATE_TWO_DIGIT_YEARS true #else #define DEPRECATE_TWO_DIGIT_YEARS false #endif
so that it can't be misdefined.
That would be liable to encourage someone to put -DDEPRECATE_TWO_DIGIT_YEARS=false on the command line, which it would then handle poorly. Pick one convention or the other for that symbol; if you want to use the other convention internally, apply it to a different symbol. -zefram
On 06/13/2017 12:59 PM, Clive D.W. Feather wrote:
Better is to have, in the code:
#ifdef DEPRECATE_TWO_DIGIT_YEARS #undef DEPRECATE_TWO_DIGIT_YEARS
I prefer the style where the builder uses -D to specify a value, and where the code defines a default if -D is not used. This is what's done for HAVE_LINK, NETBSD_INSPIRED, USG_COMPAT, etc.
Date: Tue, 13 Jun 2017 14:17:57 -0400 From: Jonathan Lennox <lennox@cs.columbia.edu> Message-ID: <22848.11349.984541.13180@compute03.cs.columbia.edu> | Since DEPRECATE_TWO_DIGIT_YEARS is used in an if statement, shouldn't this | be -DDEPRECATE_TWO_DIGIT_YEARS=true ? Otherwise it expands to | if ( && warn != IN_NONE ... | | which obviously won't compile. When did cpp change so that -DSTRING did not cause #define STRING 1 (effectively). Someone would need to do -DDEPRECATE_TWO_DIGIT_YEARS= to get the interpretation you are assuming, I believe. kre
On Wednesday, June 14 2017, "Robert Elz" wrote to "Jonathan Lennox, Paul Eggert, Time zone mailing list" saying:
Date: Tue, 13 Jun 2017 14:17:57 -0400 From: Jonathan Lennox <lennox@cs.columbia.edu> Message-ID: <22848.11349.984541.13180@compute03.cs.columbia.edu>
| Since DEPRECATE_TWO_DIGIT_YEARS is used in an if statement, shouldn't this | be -DDEPRECATE_TWO_DIGIT_YEARS=true ? Otherwise it expands to | if ( && warn != IN_NONE ... | | which obviously won't compile.
When did cpp change so that -DSTRING did not cause #define STRING 1 (effectively).
Someone would need to do -DDEPRECATE_TWO_DIGIT_YEARS= to get the interpretation you are assuming, I believe.
Ah - perhaps I never knew that feature. Regardless, it was surprising to me, so I'd recommend making the 'true' explicit. -- Jonathan Lennox lennox@cs.columbia.edu
participants (8)
-
Brian Inglis -
Clive D.W. Feather -
Ian Abbott -
Jonathan Lennox -
Paul Eggert -
Paul.Koning@dell.com -
Robert Elz -
Zefram