/* Lisp functions pertaining to editing.
-Copyright (C) 1985-1987, 1989, 1993-2011 Free Software Foundation, Inc.
+Copyright (C) 1985-1987, 1989, 1993-2012 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#endif
static void time_overflow (void) NO_RETURN;
+static Lisp_Object format_time_string (char const *, ptrdiff_t, Lisp_Object,
+ int, time_t *, struct tm **);
static int tm_diff (struct tm *, struct tm *);
static void update_buffer_properties (ptrdiff_t, ptrdiff_t);
if (NILP (uid))
return Vuser_login_name;
- id = XFLOATINT (uid);
+ CONS_TO_INTEGER (uid, uid_t, id);
BLOCK_INPUT;
pw = getpwuid (id);
UNBLOCK_INPUT;
return Vuser_full_name;
else if (NUMBERP (uid))
{
- uid_t u = XFLOATINT (uid);
+ uid_t u;
+ CONS_TO_INTEGER (uid, uid_t, u);
BLOCK_INPUT;
pw = getpwuid (u);
UNBLOCK_INPUT;
usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */)
(Lisp_Object format_string, Lisp_Object timeval, Lisp_Object universal)
{
- time_t value;
+ time_t t;
+ struct tm *tm;
+
+ CHECK_STRING (format_string);
+ format_string = code_convert_string_norecord (format_string,
+ Vlocale_coding_system, 1);
+ return format_time_string (SSDATA (format_string), SBYTES (format_string),
+ timeval, ! NILP (universal), &t, &tm);
+}
+
+static Lisp_Object
+format_time_string (char const *format, ptrdiff_t formatlen,
+ Lisp_Object timeval, int ut, time_t *tval, struct tm **tmp)
+{
ptrdiff_t size;
int usec;
int ns;
struct tm *tm;
- int ut = ! NILP (universal);
-
- CHECK_STRING (format_string);
- if (! (lisp_time_argument (timeval, &value, &usec)
- && 0 <= usec && usec < 1000000))
+ if (! lisp_time_argument (timeval, tval, &usec))
error ("Invalid time specification");
ns = usec * 1000;
- format_string = code_convert_string_norecord (format_string,
- Vlocale_coding_system, 1);
-
/* This is probably enough. */
- size = SBYTES (format_string);
+ size = formatlen;
if (size <= (STRING_BYTES_BOUND - 50) / 6)
size = size * 6 + 50;
BLOCK_INPUT;
- tm = ut ? gmtime (&value) : localtime (&value);
+ tm = ut ? gmtime (tval) : localtime (tval);
UNBLOCK_INPUT;
if (! tm)
time_overflow ();
+ *tmp = tm;
synchronize_system_time_locale ();
buf[0] = '\1';
BLOCK_INPUT;
- result = emacs_nmemftime (buf, size, SSDATA (format_string),
- SBYTES (format_string),
- tm, ut, ns);
+ result = emacs_nmemftime (buf, size, format, formatlen, tm, ut, ns);
UNBLOCK_INPUT;
if ((result > 0 && result < size) || (result == 0 && buf[0] == '\0'))
return code_convert_string_norecord (make_unibyte_string (buf, result),
/* If buffer was too small, make it bigger and try again. */
BLOCK_INPUT;
- result = emacs_nmemftime (NULL, (size_t) -1,
- SSDATA (format_string),
- SBYTES (format_string),
+ result = emacs_nmemftime (NULL, (size_t) -1, format, formatlen,
tm, ut, ns);
UNBLOCK_INPUT;
if (STRING_BYTES_BOUND <= result)
{
time_t value;
struct tm *t;
- struct tm gmt;
-
- if (!lisp_time_argument (specified_time, &value, NULL))
- t = NULL;
- else
- {
- BLOCK_INPUT;
- t = gmtime (&value);
- if (t)
- {
- gmt = *t;
- t = localtime (&value);
- }
- UNBLOCK_INPUT;
- }
+ struct tm localtm;
+ struct tm *localt;
+ Lisp_Object zone_offset, zone_name;
+
+ zone_offset = Qnil;
+ zone_name = format_time_string ("%Z", sizeof "%Z" - 1, specified_time,
+ 0, &value, &localt);
+ localtm = *localt;
+ BLOCK_INPUT;
+ t = gmtime (&value);
+ UNBLOCK_INPUT;
if (t)
{
- int offset = tm_diff (t, &gmt);
- char *s = 0;
- char buf[sizeof "+00" + INT_STRLEN_BOUND (int)];
-
-#ifdef HAVE_TM_ZONE
- if (t->tm_zone)
- s = (char *)t->tm_zone;
-#else /* not HAVE_TM_ZONE */
-#ifdef HAVE_TZNAME
- if (t->tm_isdst == 0 || t->tm_isdst == 1)
- s = tzname[t->tm_isdst];
-#endif
-#endif /* not HAVE_TM_ZONE */
-
- if (!s)
+ int offset = tm_diff (&localtm, t);
+ zone_offset = make_number (offset);
+ if (SCHARS (zone_name) == 0)
{
/* No local time zone name is available; use "+-NNNN" instead. */
int m = offset / 60;
int am = offset < 0 ? - m : m;
+ char buf[sizeof "+00" + INT_STRLEN_BOUND (int)];
sprintf (buf, "%c%02d%02d", (offset < 0 ? '-' : '+'), am/60, am%60);
- s = buf;
+ zone_name = build_string (buf);
}
-
- return Fcons (make_number (offset), Fcons (build_string (s), Qnil));
}
- else
- return Fmake_list (make_number (2), Qnil);
+
+ return list2 (zone_offset, zone_name);
}
/* This holds the value of `environ' produced by the previous
}
set_time_zone_rule (tzstring);
- free (environbuf);
+ xfree (environbuf);
environbuf = environ;
return Qnil;
enum
{
/* Maximum precision for a %f conversion such that the
- trailing output digit might be nonzero. Any precisions
+ trailing output digit might be nonzero. Any precision
larger than this will not yield useful information. */
USEFUL_PRECISION_MAX =
((1 - DBL_MIN_EXP)