/* 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.
+
+Copyright (C) 1985, 1986, 1987, 1989, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004, 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
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 <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <sys/types.h>
#include <stdio.h>
+#include <setjmp.h>
#ifdef HAVE_PWD_H
#include <pwd.h>
#include "intervals.h"
#include "buffer.h"
-#include "charset.h"
+#include "character.h"
#include "coding.h"
#include "frame.h"
#include "window.h"
#define NULL 0
#endif
+#ifndef USER_FULL_NAME
+#define USER_FULL_NAME pw->pw_gecos
+#endif
+
#ifndef USE_CRT_DLL
extern char **environ;
#endif
(1000 - TM_YEAR_BASE <= (tm_year) && (tm_year) <= 9999 - TM_YEAR_BASE)
#endif
-extern size_t emacs_strftimeu P_ ((char *, size_t, const char *,
- const struct tm *, int));
-static int tm_diff P_ ((struct tm *, struct tm *));
-static void find_field P_ ((Lisp_Object, Lisp_Object, Lisp_Object, int *, Lisp_Object, int *));
-static void update_buffer_properties P_ ((int, int));
-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 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));
+extern size_t emacs_strftimeu (char *, size_t, const char *,
+ const struct tm *, int);
+
+#ifdef WINDOWSNT
+extern Lisp_Object w32_get_internal_run_time ();
+#endif
+
+static int tm_diff (struct tm *, struct tm *);
+static void find_field (Lisp_Object, Lisp_Object, Lisp_Object, int *, Lisp_Object, int *);
+static void update_buffer_properties (int, int);
+static Lisp_Object region_limit (int);
+int lisp_time_argument (Lisp_Object, time_t *, int *);
+static size_t emacs_memftimeu (char *, size_t, const char *,
+ size_t, const struct tm *, int);
+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 (Lisp_Object);
+static Lisp_Object subst_char_in_region_unwind_1 (Lisp_Object);
+static void transpose_markers (int, int, int, int, int, int, int, int);
#ifdef HAVE_INDEX
-extern char *index P_ ((const char *, int));
+extern char *index (const char *, int);
#endif
Lisp_Object Vbuffer_access_fontify_functions;
Lisp_Object Qbuffer_access_fontify_functions;
Lisp_Object Vbuffer_access_fontified_property;
-Lisp_Object Fuser_full_name P_ ((Lisp_Object));
+Lisp_Object Fuser_full_name (Lisp_Object);
/* Non-nil means don't stop at field boundary in text motion commands. */
void
-init_editfns ()
+init_editfns (void)
{
char *user_name;
register unsigned char *p;
DEFUN ("char-to-string", Fchar_to_string, Schar_to_string, 1, 1, 0,
doc: /* Convert arg CHAR to a string containing that character.
usage: (char-to-string CHAR) */)
- (character)
- Lisp_Object character;
+ (Lisp_Object character)
{
int len;
unsigned char str[MAX_MULTIBYTE_LENGTH];
- CHECK_NUMBER (character);
+ CHECK_CHARACTER (character);
- len = (SINGLE_BYTE_CHAR_P (XFASTINT (character))
- ? (*str = (unsigned char)(XFASTINT (character)), 1)
- : char_to_string (XFASTINT (character), str));
+ len = CHAR_STRING (XFASTINT (character), str);
return make_string_from_bytes (str, 1, len);
}
+DEFUN ("byte-to-string", Fbyte_to_string, Sbyte_to_string, 1, 1, 0,
+ doc: /* Convert arg BYTE to a string containing that byte. */)
+ (Lisp_Object byte)
+{
+ unsigned char b;
+ CHECK_NUMBER (byte);
+ b = XINT (byte);
+ return make_string_from_bytes (&b, 1, 1);
+}
+
DEFUN ("string-to-char", Fstring_to_char, Sstring_to_char, 1, 1, 0,
doc: /* Convert arg STRING to a character, the first character of that string.
A multibyte character is handled correctly. */)
- (string)
- register Lisp_Object string;
+ (register Lisp_Object string)
{
register Lisp_Object val;
CHECK_STRING (string);
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));
}
}
\f
static Lisp_Object
-buildmark (charpos, bytepos)
- int charpos, bytepos;
+buildmark (int charpos, int bytepos)
{
register Lisp_Object mark;
mark = Fmake_marker ();
DEFUN ("point", Fpoint, Spoint, 0, 0, 0,
doc: /* Return value of point, as an integer.
Beginning of buffer is position (point-min). */)
- ()
+ (void)
{
Lisp_Object temp;
XSETFASTINT (temp, PT);
DEFUN ("point-marker", Fpoint_marker, Spoint_marker, 0, 0, 0,
doc: /* Return value of point, as a marker object. */)
- ()
+ (void)
{
return buildmark (PT, PT_BYTE);
}
int
-clip_to_bounds (lower, num, upper)
- int lower, num, upper;
+clip_to_bounds (int lower, int num, int upper)
{
if (num < lower)
return lower;
Beginning of buffer is position (point-min), end is (point-max).
The return value is POSITION. */)
- (position)
- register Lisp_Object position;
+ (register Lisp_Object position)
{
int pos;
If there is no region active, signal an error. */
static Lisp_Object
-region_limit (beginningp)
- int beginningp;
+region_limit (int beginningp)
{
extern Lisp_Object Vmark_even_if_inactive; /* Defined in callint.c. */
Lisp_Object m;
DEFUN ("region-beginning", Fregion_beginning, Sregion_beginning, 0, 0, 0,
doc: /* Return position of beginning of region, as an integer. */)
- ()
+ (void)
{
return region_limit (1);
}
DEFUN ("region-end", Fregion_end, Sregion_end, 0, 0, 0,
doc: /* Return position of end of region, as an integer. */)
- ()
+ (void)
{
return region_limit (0);
}
doc: /* Return this buffer's mark, as a marker object.
Watch out! Moving this marker changes the mark position.
If you set the marker not to point anywhere, the buffer will have no mark. */)
- ()
+ (void)
{
return current_buffer->mark;
}
of length LEN. */
static int
-overlays_around (pos, vec, len)
- int pos;
- Lisp_Object *vec;
- int len;
+overlays_around (int pos, Lisp_Object *vec, int len)
{
Lisp_Object overlay, start, end;
struct Lisp_Overlay *tail;
window-specific overlays are considered only if they are associated
with OBJECT. */
Lisp_Object
-get_pos_property (position, prop, object)
- Lisp_Object position, object;
- register Lisp_Object prop;
+get_pos_property (Lisp_Object position, register Lisp_Object prop, Lisp_Object object)
{
CHECK_NUMBER_COERCE_MARKER (position);
}
}
- { /* 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);
is not stored. */
static void
-find_field (pos, merge_at_boundary, beg_limit, beg, end_limit, end)
- Lisp_Object pos;
- Lisp_Object merge_at_boundary;
- Lisp_Object beg_limit, end_limit;
- int *beg, *end;
+find_field (Lisp_Object pos, Lisp_Object merge_at_boundary, Lisp_Object beg_limit, int *beg, Lisp_Object end_limit, int *end)
{
/* Fields right before and after the point. */
Lisp_Object before_field, after_field;
doc: /* Delete the field surrounding POS.
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)
- Lisp_Object pos;
+ (Lisp_Object pos)
{
int beg, end;
find_field (pos, Qnil, Qnil, &beg, Qnil, &end);
doc: /* Return the contents of the field surrounding POS as a string.
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)
- Lisp_Object pos;
+ (Lisp_Object pos)
{
int beg, end;
find_field (pos, Qnil, Qnil, &beg, Qnil, &end);
}
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)
- Lisp_Object pos;
+ (Lisp_Object pos)
{
int beg, end;
find_field (pos, Qnil, Qnil, &beg, Qnil, &end);
field, then the beginning of the *previous* field is returned.
If LIMIT is non-nil, it is a buffer position; if the beginning of the field
is before LIMIT, then LIMIT will be returned instead. */)
- (pos, escape_from_edge, limit)
- Lisp_Object pos, escape_from_edge, limit;
+ (Lisp_Object pos, Lisp_Object escape_from_edge, Lisp_Object limit)
{
int beg;
find_field (pos, escape_from_edge, limit, &beg, Qnil, 0);
then the end of the *following* field is returned.
If LIMIT is non-nil, it is a buffer position; if the end of the field
is after LIMIT, then LIMIT will be returned instead. */)
- (pos, escape_from_edge, limit)
- Lisp_Object pos, escape_from_edge, limit;
+ (Lisp_Object pos, Lisp_Object escape_from_edge, Lisp_Object limit)
{
int end;
find_field (pos, escape_from_edge, Qnil, 0, limit, &end);
a non-nil property of that name, then any field boundaries are ignored.
Field boundaries are not noticed if `inhibit-field-text-motion' is non-nil. */)
- (new_pos, old_pos, escape_from_edge, only_in_line, inhibit_capture_property)
- Lisp_Object new_pos, old_pos;
- Lisp_Object escape_from_edge, only_in_line, inhibit_capture_property;
+ (Lisp_Object new_pos, Lisp_Object old_pos, Lisp_Object escape_from_edge, Lisp_Object only_in_line, Lisp_Object inhibit_capture_property)
{
/* If non-zero, then the original point, before re-positioning. */
int orig_point = 0;
boundaries bind `inhibit-field-text-motion' to t.
This function does not move point. */)
- (n)
- Lisp_Object n;
+ (Lisp_Object n)
{
int orig, orig_byte, end;
int count = SPECPDL_INDEX ();
boundaries bind `inhibit-field-text-motion' to t.
This function does not move point. */)
- (n)
- Lisp_Object n;
+ (Lisp_Object n)
{
int end_pos;
int orig = PT;
\f
Lisp_Object
-save_excursion_save ()
+save_excursion_save (void)
{
int visible = (XBUFFER (XWINDOW (selected_window)->buffer)
== current_buffer);
}
Lisp_Object
-save_excursion_restore (info)
- Lisp_Object info;
+save_excursion_restore (Lisp_Object info)
{
Lisp_Object tem, tem1, omark, nmark;
struct gcpro gcpro1, gcpro2, gcpro3;
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;
+ (Lisp_Object args)
{
register Lisp_Object val;
int count = SPECPDL_INDEX ();
doc: /* Save the current buffer; execute BODY; restore the current buffer.
Executes BODY just like `progn'.
usage: (save-current-buffer &rest BODY) */)
- (args)
- Lisp_Object args;
+ (Lisp_Object args)
{
Lisp_Object val;
int count = SPECPDL_INDEX ();
DEFUN ("buffer-size", Fbufsize, Sbufsize, 0, 1, 0,
doc: /* Return the number of characters in the current buffer.
If BUFFER, return the number of characters in that buffer instead. */)
- (buffer)
- Lisp_Object buffer;
+ (Lisp_Object buffer)
{
if (NILP (buffer))
return make_number (Z - BEG);
DEFUN ("point-min", Fpoint_min, Spoint_min, 0, 0, 0,
doc: /* Return the minimum permissible value of point in the current buffer.
This is 1, unless narrowing (a buffer restriction) is in effect. */)
- ()
+ (void)
{
Lisp_Object temp;
XSETFASTINT (temp, BEGV);
DEFUN ("point-min-marker", Fpoint_min_marker, Spoint_min_marker, 0, 0, 0,
doc: /* Return a marker to the minimum permissible value of point in this buffer.
This is the beginning, unless narrowing (a buffer restriction) is in effect. */)
- ()
+ (void)
{
return buildmark (BEGV, BEGV_BYTE);
}
doc: /* Return the maximum permissible value of point in the current buffer.
This is (1+ (buffer-size)), unless narrowing (a buffer restriction)
is in effect, in which case it is less. */)
- ()
+ (void)
{
Lisp_Object temp;
XSETFASTINT (temp, ZV);
doc: /* Return a marker to the maximum permissible value of point in this buffer.
This is (1+ (buffer-size)), unless narrowing (a buffer restriction)
is in effect, in which case it is less. */)
- ()
+ (void)
{
return buildmark (ZV, ZV_BYTE);
}
DEFUN ("gap-position", Fgap_position, Sgap_position, 0, 0, 0,
doc: /* Return the position of the gap, in the current buffer.
See also `gap-size'. */)
- ()
+ (void)
{
Lisp_Object temp;
XSETFASTINT (temp, GPT);
DEFUN ("gap-size", Fgap_size, Sgap_size, 0, 0, 0,
doc: /* Return the size of the current buffer's gap.
See also `gap-position'. */)
- ()
+ (void)
{
Lisp_Object temp;
XSETFASTINT (temp, GAP_SIZE);
DEFUN ("position-bytes", Fposition_bytes, Sposition_bytes, 1, 1, 0,
doc: /* Return the byte position for character position POSITION.
If POSITION is out of range, the value is nil. */)
- (position)
- Lisp_Object position;
+ (Lisp_Object position)
{
CHECK_NUMBER_COERCE_MARKER (position);
if (XINT (position) < BEG || XINT (position) > Z)
DEFUN ("byte-to-position", Fbyte_to_position, Sbyte_to_position, 1, 1, 0,
doc: /* Return the character position for byte position BYTEPOS.
If BYTEPOS is out of range, the value is nil. */)
- (bytepos)
- Lisp_Object bytepos;
+ (Lisp_Object bytepos)
{
CHECK_NUMBER (bytepos);
if (XINT (bytepos) < BEG_BYTE || XINT (bytepos) > Z_BYTE)
DEFUN ("following-char", Ffollowing_char, Sfollowing_char, 0, 0, 0,
doc: /* Return the character following point, as a number.
At the end of the buffer or accessible region, return 0. */)
- ()
+ (void)
{
Lisp_Object temp;
if (PT >= ZV)
DEFUN ("preceding-char", Fprevious_char, Sprevious_char, 0, 0, 0,
doc: /* Return the character preceding point, as a number.
At the beginning of the buffer or accessible region, return 0. */)
- ()
+ (void)
{
Lisp_Object temp;
if (PT <= BEGV)
DEFUN ("bobp", Fbobp, Sbobp, 0, 0, 0,
doc: /* Return t if point is at the beginning of the buffer.
If the buffer is narrowed, this means the beginning of the narrowed part. */)
- ()
+ (void)
{
if (PT == BEGV)
return Qt;
DEFUN ("eobp", Feobp, Seobp, 0, 0, 0,
doc: /* Return t if point is at the end of the buffer.
If the buffer is narrowed, this means the end of the narrowed part. */)
- ()
+ (void)
{
if (PT == ZV)
return Qt;
DEFUN ("bolp", Fbolp, Sbolp, 0, 0, 0,
doc: /* Return t if point is at the beginning of a line. */)
- ()
+ (void)
{
if (PT == BEGV || FETCH_BYTE (PT_BYTE - 1) == '\n')
return Qt;
DEFUN ("eolp", Feolp, Seolp, 0, 0, 0,
doc: /* Return t if point is at the end of a line.
`End of a line' includes point being at the end of the buffer. */)
- ()
+ (void)
{
if (PT == ZV || FETCH_BYTE (PT_BYTE) == '\n')
return Qt;
doc: /* Return character in current buffer at position POS.
POS is an integer or a marker and defaults to point.
If POS is out of range, the value is nil. */)
- (pos)
- Lisp_Object pos;
+ (Lisp_Object pos)
{
register int pos_byte;
doc: /* Return character in current buffer preceding position POS.
POS is an integer or a marker and defaults to point.
If POS is out of range, the value is nil. */)
- (pos)
- Lisp_Object pos;
+ (Lisp_Object pos)
{
register Lisp_Object val;
register int pos_byte;
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. */)
- (uid)
- Lisp_Object uid;
+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. */)
+ (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
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);
}
doc: /* Return the name of the user's real uid, as a string.
This ignores the environment variables LOGNAME and USER, so it differs from
`user-login-name' when running under `su'. */)
- ()
+ (void)
{
/* Set up the user name info if we didn't do it before.
(That can happen if Emacs is dumpable
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. */)
+ (void)
{
/* 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. */)
+ (void)
{
/* 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);
}
of the user with that uid, or nil if there is no such user.
If UID is a string, return the full name of the user with that login
name, or nil if there is no such user. */)
- (uid)
- Lisp_Object uid;
+ (Lisp_Object uid)
{
struct passwd *pw;
register unsigned char *p, *q;
login = Fuser_login_name (make_number (pw->pw_uid));
r = (unsigned char *) alloca (strlen (p) + SCHARS (login) + 1);
- bcopy (p, r, q - p);
+ memcpy (r, p, q - p);
r[q - p] = 0;
strcat (r, SDATA (login));
r[q - p] = UPCASE (r[q - p]);
DEFUN ("system-name", Fsystem_name, Ssystem_name, 0, 0, 0,
doc: /* Return the host name of the machine you are running on, as a string. */)
- ()
+ (void)
{
return Vsystem_name;
}
/* For the benefit of callers who don't want to include lisp.h */
char *
-get_system_name ()
+get_system_name (void)
{
if (STRINGP (Vsystem_name))
return (char *) SDATA (Vsystem_name);
}
char *
-get_operating_system_release()
+get_operating_system_release (void)
{
if (STRINGP (Voperating_system_release))
return (char *) SDATA (Voperating_system_release);
DEFUN ("emacs-pid", Femacs_pid, Semacs_pid, 0, 0, 0,
doc: /* Return the process ID of Emacs, as an integer. */)
- ()
+ (void)
{
return make_number (getpid ());
}
The microsecond count is zero on systems that do not provide
resolution finer than a second. */)
- ()
+ (void)
{
EMACS_TIME t;
On systems that can't determine the run time, `get-internal-run-time'
does the same thing as `current-time'. The microsecond count is zero
on systems that do not provide resolution finer than a second. */)
- ()
+ (void)
{
#ifdef HAVE_GETRUSAGE
struct rusage usage;
return list3 (make_number ((secs >> 16) & 0xffff),
make_number ((secs >> 0) & 0xffff),
make_number (usecs));
-#else
+#else /* ! HAVE_GETRUSAGE */
+#ifdef WINDOWSNT
+ return w32_get_internal_run_time ();
+#else /* ! WINDOWSNT */
return Fcurrent_time ();
-#endif
+#endif /* WINDOWSNT */
+#endif /* HAVE_GETRUSAGE */
}
\f
int
-lisp_time_argument (specified_time, result, usec)
- Lisp_Object specified_time;
- time_t *result;
- int *usec;
+lisp_time_argument (Lisp_Object specified_time, time_t *result, int *usec)
{
if (NILP (specified_time))
{
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. */)
- (specified_time)
- Lisp_Object specified_time;
+If precise time stamps are required, use either `current-time',
+or (if you need time as a string) `format-time-string'. */)
+ (Lisp_Object specified_time)
{
time_t sec;
int usec;
This function behaves like emacs_strftimeu, except it allows null
bytes in FORMAT. */
static size_t
-emacs_memftimeu (s, maxsize, format, format_len, tp, ut)
- char *s;
- size_t maxsize;
- const char *format;
- size_t format_len;
- const struct tm *tp;
- int ut;
+emacs_memftimeu (char *s, size_t maxsize, const char *format, size_t format_len, const struct tm *tp, int ut)
{
size_t total = 0;
%OX is like %X, but uses the locale's number symbols.
For example, to produce full ISO 8601 format, use "%Y-%m-%dT%T%z". */)
- (format_string, time, universal)
- Lisp_Object format_string, time, universal;
+ (Lisp_Object format_string, Lisp_Object time, Lisp_Object universal)
{
time_t value;
int size;
otherwise nil. ZONE is an integer indicating the number of seconds
east of Greenwich. (Note that Common Lisp has different meanings for
DOW and ZONE.) */)
- (specified_time)
- Lisp_Object specified_time;
+ (Lisp_Object specified_time)
{
time_t time_spec;
struct tm save_tm;
year values as low as 1901 do work.
usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */)
- (nargs, args)
- int nargs;
- register Lisp_Object *args;
+ (int nargs, register Lisp_Object *args)
{
time_t time;
struct tm tm;
tzstring = (char *) SDATA (zone);
else if (INTEGERP (zone))
{
- int abszone = abs (XINT (zone));
+ int abszone = eabs (XINT (zone));
sprintf (tzbuf, "XXX%s%d:%02d:%02d", "-" + (XINT (zone) < 0),
abszone / (60*60), (abszone/60) % 60, abszone % 60);
tzstring = tzbuf;
}
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.
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. */)
- (specified_time)
- Lisp_Object specified_time;
+ (Lisp_Object specified_time)
{
time_t value;
struct tm *tm;
/* Yield A - B, measured in seconds.
This function is copied from the GNU C Library. */
static int
-tm_diff (a, b)
- struct tm *a, *b;
+tm_diff (struct tm *a, struct tm *b)
{
/* Compute intervening leap days correctly even if year is negative.
Take care to avoid int overflow in leap day calculations,
Some operating systems cannot provide all this information to Emacs;
in this case, `current-time-zone' returns a list containing nil for
the data it can't find. */)
- (specified_time)
- Lisp_Object specified_time;
+ (Lisp_Object specified_time)
{
time_t value;
struct tm *t;
int offset = tm_diff (t, &gmt);
char *s = 0;
char buf[6];
+
#ifdef HAVE_TM_ZONE
if (t->tm_zone)
s = (char *)t->tm_zone;
#endif
#endif /* not HAVE_TM_ZONE */
-#if defined HAVE_TM_ZONE || defined HAVE_TZNAME
- if (s)
- {
- /* On Japanese w32, we can get a Japanese string as time
- zone name. Don't accept that. */
- char *p;
- for (p = s; *p && (isalnum ((unsigned char)*p) || *p == ' '); ++p)
- ;
- if (p == s || *p)
- s = NULL;
- }
-#endif
-
if (!s)
{
/* No local time zone name is available; use "+-NNNN" instead. */
sprintf (buf, "%c%02d%02d", (offset < 0 ? '-' : '+'), am/60, am%60);
s = buf;
}
+
return Fcons (make_number (offset), Fcons (build_string (s), Qnil));
}
else
has never been called. */
static char **environbuf;
+/* This holds the startup value of the TZ environment variable so it
+ can be restored if the user calls set-time-zone-rule with a nil
+ argument. */
+static char *initial_tz;
+
DEFUN ("set-time-zone-rule", Fset_time_zone_rule, Sset_time_zone_rule, 1, 1, 0,
doc: /* Set the local time zone using TZ, a string specifying a time zone rule.
If TZ is nil, use implementation-defined default time zone information.
If TZ is t, use Universal Time. */)
- (tz)
- Lisp_Object tz;
+ (Lisp_Object tz)
{
char *tzstring;
+ /* When called for the first time, save the original TZ. */
+ if (!environbuf)
+ initial_tz = (char *) getenv ("TZ");
+
if (NILP (tz))
- tzstring = 0;
+ tzstring = initial_tz;
else if (EQ (tz, Qt))
tzstring = "UTC0";
else
}
set_time_zone_rule (tzstring);
- if (environbuf)
- free (environbuf);
+ free (environbuf);
environbuf = environ;
return Qnil;
responsibility to free. */
void
-set_time_zone_rule (tzstring)
- char *tzstring;
+set_time_zone_rule (const char *tzstring)
{
int envptrs;
char **from, **to, **newenv;
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;
for (argnum = 0; argnum < nargs; argnum++)
{
val = args[argnum];
- if (INTEGERP (val))
+ if (CHARACTERP (val))
{
unsigned char str[MAX_MULTIBYTE_LENGTH];
int len;
len = CHAR_STRING (XFASTINT (val), str);
else
{
- str[0] = (SINGLE_BYTE_CHAR_P (XINT (val))
+ str[0] = (ASCII_CHAR_P (XINT (val))
? XINT (val)
: multibyte_char_to_unibyte (XINT (val), Qnil));
len = 1;
}
void
-insert1 (arg)
- Lisp_Object arg;
+insert1 (Lisp_Object arg)
{
Finsert (1, &arg);
}
and insert the result.
usage: (insert &rest ARGS) */)
- (nargs, args)
- int nargs;
- register Lisp_Object *args;
+ (int nargs, register Lisp_Object *args)
{
general_insert_function (insert, insert_from_string, 0, nargs, args);
return Qnil;
to unibyte for insertion.
usage: (insert-and-inherit &rest ARGS) */)
- (nargs, args)
- int nargs;
- register Lisp_Object *args;
+ (int nargs, register Lisp_Object *args)
{
general_insert_function (insert_and_inherit, insert_from_string, 1,
nargs, args);
to unibyte for insertion.
usage: (insert-before-markers &rest ARGS) */)
- (nargs, args)
- int nargs;
- register Lisp_Object *args;
+ (int nargs, register Lisp_Object *args)
{
general_insert_function (insert_before_markers,
insert_from_string_before_markers, 0,
to unibyte for insertion.
usage: (insert-before-markers-and-inherit &rest ARGS) */)
- (nargs, args)
- int nargs;
- register Lisp_Object *args;
+ (int nargs, register Lisp_Object *args)
{
general_insert_function (insert_before_markers_and_inherit,
insert_from_string_before_markers, 1,
Point, and before-insertion markers, are relocated as in the function `insert'.
The optional third arg INHERIT, if non-nil, says to inherit text properties
from adjoining text, if those properties are sticky. */)
- (character, count, inherit)
- Lisp_Object character, count, inherit;
+ (Lisp_Object character, Lisp_Object count, Lisp_Object inherit)
{
register unsigned char *string;
register int strlen;
return Qnil;
}
+DEFUN ("insert-byte", Finsert_byte, Sinsert_byte, 2, 3, 0,
+ doc: /* Insert COUNT (second arg) copies of BYTE (first arg).
+Both arguments are required.
+BYTE is a number of the range 0..255.
+
+If BYTE is 128..255 and the current buffer is multibyte, the
+corresponding eight-bit character is inserted.
+
+Point, and before-insertion markers, are relocated as in the function `insert'.
+The optional third arg INHERIT, if non-nil, says to inherit text properties
+from adjoining text, if those properties are sticky. */)
+ (Lisp_Object byte, Lisp_Object count, Lisp_Object inherit)
+{
+ CHECK_NUMBER (byte);
+ if (XINT (byte) < 0 || XINT (byte) > 255)
+ args_out_of_range_3 (byte, make_number (0), make_number (255));
+ if (XINT (byte) >= 128
+ && ! NILP (current_buffer->enable_multibyte_characters))
+ XSETFASTINT (byte, BYTE8_TO_CHAR (XINT (byte)));
+ return Finsert_char (byte, count, inherit);
+}
+
\f
/* Making strings from buffer contents. */
buffer substrings. */
Lisp_Object
-make_buffer_string (start, end, props)
- int start, end;
- int props;
+make_buffer_string (int start, int end, int props)
{
int start_byte = CHAR_TO_BYTE (start);
int end_byte = CHAR_TO_BYTE (end);
buffer substrings. */
Lisp_Object
-make_buffer_string_both (start, start_byte, end, end_byte, props)
- int start, start_byte, end, end_byte;
- int props;
+make_buffer_string_both (int start, int start_byte, int end, int end_byte, int props)
{
Lisp_Object result, tem, tem1;
result = make_uninit_multibyte_string (end - start, end_byte - start_byte);
else
result = make_uninit_string (end - start);
- bcopy (BYTE_POS_ADDR (start_byte), SDATA (result),
- end_byte - start_byte);
+ memcpy (SDATA (result), BYTE_POS_ADDR (start_byte), end_byte - start_byte);
/* If desired, update and copy the text properties. */
if (props)
in the current buffer, if necessary. */
static void
-update_buffer_properties (start, end)
- int start, end;
+update_buffer_properties (int start, int end)
{
/* If this buffer has some access functions,
call them, specifying the range of the buffer being accessed. */
This function copies the text properties of that part of the buffer
into the result string; if you don't want the text properties,
use `buffer-substring-no-properties' instead. */)
- (start, end)
- Lisp_Object start, end;
+ (Lisp_Object start, Lisp_Object end)
{
register int b, e;
doc: /* Return the characters of part of the buffer, without the text properties.
The two arguments START and END are character positions;
they can be in either order. */)
- (start, end)
- Lisp_Object start, end;
+ (Lisp_Object start, Lisp_Object end)
{
register int b, e;
doc: /* Return the contents of the current buffer as a string.
If narrowing is in effect, this function returns only the visible part
of the buffer. */)
- ()
+ (void)
{
return make_buffer_string (BEGV, ZV, 1);
}
BUFFER may be a buffer or a buffer name.
Arguments START and END are character positions specifying the substring.
They default to the values of (point-min) and (point-max) in BUFFER. */)
- (buffer, start, end)
- Lisp_Object buffer, start, end;
+ (Lisp_Object buffer, Lisp_Object start, Lisp_Object end)
{
register int b, e, temp;
register struct buffer *bp, *obuf;
The value of `case-fold-search' in the current buffer
determines whether case is significant or ignored. */)
- (buffer1, start1, end1, buffer2, start2, end2)
- Lisp_Object buffer1, start1, end1, buffer2, start2, end2;
+ (Lisp_Object buffer1, Lisp_Object start1, Lisp_Object end1, Lisp_Object buffer2, Lisp_Object start2, Lisp_Object end2)
{
register int begp1, endp1, begp2, endp2, temp;
register struct buffer *bp1, *bp2;
else
{
c1 = BUF_FETCH_BYTE (bp1, i1);
- c1 = unibyte_char_to_multibyte (c1);
+ MAKE_CHAR_MULTIBYTE (c1);
i1++;
}
else
{
c2 = BUF_FETCH_BYTE (bp2, i2);
- c2 = unibyte_char_to_multibyte (c2);
+ MAKE_CHAR_MULTIBYTE (c2);
i2++;
}
}
\f
static Lisp_Object
-subst_char_in_region_unwind (arg)
- Lisp_Object arg;
+subst_char_in_region_unwind (Lisp_Object arg)
{
return current_buffer->undo_list = arg;
}
static Lisp_Object
-subst_char_in_region_unwind_1 (arg)
- Lisp_Object arg;
+subst_char_in_region_unwind_1 (Lisp_Object arg)
{
return current_buffer->filename = arg;
}
If optional arg NOUNDO is non-nil, don't record this change for undo
and don't mark the buffer as really changed.
Both characters must have the same length of multi-byte form. */)
- (start, end, fromchar, tochar, noundo)
- Lisp_Object start, end, fromchar, tochar, noundo;
+ (Lisp_Object start, Lisp_Object end, Lisp_Object fromchar, Lisp_Object tochar, Lisp_Object noundo)
{
register int pos, pos_byte, stop, i, len, end_byte;
/* Keep track of the first change in the buffer:
{
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
return Qnil;
}
+
+static Lisp_Object check_translation (int, int, int, Lisp_Object);
+
+/* Helper function for Ftranslate_region_internal.
+
+ Check if a character sequence at POS (POS_BYTE) matches an element
+ of VAL. VAL is a list (([FROM-CHAR ...] . TO) ...). If a matching
+ element is found, return it. Otherwise return Qnil. */
+
+static Lisp_Object
+check_translation (int pos, int pos_byte, int end, Lisp_Object val)
+{
+ int buf_size = 16, buf_used = 0;
+ int *buf = alloca (sizeof (int) * buf_size);
+
+ for (; CONSP (val); val = XCDR (val))
+ {
+ Lisp_Object elt;
+ int len, i;
+
+ elt = XCAR (val);
+ if (! CONSP (elt))
+ continue;
+ elt = XCAR (elt);
+ if (! VECTORP (elt))
+ continue;
+ len = ASIZE (elt);
+ if (len <= end - pos)
+ {
+ for (i = 0; i < len; i++)
+ {
+ if (buf_used <= i)
+ {
+ unsigned char *p = BYTE_POS_ADDR (pos_byte);
+ int len;
+
+ if (buf_used == buf_size)
+ {
+ int *newbuf;
+
+ buf_size += 16;
+ newbuf = alloca (sizeof (int) * buf_size);
+ memcpy (newbuf, buf, sizeof (int) * buf_used);
+ buf = newbuf;
+ }
+ buf[buf_used++] = STRING_CHAR_AND_LENGTH (p, len);
+ pos_byte += len;
+ }
+ if (XINT (AREF (elt, i)) != buf[i])
+ break;
+ }
+ if (i == len)
+ return XCAR (val);
+ }
+ }
+ return Qnil;
+}
+
+
DEFUN ("translate-region-internal", Ftranslate_region_internal,
Stranslate_region_internal, 3, 3, 0,
doc: /* Internal use only.
From START to END, translate characters according to TABLE.
-TABLE is a string; the Nth character in it is the mapping
-for the character with code N.
+TABLE is a string or a char-table; the Nth character in it is the
+mapping for the character with code N.
It returns the number of characters changed. */)
- (start, end, table)
- Lisp_Object start;
- Lisp_Object end;
- register Lisp_Object table;
+ (Lisp_Object start, Lisp_Object end, register Lisp_Object table)
{
register unsigned char *tt; /* Trans table. */
register int nc; /* New character. */
int pos, pos_byte, end_pos;
int multibyte = !NILP (current_buffer->enable_multibyte_characters);
int string_multibyte;
+ Lisp_Object val;
validate_region (&start, &end);
if (CHAR_TABLE_P (table))
{
+ if (! EQ (XCHAR_TABLE (table)->purpose, Qtranslation_table))
+ error ("Not a translation table");
size = MAX_CHAR;
tt = NULL;
}
if (! multibyte && (SCHARS (table) < SBYTES (table)))
table = string_make_unibyte (table);
string_multibyte = SCHARS (table) < SBYTES (table);
- size = SCHARS (table);
+ size = SBYTES (table);
tt = SDATA (table);
}
pos = XINT (start);
pos_byte = CHAR_TO_BYTE (pos);
end_pos = XINT (end);
- modify_region (current_buffer, pos, XINT (end), 0);
+ modify_region (current_buffer, pos, end_pos, 0);
cnt = 0;
for (; pos < end_pos; )
unsigned char *str, buf[MAX_MULTIBYTE_LENGTH];
int len, str_len;
int oc;
+ 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)
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
{
nc = tt[oc];
if (! ASCII_BYTE_P (nc) && multibyte)
{
- str_len = CHAR_STRING (nc, buf);
+ str_len = BYTE8_STRING (nc, buf);
str = buf;
}
else
}
else
{
- Lisp_Object val;
int c;
nc = oc;
val = CHAR_TABLE_REF (table, oc);
- if (INTEGERP (val)
+ if (CHARACTERP (val)
&& (c = XINT (val), CHAR_VALID_P (c, 0)))
{
nc = c;
str_len = CHAR_STRING (nc, buf);
str = buf;
}
+ else if (VECTORP (val) || (CONSP (val)))
+ {
+ /* VAL is [TO_CHAR ...] or (([FROM-CHAR ...] . TO) ...)
+ where TO is TO-CHAR or [TO-CHAR ...]. */
+ nc = -1;
+ }
}
- if (nc != oc)
+ if (nc != oc && nc >= 0)
{
+ /* Simple one char to one char translation. */
if (len != str_len)
{
Lisp_Object string;
/* This is less efficient, because it moves the gap,
- but it should multibyte characters correctly. */
+ but it should handle multibyte characters correctly. */
string = make_multibyte_string (str, 1, str_len);
replace_range (pos, pos + 1, string, 1, 0, 1);
len = str_len;
}
++cnt;
}
+ else if (nc < 0)
+ {
+ Lisp_Object string;
+
+ if (CONSP (val))
+ {
+ val = check_translation (pos, pos_byte, end_pos, val);
+ if (NILP (val))
+ {
+ pos_byte += len;
+ pos++;
+ continue;
+ }
+ /* VAL is ([FROM-CHAR ...] . TO). */
+ len = ASIZE (XCAR (val));
+ val = XCDR (val);
+ }
+ else
+ len = 1;
+
+ if (VECTORP (val))
+ {
+ string = Fconcat (1, &val);
+ }
+ else
+ {
+ string = Fmake_string (make_number (1), val);
+ }
+ replace_range (pos, pos + len, string, 1, 0, 1);
+ pos_byte += SBYTES (string);
+ pos += SCHARS (string);
+ cnt += SCHARS (string);
+ end_pos += SCHARS (string) - len;
+ continue;
+ }
}
pos_byte += len;
pos++;
When called from a program, expects two arguments,
positions (integers or markers) specifying the stretch to be deleted. */)
- (start, end)
- Lisp_Object start, end;
+ (Lisp_Object start, Lisp_Object end)
{
validate_region (&start, &end);
del_range (XINT (start), XINT (end));
DEFUN ("delete-and-extract-region", Fdelete_and_extract_region,
Sdelete_and_extract_region, 2, 2, 0,
doc: /* Delete the text between START and END and return it. */)
- (start, end)
- Lisp_Object start, end;
+ (Lisp_Object start, Lisp_Object end)
{
validate_region (&start, &end);
if (XINT (start) == XINT (end))
- return build_string ("");
+ return empty_unibyte_string;
return del_range_1 (XINT (start), XINT (end), 1, 1);
}
\f
DEFUN ("widen", Fwiden, Swiden, 0, 0, "",
doc: /* Remove restrictions (narrowing) from current buffer.
This allows the buffer's full text to be seen and edited. */)
- ()
+ (void)
{
if (BEG != BEGV || Z != ZV)
current_buffer->clip_changed = 1;
When calling from a program, pass two arguments; positions (integers
or markers) bounding the text that should remain visible. */)
- (start, end)
- register Lisp_Object start, end;
+ (register Lisp_Object start, Lisp_Object end)
{
CHECK_NUMBER_COERCE_MARKER (start);
CHECK_NUMBER_COERCE_MARKER (end);
}
Lisp_Object
-save_restriction_save ()
+save_restriction_save (void)
{
if (BEGV == BEG && ZV == Z)
/* The common case that the buffer isn't narrowed.
}
Lisp_Object
-save_restriction_restore (data)
- Lisp_Object data;
+save_restriction_restore (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)))
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. */
}
}
+ if (cur)
+ set_buffer_internal (cur);
+
return Qnil;
}
(save-excursion (save-restriction ...))
usage: (save-restriction &rest BODY) */)
- (body)
- Lisp_Object body;
+ (Lisp_Object body)
{
register Lisp_Object val;
int count = SPECPDL_INDEX ();
also `current-message'.
usage: (message FORMAT-STRING &rest ARGS) */)
- (nargs, args)
- int nargs;
- Lisp_Object *args;
+ (int nargs, Lisp_Object *args)
{
if (NILP (args[0])
|| (STRINGP (args[0])
message; let the minibuffer contents show.
usage: (message-box FORMAT-STRING &rest ARGS) */)
- (nargs, args)
- int nargs;
- Lisp_Object *args;
+ (int nargs, Lisp_Object *args)
{
if (NILP (args[0]))
{
message_length = SBYTES (val);
message_text = (char *)xrealloc (message_text, message_length);
}
- bcopy (SDATA (val), message_text, SBYTES (val));
+ memcpy (message_text, SDATA (val), SBYTES (val));
message2 (message_text, SBYTES (val),
STRING_MULTIBYTE (val));
return val;
message; let the minibuffer contents show.
usage: (message-or-box FORMAT-STRING &rest ARGS) */)
- (nargs, args)
- int nargs;
- Lisp_Object *args;
+ (int nargs, Lisp_Object *args)
{
#ifdef HAVE_MENUS
if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
DEFUN ("current-message", Fcurrent_message, Scurrent_message, 0, 0, 0,
doc: /* Return the string currently displayed in the echo area, or nil if none. */)
- ()
+ (void)
{
return current_message ();
}
Remaining arguments form a sequence of PROPERTY VALUE pairs for text
properties to add to the result.
usage: (propertize STRING &rest PROPERTIES) */)
- (nargs, args)
- int nargs;
- Lisp_Object *args;
+ (int nargs, Lisp_Object *args)
{
Lisp_Object properties, string;
struct gcpro gcpro1, gcpro2;
doc: /* Format a string out of a format-string and arguments.
The first argument is a format control string.
The other arguments are substituted into it to make the result, a string.
-It may contain %-sequences meaning to substitute the next argument.
+
+The format control string may contain %-sequences meaning to substitute
+the next available argument:
+
%s means print a string argument. Actually, prints any object, with `princ'.
%d means print as number in decimal (%o octal, %x hex).
%X is like %x, but uses upper case.
or decimal-point notation, whichever uses fewer characters.
%c means print a number as a single character.
%S means print any object as an s-expression (using `prin1').
- The argument used for %d, %o, %x, %e, %f, %g or %c must be a number.
+
+The argument used for %d, %o, %x, %e, %f, %g or %c must be a number.
Use %% to put a single % into the output.
-The basic structure of a %-sequence is
- % <flags> <width> <precision> character
-where flags is [-+ #0]+, width is [0-9]+, and precision is .[0-9]+
+A %-sequence may contain optional flag, width, and precision
+specifiers, as follows:
+
+ %<flags><width><precision>character
+
+where flags is [+ #-0]+, width is [0-9]+, and precision is .[0-9]+
+
+The + flag character inserts a + before any positive number, while a
+space inserts a space before any positive number; these flags only
+affect %d, %e, %f, and %g sequences, and the + flag takes precedence.
+The # flag means to use an alternate display form for %o, %x, %X, %e,
+%f, and %g sequences. The - and 0 flags affect the width specifier,
+as described below.
+
+The width specifier supplies a lower limit for the length of the
+printed representation. The padding, if any, normally goes on the
+left, but it goes on the right if the - flag is present. The padding
+character is normally a space, but it is 0 if the 0 flag is present.
+The - flag takes precedence over the 0 flag.
+
+For %e, %f, and %g sequences, the number after the "." in the
+precision specifier says how many decimal places to show; if zero, the
+decimal point itself is omitted. For %s and %S, the precision
+specifier truncates the string to the given width.
usage: (format STRING &rest OBJECTS) */)
- (nargs, args)
- int nargs;
- register Lisp_Object *args;
+ (int nargs, register Lisp_Object *args)
{
register int n; /* The number of the next arg to substitute */
register int total; /* An estimate of the final length */
string itself, will not be used. Element NARGS, corresponding to
no argument, *will* be assigned to in the case that a `%' and `.'
occur after the final format specifier. */
- int *precision = (int *) (alloca((nargs + 1) * sizeof (int)));
+ int *precision = (int *) (alloca ((nargs + 1) * sizeof (int)));
int longest_format;
Lisp_Object val;
int arg_intervals = 0;
int i;
if (!info)
info = (struct info *) alloca (nbytes);
- bzero (info, nbytes);
+ memset (info, 0, nbytes);
for (i = 0; i <= nargs; i++)
info[i].start = -1;
if (!discarded)
SAFE_ALLOCA (discarded, char *, SBYTES (args[0]));
- bzero (discarded, SBYTES (args[0]));
+ memset (discarded, 0, SBYTES (args[0]));
}
/* Add to TOTAL enough space to hold the converted arguments. */
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')
thissize = 30 + (precision[n] > 0 ? precision[n] : 0);
if (*format == 'c')
{
- if (! SINGLE_BYTE_CHAR_P (XINT (args[n]))
- /* Note: No one can remember why we have to treat
+ if (! ASCII_CHAR_P (XINT (args[n]))
+ /* Note: No one can remeber why we have to treat
the character 0 as a multibyte character here.
But, until it causes a real problem, let's
don't change it. */
discarded[format - format_start] = 1;
format++;
- while (index("-+0# ", *format))
+ while (index ("-+0# ", *format))
{
if (*format == '-')
{
{
int this_nchars;
- bcopy (this_format_start, this_format,
- format - this_format_start);
+ memcpy (this_format, this_format_start,
+ format - this_format_start);
this_format[format - this_format_start] = 0;
if (format[-1] == 'e' || format[-1] == 'f' || format[-1] == 'g')
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);
}
Lisp_Object
-format2 (string1, arg0, arg1)
- char *string1;
- Lisp_Object arg0, arg1;
+format2 (const char *string1, Lisp_Object arg0, Lisp_Object arg1)
{
Lisp_Object args[3];
args[0] = build_string (string1);
doc: /* Return t if two characters match, optionally ignoring case.
Both arguments must be characters (i.e. integers).
Case is ignored if `case-fold-search' is non-nil in the current buffer. */)
- (c1, c2)
- register Lisp_Object c1, c2;
+ (register Lisp_Object c1, Lisp_Object c2)
{
int i1, i2;
- CHECK_NUMBER (c1);
- CHECK_NUMBER (c2);
+ /* Check they're chars, not just integers, otherwise we could get array
+ bounds violations in DOWNCASE. */
+ CHECK_CHARACTER (c1);
+ CHECK_CHARACTER (c2);
if (XINT (c1) == XINT (c2))
return Qt;
/* Do these in separate statements,
then compare the variables.
because of the way DOWNCASE uses temp variables. */
- i1 = DOWNCASE (XFASTINT (c1));
- i2 = DOWNCASE (XFASTINT (c2));
+ i1 = XFASTINT (c1);
+ if (NILP (current_buffer->enable_multibyte_characters)
+ && ! ASCII_CHAR_P (i1))
+ {
+ MAKE_CHAR_MULTIBYTE (i1);
+ }
+ i2 = XFASTINT (c2);
+ if (NILP (current_buffer->enable_multibyte_characters)
+ && ! ASCII_CHAR_P (i2))
+ {
+ MAKE_CHAR_MULTIBYTE (i2);
+ }
+ i1 = DOWNCASE (i1);
+ i2 = DOWNCASE (i2);
return (i1 == i2 ? Qt : Qnil);
}
\f
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
any markers that happen to be located in the regions.
Transposing beyond buffer boundaries is an error. */)
- (startr1, endr1, startr2, endr2, leave_markers)
- Lisp_Object startr1, endr1, startr2, endr2, leave_markers;
+ (Lisp_Object startr1, Lisp_Object endr1, Lisp_Object startr2, Lisp_Object endr2, Lisp_Object leave_markers)
{
- register int start1, end1, start2, end2;
- int start1_byte, start2_byte, len1_byte, len2_byte;
- int gap, len1, len_mid, len2;
+ register EMACS_INT start1, end1, start2, end2;
+ EMACS_INT start1_byte, start2_byte, len1_byte, len2_byte;
+ EMACS_INT gap, len1, len_mid, len2;
unsigned char *start1_addr, *start2_addr, *temp;
INTERVAL cur_intv, tmp_interval1, tmp_interval_mid, tmp_interval2, tmp_interval3;
start1_addr = BYTE_POS_ADDR (start1_byte);
start2_addr = BYTE_POS_ADDR (start2_byte);
- bcopy (start2_addr, temp, len2_byte);
- bcopy (start1_addr, start1_addr + len2_byte, len1_byte);
- bcopy (temp, start1_addr, len2_byte);
+ memcpy (temp, start2_addr, len2_byte);
+ memcpy (start1_addr + len2_byte, start1_addr, len1_byte);
+ memcpy (start1_addr, temp, len2_byte);
SAFE_FREE ();
}
else
SAFE_ALLOCA (temp, unsigned char *, len1_byte);
start1_addr = BYTE_POS_ADDR (start1_byte);
start2_addr = BYTE_POS_ADDR (start2_byte);
- bcopy (start1_addr, temp, len1_byte);
- bcopy (start2_addr, start1_addr, len2_byte);
- bcopy (temp, start1_addr + len2_byte, len1_byte);
+ memcpy (temp, start1_addr, len1_byte);
+ memcpy (start1_addr, start2_addr, len2_byte);
+ memcpy (start1_addr + len2_byte, temp, len1_byte);
SAFE_FREE ();
}
graft_intervals_into_buffer (tmp_interval1, start1 + len2,
SAFE_ALLOCA (temp, unsigned char *, len1_byte);
start1_addr = BYTE_POS_ADDR (start1_byte);
start2_addr = BYTE_POS_ADDR (start2_byte);
- bcopy (start1_addr, temp, len1_byte);
- bcopy (start2_addr, start1_addr, len2_byte);
- bcopy (temp, start2_addr, len1_byte);
+ memcpy (temp, start1_addr, len1_byte);
+ memcpy (start1_addr, start2_addr, len2_byte);
+ memcpy (start2_addr, temp, len1_byte);
SAFE_FREE ();
graft_intervals_into_buffer (tmp_interval1, start2,
SAFE_ALLOCA (temp, unsigned char *, len2_byte);
start1_addr = BYTE_POS_ADDR (start1_byte);
start2_addr = BYTE_POS_ADDR (start2_byte);
- bcopy (start2_addr, temp, len2_byte);
- bcopy (start1_addr, start1_addr + len_mid + len2_byte, len1_byte);
- safe_bcopy (start1_addr + len1_byte, start1_addr + len2_byte, len_mid);
- bcopy (temp, start1_addr, len2_byte);
+ memcpy (temp, start2_addr, len2_byte);
+ memcpy (start1_addr + len_mid + len2_byte, start1_addr, len1_byte);
+ memmove (start1_addr + len2_byte, start1_addr + len1_byte, len_mid);
+ memcpy (start1_addr, temp, len2_byte);
SAFE_FREE ();
graft_intervals_into_buffer (tmp_interval1, end2 - len1,
SAFE_ALLOCA (temp, unsigned char *, len1_byte);
start1_addr = BYTE_POS_ADDR (start1_byte);
start2_addr = BYTE_POS_ADDR (start2_byte);
- bcopy (start1_addr, temp, len1_byte);
- bcopy (start2_addr, start1_addr, len2_byte);
- bcopy (start1_addr + len1_byte, start1_addr + len2_byte, len_mid);
- bcopy (temp, start1_addr + len2_byte + len_mid, len1_byte);
+ memcpy (temp, start1_addr, len1_byte);
+ memcpy (start1_addr, start2_addr, len2_byte);
+ memcpy (start1_addr + len2_byte, start1_addr + len1_byte, len_mid);
+ memcpy (start1_addr + len2_byte + len_mid, temp, len1_byte);
SAFE_FREE ();
graft_intervals_into_buffer (tmp_interval1, end2 - len1,
\f
void
-syms_of_editfns ()
+syms_of_editfns (void)
{
environbuf = 0;
+ 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,
/* 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);
}
defsubr (&Sgoto_char);
defsubr (&Sstring_to_char);
defsubr (&Schar_to_string);
+ defsubr (&Sbyte_to_string);
defsubr (&Sbuffer_substring);
defsubr (&Sbuffer_substring_no_properties);
defsubr (&Sbuffer_string);
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);
defsubr (&Sinsert_and_inherit);
defsubr (&Sinsert_and_inherit_before_markers);
defsubr (&Sinsert_char);
+ defsubr (&Sinsert_byte);
defsubr (&Suser_login_name);
defsubr (&Suser_real_login_name);