aboutsummaryrefslogtreecommitdiffstats
path: root/src/editfns.c
diff options
context:
space:
mode:
authorPaul Eggert2012-05-03 13:04:29 -0700
committerPaul Eggert2012-05-03 13:04:29 -0700
commitab0fa4e4ba0b2b93a9ef007842523d8d5f9eb758 (patch)
tree9adfb1831b29c6f4d68b5d1ea6de54f05617bc6a /src/editfns.c
parentf7ae6719123ad5f4f505290621810318d9ee5484 (diff)
downloademacs-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.c39
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
84extern Lisp_Object w32_get_internal_run_time (void); 77extern 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.