aboutsummaryrefslogtreecommitdiffstats
path: root/src/editfns.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/editfns.c')
-rw-r--r--src/editfns.c186
1 files changed, 85 insertions, 101 deletions
diff --git a/src/editfns.c b/src/editfns.c
index bb36d0dee71..a41565d8588 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -1,6 +1,6 @@
1/* Lisp functions pertaining to editing. 1/* Lisp functions pertaining to editing.
2 2
3Copyright (C) 1985-1987, 1989, 1993-2011 Free Software Foundation, Inc. 3Copyright (C) 1985-1987, 1989, 1993-2012 Free Software Foundation, Inc.
4 4
5This file is part of GNU Emacs. 5This file is part of GNU Emacs.
6 6
@@ -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 (EMACS_INT, EMACS_INT); 91static void update_buffer_properties (EMACS_INT, EMACS_INT);
90 92
@@ -146,7 +148,7 @@ init_editfns (void)
146 /* If the user name claimed in the environment vars differs from 148 /* If the user name claimed in the environment vars differs from
147 the real uid, use the claimed name to find the full name. */ 149 the real uid, use the claimed name to find the full name. */
148 tem = Fstring_equal (Vuser_login_name, Vuser_real_login_name); 150 tem = Fstring_equal (Vuser_login_name, Vuser_real_login_name);
149 Vuser_full_name = Fuser_full_name (NILP (tem)? make_number (geteuid()) 151 Vuser_full_name = Fuser_full_name (NILP (tem)? make_number (geteuid ())
150 : Vuser_login_name); 152 : Vuser_login_name);
151 153
152 p = getenv ("NAME"); 154 p = getenv ("NAME");
@@ -194,8 +196,7 @@ DEFUN ("byte-to-string", Fbyte_to_string, Sbyte_to_string, 1, 1, 0,
194} 196}
195 197
196DEFUN ("string-to-char", Fstring_to_char, Sstring_to_char, 1, 1, 0, 198DEFUN ("string-to-char", Fstring_to_char, Sstring_to_char, 1, 1, 0,
197 doc: /* Convert arg STRING to a character, the first character of that string. 199 doc: /* Return the first character in STRING. */)
198A multibyte character is handled correctly. */)
199 (register Lisp_Object string) 200 (register Lisp_Object string)
200{ 201{
201 register Lisp_Object val; 202 register Lisp_Object val;
@@ -662,10 +663,11 @@ is after LIMIT, then LIMIT will be returned instead. */)
662 663
663DEFUN ("constrain-to-field", Fconstrain_to_field, Sconstrain_to_field, 2, 5, 0, 664DEFUN ("constrain-to-field", Fconstrain_to_field, Sconstrain_to_field, 2, 5, 0,
664 doc: /* Return the position closest to NEW-POS that is in the same field as OLD-POS. 665 doc: /* Return the position closest to NEW-POS that is in the same field as OLD-POS.
665
666A field is a region of text with the same `field' property. 666A field is a region of text with the same `field' property.
667If NEW-POS is nil, then the current point is used instead, and set to the 667
668constrained position if that is different. 668If NEW-POS is nil, then use the current point instead, and move point
669to the resulting constrained position, in addition to returning that
670position.
669 671
670If OLD-POS is at the boundary of two fields, then the allowable 672If OLD-POS is at the boundary of two fields, then the allowable
671positions for NEW-POS depends on the value of the optional argument 673positions for NEW-POS depends on the value of the optional argument
@@ -1696,36 +1698,46 @@ The modifiers are `E' and `O'. For certain characters X,
1696%EX is a locale's alternative version of %X; 1698%EX is a locale's alternative version of %X;
1697%OX is like %X, but uses the locale's number symbols. 1699%OX is like %X, but uses the locale's number symbols.
1698 1700
1699For example, to produce full ISO 8601 format, use "%Y-%m-%dT%T%z". */) 1701For example, to produce full ISO 8601 format, use "%Y-%m-%dT%T%z".
1702
1703usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */)
1700 (Lisp_Object format_string, Lisp_Object timeval, Lisp_Object universal) 1704 (Lisp_Object format_string, Lisp_Object timeval, Lisp_Object universal)
1701{ 1705{
1702 time_t value; 1706 time_t t;
1707 struct tm *tm;
1708
1709 CHECK_STRING (format_string);
1710 format_string = code_convert_string_norecord (format_string,
1711 Vlocale_coding_system, 1);
1712 return format_time_string (SSDATA (format_string), SBYTES (format_string),
1713 timeval, ! NILP (universal), &t, &tm);
1714}
1715
1716static Lisp_Object
1717format_time_string (char const *format, ptrdiff_t formatlen,
1718 Lisp_Object timeval, int ut, time_t *tval, struct tm **tmp)
1719{
1703 ptrdiff_t size; 1720 ptrdiff_t size;
1704 int usec; 1721 int usec;
1705 int ns; 1722 int ns;
1706 struct tm *tm; 1723 struct tm *tm;
1707 int ut = ! NILP (universal);
1708
1709 CHECK_STRING (format_string);
1710 1724
1711 if (! (lisp_time_argument (timeval, &value, &usec) 1725 if (! (lisp_time_argument (timeval, tval, &usec)
1712 && 0 <= usec && usec < 1000000)) 1726 && 0 <= usec && usec < 1000000))
1713 error ("Invalid time specification"); 1727 error ("Invalid time specification");
1714 ns = usec * 1000; 1728 ns = usec * 1000;
1715 1729
1716 format_string = code_convert_string_norecord (format_string,
1717 Vlocale_coding_system, 1);
1718
1719 /* This is probably enough. */ 1730 /* This is probably enough. */
1720 size = SBYTES (format_string); 1731 size = formatlen;
1721 if (size <= (STRING_BYTES_BOUND - 50) / 6) 1732 if (size <= (STRING_BYTES_BOUND - 50) / 6)
1722 size = size * 6 + 50; 1733 size = size * 6 + 50;
1723 1734
1724 BLOCK_INPUT; 1735 BLOCK_INPUT;
1725 tm = ut ? gmtime (&value) : localtime (&value); 1736 tm = ut ? gmtime (tval) : localtime (tval);
1726 UNBLOCK_INPUT; 1737 UNBLOCK_INPUT;
1727 if (! tm) 1738 if (! tm)
1728 time_overflow (); 1739 time_overflow ();
1740 *tmp = tm;
1729 1741
1730 synchronize_system_time_locale (); 1742 synchronize_system_time_locale ();
1731 1743
@@ -1736,9 +1748,7 @@ For example, to produce full ISO 8601 format, use "%Y-%m-%dT%T%z". */)
1736 1748
1737 buf[0] = '\1'; 1749 buf[0] = '\1';
1738 BLOCK_INPUT; 1750 BLOCK_INPUT;
1739 result = emacs_nmemftime (buf, size, SSDATA (format_string), 1751 result = emacs_nmemftime (buf, size, format, formatlen, tm, ut, ns);
1740 SBYTES (format_string),
1741 tm, ut, ns);
1742 UNBLOCK_INPUT; 1752 UNBLOCK_INPUT;
1743 if ((result > 0 && result < size) || (result == 0 && buf[0] == '\0')) 1753 if ((result > 0 && result < size) || (result == 0 && buf[0] == '\0'))
1744 return code_convert_string_norecord (make_unibyte_string (buf, result), 1754 return code_convert_string_norecord (make_unibyte_string (buf, result),
@@ -1746,9 +1756,7 @@ For example, to produce full ISO 8601 format, use "%Y-%m-%dT%T%z". */)
1746 1756
1747 /* If buffer was too small, make it bigger and try again. */ 1757 /* If buffer was too small, make it bigger and try again. */
1748 BLOCK_INPUT; 1758 BLOCK_INPUT;
1749 result = emacs_nmemftime (NULL, (size_t) -1, 1759 result = emacs_nmemftime (NULL, (size_t) -1, format, formatlen,
1750 SSDATA (format_string),
1751 SBYTES (format_string),
1752 tm, ut, ns); 1760 tm, ut, ns);
1753 UNBLOCK_INPUT; 1761 UNBLOCK_INPUT;
1754 if (STRING_BYTES_BOUND <= result) 1762 if (STRING_BYTES_BOUND <= result)
@@ -1993,50 +2001,34 @@ the data it can't find. */)
1993{ 2001{
1994 time_t value; 2002 time_t value;
1995 struct tm *t; 2003 struct tm *t;
1996 struct tm gmt; 2004 struct tm localtm;
1997 2005 struct tm *localt;
1998 if (!lisp_time_argument (specified_time, &value, NULL)) 2006 Lisp_Object zone_offset, zone_name;
1999 t = NULL; 2007
2000 else 2008 zone_offset = Qnil;
2001 { 2009 zone_name = format_time_string ("%Z", sizeof "%Z" - 1, specified_time,
2002 BLOCK_INPUT; 2010 0, &value, &localt);
2003 t = gmtime (&value); 2011 localtm = *localt;
2004 if (t) 2012 BLOCK_INPUT;
2005 { 2013 t = gmtime (&value);
2006 gmt = *t; 2014 UNBLOCK_INPUT;
2007 t = localtime (&value);
2008 }
2009 UNBLOCK_INPUT;
2010 }
2011 2015
2012 if (t) 2016 if (t)
2013 { 2017 {
2014 int offset = tm_diff (t, &gmt); 2018 int offset = tm_diff (&localtm, t);
2015 char *s = 0; 2019 zone_offset = make_number (offset);
2016 char buf[6]; 2020 if (SCHARS (zone_name) == 0)
2017
2018#ifdef HAVE_TM_ZONE
2019 if (t->tm_zone)
2020 s = (char *)t->tm_zone;
2021#else /* not HAVE_TM_ZONE */
2022#ifdef HAVE_TZNAME
2023 if (t->tm_isdst == 0 || t->tm_isdst == 1)
2024 s = tzname[t->tm_isdst];
2025#endif
2026#endif /* not HAVE_TM_ZONE */
2027
2028 if (!s)
2029 { 2021 {
2030 /* No local time zone name is available; use "+-NNNN" instead. */ 2022 /* No local time zone name is available; use "+-NNNN" instead. */
2031 int am = (offset < 0 ? -offset : offset) / 60; 2023 int m = offset / 60;
2024 int am = offset < 0 ? - m : m;
2025 char buf[sizeof "+00" + INT_STRLEN_BOUND (int)];
2032 sprintf (buf, "%c%02d%02d", (offset < 0 ? '-' : '+'), am/60, am%60); 2026 sprintf (buf, "%c%02d%02d", (offset < 0 ? '-' : '+'), am/60, am%60);
2033 s = buf; 2027 zone_name = build_string (buf);
2034 } 2028 }
2035
2036 return Fcons (make_number (offset), Fcons (build_string (s), Qnil));
2037 } 2029 }
2038 else 2030
2039 return Fmake_list (make_number (2), Qnil); 2031 return list2 (zone_offset, zone_name);
2040} 2032}
2041 2033
2042/* This holds the value of `environ' produced by the previous 2034/* This holds the value of `environ' produced by the previous
@@ -2052,7 +2044,12 @@ static char *initial_tz;
2052DEFUN ("set-time-zone-rule", Fset_time_zone_rule, Sset_time_zone_rule, 1, 1, 0, 2044DEFUN ("set-time-zone-rule", Fset_time_zone_rule, Sset_time_zone_rule, 1, 1, 0,
2053 doc: /* Set the local time zone using TZ, a string specifying a time zone rule. 2045 doc: /* Set the local time zone using TZ, a string specifying a time zone rule.
2054If TZ is nil, use implementation-defined default time zone information. 2046If TZ is nil, use implementation-defined default time zone information.
2055If TZ is t, use Universal Time. */) 2047If TZ is t, use Universal Time.
2048
2049Instead of calling this function, you typically want (setenv "TZ" TZ).
2050That changes both the environment of the Emacs process and the
2051variable `process-environment', whereas `set-time-zone-rule' affects
2052only the former. */)
2056 (Lisp_Object tz) 2053 (Lisp_Object tz)
2057{ 2054{
2058 const char *tzstring; 2055 const char *tzstring;
@@ -2072,7 +2069,7 @@ If TZ is t, use Universal Time. */)
2072 } 2069 }
2073 2070
2074 set_time_zone_rule (tzstring); 2071 set_time_zone_rule (tzstring);
2075 free (environbuf); 2072 xfree (environbuf);
2076 environbuf = environ; 2073 environbuf = environ;
2077 2074
2078 return Qnil; 2075 return Qnil;
@@ -2101,7 +2098,7 @@ static char set_time_zone_rule_tz2[] = "TZ=GMT+1";
2101void 2098void
2102set_time_zone_rule (const char *tzstring) 2099set_time_zone_rule (const char *tzstring)
2103{ 2100{
2104 int envptrs; 2101 ptrdiff_t envptrs;
2105 char **from, **to, **newenv; 2102 char **from, **to, **newenv;
2106 2103
2107 /* Make the ENVIRON vector longer with room for TZSTRING. */ 2104 /* Make the ENVIRON vector longer with room for TZSTRING. */
@@ -3156,10 +3153,9 @@ It returns the number of characters changed. */)
3156} 3153}
3157 3154
3158DEFUN ("delete-region", Fdelete_region, Sdelete_region, 2, 2, "r", 3155DEFUN ("delete-region", Fdelete_region, Sdelete_region, 2, 2, "r",
3159 doc: /* Delete the text between point and mark. 3156 doc: /* Delete the text between START and END.
3160 3157If called interactively, delete the region between point and mark.
3161When called from a program, expects two arguments, 3158This command deletes buffer text without modifying the kill ring. */)
3162positions (integers or markers) specifying the stretch to be deleted. */)
3163 (Lisp_Object start, Lisp_Object end) 3159 (Lisp_Object start, Lisp_Object end)
3164{ 3160{
3165 validate_region (&start, &end); 3161 validate_region (&start, &end);
@@ -3248,7 +3244,7 @@ save_restriction_save (void)
3248 end = buildmark (ZV, ZV_BYTE); 3244 end = buildmark (ZV, ZV_BYTE);
3249 3245
3250 /* END must move forward if text is inserted at its exact location. */ 3246 /* END must move forward if text is inserted at its exact location. */
3251 XMARKER(end)->insertion_type = 1; 3247 XMARKER (end)->insertion_type = 1;
3252 3248
3253 return Fcons (beg, end); 3249 return Fcons (beg, end);
3254 } 3250 }
@@ -3352,7 +3348,7 @@ usage: (save-restriction &rest BODY) */)
3352static char *message_text; 3348static char *message_text;
3353 3349
3354/* Allocated length of that buffer. */ 3350/* Allocated length of that buffer. */
3355static int message_length; 3351static ptrdiff_t message_length;
3356 3352
3357DEFUN ("message", Fmessage, Smessage, 1, MANY, 0, 3353DEFUN ("message", Fmessage, Smessage, 1, MANY, 0,
3358 doc: /* Display a message at the bottom of the screen. 3354 doc: /* Display a message at the bottom of the screen.
@@ -3434,8 +3430,8 @@ usage: (message-box FORMAT-STRING &rest ARGS) */)
3434 } 3430 }
3435 if (SBYTES (val) > message_length) 3431 if (SBYTES (val) > message_length)
3436 { 3432 {
3433 message_text = (char *) xrealloc (message_text, SBYTES (val));
3437 message_length = SBYTES (val); 3434 message_length = SBYTES (val);
3438 message_text = (char *)xrealloc (message_text, message_length);
3439 } 3435 }
3440 memcpy (message_text, SDATA (val), SBYTES (val)); 3436 memcpy (message_text, SDATA (val), SBYTES (val));
3441 message2 (message_text, SBYTES (val), 3437 message2 (message_text, SBYTES (val),
@@ -3506,22 +3502,6 @@ usage: (propertize STRING &rest PROPERTIES) */)
3506 RETURN_UNGCPRO (string); 3502 RETURN_UNGCPRO (string);
3507} 3503}
3508 3504
3509/* pWIDE is a conversion for printing large decimal integers (possibly with a
3510 trailing "d" that is ignored). pWIDElen is its length. signed_wide and
3511 unsigned_wide are signed and unsigned types for printing them. Use widest
3512 integers if available so that more floating point values can be converted. */
3513#ifdef PRIdMAX
3514# define pWIDE PRIdMAX
3515enum { pWIDElen = sizeof PRIdMAX - 2 }; /* Don't count trailing "d". */
3516typedef intmax_t signed_wide;
3517typedef uintmax_t unsigned_wide;
3518#else
3519# define pWIDE pI
3520enum { pWIDElen = sizeof pI - 1 };
3521typedef EMACS_INT signed_wide;
3522typedef EMACS_UINT unsigned_wide;
3523#endif
3524
3525DEFUN ("format", Fformat, Sformat, 1, MANY, 0, 3505DEFUN ("format", Fformat, Sformat, 1, MANY, 0,
3526 doc: /* Format a string out of a format-string and arguments. 3506 doc: /* Format a string out of a format-string and arguments.
3527The first argument is a format control string. 3507The first argument is a format control string.
@@ -3891,7 +3871,7 @@ usage: (format STRING &rest OBJECTS) */)
3891 enum 3871 enum
3892 { 3872 {
3893 /* Maximum precision for a %f conversion such that the 3873 /* Maximum precision for a %f conversion such that the
3894 trailing output digit might be nonzero. Any precisions 3874 trailing output digit might be nonzero. Any precision
3895 larger than this will not yield useful information. */ 3875 larger than this will not yield useful information. */
3896 USEFUL_PRECISION_MAX = 3876 USEFUL_PRECISION_MAX =
3897 ((1 - DBL_MIN_EXP) 3877 ((1 - DBL_MIN_EXP)
@@ -3900,10 +3880,14 @@ usage: (format STRING &rest OBJECTS) */)
3900 : -1)), 3880 : -1)),
3901 3881
3902 /* Maximum number of bytes generated by any format, if 3882 /* Maximum number of bytes generated by any format, if
3903 precision is no more than DBL_USEFUL_PRECISION_MAX. 3883 precision is no more than USEFUL_PRECISION_MAX.
3904 On all practical hosts, %f is the worst case. */ 3884 On all practical hosts, %f is the worst case. */
3905 SPRINTF_BUFSIZE = 3885 SPRINTF_BUFSIZE =
3906 sizeof "-." + (DBL_MAX_10_EXP + 1) + USEFUL_PRECISION_MAX 3886 sizeof "-." + (DBL_MAX_10_EXP + 1) + USEFUL_PRECISION_MAX,
3887
3888 /* Length of pM (that is, of pMd without the
3889 trailing "d"). */
3890 pMlen = sizeof pMd - 2
3907 }; 3891 };
3908 verify (0 < USEFUL_PRECISION_MAX); 3892 verify (0 < USEFUL_PRECISION_MAX);
3909 3893
@@ -3916,7 +3900,7 @@ usage: (format STRING &rest OBJECTS) */)
3916 3900
3917 /* Copy of conversion specification, modified somewhat. 3901 /* Copy of conversion specification, modified somewhat.
3918 At most three flags F can be specified at once. */ 3902 At most three flags F can be specified at once. */
3919 char convspec[sizeof "%FFF.*d" + pWIDElen]; 3903 char convspec[sizeof "%FFF.*d" + pMlen];
3920 3904
3921 /* Avoid undefined behavior in underlying sprintf. */ 3905 /* Avoid undefined behavior in underlying sprintf. */
3922 if (conversion == 'd' || conversion == 'i') 3906 if (conversion == 'd' || conversion == 'i')
@@ -3924,7 +3908,7 @@ usage: (format STRING &rest OBJECTS) */)
3924 3908
3925 /* Create the copy of the conversion specification, with 3909 /* Create the copy of the conversion specification, with
3926 any width and precision removed, with ".*" inserted, 3910 any width and precision removed, with ".*" inserted,
3927 and with pWIDE inserted for integer formats. */ 3911 and with pM inserted for integer formats. */
3928 { 3912 {
3929 char *f = convspec; 3913 char *f = convspec;
3930 *f++ = '%'; 3914 *f++ = '%';
@@ -3939,8 +3923,8 @@ usage: (format STRING &rest OBJECTS) */)
3939 || conversion == 'o' || conversion == 'x' 3923 || conversion == 'o' || conversion == 'x'
3940 || conversion == 'X') 3924 || conversion == 'X')
3941 { 3925 {
3942 memcpy (f, pWIDE, pWIDElen); 3926 memcpy (f, pMd, pMlen);
3943 f += pWIDElen; 3927 f += pMlen;
3944 zero_flag &= ~ precision_given; 3928 zero_flag &= ~ precision_given;
3945 } 3929 }
3946 *f++ = conversion; 3930 *f++ = conversion;
@@ -3980,7 +3964,7 @@ usage: (format STRING &rest OBJECTS) */)
3980 /* For float, maybe we should use "%1.0f" 3964 /* For float, maybe we should use "%1.0f"
3981 instead so it also works for values outside 3965 instead so it also works for values outside
3982 the integer range. */ 3966 the integer range. */
3983 signed_wide x; 3967 printmax_t x;
3984 if (INTEGERP (args[n])) 3968 if (INTEGERP (args[n]))
3985 x = XINT (args[n]); 3969 x = XINT (args[n]);
3986 else 3970 else
@@ -3988,13 +3972,13 @@ usage: (format STRING &rest OBJECTS) */)
3988 double d = XFLOAT_DATA (args[n]); 3972 double d = XFLOAT_DATA (args[n]);
3989 if (d < 0) 3973 if (d < 0)
3990 { 3974 {
3991 x = TYPE_MINIMUM (signed_wide); 3975 x = TYPE_MINIMUM (printmax_t);
3992 if (x < d) 3976 if (x < d)
3993 x = d; 3977 x = d;
3994 } 3978 }
3995 else 3979 else
3996 { 3980 {
3997 x = TYPE_MAXIMUM (signed_wide); 3981 x = TYPE_MAXIMUM (printmax_t);
3998 if (d < x) 3982 if (d < x)
3999 x = d; 3983 x = d;
4000 } 3984 }
@@ -4004,7 +3988,7 @@ usage: (format STRING &rest OBJECTS) */)
4004 else 3988 else
4005 { 3989 {
4006 /* Don't sign-extend for octal or hex printing. */ 3990 /* Don't sign-extend for octal or hex printing. */
4007 unsigned_wide x; 3991 uprintmax_t x;
4008 if (INTEGERP (args[n])) 3992 if (INTEGERP (args[n]))
4009 x = XUINT (args[n]); 3993 x = XUINT (args[n]);
4010 else 3994 else
@@ -4014,7 +3998,7 @@ usage: (format STRING &rest OBJECTS) */)
4014 x = 0; 3998 x = 0;
4015 else 3999 else
4016 { 4000 {
4017 x = TYPE_MAXIMUM (unsigned_wide); 4001 x = TYPE_MAXIMUM (uprintmax_t);
4018 if (d < x) 4002 if (d < x)
4019 x = d; 4003 x = d;
4020 } 4004 }
@@ -4143,8 +4127,8 @@ usage: (format STRING &rest OBJECTS) */)
4143 format++; 4127 format++;
4144 while (! CHAR_HEAD_P (*format)); 4128 while (! CHAR_HEAD_P (*format));
4145 4129
4146 convbytes = format - format0; 4130 convbytes = format - src;
4147 memset (&discarded[format0 + 1 - format_start], 2, convbytes - 1); 4131 memset (&discarded[src + 1 - format_start], 2, convbytes - 1);
4148 } 4132 }
4149 else 4133 else
4150 { 4134 {
@@ -4172,7 +4156,7 @@ usage: (format STRING &rest OBJECTS) */)
4172 character. CONVBYTES says how much room is needed. Allocate 4156 character. CONVBYTES says how much room is needed. Allocate
4173 enough room (and then some) and do it again. */ 4157 enough room (and then some) and do it again. */
4174 { 4158 {
4175 EMACS_INT used = p - buf; 4159 ptrdiff_t used = p - buf;
4176 4160
4177 if (max_bufsize - used < convbytes) 4161 if (max_bufsize - used < convbytes)
4178 string_overflow (); 4162 string_overflow ();