X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/253c3c8280d304b37961df50fa209ec3c4c7eb44..92848133b2c17d028b2172b6f3ef43e6c1a1370c:/src/editfns.c
diff --git a/src/editfns.c b/src/editfns.c
index 264097ffe5..9f30ea0641 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -1,14 +1,14 @@
/* Lisp functions pertaining to editing.
Copyright (C) 1985, 1986, 1987, 1989, 1993, 1994, 1995, 1996,
1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+ 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
This file is part of GNU Emacs.
-GNU Emacs is free software; you can redistribute it and/or modify
+GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -16,14 +16,13 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA. */
+along with GNU Emacs. If not, see . */
#include
#include
#include
+#include
#ifdef HAVE_PWD_H
#include
@@ -69,6 +68,10 @@ Boston, MA 02110-1301, USA. */
#define NULL 0
#endif
+#ifndef USER_FULL_NAME
+#define USER_FULL_NAME pw->pw_gecos
+#endif
+
#ifndef USE_CRT_DLL
extern char **environ;
#endif
@@ -96,10 +99,11 @@ static Lisp_Object region_limit P_ ((int));
int lisp_time_argument P_ ((Lisp_Object, time_t *, int *));
static size_t emacs_memftimeu P_ ((char *, size_t, const char *,
size_t, const struct tm *, int));
-static void general_insert_function P_ ((void (*) (const unsigned char *, int),
- void (*) (Lisp_Object, int, int, int,
- int, int),
- int, int, Lisp_Object *));
+static void general_insert_function (void (*) (const unsigned char *, EMACS_INT),
+ void (*) (Lisp_Object, EMACS_INT,
+ EMACS_INT, EMACS_INT,
+ EMACS_INT, int),
+ int, int, Lisp_Object *);
static Lisp_Object subst_char_in_region_unwind P_ ((Lisp_Object));
static Lisp_Object subst_char_in_region_unwind_1 P_ ((Lisp_Object));
static void transpose_markers P_ ((int, int, int, int, int, int, int, int));
@@ -227,7 +231,7 @@ A multibyte character is handled correctly. */)
if (SCHARS (string))
{
if (STRING_MULTIBYTE (string))
- XSETFASTINT (val, STRING_CHAR (SDATA (string), SBYTES (string)));
+ XSETFASTINT (val, STRING_CHAR (SDATA (string)));
else
XSETFASTINT (val, SREF (string, 0));
}
@@ -482,7 +486,7 @@ get_pos_property (position, prop, object)
}
}
- { /* Now check the text-properties. */
+ { /* Now check the text properties. */
int stickiness = text_property_stickiness (prop, position, object);
if (stickiness > 0)
return Fget_text_property (position, prop, object);
@@ -658,7 +662,7 @@ If POS is nil, the value of point is used for POS. */)
}
DEFUN ("field-string-no-properties", Ffield_string_no_properties, Sfield_string_no_properties, 0, 1, 0,
- doc: /* Return the contents of the field around POS, without text-properties.
+ doc: /* Return the contents of the field around POS, without text properties.
A field is a region of text with the same `field' property.
If POS is nil, the value of point is used for POS. */)
(pos)
@@ -993,6 +997,9 @@ functions that change the buffer will still cause deactivation
of the mark at the end of the command. To prevent that, bind
`deactivate-mark' with `let'.
+If you only want to save the current buffer but not point nor mark,
+then just use `save-current-buffer', or even `with-current-buffer'.
+
usage: (save-excursion &rest BODY) */)
(args)
Lisp_Object args;
@@ -1276,12 +1283,13 @@ This is based on the effective uid, not the real uid.
Also, if the environment variables LOGNAME or USER are set,
that determines the value of this function.
-If optional argument UID is an integer, return the login name of the user
-with that uid, or nil if there is no such user. */)
+If optional argument UID is an integer or a float, return the login name
+of the user with that uid, or nil if there is no such user. */)
(uid)
Lisp_Object uid;
{
struct passwd *pw;
+ uid_t id;
/* Set up the user name info if we didn't do it before.
(That can happen if Emacs is dumpable
@@ -1292,9 +1300,9 @@ with that uid, or nil if there is no such user. */)
if (NILP (uid))
return Vuser_login_name;
- CHECK_NUMBER (uid);
+ id = (uid_t)XFLOATINT (uid);
BLOCK_INPUT;
- pw = (struct passwd *) getpwuid (XINT (uid));
+ pw = (struct passwd *) getpwuid (id);
UNBLOCK_INPUT;
return (pw ? build_string (pw->pw_name) : Qnil);
}
@@ -1316,23 +1324,33 @@ This ignores the environment variables LOGNAME and USER, so it differs from
DEFUN ("user-uid", Fuser_uid, Suser_uid, 0, 0, 0,
doc: /* Return the effective uid of Emacs.
-Value is an integer or float, depending on the value. */)
+Value is an integer or a float, depending on the value. */)
()
{
/* Assignment to EMACS_INT stops GCC whining about limited range of
data type. */
EMACS_INT euid = geteuid ();
+
+ /* Make sure we don't produce a negative UID due to signed integer
+ overflow. */
+ if (euid < 0)
+ return make_float ((double)geteuid ());
return make_fixnum_or_float (euid);
}
DEFUN ("user-real-uid", Fuser_real_uid, Suser_real_uid, 0, 0, 0,
doc: /* Return the real uid of Emacs.
-Value is an integer or float, depending on the value. */)
+Value is an integer or a float, depending on the value. */)
()
{
/* Assignment to EMACS_INT stops GCC whining about limited range of
data type. */
EMACS_INT uid = getuid ();
+
+ /* Make sure we don't produce a negative UID due to signed integer
+ overflow. */
+ if (uid < 0)
+ return make_float ((double)getuid ());
return make_fixnum_or_float (uid);
}
@@ -1487,7 +1505,7 @@ on systems that do not provide resolution finer than a second. */)
make_number ((secs >> 0) & 0xffff),
make_number (usecs));
#else /* ! HAVE_GETRUSAGE */
-#if WINDOWSNT
+#ifdef WINDOWSNT
return w32_get_internal_run_time ();
#else /* ! WINDOWSNT */
return Fcurrent_time ();
@@ -1551,12 +1569,13 @@ DEFUN ("float-time", Ffloat_time, Sfloat_time, 0, 1, 0,
doc: /* Return the current time, as a float number of seconds since the epoch.
If SPECIFIED-TIME is given, it is the time to convert to float
instead of the current time. The argument should have the form
-(HIGH LOW . IGNORED). Thus, you can use times obtained from
+(HIGH LOW) or (HIGH LOW USEC). Thus, you can use times obtained from
`current-time' and from `file-attributes'. SPECIFIED-TIME can also
have the form (HIGH . LOW), but this is considered obsolete.
WARNING: Since the result is floating point, it may not be exact.
-Do not use this function if precise time stamps are required. */)
+If precise time stamps are required, use either `current-time',
+or (if you need time as a string) `format-time-string'. */)
(specified_time)
Lisp_Object specified_time;
{
@@ -1878,7 +1897,7 @@ usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */)
}
DEFUN ("current-time-string", Fcurrent_time_string, Scurrent_time_string, 0, 1, 0,
- doc: /* Return the current time, as a human-readable string.
+ doc: /* Return the current local time, as a human-readable string.
Programs can use this function to decode a time,
since the number of columns in each field is fixed
if the year is in the range 1000-9999.
@@ -2040,8 +2059,7 @@ If TZ is t, use Universal Time. */)
}
set_time_zone_rule (tzstring);
- if (environbuf)
- free (environbuf);
+ free (environbuf);
environbuf = environ;
return Qnil;
@@ -2149,12 +2167,12 @@ set_time_zone_rule (tzstring)
INSERT_FROM_STRING_FUNC as the last argument. */
static void
-general_insert_function (insert_func, insert_from_string_func,
- inherit, nargs, args)
- void (*insert_func) P_ ((const unsigned char *, int));
- void (*insert_from_string_func) P_ ((Lisp_Object, int, int, int, int, int));
- int inherit, nargs;
- register Lisp_Object *args;
+general_insert_function (void (*insert_func)
+ (const unsigned char *, EMACS_INT),
+ void (*insert_from_string_func)
+ (Lisp_Object, EMACS_INT, EMACS_INT,
+ EMACS_INT, EMACS_INT, int),
+ int inherit, int nargs, Lisp_Object *args)
{
register int argnum;
register Lisp_Object val;
@@ -2685,7 +2703,7 @@ determines whether case is significant or ignored. */)
else
{
c1 = BUF_FETCH_BYTE (bp1, i1);
- c1 = unibyte_char_to_multibyte (c1);
+ MAKE_CHAR_MULTIBYTE (c1);
i1++;
}
@@ -2698,7 +2716,7 @@ determines whether case is significant or ignored. */)
else
{
c2 = BUF_FETCH_BYTE (bp2, i2);
- c2 = unibyte_char_to_multibyte (c2);
+ MAKE_CHAR_MULTIBYTE (c2);
i2++;
}
@@ -2852,8 +2870,8 @@ Both characters must have the same length of multi-byte form. */)
{
if (MODIFF - 1 == SAVE_MODIFF)
SAVE_MODIFF++;
- if (MODIFF - 1 == current_buffer->auto_save_modified)
- current_buffer->auto_save_modified++;
+ if (MODIFF - 1 == BUF_AUTOSAVE_MODIFF (current_buffer))
+ BUF_AUTOSAVE_MODIFF (current_buffer)++;
}
/* The before-change-function may have moved the gap
@@ -2969,7 +2987,7 @@ check_translation (pos, pos_byte, end, val)
memcpy (newbuf, buf, sizeof (int) * buf_used);
buf = newbuf;
}
- buf[buf_used++] = STRING_CHAR_AND_LENGTH (p, 0, len);
+ buf[buf_used++] = STRING_CHAR_AND_LENGTH (p, len);
pos_byte += len;
}
if (XINT (AREF (elt, i)) != buf[i])
@@ -3038,7 +3056,7 @@ It returns the number of characters changed. */)
Lisp_Object val;
if (multibyte)
- oc = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, len);
+ oc = STRING_CHAR_AND_LENGTH (p, len);
else
oc = *p, len = 1;
if (oc < size)
@@ -3050,8 +3068,7 @@ It returns the number of characters changed. */)
if (string_multibyte)
{
str = tt + string_char_to_byte (table, oc);
- nc = STRING_CHAR_AND_LENGTH (str, MAX_MULTIBYTE_LENGTH,
- str_len);
+ nc = STRING_CHAR_AND_LENGTH (str, str_len);
}
else
{
@@ -3134,12 +3151,7 @@ It returns the number of characters changed. */)
if (VECTORP (val))
{
- int i;
-
- string = Fmake_string (make_number (ASIZE (val)),
- AREF (val, 0));
- for (i = 1; i < ASIZE (val); i++)
- Faset (string, make_number (i), AREF (val, i));
+ string = Fconcat (1, &val);
}
else
{
@@ -3266,12 +3278,26 @@ Lisp_Object
save_restriction_restore (data)
Lisp_Object data;
{
+ struct buffer *cur = NULL;
+ struct buffer *buf = (CONSP (data)
+ ? XMARKER (XCAR (data))->buffer
+ : XBUFFER (data));
+
+ if (buf && buf != current_buffer && !NILP (buf->pt_marker))
+ { /* If `buf' uses markers to keep track of PT, BEGV, and ZV (as
+ is the case if it is or has an indirect buffer), then make
+ sure it is current before we update BEGV, so
+ set_buffer_internal takes care of managing those markers. */
+ cur = current_buffer;
+ set_buffer_internal (buf);
+ }
+
if (CONSP (data))
/* A pair of marks bounding a saved restriction. */
{
struct Lisp_Marker *beg = XMARKER (XCAR (data));
struct Lisp_Marker *end = XMARKER (XCDR (data));
- struct buffer *buf = beg->buffer; /* END should have the same buffer. */
+ eassert (buf == end->buffer);
if (buf /* Verify marker still points to a buffer. */
&& (beg->charpos != BUF_BEGV (buf) || end->charpos != BUF_ZV (buf)))
@@ -3296,8 +3322,6 @@ save_restriction_restore (data)
else
/* A buffer, which means that there was no old restriction. */
{
- struct buffer *buf = XBUFFER (data);
-
if (buf /* Verify marker still points to a buffer. */
&& (BUF_BEGV (buf) != BUF_BEG (buf) || BUF_ZV (buf) != BUF_Z (buf)))
/* The buffer has been narrowed, get rid of the narrowing. */
@@ -3309,6 +3333,9 @@ save_restriction_restore (data)
}
}
+ if (cur)
+ set_buffer_internal (cur);
+
return Qnil;
}
@@ -3755,7 +3782,11 @@ usage: (format STRING &rest OBJECTS) */)
to be as large as is calculated here. Easy check for
the case PRECISION = 0. */
thissize = precision[n] ? CONVERTED_BYTE_SIZE (multibyte, args[n]) : 0;
+ /* The precision also constrains how much of the argument
+ string will finally appear (Bug#5710). */
actual_width = lisp_string_width (args[n], -1, NULL, NULL);
+ if (precision[n] != -1)
+ actual_width = min(actual_width,precision[n]);
}
/* Would get MPV otherwise, since Lisp_Int's `point' to low memory. */
else if (INTEGERP (args[n]) && *format != 's')
@@ -4150,8 +4181,8 @@ usage: (format STRING &rest OBJECTS) */)
len = make_number (SCHARS (args[n]));
new_len = make_number (info[n].end - info[n].start);
props = text_property_list (args[n], make_number (0), len, Qnil);
- extend_property_ranges (props, len, new_len);
- /* If successive arguments have properites, be sure that
+ props = extend_property_ranges (props, new_len);
+ /* If successive arguments have properties, be sure that
the value of `composition' property be the copy. */
if (n > 1 && info[n - 1].end)
make_composition_value_copy (props);
@@ -4301,7 +4332,7 @@ transpose_markers (start1, end1, start2, end2,
DEFUN ("transpose-regions", Ftranspose_regions, Stranspose_regions, 4, 5, 0,
doc: /* Transpose region STARTR1 to ENDR1 with STARTR2 to ENDR2.
-The regions may not be overlapping, because the size of the buffer is
+The regions should not be overlapping, because the size of the buffer is
never changed in a transposition.
Optional fifth arg LEAVE-MARKERS, if non-nil, means don't update
@@ -4602,7 +4633,7 @@ syms_of_editfns ()
initial_tz = 0;
Qbuffer_access_fontify_functions
- = intern ("buffer-access-fontify-functions");
+ = intern_c_string ("buffer-access-fontify-functions");
staticpro (&Qbuffer_access_fontify_functions);
DEFVAR_LISP ("inhibit-field-text-motion", &Vinhibit_field_text_motion,
@@ -4623,7 +4654,7 @@ of the buffer being accessed. */);
/* Do this here, because init_buffer_once is too early--it won't work. */
Fset_buffer (Vprin1_to_string_buffer);
/* Make sure buffer-access-fontify-functions is nil in this buffer. */
- Fset (Fmake_local_variable (intern ("buffer-access-fontify-functions")),
+ Fset (Fmake_local_variable (intern_c_string ("buffer-access-fontify-functions")),
Qnil);
Fset_buffer (obuf);
}
@@ -4666,9 +4697,9 @@ functions if all the text being accessed has this property. */);
defsubr (&Sregion_end);
staticpro (&Qfield);
- Qfield = intern ("field");
+ Qfield = intern_c_string ("field");
staticpro (&Qboundary);
- Qboundary = intern ("boundary");
+ Qboundary = intern_c_string ("boundary");
defsubr (&Sfield_beginning);
defsubr (&Sfield_end);
defsubr (&Sfield_string);