aboutsummaryrefslogtreecommitdiffstats
path: root/src/editfns.c
diff options
context:
space:
mode:
authorPaul Eggert2011-10-22 23:38:24 -0700
committerPaul Eggert2011-10-22 23:38:24 -0700
commitcfc09582247ffef6a46b6249e2fba9136a62d21e (patch)
tree50e102f64a2b88c692d9110990abd416c78c32f0 /src/editfns.c
parent92c938895c639463681ae1c58a944cae62b70b87 (diff)
parent86c606818495d9411fd5d6b1477f9a097eb18020 (diff)
downloademacs-cfc09582247ffef6a46b6249e2fba9136a62d21e.tar.gz
emacs-cfc09582247ffef6a46b6249e2fba9136a62d21e.zip
Merge from trunk.
Diffstat (limited to 'src/editfns.c')
-rw-r--r--src/editfns.c91
1 files changed, 40 insertions, 51 deletions
diff --git a/src/editfns.c b/src/editfns.c
index b376c3a7c51..16e552afe1d 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -85,6 +85,8 @@ extern Lisp_Object w32_get_internal_run_time (void);
85#endif 85#endif
86 86
87static void time_overflow (void) NO_RETURN; 87static void time_overflow (void) NO_RETURN;
88static Lisp_Object format_time_string (char const *, ptrdiff_t, Lisp_Object,
89 int, time_t *, struct tm **);
88static int tm_diff (struct tm *, struct tm *); 90static int tm_diff (struct tm *, struct tm *);
89static void update_buffer_properties (ptrdiff_t, ptrdiff_t); 91static void update_buffer_properties (ptrdiff_t, ptrdiff_t);
90 92
@@ -1687,32 +1689,40 @@ For example, to produce full ISO 8601 format, use "%Y-%m-%dT%T%z".
1687usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */) 1689usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */)
1688 (Lisp_Object format_string, Lisp_Object timeval, Lisp_Object universal) 1690 (Lisp_Object format_string, Lisp_Object timeval, Lisp_Object universal)
1689{ 1691{
1690 time_t value; 1692 time_t t;
1693 struct tm *tm;
1694
1695 CHECK_STRING (format_string);
1696 format_string = code_convert_string_norecord (format_string,
1697 Vlocale_coding_system, 1);
1698 return format_time_string (SSDATA (format_string), SBYTES (format_string),
1699 timeval, ! NILP (universal), &t, &tm);
1700}
1701
1702static Lisp_Object
1703format_time_string (char const *format, ptrdiff_t formatlen,
1704 Lisp_Object timeval, int ut, time_t *tval, struct tm **tmp)
1705{
1691 ptrdiff_t size; 1706 ptrdiff_t size;
1692 int usec; 1707 int usec;
1693 int ns; 1708 int ns;
1694 struct tm *tm; 1709 struct tm *tm;
1695 int ut = ! NILP (universal);
1696
1697 CHECK_STRING (format_string);
1698 1710
1699 if (! lisp_time_argument (timeval, &value, &usec)) 1711 if (! lisp_time_argument (timeval, tval, &usec))
1700 error ("Invalid time specification"); 1712 error ("Invalid time specification");
1701 ns = usec * 1000; 1713 ns = usec * 1000;
1702 1714
1703 format_string = code_convert_string_norecord (format_string,
1704 Vlocale_coding_system, 1);
1705
1706 /* This is probably enough. */ 1715 /* This is probably enough. */
1707 size = SBYTES (format_string); 1716 size = formatlen;
1708 if (size <= (STRING_BYTES_BOUND - 50) / 6) 1717 if (size <= (STRING_BYTES_BOUND - 50) / 6)
1709 size = size * 6 + 50; 1718 size = size * 6 + 50;
1710 1719
1711 BLOCK_INPUT; 1720 BLOCK_INPUT;
1712 tm = ut ? gmtime (&value) : localtime (&value); 1721 tm = ut ? gmtime (tval) : localtime (tval);
1713 UNBLOCK_INPUT; 1722 UNBLOCK_INPUT;
1714 if (! tm) 1723 if (! tm)
1715 time_overflow (); 1724 time_overflow ();
1725 *tmp = tm;
1716 1726
1717 synchronize_system_time_locale (); 1727 synchronize_system_time_locale ();
1718 1728
@@ -1723,9 +1733,7 @@ usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */)
1723 1733
1724 buf[0] = '\1'; 1734 buf[0] = '\1';
1725 BLOCK_INPUT; 1735 BLOCK_INPUT;
1726 result = emacs_nmemftime (buf, size, SSDATA (format_string), 1736 result = emacs_nmemftime (buf, size, format, formatlen, tm, ut, ns);
1727 SBYTES (format_string),
1728 tm, ut, ns);
1729 UNBLOCK_INPUT; 1737 UNBLOCK_INPUT;
1730 if ((result > 0 && result < size) || (result == 0 && buf[0] == '\0')) 1738 if ((result > 0 && result < size) || (result == 0 && buf[0] == '\0'))
1731 return code_convert_string_norecord (make_unibyte_string (buf, result), 1739 return code_convert_string_norecord (make_unibyte_string (buf, result),
@@ -1733,9 +1741,7 @@ usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */)
1733 1741
1734 /* If buffer was too small, make it bigger and try again. */ 1742 /* If buffer was too small, make it bigger and try again. */
1735 BLOCK_INPUT; 1743 BLOCK_INPUT;
1736 result = emacs_nmemftime (NULL, (size_t) -1, 1744 result = emacs_nmemftime (NULL, (size_t) -1, format, formatlen,
1737 SSDATA (format_string),
1738 SBYTES (format_string),
1739 tm, ut, ns); 1745 tm, ut, ns);
1740 UNBLOCK_INPUT; 1746 UNBLOCK_INPUT;
1741 if (STRING_BYTES_BOUND <= result) 1747 if (STRING_BYTES_BOUND <= result)
@@ -1983,51 +1989,34 @@ the data it can't find. */)
1983{ 1989{
1984 time_t value; 1990 time_t value;
1985 struct tm *t; 1991 struct tm *t;
1986 struct tm gmt; 1992 struct tm localtm;
1987 1993 struct tm *localt;
1988 if (!lisp_time_argument (specified_time, &value, NULL)) 1994 Lisp_Object zone_offset, zone_name;
1989 t = NULL; 1995
1990 else 1996 zone_offset = Qnil;
1991 { 1997 zone_name = format_time_string ("%Z", sizeof "%Z" - 1, specified_time,
1992 BLOCK_INPUT; 1998 0, &value, &localt);
1993 t = gmtime (&value); 1999 localtm = *localt;
1994 if (t) 2000 BLOCK_INPUT;
1995 { 2001 t = gmtime (&value);
1996 gmt = *t; 2002 UNBLOCK_INPUT;
1997 t = localtime (&value);
1998 }
1999 UNBLOCK_INPUT;
2000 }
2001 2003
2002 if (t) 2004 if (t)
2003 { 2005 {
2004 int offset = tm_diff (t, &gmt); 2006 int offset = tm_diff (&localtm, t);
2005 char *s = 0; 2007 zone_offset = make_number (offset);
2006 char buf[sizeof "+00" + INT_STRLEN_BOUND (int)]; 2008 if (SCHARS (zone_name) == 0)
2007
2008#ifdef HAVE_TM_ZONE
2009 if (t->tm_zone)
2010 s = (char *)t->tm_zone;
2011#else /* not HAVE_TM_ZONE */
2012#ifdef HAVE_TZNAME
2013 if (t->tm_isdst == 0 || t->tm_isdst == 1)
2014 s = tzname[t->tm_isdst];
2015#endif
2016#endif /* not HAVE_TM_ZONE */
2017
2018 if (!s)
2019 { 2009 {
2020 /* No local time zone name is available; use "+-NNNN" instead. */ 2010 /* No local time zone name is available; use "+-NNNN" instead. */
2021 int m = offset / 60; 2011 int m = offset / 60;
2022 int am = offset < 0 ? - m : m; 2012 int am = offset < 0 ? - m : m;
2013 char buf[sizeof "+00" + INT_STRLEN_BOUND (int)];
2023 sprintf (buf, "%c%02d%02d", (offset < 0 ? '-' : '+'), am/60, am%60); 2014 sprintf (buf, "%c%02d%02d", (offset < 0 ? '-' : '+'), am/60, am%60);
2024 s = buf; 2015 zone_name = build_string (buf);
2025 } 2016 }
2026
2027 return Fcons (make_number (offset), Fcons (build_string (s), Qnil));
2028 } 2017 }
2029 else 2018
2030 return Fmake_list (make_number (2), Qnil); 2019 return list2 (zone_offset, zone_name);
2031} 2020}
2032 2021
2033/* This holds the value of `environ' produced by the previous 2022/* This holds the value of `environ' produced by the previous