diff options
| author | Paul Eggert | 2012-05-03 13:04:29 -0700 |
|---|---|---|
| committer | Paul Eggert | 2012-05-03 13:04:29 -0700 |
| commit | ab0fa4e4ba0b2b93a9ef007842523d8d5f9eb758 (patch) | |
| tree | 9adfb1831b29c6f4d68b5d1ea6de54f05617bc6a /src/editfns.c | |
| parent | f7ae6719123ad5f4f505290621810318d9ee5484 (diff) | |
| download | emacs-ab0fa4e4ba0b2b93a9ef007842523d8d5f9eb758.tar.gz emacs-ab0fa4e4ba0b2b93a9ef007842523d8d5f9eb758.zip | |
Do not limit current-time-string to years 1000..9999.
* src/editfns.c (TM_YEAR_IN_ASCTIME_RANGE): Remove.
(Fcurrent_time_string): Support any year that is supported by the
underlying localtime representation. Don't use asctime, as it
has undefined behavior for years outside the range -999..9999.
* doc/lispref/os.texi (Time of Day): Do not limit current-time-string
to years 1000..9999.
* etc/NEWS: Do not limit current-time-string to years 1000..9999.
Diffstat (limited to 'src/editfns.c')
| -rw-r--r-- | src/editfns.c | 39 |
1 files changed, 20 insertions, 19 deletions
diff --git a/src/editfns.c b/src/editfns.c index b52bc0c2a99..d266ca9951d 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -73,13 +73,6 @@ extern char **environ; | |||
| 73 | 73 | ||
| 74 | #define TM_YEAR_BASE 1900 | 74 | #define TM_YEAR_BASE 1900 |
| 75 | 75 | ||
| 76 | /* Nonzero if TM_YEAR is a struct tm's tm_year value that causes | ||
| 77 | asctime to have well-defined behavior. */ | ||
| 78 | #ifndef TM_YEAR_IN_ASCTIME_RANGE | ||
| 79 | # define TM_YEAR_IN_ASCTIME_RANGE(tm_year) \ | ||
| 80 | (1000 - TM_YEAR_BASE <= (tm_year) && (tm_year) <= 9999 - TM_YEAR_BASE) | ||
| 81 | #endif | ||
| 82 | |||
| 83 | #ifdef WINDOWSNT | 76 | #ifdef WINDOWSNT |
| 84 | extern Lisp_Object w32_get_internal_run_time (void); | 77 | extern Lisp_Object w32_get_internal_run_time (void); |
| 85 | #endif | 78 | #endif |
| @@ -1943,29 +1936,37 @@ but this is considered obsolete. */) | |||
| 1943 | { | 1936 | { |
| 1944 | time_t value; | 1937 | time_t value; |
| 1945 | struct tm *tm; | 1938 | struct tm *tm; |
| 1946 | char *tem = NULL; | 1939 | char buf[sizeof "Mon Apr 30 12:49:17 " + INT_STRLEN_BOUND (int) + 1]; |
| 1947 | char buf[sizeof "Mon Apr 30 12:49:17 2012" - 1]; | 1940 | int len IF_LINT (= 0); |
| 1948 | 1941 | ||
| 1949 | if (! lisp_time_argument (specified_time, &value, NULL)) | 1942 | if (! lisp_time_argument (specified_time, &value, NULL)) |
| 1950 | error ("Invalid time specification"); | 1943 | error ("Invalid time specification"); |
| 1951 | 1944 | ||
| 1952 | /* Convert to a string, checking for out-of-range time stamps. | 1945 | /* Convert to a string in ctime format, except without the trailing |
| 1953 | Omit the trailing newline. | 1946 | newline, and without the 4-digit year limit. Don't use asctime |
| 1954 | Don't use 'ctime', as that might dump core if VALUE is out of | 1947 | or ctime, as they might dump core if the year is outside the |
| 1955 | range. */ | 1948 | range -999 .. 9999. */ |
| 1956 | BLOCK_INPUT; | 1949 | BLOCK_INPUT; |
| 1957 | tm = localtime (&value); | 1950 | tm = localtime (&value); |
| 1958 | if (tm && TM_YEAR_IN_ASCTIME_RANGE (tm->tm_year)) | 1951 | if (tm) |
| 1959 | { | 1952 | { |
| 1960 | tem = asctime (tm); | 1953 | static char const wday_name[][4] = |
| 1961 | if (tem) | 1954 | { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; |
| 1962 | memcpy (buf, tem, sizeof buf); | 1955 | static char const mon_name[][4] = |
| 1956 | { "Jan", "Feb", "Mar", "Apr", "May", "Jun", | ||
| 1957 | "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; | ||
| 1958 | printmax_t year_base = TM_YEAR_BASE; | ||
| 1959 | |||
| 1960 | len = sprintf (buf, "%s %s%3d %02d:%02d:%02d %"pMd, | ||
| 1961 | wday_name[tm->tm_wday], mon_name[tm->tm_mon], tm->tm_mday, | ||
| 1962 | tm->tm_hour, tm->tm_min, tm->tm_sec, | ||
| 1963 | tm->tm_year + year_base); | ||
| 1963 | } | 1964 | } |
| 1964 | UNBLOCK_INPUT; | 1965 | UNBLOCK_INPUT; |
| 1965 | if (! tem) | 1966 | if (! tm) |
| 1966 | time_overflow (); | 1967 | time_overflow (); |
| 1967 | 1968 | ||
| 1968 | return make_unibyte_string (buf, sizeof buf); | 1969 | return make_unibyte_string (buf, len); |
| 1969 | } | 1970 | } |
| 1970 | 1971 | ||
| 1971 | /* Yield A - B, measured in seconds. | 1972 | /* Yield A - B, measured in seconds. |