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);