*** empty log message ***
[emacs.git] / src / editfns.c
blobb4044d2bb78af7eeed16c2ba0783b15b8b9de41b
1 /* Lisp functions pertaining to editing.
2 Copyright (C) 1985,86,87,89,93,94,95,96,97,98, 1999, 2000
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
23 #include <config.h>
24 #include <sys/types.h>
26 #ifdef VMS
27 #include "vms-pwd.h"
28 #else
29 #include <pwd.h>
30 #endif
32 #ifdef HAVE_UNISTD_H
33 #include <unistd.h>
34 #endif
36 #include "lisp.h"
37 #include "intervals.h"
38 #include "buffer.h"
39 #include "charset.h"
40 #include "coding.h"
41 #include "window.h"
43 #include "systime.h"
45 #define min(a, b) ((a) < (b) ? (a) : (b))
46 #define max(a, b) ((a) > (b) ? (a) : (b))
48 #ifndef NULL
49 #define NULL 0
50 #endif
52 #ifndef USE_CRT_DLL
53 extern char **environ;
54 #endif
56 extern Lisp_Object make_time P_ ((time_t));
57 extern size_t emacs_strftimeu P_ ((char *, size_t, const char *,
58 const struct tm *, int));
59 static int tm_diff P_ ((struct tm *, struct tm *));
60 static void find_field P_ ((Lisp_Object, Lisp_Object, int *, int *));
61 static void update_buffer_properties P_ ((int, int));
62 static Lisp_Object region_limit P_ ((int));
63 static int lisp_time_argument P_ ((Lisp_Object, time_t *, int *));
64 static size_t emacs_memftimeu P_ ((char *, size_t, const char *,
65 size_t, const struct tm *, int));
66 static void general_insert_function P_ ((void (*) (unsigned char *, int),
67 void (*) (Lisp_Object, int, int, int,
68 int, int),
69 int, int, Lisp_Object *));
70 static Lisp_Object subst_char_in_region_unwind P_ ((Lisp_Object));
71 static Lisp_Object subst_char_in_region_unwind_1 P_ ((Lisp_Object));
72 static void transpose_markers P_ ((int, int, int, int, int, int, int, int));
74 Lisp_Object Vbuffer_access_fontify_functions;
75 Lisp_Object Qbuffer_access_fontify_functions;
76 Lisp_Object Vbuffer_access_fontified_property;
78 Lisp_Object Fuser_full_name P_ ((Lisp_Object));
80 /* Non-nil means don't stop at field boundary in text motion commands. */
82 Lisp_Object Vinhibit_field_text_motion;
84 /* Some static data, and a function to initialize it for each run */
86 Lisp_Object Vsystem_name;
87 Lisp_Object Vuser_real_login_name; /* login name of current user ID */
88 Lisp_Object Vuser_full_name; /* full name of current user */
89 Lisp_Object Vuser_login_name; /* user name from LOGNAME or USER */
91 /* Symbol for the text property used to mark fields. */
93 Lisp_Object Qfield;
95 /* A special value for Qfield properties. */
97 Lisp_Object Qboundary;
100 void
101 init_editfns ()
103 char *user_name;
104 register unsigned char *p;
105 struct passwd *pw; /* password entry for the current user */
106 Lisp_Object tem;
108 /* Set up system_name even when dumping. */
109 init_system_name ();
111 #ifndef CANNOT_DUMP
112 /* Don't bother with this on initial start when just dumping out */
113 if (!initialized)
114 return;
115 #endif /* not CANNOT_DUMP */
117 pw = (struct passwd *) getpwuid (getuid ());
118 #ifdef MSDOS
119 /* We let the real user name default to "root" because that's quite
120 accurate on MSDOG and because it lets Emacs find the init file.
121 (The DVX libraries override the Djgpp libraries here.) */
122 Vuser_real_login_name = build_string (pw ? pw->pw_name : "root");
123 #else
124 Vuser_real_login_name = build_string (pw ? pw->pw_name : "unknown");
125 #endif
127 /* Get the effective user name, by consulting environment variables,
128 or the effective uid if those are unset. */
129 user_name = (char *) getenv ("LOGNAME");
130 if (!user_name)
131 #ifdef WINDOWSNT
132 user_name = (char *) getenv ("USERNAME"); /* it's USERNAME on NT */
133 #else /* WINDOWSNT */
134 user_name = (char *) getenv ("USER");
135 #endif /* WINDOWSNT */
136 if (!user_name)
138 pw = (struct passwd *) getpwuid (geteuid ());
139 user_name = (char *) (pw ? pw->pw_name : "unknown");
141 Vuser_login_name = build_string (user_name);
143 /* If the user name claimed in the environment vars differs from
144 the real uid, use the claimed name to find the full name. */
145 tem = Fstring_equal (Vuser_login_name, Vuser_real_login_name);
146 Vuser_full_name = Fuser_full_name (NILP (tem)? make_number (geteuid())
147 : Vuser_login_name);
149 p = (unsigned char *) getenv ("NAME");
150 if (p)
151 Vuser_full_name = build_string (p);
152 else if (NILP (Vuser_full_name))
153 Vuser_full_name = build_string ("unknown");
156 DEFUN ("char-to-string", Fchar_to_string, Schar_to_string, 1, 1, 0,
157 "Convert arg CHAR to a string containing that character.")
158 (character)
159 Lisp_Object character;
161 int len;
162 unsigned char str[MAX_MULTIBYTE_LENGTH];
164 CHECK_NUMBER (character, 0);
166 len = CHAR_STRING (XFASTINT (character), str);
167 return make_string_from_bytes (str, 1, len);
170 DEFUN ("string-to-char", Fstring_to_char, Sstring_to_char, 1, 1, 0,
171 "Convert arg STRING to a character, the first character of that string.\n\
172 A multibyte character is handled correctly.")
173 (string)
174 register Lisp_Object string;
176 register Lisp_Object val;
177 register struct Lisp_String *p;
178 CHECK_STRING (string, 0);
179 p = XSTRING (string);
180 if (p->size)
182 if (STRING_MULTIBYTE (string))
183 XSETFASTINT (val, STRING_CHAR (p->data, STRING_BYTES (p)));
184 else
185 XSETFASTINT (val, p->data[0]);
187 else
188 XSETFASTINT (val, 0);
189 return val;
192 static Lisp_Object
193 buildmark (charpos, bytepos)
194 int charpos, bytepos;
196 register Lisp_Object mark;
197 mark = Fmake_marker ();
198 set_marker_both (mark, Qnil, charpos, bytepos);
199 return mark;
202 DEFUN ("point", Fpoint, Spoint, 0, 0, 0,
203 "Return value of point, as an integer.\n\
204 Beginning of buffer is position (point-min)")
207 Lisp_Object temp;
208 XSETFASTINT (temp, PT);
209 return temp;
212 DEFUN ("point-marker", Fpoint_marker, Spoint_marker, 0, 0, 0,
213 "Return value of point, as a marker object.")
216 return buildmark (PT, PT_BYTE);
220 clip_to_bounds (lower, num, upper)
221 int lower, num, upper;
223 if (num < lower)
224 return lower;
225 else if (num > upper)
226 return upper;
227 else
228 return num;
231 DEFUN ("goto-char", Fgoto_char, Sgoto_char, 1, 1, "NGoto char: ",
232 "Set point to POSITION, a number or marker.\n\
233 Beginning of buffer is position (point-min), end is (point-max).\n\
234 If the position is in the middle of a multibyte form,\n\
235 the actual point is set at the head of the multibyte form\n\
236 except in the case that `enable-multibyte-characters' is nil.")
237 (position)
238 register Lisp_Object position;
240 int pos;
242 if (MARKERP (position)
243 && current_buffer == XMARKER (position)->buffer)
245 pos = marker_position (position);
246 if (pos < BEGV)
247 SET_PT_BOTH (BEGV, BEGV_BYTE);
248 else if (pos > ZV)
249 SET_PT_BOTH (ZV, ZV_BYTE);
250 else
251 SET_PT_BOTH (pos, marker_byte_position (position));
253 return position;
256 CHECK_NUMBER_COERCE_MARKER (position, 0);
258 pos = clip_to_bounds (BEGV, XINT (position), ZV);
259 SET_PT (pos);
260 return position;
264 /* Return the start or end position of the region.
265 BEGINNINGP non-zero means return the start.
266 If there is no region active, signal an error. */
268 static Lisp_Object
269 region_limit (beginningp)
270 int beginningp;
272 extern Lisp_Object Vmark_even_if_inactive; /* Defined in callint.c. */
273 Lisp_Object m;
275 if (!NILP (Vtransient_mark_mode)
276 && NILP (Vmark_even_if_inactive)
277 && NILP (current_buffer->mark_active))
278 Fsignal (Qmark_inactive, Qnil);
280 m = Fmarker_position (current_buffer->mark);
281 if (NILP (m))
282 error ("There is no region now");
284 if ((PT < XFASTINT (m)) == beginningp)
285 m = make_number (PT);
286 return m;
289 DEFUN ("region-beginning", Fregion_beginning, Sregion_beginning, 0, 0, 0,
290 "Return position of beginning of region, as an integer.")
293 return region_limit (1);
296 DEFUN ("region-end", Fregion_end, Sregion_end, 0, 0, 0,
297 "Return position of end of region, as an integer.")
300 return region_limit (0);
303 DEFUN ("mark-marker", Fmark_marker, Smark_marker, 0, 0, 0,
304 "Return this buffer's mark, as a marker object.\n\
305 Watch out! Moving this marker changes the mark position.\n\
306 If you set the marker not to point anywhere, the buffer will have no mark.")
309 return current_buffer->mark;
313 /* Return nonzero if POS1 and POS2 have the same value
314 for the text property PROP. */
316 static int
317 char_property_eq (prop, pos1, pos2)
318 Lisp_Object prop;
319 Lisp_Object pos1, pos2;
321 Lisp_Object pval1, pval2;
323 pval1 = Fget_char_property (pos1, prop, Qnil);
324 pval2 = Fget_char_property (pos2, prop, Qnil);
326 return EQ (pval1, pval2);
329 /* Return the direction from which the char-property PROP would be
330 inherited by any new text inserted at POS: 1 if it would be
331 inherited from the char after POS, -1 if it would be inherited from
332 the char before POS, and 0 if from neither. */
334 static int
335 char_property_stickiness (prop, pos)
336 Lisp_Object prop;
337 Lisp_Object pos;
339 Lisp_Object front_sticky;
341 if (XINT (pos) > BEGV)
342 /* Consider previous character. */
344 Lisp_Object prev_pos, rear_non_sticky;
346 prev_pos = make_number (XINT (pos) - 1);
347 rear_non_sticky = Fget_char_property (prev_pos, Qrear_nonsticky, Qnil);
349 if (EQ (rear_non_sticky, Qnil)
350 || (CONSP (rear_non_sticky)
351 && NILP (Fmemq (prop, rear_non_sticky))))
352 /* PROP is not rear-non-sticky, and since this takes precedence over
353 any front-stickiness, PROP is inherited from before. */
354 return -1;
357 /* Consider following character. */
358 front_sticky = Fget_char_property (pos, Qfront_sticky, Qnil);
360 if (EQ (front_sticky, Qt)
361 || (CONSP (front_sticky)
362 && !NILP (Fmemq (prop, front_sticky))))
363 /* PROP is inherited from after. */
364 return 1;
366 /* PROP is not inherited from either side. */
367 return 0;
371 /* Find the field surrounding POS in *BEG and *END. If POS is nil,
372 the value of point is used instead. If BEG or END null,
373 means don't store the beginning or end of the field.
375 If MERGE_AT_BOUNDARY is nonzero, then if POS is at the very first
376 position of a field, then the beginning of the previous field is
377 returned instead of the beginning of POS's field (since the end of a
378 field is actually also the beginning of the next input field, this
379 behavior is sometimes useful). Additionally in the MERGE_AT_BOUNDARY
380 true case, if two fields are separated by a field with the special
381 value `boundary', and POS lies within it, then the two separated
382 fields are considered to be adjacent, and POS between them, when
383 finding the beginning and ending of the "merged" field.
385 Either BEG or END may be 0, in which case the corresponding value
386 is not stored. */
388 static void
389 find_field (pos, merge_at_boundary, beg, end)
390 Lisp_Object pos;
391 Lisp_Object merge_at_boundary;
392 int *beg, *end;
394 /* Fields right before and after the point. */
395 Lisp_Object before_field, after_field;
396 /* 1 if POS counts as the start of a field. */
397 int at_field_start = 0;
398 /* 1 if POS counts as the end of a field. */
399 int at_field_end = 0;
401 if (NILP (pos))
402 XSETFASTINT (pos, PT);
403 else
404 CHECK_NUMBER_COERCE_MARKER (pos, 0);
406 after_field
407 = Fget_char_property (pos, Qfield, Qnil);
408 before_field
409 = (XFASTINT (pos) > BEGV
410 ? Fget_char_property (make_number (XINT (pos) - 1), Qfield, Qnil)
411 : Qnil);
413 /* See if we need to handle the case where MERGE_AT_BOUNDARY is nil
414 and POS is at beginning of a field, which can also be interpreted
415 as the end of the previous field. Note that the case where if
416 MERGE_AT_BOUNDARY is non-nil (see function comment) is actually the
417 more natural one; then we avoid treating the beginning of a field
418 specially. */
419 if (NILP (merge_at_boundary) && !EQ (after_field, before_field))
420 /* We are at a boundary, see which direction is inclusive. We
421 decide by seeing which field the `field' property sticks to. */
423 int stickiness = char_property_stickiness (Qfield, pos);
425 if (stickiness > 0)
426 at_field_start = 1;
427 else if (stickiness < 0)
428 at_field_end = 1;
429 else
430 /* STICKINESS == 0 means that any inserted text will get a
431 `field' char-property of nil, so check to see if that
432 matches either of the adjacent characters (this being a
433 kind of "stickiness by default"). */
435 if (NILP (before_field))
436 at_field_end = 1; /* Sticks to the left. */
437 else if (NILP (after_field))
438 at_field_start = 1; /* Sticks to the right. */
442 /* Note about special `boundary' fields:
444 Consider the case where the point (`.') is between the fields `x' and `y':
446 xxxx.yyyy
448 In this situation, if merge_at_boundary is true, we consider the
449 `x' and `y' fields as forming one big merged field, and so the end
450 of the field is the end of `y'.
452 However, if `x' and `y' are separated by a special `boundary' field
453 (a field with a `field' char-property of 'boundary), then we ignore
454 this special field when merging adjacent fields. Here's the same
455 situation, but with a `boundary' field between the `x' and `y' fields:
457 xxx.BBBByyyy
459 Here, if point is at the end of `x', the beginning of `y', or
460 anywhere in-between (within the `boundary' field), we merge all
461 three fields and consider the beginning as being the beginning of
462 the `x' field, and the end as being the end of the `y' field. */
464 if (beg)
466 if (at_field_start)
467 /* POS is at the edge of a field, and we should consider it as
468 the beginning of the following field. */
469 *beg = XFASTINT (pos);
470 else
471 /* Find the previous field boundary. */
473 if (!NILP (merge_at_boundary) && EQ (before_field, Qboundary))
474 /* Skip a `boundary' field. */
475 pos = Fprevious_single_char_property_change (pos, Qfield, Qnil,Qnil);
477 pos = Fprevious_single_char_property_change (pos, Qfield, Qnil, Qnil);
478 *beg = NILP (pos) ? BEGV : XFASTINT (pos);
482 if (end)
484 if (at_field_end)
485 /* POS is at the edge of a field, and we should consider it as
486 the end of the previous field. */
487 *end = XFASTINT (pos);
488 else
489 /* Find the next field boundary. */
491 if (!NILP (merge_at_boundary) && EQ (after_field, Qboundary))
492 /* Skip a `boundary' field. */
493 pos = Fnext_single_char_property_change (pos, Qfield, Qnil, Qnil);
495 pos = Fnext_single_char_property_change (pos, Qfield, Qnil, Qnil);
496 *end = NILP (pos) ? ZV : XFASTINT (pos);
502 DEFUN ("delete-field", Fdelete_field, Sdelete_field, 0, 1, 0,
503 "Delete the field surrounding POS.\n\
504 A field is a region of text with the same `field' property.\n\
505 If POS is nil, the value of point is used for POS.")
506 (pos)
507 Lisp_Object pos;
509 int beg, end;
510 find_field (pos, Qnil, &beg, &end);
511 if (beg != end)
512 del_range (beg, end);
513 return Qnil;
516 DEFUN ("field-string", Ffield_string, Sfield_string, 0, 1, 0,
517 "Return the contents of the field surrounding POS as a string.\n\
518 A field is a region of text with the same `field' property.\n\
519 If POS is nil, the value of point is used for POS.")
520 (pos)
521 Lisp_Object pos;
523 int beg, end;
524 find_field (pos, Qnil, &beg, &end);
525 return make_buffer_string (beg, end, 1);
528 DEFUN ("field-string-no-properties", Ffield_string_no_properties, Sfield_string_no_properties, 0, 1, 0,
529 "Return the contents of the field around POS, without text-properties.\n\
530 A field is a region of text with the same `field' property.\n\
531 If POS is nil, the value of point is used for POS.")
532 (pos)
533 Lisp_Object pos;
535 int beg, end;
536 find_field (pos, Qnil, &beg, &end);
537 return make_buffer_string (beg, end, 0);
540 DEFUN ("field-beginning", Ffield_beginning, Sfield_beginning, 0, 2, 0,
541 "Return the beginning of the field surrounding POS.\n\
542 A field is a region of text with the same `field' property.\n\
543 If POS is nil, the value of point is used for POS.\n\
544 If ESCAPE-FROM-EDGE is non-nil and POS is at the beginning of its\n\
545 field, then the beginning of the *previous* field is returned.")
546 (pos, escape_from_edge)
547 Lisp_Object pos, escape_from_edge;
549 int beg;
550 find_field (pos, escape_from_edge, &beg, 0);
551 return make_number (beg);
554 DEFUN ("field-end", Ffield_end, Sfield_end, 0, 2, 0,
555 "Return the end of the field surrounding POS.\n\
556 A field is a region of text with the same `field' property.\n\
557 If POS is nil, the value of point is used for POS.\n\
558 If ESCAPE-FROM-EDGE is non-nil and POS is at the end of its field,\n\
559 then the end of the *following* field is returned.")
560 (pos, escape_from_edge)
561 Lisp_Object pos, escape_from_edge;
563 int end;
564 find_field (pos, escape_from_edge, 0, &end);
565 return make_number (end);
568 DEFUN ("constrain-to-field", Fconstrain_to_field, Sconstrain_to_field, 2, 5, 0,
569 "Return the position closest to NEW-POS that is in the same field as OLD-POS.\n\
571 A field is a region of text with the same `field' property.\n\
572 If NEW-POS is nil, then the current point is used instead, and set to the\n\
573 constrained position if that is is different.\n\
575 If OLD-POS is at the boundary of two fields, then the allowable\n\
576 positions for NEW-POS depends on the value of the optional argument\n\
577 ESCAPE-FROM-EDGE: If ESCAPE-FROM-EDGE is nil, then NEW-POS is\n\
578 constrained to the field that has the same `field' char-property\n\
579 as any new characters inserted at OLD-POS, whereas if ESCAPE-FROM-EDGE\n\
580 is non-nil, NEW-POS is constrained to the union of the two adjacent\n\
581 fields. Additionally, if two fields are separated by another field with\n\
582 the special value `boundary', then any point within this special field is\n\
583 also considered to be `on the boundary'.\n\
585 If the optional argument ONLY-IN-LINE is non-nil and constraining\n\
586 NEW-POS would move it to a different line, NEW-POS is returned\n\
587 unconstrained. This useful for commands that move by line, like\n\
588 \\[next-line] or \\[beginning-of-line], which should generally respect field boundaries\n\
589 only in the case where they can still move to the right line.\n\
591 If the optional argument INHIBIT-CAPTURE-PROPERTY is non-nil, and OLD-POS has\n\
592 a non-nil property of that name, then any field boundaries are ignored.\n\
594 Field boundaries are not noticed if `inhibit-field-text-motion' is non-nil.")
595 (new_pos, old_pos, escape_from_edge, only_in_line, inhibit_capture_property)
596 Lisp_Object new_pos, old_pos;
597 Lisp_Object escape_from_edge, only_in_line, inhibit_capture_property;
599 /* If non-zero, then the original point, before re-positioning. */
600 int orig_point = 0;
602 if (NILP (new_pos))
603 /* Use the current point, and afterwards, set it. */
605 orig_point = PT;
606 XSETFASTINT (new_pos, PT);
609 if (NILP (Vinhibit_field_text_motion)
610 && !EQ (new_pos, old_pos)
611 && !char_property_eq (Qfield, new_pos, old_pos)
612 && (NILP (inhibit_capture_property)
613 || NILP (Fget_char_property(old_pos, inhibit_capture_property, Qnil))))
614 /* NEW_POS is not within the same field as OLD_POS; try to
615 move NEW_POS so that it is. */
617 int fwd, shortage;
618 Lisp_Object field_bound;
620 CHECK_NUMBER_COERCE_MARKER (new_pos, 0);
621 CHECK_NUMBER_COERCE_MARKER (old_pos, 0);
623 fwd = (XFASTINT (new_pos) > XFASTINT (old_pos));
625 if (fwd)
626 field_bound = Ffield_end (old_pos, escape_from_edge);
627 else
628 field_bound = Ffield_beginning (old_pos, escape_from_edge);
630 if (/* See if ESCAPE_FROM_EDGE caused FIELD_BOUND to jump to the
631 other side of NEW_POS, which would mean that NEW_POS is
632 already acceptable, and it's not necessary to constrain it
633 to FIELD_BOUND. */
634 ((XFASTINT (field_bound) < XFASTINT (new_pos)) ? fwd : !fwd)
635 /* NEW_POS should be constrained, but only if either
636 ONLY_IN_LINE is nil (in which case any constraint is OK),
637 or NEW_POS and FIELD_BOUND are on the same line (in which
638 case the constraint is OK even if ONLY_IN_LINE is non-nil). */
639 && (NILP (only_in_line)
640 /* This is the ONLY_IN_LINE case, check that NEW_POS and
641 FIELD_BOUND are on the same line by seeing whether
642 there's an intervening newline or not. */
643 || (scan_buffer ('\n',
644 XFASTINT (new_pos), XFASTINT (field_bound),
645 fwd ? -1 : 1, &shortage, 1),
646 shortage != 0)))
647 /* Constrain NEW_POS to FIELD_BOUND. */
648 new_pos = field_bound;
650 if (orig_point && XFASTINT (new_pos) != orig_point)
651 /* The NEW_POS argument was originally nil, so automatically set PT. */
652 SET_PT (XFASTINT (new_pos));
655 return new_pos;
659 DEFUN ("line-beginning-position", Fline_beginning_position, Sline_beginning_position,
660 0, 1, 0,
661 "Return the character position of the first character on the current line.\n\
662 With argument N not nil or 1, move forward N - 1 lines first.\n\
663 If scan reaches end of buffer, return that position.\n\
664 The scan does not cross a field boundary unless it would move\n\
665 beyond there to a different line. Field boundaries are not noticed if\n\
666 `inhibit-field-text-motion' is non-nil. .And if N is nil or 1,\n\
667 and scan starts at a field boundary, the scan stops as soon as it starts.\n\
669 This function does not move point.")
671 Lisp_Object n;
673 int orig, orig_byte, end;
675 if (NILP (n))
676 XSETFASTINT (n, 1);
677 else
678 CHECK_NUMBER (n, 0);
680 orig = PT;
681 orig_byte = PT_BYTE;
682 Fforward_line (make_number (XINT (n) - 1));
683 end = PT;
685 SET_PT_BOTH (orig, orig_byte);
687 /* Return END constrained to the current input field. */
688 return Fconstrain_to_field (make_number (end), make_number (orig),
689 XINT (n) != 1 ? Qt : Qnil,
690 Qt, Qnil);
693 DEFUN ("line-end-position", Fline_end_position, Sline_end_position,
694 0, 1, 0,
695 "Return the character position of the last character on the current line.\n\
696 With argument N not nil or 1, move forward N - 1 lines first.\n\
697 If scan reaches end of buffer, return that position.\n\
698 This function does not move point.")
700 Lisp_Object n;
702 int end_pos;
703 int orig = PT;
705 if (NILP (n))
706 XSETFASTINT (n, 1);
707 else
708 CHECK_NUMBER (n, 0);
710 end_pos = find_before_next_newline (orig, 0, XINT (n) - (XINT (n) <= 0));
712 /* Return END_POS constrained to the current input field. */
713 return Fconstrain_to_field (make_number (end_pos), make_number (orig),
714 Qnil, Qt, Qnil);
717 Lisp_Object
718 save_excursion_save ()
720 int visible = (XBUFFER (XWINDOW (selected_window)->buffer)
721 == current_buffer);
723 return Fcons (Fpoint_marker (),
724 Fcons (Fcopy_marker (current_buffer->mark, Qnil),
725 Fcons (visible ? Qt : Qnil,
726 current_buffer->mark_active)));
729 Lisp_Object
730 save_excursion_restore (info)
731 Lisp_Object info;
733 Lisp_Object tem, tem1, omark, nmark;
734 struct gcpro gcpro1, gcpro2, gcpro3;
736 tem = Fmarker_buffer (Fcar (info));
737 /* If buffer being returned to is now deleted, avoid error */
738 /* Otherwise could get error here while unwinding to top level
739 and crash */
740 /* In that case, Fmarker_buffer returns nil now. */
741 if (NILP (tem))
742 return Qnil;
744 omark = nmark = Qnil;
745 GCPRO3 (info, omark, nmark);
747 Fset_buffer (tem);
748 tem = Fcar (info);
749 Fgoto_char (tem);
750 unchain_marker (tem);
751 tem = Fcar (Fcdr (info));
752 omark = Fmarker_position (current_buffer->mark);
753 Fset_marker (current_buffer->mark, tem, Fcurrent_buffer ());
754 nmark = Fmarker_position (tem);
755 unchain_marker (tem);
756 tem = Fcdr (Fcdr (info));
757 #if 0 /* We used to make the current buffer visible in the selected window
758 if that was true previously. That avoids some anomalies.
759 But it creates others, and it wasn't documented, and it is simpler
760 and cleaner never to alter the window/buffer connections. */
761 tem1 = Fcar (tem);
762 if (!NILP (tem1)
763 && current_buffer != XBUFFER (XWINDOW (selected_window)->buffer))
764 Fswitch_to_buffer (Fcurrent_buffer (), Qnil);
765 #endif /* 0 */
767 tem1 = current_buffer->mark_active;
768 current_buffer->mark_active = Fcdr (tem);
769 if (!NILP (Vrun_hooks))
771 /* If mark is active now, and either was not active
772 or was at a different place, run the activate hook. */
773 if (! NILP (current_buffer->mark_active))
775 if (! EQ (omark, nmark))
776 call1 (Vrun_hooks, intern ("activate-mark-hook"));
778 /* If mark has ceased to be active, run deactivate hook. */
779 else if (! NILP (tem1))
780 call1 (Vrun_hooks, intern ("deactivate-mark-hook"));
782 UNGCPRO;
783 return Qnil;
786 DEFUN ("save-excursion", Fsave_excursion, Ssave_excursion, 0, UNEVALLED, 0,
787 "Save point, mark, and current buffer; execute BODY; restore those things.\n\
788 Executes BODY just like `progn'.\n\
789 The values of point, mark and the current buffer are restored\n\
790 even in case of abnormal exit (throw or error).\n\
791 The state of activation of the mark is also restored.\n\
793 This construct does not save `deactivate-mark', and therefore\n\
794 functions that change the buffer will still cause deactivation\n\
795 of the mark at the end of the command. To prevent that, bind\n\
796 `deactivate-mark' with `let'.")
797 (args)
798 Lisp_Object args;
800 register Lisp_Object val;
801 int count = specpdl_ptr - specpdl;
803 record_unwind_protect (save_excursion_restore, save_excursion_save ());
805 val = Fprogn (args);
806 return unbind_to (count, val);
809 DEFUN ("save-current-buffer", Fsave_current_buffer, Ssave_current_buffer, 0, UNEVALLED, 0,
810 "Save the current buffer; execute BODY; restore the current buffer.\n\
811 Executes BODY just like `progn'.")
812 (args)
813 Lisp_Object args;
815 Lisp_Object val;
816 int count = specpdl_ptr - specpdl;
818 record_unwind_protect (set_buffer_if_live, Fcurrent_buffer ());
820 val = Fprogn (args);
821 return unbind_to (count, val);
824 DEFUN ("buffer-size", Fbufsize, Sbufsize, 0, 1, 0,
825 "Return the number of characters in the current buffer.\n\
826 If BUFFER, return the number of characters in that buffer instead.")
827 (buffer)
828 Lisp_Object buffer;
830 if (NILP (buffer))
831 return make_number (Z - BEG);
832 else
834 CHECK_BUFFER (buffer, 1);
835 return make_number (BUF_Z (XBUFFER (buffer))
836 - BUF_BEG (XBUFFER (buffer)));
840 DEFUN ("point-min", Fpoint_min, Spoint_min, 0, 0, 0,
841 "Return the minimum permissible value of point in the current buffer.\n\
842 This is 1, unless narrowing (a buffer restriction) is in effect.")
845 Lisp_Object temp;
846 XSETFASTINT (temp, BEGV);
847 return temp;
850 DEFUN ("point-min-marker", Fpoint_min_marker, Spoint_min_marker, 0, 0, 0,
851 "Return a marker to the minimum permissible value of point in this buffer.\n\
852 This is the beginning, unless narrowing (a buffer restriction) is in effect.")
855 return buildmark (BEGV, BEGV_BYTE);
858 DEFUN ("point-max", Fpoint_max, Spoint_max, 0, 0, 0,
859 "Return the maximum permissible value of point in the current buffer.\n\
860 This is (1+ (buffer-size)), unless narrowing (a buffer restriction)\n\
861 is in effect, in which case it is less.")
864 Lisp_Object temp;
865 XSETFASTINT (temp, ZV);
866 return temp;
869 DEFUN ("point-max-marker", Fpoint_max_marker, Spoint_max_marker, 0, 0, 0,
870 "Return a marker to the maximum permissible value of point in this buffer.\n\
871 This is (1+ (buffer-size)), unless narrowing (a buffer restriction)\n\
872 is in effect, in which case it is less.")
875 return buildmark (ZV, ZV_BYTE);
878 DEFUN ("gap-position", Fgap_position, Sgap_position, 0, 0, 0,
879 "Return the position of the gap, in the current buffer.\n\
880 See also `gap-size'.")
883 Lisp_Object temp;
884 XSETFASTINT (temp, GPT);
885 return temp;
888 DEFUN ("gap-size", Fgap_size, Sgap_size, 0, 0, 0,
889 "Return the size of the current buffer's gap.\n\
890 See also `gap-position'.")
893 Lisp_Object temp;
894 XSETFASTINT (temp, GAP_SIZE);
895 return temp;
898 DEFUN ("position-bytes", Fposition_bytes, Sposition_bytes, 1, 1, 0,
899 "Return the byte position for character position POSITION.\n\
900 If POSITION is out of range, the value is nil.")
901 (position)
902 Lisp_Object position;
904 CHECK_NUMBER_COERCE_MARKER (position, 1);
905 if (XINT (position) < BEG || XINT (position) > Z)
906 return Qnil;
907 return make_number (CHAR_TO_BYTE (XINT (position)));
910 DEFUN ("byte-to-position", Fbyte_to_position, Sbyte_to_position, 1, 1, 0,
911 "Return the character position for byte position BYTEPOS.\n\
912 If BYTEPOS is out of range, the value is nil.")
913 (bytepos)
914 Lisp_Object bytepos;
916 CHECK_NUMBER (bytepos, 1);
917 if (XINT (bytepos) < BEG_BYTE || XINT (bytepos) > Z_BYTE)
918 return Qnil;
919 return make_number (BYTE_TO_CHAR (XINT (bytepos)));
922 DEFUN ("following-char", Ffollowing_char, Sfollowing_char, 0, 0, 0,
923 "Return the character following point, as a number.\n\
924 At the end of the buffer or accessible region, return 0.")
927 Lisp_Object temp;
928 if (PT >= ZV)
929 XSETFASTINT (temp, 0);
930 else
931 XSETFASTINT (temp, FETCH_CHAR (PT_BYTE));
932 return temp;
935 DEFUN ("preceding-char", Fprevious_char, Sprevious_char, 0, 0, 0,
936 "Return the character preceding point, as a number.\n\
937 At the beginning of the buffer or accessible region, return 0.")
940 Lisp_Object temp;
941 if (PT <= BEGV)
942 XSETFASTINT (temp, 0);
943 else if (!NILP (current_buffer->enable_multibyte_characters))
945 int pos = PT_BYTE;
946 DEC_POS (pos);
947 XSETFASTINT (temp, FETCH_CHAR (pos));
949 else
950 XSETFASTINT (temp, FETCH_BYTE (PT_BYTE - 1));
951 return temp;
954 DEFUN ("bobp", Fbobp, Sbobp, 0, 0, 0,
955 "Return t if point is at the beginning of the buffer.\n\
956 If the buffer is narrowed, this means the beginning of the narrowed part.")
959 if (PT == BEGV)
960 return Qt;
961 return Qnil;
964 DEFUN ("eobp", Feobp, Seobp, 0, 0, 0,
965 "Return t if point is at the end of the buffer.\n\
966 If the buffer is narrowed, this means the end of the narrowed part.")
969 if (PT == ZV)
970 return Qt;
971 return Qnil;
974 DEFUN ("bolp", Fbolp, Sbolp, 0, 0, 0,
975 "Return t if point is at the beginning of a line.")
978 if (PT == BEGV || FETCH_BYTE (PT_BYTE - 1) == '\n')
979 return Qt;
980 return Qnil;
983 DEFUN ("eolp", Feolp, Seolp, 0, 0, 0,
984 "Return t if point is at the end of a line.\n\
985 `End of a line' includes point being at the end of the buffer.")
988 if (PT == ZV || FETCH_BYTE (PT_BYTE) == '\n')
989 return Qt;
990 return Qnil;
993 DEFUN ("char-after", Fchar_after, Schar_after, 0, 1, 0,
994 "Return character in current buffer at position POS.\n\
995 POS is an integer or a marker.\n\
996 If POS is out of range, the value is nil.")
997 (pos)
998 Lisp_Object pos;
1000 register int pos_byte;
1002 if (NILP (pos))
1004 pos_byte = PT_BYTE;
1005 XSETFASTINT (pos, PT);
1008 if (MARKERP (pos))
1010 pos_byte = marker_byte_position (pos);
1011 if (pos_byte < BEGV_BYTE || pos_byte >= ZV_BYTE)
1012 return Qnil;
1014 else
1016 CHECK_NUMBER_COERCE_MARKER (pos, 0);
1017 if (XINT (pos) < BEGV || XINT (pos) >= ZV)
1018 return Qnil;
1020 pos_byte = CHAR_TO_BYTE (XINT (pos));
1023 return make_number (FETCH_CHAR (pos_byte));
1026 DEFUN ("char-before", Fchar_before, Schar_before, 0, 1, 0,
1027 "Return character in current buffer preceding position POS.\n\
1028 POS is an integer or a marker.\n\
1029 If POS is out of range, the value is nil.")
1030 (pos)
1031 Lisp_Object pos;
1033 register Lisp_Object val;
1034 register int pos_byte;
1036 if (NILP (pos))
1038 pos_byte = PT_BYTE;
1039 XSETFASTINT (pos, PT);
1042 if (MARKERP (pos))
1044 pos_byte = marker_byte_position (pos);
1046 if (pos_byte <= BEGV_BYTE || pos_byte > ZV_BYTE)
1047 return Qnil;
1049 else
1051 CHECK_NUMBER_COERCE_MARKER (pos, 0);
1053 if (XINT (pos) <= BEGV || XINT (pos) > ZV)
1054 return Qnil;
1056 pos_byte = CHAR_TO_BYTE (XINT (pos));
1059 if (!NILP (current_buffer->enable_multibyte_characters))
1061 DEC_POS (pos_byte);
1062 XSETFASTINT (val, FETCH_CHAR (pos_byte));
1064 else
1066 pos_byte--;
1067 XSETFASTINT (val, FETCH_BYTE (pos_byte));
1069 return val;
1072 DEFUN ("user-login-name", Fuser_login_name, Suser_login_name, 0, 1, 0,
1073 "Return the name under which the user logged in, as a string.\n\
1074 This is based on the effective uid, not the real uid.\n\
1075 Also, if the environment variable LOGNAME or USER is set,\n\
1076 that determines the value of this function.\n\n\
1077 If optional argument UID is an integer, return the login name of the user\n\
1078 with that uid, or nil if there is no such user.")
1079 (uid)
1080 Lisp_Object uid;
1082 struct passwd *pw;
1084 /* Set up the user name info if we didn't do it before.
1085 (That can happen if Emacs is dumpable
1086 but you decide to run `temacs -l loadup' and not dump. */
1087 if (INTEGERP (Vuser_login_name))
1088 init_editfns ();
1090 if (NILP (uid))
1091 return Vuser_login_name;
1093 CHECK_NUMBER (uid, 0);
1094 pw = (struct passwd *) getpwuid (XINT (uid));
1095 return (pw ? build_string (pw->pw_name) : Qnil);
1098 DEFUN ("user-real-login-name", Fuser_real_login_name, Suser_real_login_name,
1099 0, 0, 0,
1100 "Return the name of the user's real uid, as a string.\n\
1101 This ignores the environment variables LOGNAME and USER, so it differs from\n\
1102 `user-login-name' when running under `su'.")
1105 /* Set up the user name info if we didn't do it before.
1106 (That can happen if Emacs is dumpable
1107 but you decide to run `temacs -l loadup' and not dump. */
1108 if (INTEGERP (Vuser_login_name))
1109 init_editfns ();
1110 return Vuser_real_login_name;
1113 DEFUN ("user-uid", Fuser_uid, Suser_uid, 0, 0, 0,
1114 "Return the effective uid of Emacs, as an integer.")
1117 return make_number (geteuid ());
1120 DEFUN ("user-real-uid", Fuser_real_uid, Suser_real_uid, 0, 0, 0,
1121 "Return the real uid of Emacs, as an integer.")
1124 return make_number (getuid ());
1127 DEFUN ("user-full-name", Fuser_full_name, Suser_full_name, 0, 1, 0,
1128 "Return the full name of the user logged in, as a string.\n\
1129 If the full name corresponding to Emacs's userid is not known,\n\
1130 return \"unknown\".\n\
1132 If optional argument UID is an integer, return the full name of the user\n\
1133 with that uid, or nil if there is no such user.\n\
1134 If UID is a string, return the full name of the user with that login\n\
1135 name, or nil if there is no such user.")
1136 (uid)
1137 Lisp_Object uid;
1139 struct passwd *pw;
1140 register unsigned char *p, *q;
1141 extern char *index ();
1142 Lisp_Object full;
1144 if (NILP (uid))
1145 return Vuser_full_name;
1146 else if (NUMBERP (uid))
1147 pw = (struct passwd *) getpwuid (XINT (uid));
1148 else if (STRINGP (uid))
1149 pw = (struct passwd *) getpwnam (XSTRING (uid)->data);
1150 else
1151 error ("Invalid UID specification");
1153 if (!pw)
1154 return Qnil;
1156 p = (unsigned char *) USER_FULL_NAME;
1157 /* Chop off everything after the first comma. */
1158 q = (unsigned char *) index (p, ',');
1159 full = make_string (p, q ? q - p : strlen (p));
1161 #ifdef AMPERSAND_FULL_NAME
1162 p = XSTRING (full)->data;
1163 q = (unsigned char *) index (p, '&');
1164 /* Substitute the login name for the &, upcasing the first character. */
1165 if (q)
1167 register unsigned char *r;
1168 Lisp_Object login;
1170 login = Fuser_login_name (make_number (pw->pw_uid));
1171 r = (unsigned char *) alloca (strlen (p) + XSTRING (login)->size + 1);
1172 bcopy (p, r, q - p);
1173 r[q - p] = 0;
1174 strcat (r, XSTRING (login)->data);
1175 r[q - p] = UPCASE (r[q - p]);
1176 strcat (r, q + 1);
1177 full = build_string (r);
1179 #endif /* AMPERSAND_FULL_NAME */
1181 return full;
1184 DEFUN ("system-name", Fsystem_name, Ssystem_name, 0, 0, 0,
1185 "Return the name of the machine you are running on, as a string.")
1188 return Vsystem_name;
1191 /* For the benefit of callers who don't want to include lisp.h */
1193 char *
1194 get_system_name ()
1196 if (STRINGP (Vsystem_name))
1197 return (char *) XSTRING (Vsystem_name)->data;
1198 else
1199 return "";
1202 DEFUN ("emacs-pid", Femacs_pid, Semacs_pid, 0, 0, 0,
1203 "Return the process ID of Emacs, as an integer.")
1206 return make_number (getpid ());
1209 DEFUN ("current-time", Fcurrent_time, Scurrent_time, 0, 0, 0,
1210 "Return the current time, as the number of seconds since 1970-01-01 00:00:00.\n\
1211 The time is returned as a list of three integers. The first has the\n\
1212 most significant 16 bits of the seconds, while the second has the\n\
1213 least significant 16 bits. The third integer gives the microsecond\n\
1214 count.\n\
1216 The microsecond count is zero on systems that do not provide\n\
1217 resolution finer than a second.")
1220 EMACS_TIME t;
1221 Lisp_Object result[3];
1223 EMACS_GET_TIME (t);
1224 XSETINT (result[0], (EMACS_SECS (t) >> 16) & 0xffff);
1225 XSETINT (result[1], (EMACS_SECS (t) >> 0) & 0xffff);
1226 XSETINT (result[2], EMACS_USECS (t));
1228 return Flist (3, result);
1232 static int
1233 lisp_time_argument (specified_time, result, usec)
1234 Lisp_Object specified_time;
1235 time_t *result;
1236 int *usec;
1238 if (NILP (specified_time))
1240 if (usec)
1242 EMACS_TIME t;
1244 EMACS_GET_TIME (t);
1245 *usec = EMACS_USECS (t);
1246 *result = EMACS_SECS (t);
1247 return 1;
1249 else
1250 return time (result) != -1;
1252 else
1254 Lisp_Object high, low;
1255 high = Fcar (specified_time);
1256 CHECK_NUMBER (high, 0);
1257 low = Fcdr (specified_time);
1258 if (CONSP (low))
1260 if (usec)
1262 Lisp_Object usec_l = Fcdr (low);
1263 if (CONSP (usec_l))
1264 usec_l = Fcar (usec_l);
1265 if (NILP (usec_l))
1266 *usec = 0;
1267 else
1269 CHECK_NUMBER (usec_l, 0);
1270 *usec = XINT (usec_l);
1273 low = Fcar (low);
1275 else if (usec)
1276 *usec = 0;
1277 CHECK_NUMBER (low, 0);
1278 *result = (XINT (high) << 16) + (XINT (low) & 0xffff);
1279 return *result >> 16 == XINT (high);
1283 DEFUN ("float-time", Ffloat_time, Sfloat_time, 0, 1, 0,
1284 "Return the current time, as a float number of seconds since the epoch.\n\
1285 If an argument is given, it specifies a time to convert to float\n\
1286 instead of the current time. The argument should have the forms:\n\
1287 (HIGH . LOW) or (HIGH LOW USEC) or (HIGH LOW . USEC).\n\
1288 Thus, you can use times obtained from `current-time'\n\
1289 and from `file-attributes'.")
1290 (specified_time)
1291 Lisp_Object specified_time;
1293 time_t sec;
1294 int usec;
1296 if (! lisp_time_argument (specified_time, &sec, &usec))
1297 error ("Invalid time specification");
1299 return make_float (sec + usec * 0.0000001);
1302 /* Write information into buffer S of size MAXSIZE, according to the
1303 FORMAT of length FORMAT_LEN, using time information taken from *TP.
1304 Default to Universal Time if UT is nonzero, local time otherwise.
1305 Return the number of bytes written, not including the terminating
1306 '\0'. If S is NULL, nothing will be written anywhere; so to
1307 determine how many bytes would be written, use NULL for S and
1308 ((size_t) -1) for MAXSIZE.
1310 This function behaves like emacs_strftimeu, except it allows null
1311 bytes in FORMAT. */
1312 static size_t
1313 emacs_memftimeu (s, maxsize, format, format_len, tp, ut)
1314 char *s;
1315 size_t maxsize;
1316 const char *format;
1317 size_t format_len;
1318 const struct tm *tp;
1319 int ut;
1321 size_t total = 0;
1323 /* Loop through all the null-terminated strings in the format
1324 argument. Normally there's just one null-terminated string, but
1325 there can be arbitrarily many, concatenated together, if the
1326 format contains '\0' bytes. emacs_strftimeu stops at the first
1327 '\0' byte so we must invoke it separately for each such string. */
1328 for (;;)
1330 size_t len;
1331 size_t result;
1333 if (s)
1334 s[0] = '\1';
1336 result = emacs_strftimeu (s, maxsize, format, tp, ut);
1338 if (s)
1340 if (result == 0 && s[0] != '\0')
1341 return 0;
1342 s += result + 1;
1345 maxsize -= result + 1;
1346 total += result;
1347 len = strlen (format);
1348 if (len == format_len)
1349 return total;
1350 total++;
1351 format += len + 1;
1352 format_len -= len + 1;
1357 DEFUN ("format-time-string", Fformat_time_string, Sformat_time_string, 1, 3, 0,
1358 "Use FORMAT-STRING to format the time TIME, or now if omitted.\n\
1359 TIME is specified as (HIGH LOW . IGNORED) or (HIGH . LOW), as returned by\n\
1360 `current-time' or `file-attributes'.\n\
1361 The third, optional, argument UNIVERSAL, if non-nil, means describe TIME\n\
1362 as Universal Time; nil means describe TIME in the local time zone.\n\
1363 The value is a copy of FORMAT-STRING, but with certain constructs replaced\n\
1364 by text that describes the specified date and time in TIME:\n\
1366 %Y is the year, %y within the century, %C the century.\n\
1367 %G is the year corresponding to the ISO week, %g within the century.\n\
1368 %m is the numeric month.\n\
1369 %b and %h are the locale's abbreviated month name, %B the full name.\n\
1370 %d is the day of the month, zero-padded, %e is blank-padded.\n\
1371 %u is the numeric day of week from 1 (Monday) to 7, %w from 0 (Sunday) to 6.\n\
1372 %a is the locale's abbreviated name of the day of week, %A the full name.\n\
1373 %U is the week number starting on Sunday, %W starting on Monday,\n\
1374 %V according to ISO 8601.\n\
1375 %j is the day of the year.\n\
1377 %H is the hour on a 24-hour clock, %I is on a 12-hour clock, %k is like %H\n\
1378 only blank-padded, %l is like %I blank-padded.\n\
1379 %p is the locale's equivalent of either AM or PM.\n\
1380 %M is the minute.\n\
1381 %S is the second.\n\
1382 %Z is the time zone name, %z is the numeric form.\n\
1383 %s is the number of seconds since 1970-01-01 00:00:00 +0000.\n\
1385 %c is the locale's date and time format.\n\
1386 %x is the locale's \"preferred\" date format.\n\
1387 %D is like \"%m/%d/%y\".\n\
1389 %R is like \"%H:%M\", %T is like \"%H:%M:%S\", %r is like \"%I:%M:%S %p\".\n\
1390 %X is the locale's \"preferred\" time format.\n\
1392 Finally, %n is a newline, %t is a tab, %% is a literal %.\n\
1394 Certain flags and modifiers are available with some format controls.\n\
1395 The flags are `_' and `-'. For certain characters X, %_X is like %X,\n\
1396 but padded with blanks; %-X is like %X, but without padding.\n\
1397 %NX (where N stands for an integer) is like %X,\n\
1398 but takes up at least N (a number) positions.\n\
1399 The modifiers are `E' and `O'. For certain characters X,\n\
1400 %EX is a locale's alternative version of %X;\n\
1401 %OX is like %X, but uses the locale's number symbols.\n\
1403 For example, to produce full ISO 8601 format, use \"%Y-%m-%dT%T%z\".")
1404 (format_string, time, universal)
1407 DEFUN ("format-time-string", Fformat_time_string, Sformat_time_string, 1, 3, 0,
1408 0 /* See immediately above */)
1409 (format_string, time, universal)
1410 Lisp_Object format_string, time, universal;
1412 time_t value;
1413 int size;
1414 struct tm *tm;
1415 int ut = ! NILP (universal);
1417 CHECK_STRING (format_string, 1);
1419 if (! lisp_time_argument (time, &value, NULL))
1420 error ("Invalid time specification");
1422 format_string = code_convert_string_norecord (format_string,
1423 Vlocale_coding_system, 1);
1425 /* This is probably enough. */
1426 size = STRING_BYTES (XSTRING (format_string)) * 6 + 50;
1428 tm = ut ? gmtime (&value) : localtime (&value);
1429 if (! tm)
1430 error ("Specified time is not representable");
1432 synchronize_system_time_locale ();
1434 while (1)
1436 char *buf = (char *) alloca (size + 1);
1437 int result;
1439 buf[0] = '\1';
1440 result = emacs_memftimeu (buf, size, XSTRING (format_string)->data,
1441 STRING_BYTES (XSTRING (format_string)),
1442 tm, ut);
1443 if ((result > 0 && result < size) || (result == 0 && buf[0] == '\0'))
1444 return code_convert_string_norecord (make_string (buf, result),
1445 Vlocale_coding_system, 0);
1447 /* If buffer was too small, make it bigger and try again. */
1448 result = emacs_memftimeu (NULL, (size_t) -1,
1449 XSTRING (format_string)->data,
1450 STRING_BYTES (XSTRING (format_string)),
1451 tm, ut);
1452 size = result + 1;
1456 DEFUN ("decode-time", Fdecode_time, Sdecode_time, 0, 1, 0,
1457 "Decode a time value as (SEC MINUTE HOUR DAY MONTH YEAR DOW DST ZONE).\n\
1458 The optional SPECIFIED-TIME should be a list of (HIGH LOW . IGNORED)\n\
1459 or (HIGH . LOW), as from `current-time' and `file-attributes', or `nil'\n\
1460 to use the current time. The list has the following nine members:\n\
1461 SEC is an integer between 0 and 60; SEC is 60 for a leap second, which\n\
1462 only some operating systems support. MINUTE is an integer between 0 and 59.\n\
1463 HOUR is an integer between 0 and 23. DAY is an integer between 1 and 31.\n\
1464 MONTH is an integer between 1 and 12. YEAR is an integer indicating the\n\
1465 four-digit year. DOW is the day of week, an integer between 0 and 6, where\n\
1466 0 is Sunday. DST is t if daylight savings time is effect, otherwise nil.\n\
1467 ZONE is an integer indicating the number of seconds east of Greenwich.\n\
1468 \(Note that Common Lisp has different meanings for DOW and ZONE.)")
1469 (specified_time)
1470 Lisp_Object specified_time;
1472 time_t time_spec;
1473 struct tm save_tm;
1474 struct tm *decoded_time;
1475 Lisp_Object list_args[9];
1477 if (! lisp_time_argument (specified_time, &time_spec, NULL))
1478 error ("Invalid time specification");
1480 decoded_time = localtime (&time_spec);
1481 if (! decoded_time)
1482 error ("Specified time is not representable");
1483 XSETFASTINT (list_args[0], decoded_time->tm_sec);
1484 XSETFASTINT (list_args[1], decoded_time->tm_min);
1485 XSETFASTINT (list_args[2], decoded_time->tm_hour);
1486 XSETFASTINT (list_args[3], decoded_time->tm_mday);
1487 XSETFASTINT (list_args[4], decoded_time->tm_mon + 1);
1488 XSETINT (list_args[5], decoded_time->tm_year + 1900);
1489 XSETFASTINT (list_args[6], decoded_time->tm_wday);
1490 list_args[7] = (decoded_time->tm_isdst)? Qt : Qnil;
1492 /* Make a copy, in case gmtime modifies the struct. */
1493 save_tm = *decoded_time;
1494 decoded_time = gmtime (&time_spec);
1495 if (decoded_time == 0)
1496 list_args[8] = Qnil;
1497 else
1498 XSETINT (list_args[8], tm_diff (&save_tm, decoded_time));
1499 return Flist (9, list_args);
1502 DEFUN ("encode-time", Fencode_time, Sencode_time, 6, MANY, 0,
1503 "Convert SECOND, MINUTE, HOUR, DAY, MONTH, YEAR and ZONE to internal time.\n\
1504 This is the reverse operation of `decode-time', which see.\n\
1505 ZONE defaults to the current time zone rule. This can\n\
1506 be a string or t (as from `set-time-zone-rule'), or it can be a list\n\
1507 \(as from `current-time-zone') or an integer (as from `decode-time')\n\
1508 applied without consideration for daylight savings time.\n\
1510 You can pass more than 7 arguments; then the first six arguments\n\
1511 are used as SECOND through YEAR, and the *last* argument is used as ZONE.\n\
1512 The intervening arguments are ignored.\n\
1513 This feature lets (apply 'encode-time (decode-time ...)) work.\n\
1515 Out-of-range values for SEC, MINUTE, HOUR, DAY, or MONTH are allowed;\n\
1516 for example, a DAY of 0 means the day preceding the given month.\n\
1517 Year numbers less than 100 are treated just like other year numbers.\n\
1518 If you want them to stand for years in this century, you must do that yourself.")
1519 (nargs, args)
1520 int nargs;
1521 register Lisp_Object *args;
1523 time_t time;
1524 struct tm tm;
1525 Lisp_Object zone = (nargs > 6 ? args[nargs - 1] : Qnil);
1527 CHECK_NUMBER (args[0], 0); /* second */
1528 CHECK_NUMBER (args[1], 1); /* minute */
1529 CHECK_NUMBER (args[2], 2); /* hour */
1530 CHECK_NUMBER (args[3], 3); /* day */
1531 CHECK_NUMBER (args[4], 4); /* month */
1532 CHECK_NUMBER (args[5], 5); /* year */
1534 tm.tm_sec = XINT (args[0]);
1535 tm.tm_min = XINT (args[1]);
1536 tm.tm_hour = XINT (args[2]);
1537 tm.tm_mday = XINT (args[3]);
1538 tm.tm_mon = XINT (args[4]) - 1;
1539 tm.tm_year = XINT (args[5]) - 1900;
1540 tm.tm_isdst = -1;
1542 if (CONSP (zone))
1543 zone = Fcar (zone);
1544 if (NILP (zone))
1545 time = mktime (&tm);
1546 else
1548 char tzbuf[100];
1549 char *tzstring;
1550 char **oldenv = environ, **newenv;
1552 if (EQ (zone, Qt))
1553 tzstring = "UTC0";
1554 else if (STRINGP (zone))
1555 tzstring = (char *) XSTRING (zone)->data;
1556 else if (INTEGERP (zone))
1558 int abszone = abs (XINT (zone));
1559 sprintf (tzbuf, "XXX%s%d:%02d:%02d", "-" + (XINT (zone) < 0),
1560 abszone / (60*60), (abszone/60) % 60, abszone % 60);
1561 tzstring = tzbuf;
1563 else
1564 error ("Invalid time zone specification");
1566 /* Set TZ before calling mktime; merely adjusting mktime's returned
1567 value doesn't suffice, since that would mishandle leap seconds. */
1568 set_time_zone_rule (tzstring);
1570 time = mktime (&tm);
1572 /* Restore TZ to previous value. */
1573 newenv = environ;
1574 environ = oldenv;
1575 xfree (newenv);
1576 #ifdef LOCALTIME_CACHE
1577 tzset ();
1578 #endif
1581 if (time == (time_t) -1)
1582 error ("Specified time is not representable");
1584 return make_time (time);
1587 DEFUN ("current-time-string", Fcurrent_time_string, Scurrent_time_string, 0, 1, 0,
1588 "Return the current time, as a human-readable string.\n\
1589 Programs can use this function to decode a time,\n\
1590 since the number of columns in each field is fixed.\n\
1591 The format is `Sun Sep 16 01:03:52 1973'.\n\
1592 However, see also the functions `decode-time' and `format-time-string'\n\
1593 which provide a much more powerful and general facility.\n\
1595 If an argument is given, it specifies a time to format\n\
1596 instead of the current time. The argument should have the form:\n\
1597 (HIGH . LOW)\n\
1598 or the form:\n\
1599 (HIGH LOW . IGNORED).\n\
1600 Thus, you can use times obtained from `current-time'\n\
1601 and from `file-attributes'.")
1602 (specified_time)
1603 Lisp_Object specified_time;
1605 time_t value;
1606 char buf[30];
1607 register char *tem;
1609 if (! lisp_time_argument (specified_time, &value, NULL))
1610 value = -1;
1611 tem = (char *) ctime (&value);
1613 strncpy (buf, tem, 24);
1614 buf[24] = 0;
1616 return build_string (buf);
1619 #define TM_YEAR_BASE 1900
1621 /* Yield A - B, measured in seconds.
1622 This function is copied from the GNU C Library. */
1623 static int
1624 tm_diff (a, b)
1625 struct tm *a, *b;
1627 /* Compute intervening leap days correctly even if year is negative.
1628 Take care to avoid int overflow in leap day calculations,
1629 but it's OK to assume that A and B are close to each other. */
1630 int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
1631 int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
1632 int a100 = a4 / 25 - (a4 % 25 < 0);
1633 int b100 = b4 / 25 - (b4 % 25 < 0);
1634 int a400 = a100 >> 2;
1635 int b400 = b100 >> 2;
1636 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
1637 int years = a->tm_year - b->tm_year;
1638 int days = (365 * years + intervening_leap_days
1639 + (a->tm_yday - b->tm_yday));
1640 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
1641 + (a->tm_min - b->tm_min))
1642 + (a->tm_sec - b->tm_sec));
1645 DEFUN ("current-time-zone", Fcurrent_time_zone, Scurrent_time_zone, 0, 1, 0,
1646 "Return the offset and name for the local time zone.\n\
1647 This returns a list of the form (OFFSET NAME).\n\
1648 OFFSET is an integer number of seconds ahead of UTC (east of Greenwich).\n\
1649 A negative value means west of Greenwich.\n\
1650 NAME is a string giving the name of the time zone.\n\
1651 If an argument is given, it specifies when the time zone offset is determined\n\
1652 instead of using the current time. The argument should have the form:\n\
1653 (HIGH . LOW)\n\
1654 or the form:\n\
1655 (HIGH LOW . IGNORED).\n\
1656 Thus, you can use times obtained from `current-time'\n\
1657 and from `file-attributes'.\n\
1659 Some operating systems cannot provide all this information to Emacs;\n\
1660 in this case, `current-time-zone' returns a list containing nil for\n\
1661 the data it can't find.")
1662 (specified_time)
1663 Lisp_Object specified_time;
1665 time_t value;
1666 struct tm *t;
1667 struct tm gmt;
1669 if (lisp_time_argument (specified_time, &value, NULL)
1670 && (t = gmtime (&value)) != 0
1671 && (gmt = *t, t = localtime (&value)) != 0)
1673 int offset = tm_diff (t, &gmt);
1674 char *s = 0;
1675 char buf[6];
1676 #ifdef HAVE_TM_ZONE
1677 if (t->tm_zone)
1678 s = (char *)t->tm_zone;
1679 #else /* not HAVE_TM_ZONE */
1680 #ifdef HAVE_TZNAME
1681 if (t->tm_isdst == 0 || t->tm_isdst == 1)
1682 s = tzname[t->tm_isdst];
1683 #endif
1684 #endif /* not HAVE_TM_ZONE */
1685 if (!s)
1687 /* No local time zone name is available; use "+-NNNN" instead. */
1688 int am = (offset < 0 ? -offset : offset) / 60;
1689 sprintf (buf, "%c%02d%02d", (offset < 0 ? '-' : '+'), am/60, am%60);
1690 s = buf;
1692 return Fcons (make_number (offset), Fcons (build_string (s), Qnil));
1694 else
1695 return Fmake_list (make_number (2), Qnil);
1698 /* This holds the value of `environ' produced by the previous
1699 call to Fset_time_zone_rule, or 0 if Fset_time_zone_rule
1700 has never been called. */
1701 static char **environbuf;
1703 DEFUN ("set-time-zone-rule", Fset_time_zone_rule, Sset_time_zone_rule, 1, 1, 0,
1704 "Set the local time zone using TZ, a string specifying a time zone rule.\n\
1705 If TZ is nil, use implementation-defined default time zone information.\n\
1706 If TZ is t, use Universal Time.")
1707 (tz)
1708 Lisp_Object tz;
1710 char *tzstring;
1712 if (NILP (tz))
1713 tzstring = 0;
1714 else if (EQ (tz, Qt))
1715 tzstring = "UTC0";
1716 else
1718 CHECK_STRING (tz, 0);
1719 tzstring = (char *) XSTRING (tz)->data;
1722 set_time_zone_rule (tzstring);
1723 if (environbuf)
1724 free (environbuf);
1725 environbuf = environ;
1727 return Qnil;
1730 #ifdef LOCALTIME_CACHE
1732 /* These two values are known to load tz files in buggy implementations,
1733 i.e. Solaris 1 executables running under either Solaris 1 or Solaris 2.
1734 Their values shouldn't matter in non-buggy implementations.
1735 We don't use string literals for these strings,
1736 since if a string in the environment is in readonly
1737 storage, it runs afoul of bugs in SVR4 and Solaris 2.3.
1738 See Sun bugs 1113095 and 1114114, ``Timezone routines
1739 improperly modify environment''. */
1741 static char set_time_zone_rule_tz1[] = "TZ=GMT+0";
1742 static char set_time_zone_rule_tz2[] = "TZ=GMT+1";
1744 #endif
1746 /* Set the local time zone rule to TZSTRING.
1747 This allocates memory into `environ', which it is the caller's
1748 responsibility to free. */
1750 void
1751 set_time_zone_rule (tzstring)
1752 char *tzstring;
1754 int envptrs;
1755 char **from, **to, **newenv;
1757 /* Make the ENVIRON vector longer with room for TZSTRING. */
1758 for (from = environ; *from; from++)
1759 continue;
1760 envptrs = from - environ + 2;
1761 newenv = to = (char **) xmalloc (envptrs * sizeof (char *)
1762 + (tzstring ? strlen (tzstring) + 4 : 0));
1764 /* Add TZSTRING to the end of environ, as a value for TZ. */
1765 if (tzstring)
1767 char *t = (char *) (to + envptrs);
1768 strcpy (t, "TZ=");
1769 strcat (t, tzstring);
1770 *to++ = t;
1773 /* Copy the old environ vector elements into NEWENV,
1774 but don't copy the TZ variable.
1775 So we have only one definition of TZ, which came from TZSTRING. */
1776 for (from = environ; *from; from++)
1777 if (strncmp (*from, "TZ=", 3) != 0)
1778 *to++ = *from;
1779 *to = 0;
1781 environ = newenv;
1783 /* If we do have a TZSTRING, NEWENV points to the vector slot where
1784 the TZ variable is stored. If we do not have a TZSTRING,
1785 TO points to the vector slot which has the terminating null. */
1787 #ifdef LOCALTIME_CACHE
1789 /* In SunOS 4.1.3_U1 and 4.1.4, if TZ has a value like
1790 "US/Pacific" that loads a tz file, then changes to a value like
1791 "XXX0" that does not load a tz file, and then changes back to
1792 its original value, the last change is (incorrectly) ignored.
1793 Also, if TZ changes twice in succession to values that do
1794 not load a tz file, tzset can dump core (see Sun bug#1225179).
1795 The following code works around these bugs. */
1797 if (tzstring)
1799 /* Temporarily set TZ to a value that loads a tz file
1800 and that differs from tzstring. */
1801 char *tz = *newenv;
1802 *newenv = (strcmp (tzstring, set_time_zone_rule_tz1 + 3) == 0
1803 ? set_time_zone_rule_tz2 : set_time_zone_rule_tz1);
1804 tzset ();
1805 *newenv = tz;
1807 else
1809 /* The implied tzstring is unknown, so temporarily set TZ to
1810 two different values that each load a tz file. */
1811 *to = set_time_zone_rule_tz1;
1812 to[1] = 0;
1813 tzset ();
1814 *to = set_time_zone_rule_tz2;
1815 tzset ();
1816 *to = 0;
1819 /* Now TZ has the desired value, and tzset can be invoked safely. */
1822 tzset ();
1823 #endif
1826 /* Insert NARGS Lisp objects in the array ARGS by calling INSERT_FUNC
1827 (if a type of object is Lisp_Int) or INSERT_FROM_STRING_FUNC (if a
1828 type of object is Lisp_String). INHERIT is passed to
1829 INSERT_FROM_STRING_FUNC as the last argument. */
1831 static void
1832 general_insert_function (insert_func, insert_from_string_func,
1833 inherit, nargs, args)
1834 void (*insert_func) P_ ((unsigned char *, int));
1835 void (*insert_from_string_func) P_ ((Lisp_Object, int, int, int, int, int));
1836 int inherit, nargs;
1837 register Lisp_Object *args;
1839 register int argnum;
1840 register Lisp_Object val;
1842 for (argnum = 0; argnum < nargs; argnum++)
1844 val = args[argnum];
1845 retry:
1846 if (INTEGERP (val))
1848 unsigned char str[MAX_MULTIBYTE_LENGTH];
1849 int len;
1851 if (!NILP (current_buffer->enable_multibyte_characters))
1852 len = CHAR_STRING (XFASTINT (val), str);
1853 else
1855 str[0] = (SINGLE_BYTE_CHAR_P (XINT (val))
1856 ? XINT (val)
1857 : multibyte_char_to_unibyte (XINT (val), Qnil));
1858 len = 1;
1860 (*insert_func) (str, len);
1862 else if (STRINGP (val))
1864 (*insert_from_string_func) (val, 0, 0,
1865 XSTRING (val)->size,
1866 STRING_BYTES (XSTRING (val)),
1867 inherit);
1869 else
1871 val = wrong_type_argument (Qchar_or_string_p, val);
1872 goto retry;
1877 void
1878 insert1 (arg)
1879 Lisp_Object arg;
1881 Finsert (1, &arg);
1885 /* Callers passing one argument to Finsert need not gcpro the
1886 argument "array", since the only element of the array will
1887 not be used after calling insert or insert_from_string, so
1888 we don't care if it gets trashed. */
1890 DEFUN ("insert", Finsert, Sinsert, 0, MANY, 0,
1891 "Insert the arguments, either strings or characters, at point.\n\
1892 Point and before-insertion markers move forward to end up\n\
1893 after the inserted text.\n\
1894 Any other markers at the point of insertion remain before the text.\n\
1896 If the current buffer is multibyte, unibyte strings are converted\n\
1897 to multibyte for insertion (see `unibyte-char-to-multibyte').\n\
1898 If the current buffer is unibyte, multibyte strings are converted\n\
1899 to unibyte for insertion.")
1900 (nargs, args)
1901 int nargs;
1902 register Lisp_Object *args;
1904 general_insert_function (insert, insert_from_string, 0, nargs, args);
1905 return Qnil;
1908 DEFUN ("insert-and-inherit", Finsert_and_inherit, Sinsert_and_inherit,
1909 0, MANY, 0,
1910 "Insert the arguments at point, inheriting properties from adjoining text.\n\
1911 Point and before-insertion markers move forward to end up\n\
1912 after the inserted text.\n\
1913 Any other markers at the point of insertion remain before the text.\n\
1915 If the current buffer is multibyte, unibyte strings are converted\n\
1916 to multibyte for insertion (see `unibyte-char-to-multibyte').\n\
1917 If the current buffer is unibyte, multibyte strings are converted\n\
1918 to unibyte for insertion.")
1919 (nargs, args)
1920 int nargs;
1921 register Lisp_Object *args;
1923 general_insert_function (insert_and_inherit, insert_from_string, 1,
1924 nargs, args);
1925 return Qnil;
1928 DEFUN ("insert-before-markers", Finsert_before_markers, Sinsert_before_markers, 0, MANY, 0,
1929 "Insert strings or characters at point, relocating markers after the text.\n\
1930 Point and markers move forward to end up after the inserted text.\n\
1932 If the current buffer is multibyte, unibyte strings are converted\n\
1933 to multibyte for insertion (see `unibyte-char-to-multibyte').\n\
1934 If the current buffer is unibyte, multibyte strings are converted\n\
1935 to unibyte for insertion.")
1936 (nargs, args)
1937 int nargs;
1938 register Lisp_Object *args;
1940 general_insert_function (insert_before_markers,
1941 insert_from_string_before_markers, 0,
1942 nargs, args);
1943 return Qnil;
1946 DEFUN ("insert-before-markers-and-inherit", Finsert_and_inherit_before_markers,
1947 Sinsert_and_inherit_before_markers, 0, MANY, 0,
1948 "Insert text at point, relocating markers and inheriting properties.\n\
1949 Point and markers move forward to end up after the inserted text.\n\
1951 If the current buffer is multibyte, unibyte strings are converted\n\
1952 to multibyte for insertion (see `unibyte-char-to-multibyte').\n\
1953 If the current buffer is unibyte, multibyte strings are converted\n\
1954 to unibyte for insertion.")
1955 (nargs, args)
1956 int nargs;
1957 register Lisp_Object *args;
1959 general_insert_function (insert_before_markers_and_inherit,
1960 insert_from_string_before_markers, 1,
1961 nargs, args);
1962 return Qnil;
1965 DEFUN ("insert-char", Finsert_char, Sinsert_char, 2, 3, 0,
1966 "Insert COUNT (second arg) copies of CHARACTER (first arg).\n\
1967 Both arguments are required.\n\
1968 Point, and before-insertion markers, are relocated as in the function `insert'.\n\
1969 The optional third arg INHERIT, if non-nil, says to inherit text properties\n\
1970 from adjoining text, if those properties are sticky.")
1971 (character, count, inherit)
1972 Lisp_Object character, count, inherit;
1974 register unsigned char *string;
1975 register int strlen;
1976 register int i, n;
1977 int len;
1978 unsigned char str[MAX_MULTIBYTE_LENGTH];
1980 CHECK_NUMBER (character, 0);
1981 CHECK_NUMBER (count, 1);
1983 if (!NILP (current_buffer->enable_multibyte_characters))
1984 len = CHAR_STRING (XFASTINT (character), str);
1985 else
1986 str[0] = XFASTINT (character), len = 1;
1987 n = XINT (count) * len;
1988 if (n <= 0)
1989 return Qnil;
1990 strlen = min (n, 256 * len);
1991 string = (unsigned char *) alloca (strlen);
1992 for (i = 0; i < strlen; i++)
1993 string[i] = str[i % len];
1994 while (n >= strlen)
1996 QUIT;
1997 if (!NILP (inherit))
1998 insert_and_inherit (string, strlen);
1999 else
2000 insert (string, strlen);
2001 n -= strlen;
2003 if (n > 0)
2005 if (!NILP (inherit))
2006 insert_and_inherit (string, n);
2007 else
2008 insert (string, n);
2010 return Qnil;
2014 /* Making strings from buffer contents. */
2016 /* Return a Lisp_String containing the text of the current buffer from
2017 START to END. If text properties are in use and the current buffer
2018 has properties in the range specified, the resulting string will also
2019 have them, if PROPS is nonzero.
2021 We don't want to use plain old make_string here, because it calls
2022 make_uninit_string, which can cause the buffer arena to be
2023 compacted. make_string has no way of knowing that the data has
2024 been moved, and thus copies the wrong data into the string. This
2025 doesn't effect most of the other users of make_string, so it should
2026 be left as is. But we should use this function when conjuring
2027 buffer substrings. */
2029 Lisp_Object
2030 make_buffer_string (start, end, props)
2031 int start, end;
2032 int props;
2034 int start_byte = CHAR_TO_BYTE (start);
2035 int end_byte = CHAR_TO_BYTE (end);
2037 return make_buffer_string_both (start, start_byte, end, end_byte, props);
2040 /* Return a Lisp_String containing the text of the current buffer from
2041 START / START_BYTE to END / END_BYTE.
2043 If text properties are in use and the current buffer
2044 has properties in the range specified, the resulting string will also
2045 have them, if PROPS is nonzero.
2047 We don't want to use plain old make_string here, because it calls
2048 make_uninit_string, which can cause the buffer arena to be
2049 compacted. make_string has no way of knowing that the data has
2050 been moved, and thus copies the wrong data into the string. This
2051 doesn't effect most of the other users of make_string, so it should
2052 be left as is. But we should use this function when conjuring
2053 buffer substrings. */
2055 Lisp_Object
2056 make_buffer_string_both (start, start_byte, end, end_byte, props)
2057 int start, start_byte, end, end_byte;
2058 int props;
2060 Lisp_Object result, tem, tem1;
2062 if (start < GPT && GPT < end)
2063 move_gap (start);
2065 if (! NILP (current_buffer->enable_multibyte_characters))
2066 result = make_uninit_multibyte_string (end - start, end_byte - start_byte);
2067 else
2068 result = make_uninit_string (end - start);
2069 bcopy (BYTE_POS_ADDR (start_byte), XSTRING (result)->data,
2070 end_byte - start_byte);
2072 /* If desired, update and copy the text properties. */
2073 if (props)
2075 update_buffer_properties (start, end);
2077 tem = Fnext_property_change (make_number (start), Qnil, make_number (end));
2078 tem1 = Ftext_properties_at (make_number (start), Qnil);
2080 if (XINT (tem) != end || !NILP (tem1))
2081 copy_intervals_to_string (result, current_buffer, start,
2082 end - start);
2085 return result;
2088 /* Call Vbuffer_access_fontify_functions for the range START ... END
2089 in the current buffer, if necessary. */
2091 static void
2092 update_buffer_properties (start, end)
2093 int start, end;
2095 /* If this buffer has some access functions,
2096 call them, specifying the range of the buffer being accessed. */
2097 if (!NILP (Vbuffer_access_fontify_functions))
2099 Lisp_Object args[3];
2100 Lisp_Object tem;
2102 args[0] = Qbuffer_access_fontify_functions;
2103 XSETINT (args[1], start);
2104 XSETINT (args[2], end);
2106 /* But don't call them if we can tell that the work
2107 has already been done. */
2108 if (!NILP (Vbuffer_access_fontified_property))
2110 tem = Ftext_property_any (args[1], args[2],
2111 Vbuffer_access_fontified_property,
2112 Qnil, Qnil);
2113 if (! NILP (tem))
2114 Frun_hook_with_args (3, args);
2116 else
2117 Frun_hook_with_args (3, args);
2121 DEFUN ("buffer-substring", Fbuffer_substring, Sbuffer_substring, 2, 2, 0,
2122 "Return the contents of part of the current buffer as a string.\n\
2123 The two arguments START and END are character positions;\n\
2124 they can be in either order.\n\
2125 The string returned is multibyte if the buffer is multibyte.")
2126 (start, end)
2127 Lisp_Object start, end;
2129 register int b, e;
2131 validate_region (&start, &end);
2132 b = XINT (start);
2133 e = XINT (end);
2135 return make_buffer_string (b, e, 1);
2138 DEFUN ("buffer-substring-no-properties", Fbuffer_substring_no_properties,
2139 Sbuffer_substring_no_properties, 2, 2, 0,
2140 "Return the characters of part of the buffer, without the text properties.\n\
2141 The two arguments START and END are character positions;\n\
2142 they can be in either order.")
2143 (start, end)
2144 Lisp_Object start, end;
2146 register int b, e;
2148 validate_region (&start, &end);
2149 b = XINT (start);
2150 e = XINT (end);
2152 return make_buffer_string (b, e, 0);
2155 DEFUN ("buffer-string", Fbuffer_string, Sbuffer_string, 0, 0, 0,
2156 "Return the contents of the current buffer as a string.\n\
2157 If narrowing is in effect, this function returns only the visible part\n\
2158 of the buffer. If in a mini-buffer, don't include the prompt in the\n\
2159 string returned.")
2162 return make_buffer_string (BEGV, ZV, 1);
2165 DEFUN ("insert-buffer-substring", Finsert_buffer_substring, Sinsert_buffer_substring,
2166 1, 3, 0,
2167 "Insert before point a substring of the contents of buffer BUFFER.\n\
2168 BUFFER may be a buffer or a buffer name.\n\
2169 Arguments START and END are character numbers specifying the substring.\n\
2170 They default to the beginning and the end of BUFFER.")
2171 (buf, start, end)
2172 Lisp_Object buf, start, end;
2174 register int b, e, temp;
2175 register struct buffer *bp, *obuf;
2176 Lisp_Object buffer;
2178 buffer = Fget_buffer (buf);
2179 if (NILP (buffer))
2180 nsberror (buf);
2181 bp = XBUFFER (buffer);
2182 if (NILP (bp->name))
2183 error ("Selecting deleted buffer");
2185 if (NILP (start))
2186 b = BUF_BEGV (bp);
2187 else
2189 CHECK_NUMBER_COERCE_MARKER (start, 0);
2190 b = XINT (start);
2192 if (NILP (end))
2193 e = BUF_ZV (bp);
2194 else
2196 CHECK_NUMBER_COERCE_MARKER (end, 1);
2197 e = XINT (end);
2200 if (b > e)
2201 temp = b, b = e, e = temp;
2203 if (!(BUF_BEGV (bp) <= b && e <= BUF_ZV (bp)))
2204 args_out_of_range (start, end);
2206 obuf = current_buffer;
2207 set_buffer_internal_1 (bp);
2208 update_buffer_properties (b, e);
2209 set_buffer_internal_1 (obuf);
2211 insert_from_buffer (bp, b, e - b, 0);
2212 return Qnil;
2215 DEFUN ("compare-buffer-substrings", Fcompare_buffer_substrings, Scompare_buffer_substrings,
2216 6, 6, 0,
2217 "Compare two substrings of two buffers; return result as number.\n\
2218 the value is -N if first string is less after N-1 chars,\n\
2219 +N if first string is greater after N-1 chars, or 0 if strings match.\n\
2220 Each substring is represented as three arguments: BUFFER, START and END.\n\
2221 That makes six args in all, three for each substring.\n\n\
2222 The value of `case-fold-search' in the current buffer\n\
2223 determines whether case is significant or ignored.")
2224 (buffer1, start1, end1, buffer2, start2, end2)
2225 Lisp_Object buffer1, start1, end1, buffer2, start2, end2;
2227 register int begp1, endp1, begp2, endp2, temp;
2228 register struct buffer *bp1, *bp2;
2229 register Lisp_Object *trt
2230 = (!NILP (current_buffer->case_fold_search)
2231 ? XCHAR_TABLE (current_buffer->case_canon_table)->contents : 0);
2232 int chars = 0;
2233 int i1, i2, i1_byte, i2_byte;
2235 /* Find the first buffer and its substring. */
2237 if (NILP (buffer1))
2238 bp1 = current_buffer;
2239 else
2241 Lisp_Object buf1;
2242 buf1 = Fget_buffer (buffer1);
2243 if (NILP (buf1))
2244 nsberror (buffer1);
2245 bp1 = XBUFFER (buf1);
2246 if (NILP (bp1->name))
2247 error ("Selecting deleted buffer");
2250 if (NILP (start1))
2251 begp1 = BUF_BEGV (bp1);
2252 else
2254 CHECK_NUMBER_COERCE_MARKER (start1, 1);
2255 begp1 = XINT (start1);
2257 if (NILP (end1))
2258 endp1 = BUF_ZV (bp1);
2259 else
2261 CHECK_NUMBER_COERCE_MARKER (end1, 2);
2262 endp1 = XINT (end1);
2265 if (begp1 > endp1)
2266 temp = begp1, begp1 = endp1, endp1 = temp;
2268 if (!(BUF_BEGV (bp1) <= begp1
2269 && begp1 <= endp1
2270 && endp1 <= BUF_ZV (bp1)))
2271 args_out_of_range (start1, end1);
2273 /* Likewise for second substring. */
2275 if (NILP (buffer2))
2276 bp2 = current_buffer;
2277 else
2279 Lisp_Object buf2;
2280 buf2 = Fget_buffer (buffer2);
2281 if (NILP (buf2))
2282 nsberror (buffer2);
2283 bp2 = XBUFFER (buf2);
2284 if (NILP (bp2->name))
2285 error ("Selecting deleted buffer");
2288 if (NILP (start2))
2289 begp2 = BUF_BEGV (bp2);
2290 else
2292 CHECK_NUMBER_COERCE_MARKER (start2, 4);
2293 begp2 = XINT (start2);
2295 if (NILP (end2))
2296 endp2 = BUF_ZV (bp2);
2297 else
2299 CHECK_NUMBER_COERCE_MARKER (end2, 5);
2300 endp2 = XINT (end2);
2303 if (begp2 > endp2)
2304 temp = begp2, begp2 = endp2, endp2 = temp;
2306 if (!(BUF_BEGV (bp2) <= begp2
2307 && begp2 <= endp2
2308 && endp2 <= BUF_ZV (bp2)))
2309 args_out_of_range (start2, end2);
2311 i1 = begp1;
2312 i2 = begp2;
2313 i1_byte = buf_charpos_to_bytepos (bp1, i1);
2314 i2_byte = buf_charpos_to_bytepos (bp2, i2);
2316 while (i1 < endp1 && i2 < endp2)
2318 /* When we find a mismatch, we must compare the
2319 characters, not just the bytes. */
2320 int c1, c2;
2322 if (! NILP (bp1->enable_multibyte_characters))
2324 c1 = BUF_FETCH_MULTIBYTE_CHAR (bp1, i1_byte);
2325 BUF_INC_POS (bp1, i1_byte);
2326 i1++;
2328 else
2330 c1 = BUF_FETCH_BYTE (bp1, i1);
2331 c1 = unibyte_char_to_multibyte (c1);
2332 i1++;
2335 if (! NILP (bp2->enable_multibyte_characters))
2337 c2 = BUF_FETCH_MULTIBYTE_CHAR (bp2, i2_byte);
2338 BUF_INC_POS (bp2, i2_byte);
2339 i2++;
2341 else
2343 c2 = BUF_FETCH_BYTE (bp2, i2);
2344 c2 = unibyte_char_to_multibyte (c2);
2345 i2++;
2348 if (trt)
2350 c1 = XINT (trt[c1]);
2351 c2 = XINT (trt[c2]);
2353 if (c1 < c2)
2354 return make_number (- 1 - chars);
2355 if (c1 > c2)
2356 return make_number (chars + 1);
2358 chars++;
2361 /* The strings match as far as they go.
2362 If one is shorter, that one is less. */
2363 if (chars < endp1 - begp1)
2364 return make_number (chars + 1);
2365 else if (chars < endp2 - begp2)
2366 return make_number (- chars - 1);
2368 /* Same length too => they are equal. */
2369 return make_number (0);
2372 static Lisp_Object
2373 subst_char_in_region_unwind (arg)
2374 Lisp_Object arg;
2376 return current_buffer->undo_list = arg;
2379 static Lisp_Object
2380 subst_char_in_region_unwind_1 (arg)
2381 Lisp_Object arg;
2383 return current_buffer->filename = arg;
2386 DEFUN ("subst-char-in-region", Fsubst_char_in_region,
2387 Ssubst_char_in_region, 4, 5, 0,
2388 "From START to END, replace FROMCHAR with TOCHAR each time it occurs.\n\
2389 If optional arg NOUNDO is non-nil, don't record this change for undo\n\
2390 and don't mark the buffer as really changed.\n\
2391 Both characters must have the same length of multi-byte form.")
2392 (start, end, fromchar, tochar, noundo)
2393 Lisp_Object start, end, fromchar, tochar, noundo;
2395 register int pos, pos_byte, stop, i, len, end_byte;
2396 int changed = 0;
2397 unsigned char fromstr[MAX_MULTIBYTE_LENGTH], tostr[MAX_MULTIBYTE_LENGTH];
2398 unsigned char *p;
2399 int count = specpdl_ptr - specpdl;
2400 #define COMBINING_NO 0
2401 #define COMBINING_BEFORE 1
2402 #define COMBINING_AFTER 2
2403 #define COMBINING_BOTH (COMBINING_BEFORE | COMBINING_AFTER)
2404 int maybe_byte_combining = COMBINING_NO;
2405 int last_changed;
2406 int multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2408 validate_region (&start, &end);
2409 CHECK_NUMBER (fromchar, 2);
2410 CHECK_NUMBER (tochar, 3);
2412 if (multibyte_p)
2414 len = CHAR_STRING (XFASTINT (fromchar), fromstr);
2415 if (CHAR_STRING (XFASTINT (tochar), tostr) != len)
2416 error ("Characters in subst-char-in-region have different byte-lengths");
2417 if (!ASCII_BYTE_P (*tostr))
2419 /* If *TOSTR is in the range 0x80..0x9F and TOCHAR is not a
2420 complete multibyte character, it may be combined with the
2421 after bytes. If it is in the range 0xA0..0xFF, it may be
2422 combined with the before and after bytes. */
2423 if (!CHAR_HEAD_P (*tostr))
2424 maybe_byte_combining = COMBINING_BOTH;
2425 else if (BYTES_BY_CHAR_HEAD (*tostr) > len)
2426 maybe_byte_combining = COMBINING_AFTER;
2429 else
2431 len = 1;
2432 fromstr[0] = XFASTINT (fromchar);
2433 tostr[0] = XFASTINT (tochar);
2436 pos = XINT (start);
2437 pos_byte = CHAR_TO_BYTE (pos);
2438 stop = CHAR_TO_BYTE (XINT (end));
2439 end_byte = stop;
2441 /* If we don't want undo, turn off putting stuff on the list.
2442 That's faster than getting rid of things,
2443 and it prevents even the entry for a first change.
2444 Also inhibit locking the file. */
2445 if (!NILP (noundo))
2447 record_unwind_protect (subst_char_in_region_unwind,
2448 current_buffer->undo_list);
2449 current_buffer->undo_list = Qt;
2450 /* Don't do file-locking. */
2451 record_unwind_protect (subst_char_in_region_unwind_1,
2452 current_buffer->filename);
2453 current_buffer->filename = Qnil;
2456 if (pos_byte < GPT_BYTE)
2457 stop = min (stop, GPT_BYTE);
2458 while (1)
2460 int pos_byte_next = pos_byte;
2462 if (pos_byte >= stop)
2464 if (pos_byte >= end_byte) break;
2465 stop = end_byte;
2467 p = BYTE_POS_ADDR (pos_byte);
2468 if (multibyte_p)
2469 INC_POS (pos_byte_next);
2470 else
2471 ++pos_byte_next;
2472 if (pos_byte_next - pos_byte == len
2473 && p[0] == fromstr[0]
2474 && (len == 1
2475 || (p[1] == fromstr[1]
2476 && (len == 2 || (p[2] == fromstr[2]
2477 && (len == 3 || p[3] == fromstr[3]))))))
2479 if (! changed)
2481 changed = pos;
2482 modify_region (current_buffer, changed, XINT (end));
2484 if (! NILP (noundo))
2486 if (MODIFF - 1 == SAVE_MODIFF)
2487 SAVE_MODIFF++;
2488 if (MODIFF - 1 == current_buffer->auto_save_modified)
2489 current_buffer->auto_save_modified++;
2493 /* Take care of the case where the new character
2494 combines with neighboring bytes. */
2495 if (maybe_byte_combining
2496 && (maybe_byte_combining == COMBINING_AFTER
2497 ? (pos_byte_next < Z_BYTE
2498 && ! CHAR_HEAD_P (FETCH_BYTE (pos_byte_next)))
2499 : ((pos_byte_next < Z_BYTE
2500 && ! CHAR_HEAD_P (FETCH_BYTE (pos_byte_next)))
2501 || (pos_byte > BEG_BYTE
2502 && ! ASCII_BYTE_P (FETCH_BYTE (pos_byte - 1))))))
2504 Lisp_Object tem, string;
2506 struct gcpro gcpro1;
2508 tem = current_buffer->undo_list;
2509 GCPRO1 (tem);
2511 /* Make a multibyte string containing this single character. */
2512 string = make_multibyte_string (tostr, 1, len);
2513 /* replace_range is less efficient, because it moves the gap,
2514 but it handles combining correctly. */
2515 replace_range (pos, pos + 1, string,
2516 0, 0, 1);
2517 pos_byte_next = CHAR_TO_BYTE (pos);
2518 if (pos_byte_next > pos_byte)
2519 /* Before combining happened. We should not increment
2520 POS. So, to cancel the later increment of POS,
2521 decrease it now. */
2522 pos--;
2523 else
2524 INC_POS (pos_byte_next);
2526 if (! NILP (noundo))
2527 current_buffer->undo_list = tem;
2529 UNGCPRO;
2531 else
2533 if (NILP (noundo))
2534 record_change (pos, 1);
2535 for (i = 0; i < len; i++) *p++ = tostr[i];
2537 last_changed = pos + 1;
2539 pos_byte = pos_byte_next;
2540 pos++;
2543 if (changed)
2545 signal_after_change (changed,
2546 last_changed - changed, last_changed - changed);
2547 update_compositions (changed, last_changed, CHECK_ALL);
2550 unbind_to (count, Qnil);
2551 return Qnil;
2554 DEFUN ("translate-region", Ftranslate_region, Stranslate_region, 3, 3, 0,
2555 "From START to END, translate characters according to TABLE.\n\
2556 TABLE is a string; the Nth character in it is the mapping\n\
2557 for the character with code N.\n\
2558 This function does not alter multibyte characters.\n\
2559 It returns the number of characters changed.")
2560 (start, end, table)
2561 Lisp_Object start;
2562 Lisp_Object end;
2563 register Lisp_Object table;
2565 register int pos_byte, stop; /* Limits of the region. */
2566 register unsigned char *tt; /* Trans table. */
2567 register int nc; /* New character. */
2568 int cnt; /* Number of changes made. */
2569 int size; /* Size of translate table. */
2570 int pos;
2571 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
2573 validate_region (&start, &end);
2574 CHECK_STRING (table, 2);
2576 size = STRING_BYTES (XSTRING (table));
2577 tt = XSTRING (table)->data;
2579 pos_byte = CHAR_TO_BYTE (XINT (start));
2580 stop = CHAR_TO_BYTE (XINT (end));
2581 modify_region (current_buffer, XINT (start), XINT (end));
2582 pos = XINT (start);
2584 cnt = 0;
2585 for (; pos_byte < stop; )
2587 register unsigned char *p = BYTE_POS_ADDR (pos_byte);
2588 int len;
2589 int oc;
2590 int pos_byte_next;
2592 if (multibyte)
2593 oc = STRING_CHAR_AND_LENGTH (p, stop - pos_byte, len);
2594 else
2595 oc = *p, len = 1;
2596 pos_byte_next = pos_byte + len;
2597 if (oc < size && len == 1)
2599 nc = tt[oc];
2600 if (nc != oc)
2602 /* Take care of the case where the new character
2603 combines with neighboring bytes. */
2604 if (!ASCII_BYTE_P (nc)
2605 && (CHAR_HEAD_P (nc)
2606 ? ! CHAR_HEAD_P (FETCH_BYTE (pos_byte + 1))
2607 : (pos_byte > BEG_BYTE
2608 && ! ASCII_BYTE_P (FETCH_BYTE (pos_byte - 1)))))
2610 Lisp_Object string;
2612 string = make_multibyte_string (tt + oc, 1, 1);
2613 /* This is less efficient, because it moves the gap,
2614 but it handles combining correctly. */
2615 replace_range (pos, pos + 1, string,
2616 1, 0, 1);
2617 pos_byte_next = CHAR_TO_BYTE (pos);
2618 if (pos_byte_next > pos_byte)
2619 /* Before combining happened. We should not
2620 increment POS. So, to cancel the later
2621 increment of POS, we decrease it now. */
2622 pos--;
2623 else
2624 INC_POS (pos_byte_next);
2626 else
2628 record_change (pos, 1);
2629 *p = nc;
2630 signal_after_change (pos, 1, 1);
2631 update_compositions (pos, pos + 1, CHECK_BORDER);
2633 ++cnt;
2636 pos_byte = pos_byte_next;
2637 pos++;
2640 return make_number (cnt);
2643 DEFUN ("delete-region", Fdelete_region, Sdelete_region, 2, 2, "r",
2644 "Delete the text between point and mark.\n\
2645 When called from a program, expects two arguments,\n\
2646 positions (integers or markers) specifying the stretch to be deleted.")
2647 (start, end)
2648 Lisp_Object start, end;
2650 validate_region (&start, &end);
2651 del_range (XINT (start), XINT (end));
2652 return Qnil;
2655 DEFUN ("delete-and-extract-region", Fdelete_and_extract_region,
2656 Sdelete_and_extract_region, 2, 2, 0,
2657 "Delete the text between START and END and return it.")
2658 (start, end)
2659 Lisp_Object start, end;
2661 validate_region (&start, &end);
2662 return del_range_1 (XINT (start), XINT (end), 1, 1);
2665 DEFUN ("widen", Fwiden, Swiden, 0, 0, "",
2666 "Remove restrictions (narrowing) from current buffer.\n\
2667 This allows the buffer's full text to be seen and edited.")
2670 if (BEG != BEGV || Z != ZV)
2671 current_buffer->clip_changed = 1;
2672 BEGV = BEG;
2673 BEGV_BYTE = BEG_BYTE;
2674 SET_BUF_ZV_BOTH (current_buffer, Z, Z_BYTE);
2675 /* Changing the buffer bounds invalidates any recorded current column. */
2676 invalidate_current_column ();
2677 return Qnil;
2680 DEFUN ("narrow-to-region", Fnarrow_to_region, Snarrow_to_region, 2, 2, "r",
2681 "Restrict editing in this buffer to the current region.\n\
2682 The rest of the text becomes temporarily invisible and untouchable\n\
2683 but is not deleted; if you save the buffer in a file, the invisible\n\
2684 text is included in the file. \\[widen] makes all visible again.\n\
2685 See also `save-restriction'.\n\
2687 When calling from a program, pass two arguments; positions (integers\n\
2688 or markers) bounding the text that should remain visible.")
2689 (start, end)
2690 register Lisp_Object start, end;
2692 CHECK_NUMBER_COERCE_MARKER (start, 0);
2693 CHECK_NUMBER_COERCE_MARKER (end, 1);
2695 if (XINT (start) > XINT (end))
2697 Lisp_Object tem;
2698 tem = start; start = end; end = tem;
2701 if (!(BEG <= XINT (start) && XINT (start) <= XINT (end) && XINT (end) <= Z))
2702 args_out_of_range (start, end);
2704 if (BEGV != XFASTINT (start) || ZV != XFASTINT (end))
2705 current_buffer->clip_changed = 1;
2707 SET_BUF_BEGV (current_buffer, XFASTINT (start));
2708 SET_BUF_ZV (current_buffer, XFASTINT (end));
2709 if (PT < XFASTINT (start))
2710 SET_PT (XFASTINT (start));
2711 if (PT > XFASTINT (end))
2712 SET_PT (XFASTINT (end));
2713 /* Changing the buffer bounds invalidates any recorded current column. */
2714 invalidate_current_column ();
2715 return Qnil;
2718 Lisp_Object
2719 save_restriction_save ()
2721 if (BEGV == BEG && ZV == Z)
2722 /* The common case that the buffer isn't narrowed.
2723 We return just the buffer object, which save_restriction_restore
2724 recognizes as meaning `no restriction'. */
2725 return Fcurrent_buffer ();
2726 else
2727 /* We have to save a restriction, so return a pair of markers, one
2728 for the beginning and one for the end. */
2730 Lisp_Object beg, end;
2732 beg = buildmark (BEGV, BEGV_BYTE);
2733 end = buildmark (ZV, ZV_BYTE);
2735 /* END must move forward if text is inserted at its exact location. */
2736 XMARKER(end)->insertion_type = 1;
2738 return Fcons (beg, end);
2742 Lisp_Object
2743 save_restriction_restore (data)
2744 Lisp_Object data;
2746 if (CONSP (data))
2747 /* A pair of marks bounding a saved restriction. */
2749 struct Lisp_Marker *beg = XMARKER (XCAR (data));
2750 struct Lisp_Marker *end = XMARKER (XCDR (data));
2751 struct buffer *buf = beg->buffer; /* END should have the same buffer. */
2753 if (beg->charpos != BUF_BEGV(buf) || end->charpos != BUF_ZV(buf))
2754 /* The restriction has changed from the saved one, so restore
2755 the saved restriction. */
2757 int pt = BUF_PT (buf);
2759 SET_BUF_BEGV_BOTH (buf, beg->charpos, beg->bytepos);
2760 SET_BUF_ZV_BOTH (buf, end->charpos, end->bytepos);
2762 if (pt < beg->charpos || pt > end->charpos)
2763 /* The point is outside the new visible range, move it inside. */
2764 SET_BUF_PT_BOTH (buf,
2765 clip_to_bounds (beg->charpos, pt, end->charpos),
2766 clip_to_bounds (beg->bytepos, BUF_PT_BYTE(buf),
2767 end->bytepos));
2769 buf->clip_changed = 1; /* Remember that the narrowing changed. */
2772 else
2773 /* A buffer, which means that there was no old restriction. */
2775 struct buffer *buf = XBUFFER (data);
2777 if (BUF_BEGV(buf) != BUF_BEG(buf) || BUF_ZV(buf) != BUF_Z(buf))
2778 /* The buffer has been narrowed, get rid of the narrowing. */
2780 SET_BUF_BEGV_BOTH (buf, BUF_BEG(buf), BUF_BEG_BYTE(buf));
2781 SET_BUF_ZV_BOTH (buf, BUF_Z(buf), BUF_Z_BYTE(buf));
2783 buf->clip_changed = 1; /* Remember that the narrowing changed. */
2787 return Qnil;
2790 DEFUN ("save-restriction", Fsave_restriction, Ssave_restriction, 0, UNEVALLED, 0,
2791 "Execute BODY, saving and restoring current buffer's restrictions.\n\
2792 The buffer's restrictions make parts of the beginning and end invisible.\n\
2793 \(They are set up with `narrow-to-region' and eliminated with `widen'.)\n\
2794 This special form, `save-restriction', saves the current buffer's restrictions\n\
2795 when it is entered, and restores them when it is exited.\n\
2796 So any `narrow-to-region' within BODY lasts only until the end of the form.\n\
2797 The old restrictions settings are restored\n\
2798 even in case of abnormal exit (throw or error).\n\
2800 The value returned is the value of the last form in BODY.\n\
2802 Note: if you are using both `save-excursion' and `save-restriction',\n\
2803 use `save-excursion' outermost:\n\
2804 (save-excursion (save-restriction ...))")
2805 (body)
2806 Lisp_Object body;
2808 register Lisp_Object val;
2809 int count = specpdl_ptr - specpdl;
2811 record_unwind_protect (save_restriction_restore, save_restriction_save ());
2812 val = Fprogn (body);
2813 return unbind_to (count, val);
2816 #ifndef HAVE_MENUS
2818 /* Buffer for the most recent text displayed by Fmessage. */
2819 static char *message_text;
2821 /* Allocated length of that buffer. */
2822 static int message_length;
2824 #endif /* not HAVE_MENUS */
2826 DEFUN ("message", Fmessage, Smessage, 1, MANY, 0,
2827 "Print a one-line message at the bottom of the screen.\n\
2828 The first argument is a format control string, and the rest are data\n\
2829 to be formatted under control of the string. See `format' for details.\n\
2831 If the first argument is nil, clear any existing message; let the\n\
2832 minibuffer contents show.")
2833 (nargs, args)
2834 int nargs;
2835 Lisp_Object *args;
2837 if (NILP (args[0]))
2839 message (0);
2840 return Qnil;
2842 else
2844 register Lisp_Object val;
2845 val = Fformat (nargs, args);
2846 message3 (val, STRING_BYTES (XSTRING (val)), STRING_MULTIBYTE (val));
2847 return val;
2851 DEFUN ("message-box", Fmessage_box, Smessage_box, 1, MANY, 0,
2852 "Display a message, in a dialog box if possible.\n\
2853 If a dialog box is not available, use the echo area.\n\
2854 The first argument is a format control string, and the rest are data\n\
2855 to be formatted under control of the string. See `format' for details.\n\
2857 If the first argument is nil, clear any existing message; let the\n\
2858 minibuffer contents show.")
2859 (nargs, args)
2860 int nargs;
2861 Lisp_Object *args;
2863 if (NILP (args[0]))
2865 message (0);
2866 return Qnil;
2868 else
2870 register Lisp_Object val;
2871 val = Fformat (nargs, args);
2872 #ifdef HAVE_MENUS
2874 Lisp_Object pane, menu, obj;
2875 struct gcpro gcpro1;
2876 pane = Fcons (Fcons (build_string ("OK"), Qt), Qnil);
2877 GCPRO1 (pane);
2878 menu = Fcons (val, pane);
2879 obj = Fx_popup_dialog (Qt, menu);
2880 UNGCPRO;
2881 return val;
2883 #else /* not HAVE_MENUS */
2884 /* Copy the data so that it won't move when we GC. */
2885 if (! message_text)
2887 message_text = (char *)xmalloc (80);
2888 message_length = 80;
2890 if (STRING_BYTES (XSTRING (val)) > message_length)
2892 message_length = STRING_BYTES (XSTRING (val));
2893 message_text = (char *)xrealloc (message_text, message_length);
2895 bcopy (XSTRING (val)->data, message_text, STRING_BYTES (XSTRING (val)));
2896 message2 (message_text, STRING_BYTES (XSTRING (val)),
2897 STRING_MULTIBYTE (val));
2898 return val;
2899 #endif /* not HAVE_MENUS */
2902 #ifdef HAVE_MENUS
2903 extern Lisp_Object last_nonmenu_event;
2904 #endif
2906 DEFUN ("message-or-box", Fmessage_or_box, Smessage_or_box, 1, MANY, 0,
2907 "Display a message in a dialog box or in the echo area.\n\
2908 If this command was invoked with the mouse, use a dialog box.\n\
2909 Otherwise, use the echo area.\n\
2910 The first argument is a format control string, and the rest are data\n\
2911 to be formatted under control of the string. See `format' for details.\n\
2913 If the first argument is nil, clear any existing message; let the\n\
2914 minibuffer contents show.")
2915 (nargs, args)
2916 int nargs;
2917 Lisp_Object *args;
2919 #ifdef HAVE_MENUS
2920 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
2921 && use_dialog_box)
2922 return Fmessage_box (nargs, args);
2923 #endif
2924 return Fmessage (nargs, args);
2927 DEFUN ("current-message", Fcurrent_message, Scurrent_message, 0, 0, 0,
2928 "Return the string currently displayed in the echo area, or nil if none.")
2931 return current_message ();
2935 DEFUN ("propertize", Fpropertize, Spropertize, 3, MANY, 0,
2936 "Return a copy of STRING with text properties added.\n\
2937 First argument is the string to copy.\n\
2938 Remaining arguments form a sequence of PROPERTY VALUE pairs for text\n\
2939 properties to add to the result ")
2940 (nargs, args)
2941 int nargs;
2942 Lisp_Object *args;
2944 Lisp_Object properties, string;
2945 struct gcpro gcpro1, gcpro2;
2946 int i;
2948 /* Number of args must be odd. */
2949 if ((nargs & 1) == 0 || nargs < 3)
2950 error ("Wrong number of arguments");
2952 properties = string = Qnil;
2953 GCPRO2 (properties, string);
2955 /* First argument must be a string. */
2956 CHECK_STRING (args[0], 0);
2957 string = Fcopy_sequence (args[0]);
2959 for (i = 1; i < nargs; i += 2)
2961 CHECK_SYMBOL (args[i], i);
2962 properties = Fcons (args[i], Fcons (args[i + 1], properties));
2965 Fadd_text_properties (make_number (0),
2966 make_number (XSTRING (string)->size),
2967 properties, string);
2968 RETURN_UNGCPRO (string);
2972 /* Number of bytes that STRING will occupy when put into the result.
2973 MULTIBYTE is nonzero if the result should be multibyte. */
2975 #define CONVERTED_BYTE_SIZE(MULTIBYTE, STRING) \
2976 (((MULTIBYTE) && ! STRING_MULTIBYTE (STRING)) \
2977 ? count_size_as_multibyte (XSTRING (STRING)->data, \
2978 STRING_BYTES (XSTRING (STRING))) \
2979 : STRING_BYTES (XSTRING (STRING)))
2981 DEFUN ("format", Fformat, Sformat, 1, MANY, 0,
2982 "Format a string out of a control-string and arguments.\n\
2983 The first argument is a control string.\n\
2984 The other arguments are substituted into it to make the result, a string.\n\
2985 It may contain %-sequences meaning to substitute the next argument.\n\
2986 %s means print a string argument. Actually, prints any object, with `princ'.\n\
2987 %d means print as number in decimal (%o octal, %x hex).\n\
2988 %e means print a number in exponential notation.\n\
2989 %f means print a number in decimal-point notation.\n\
2990 %g means print a number in exponential notation\n\
2991 or decimal-point notation, whichever uses fewer characters.\n\
2992 %c means print a number as a single character.\n\
2993 %S means print any object as an s-expression (using `prin1').\n\
2994 The argument used for %d, %o, %x, %e, %f, %g or %c must be a number.\n\
2995 Use %% to put a single % into the output.")
2996 (nargs, args)
2997 int nargs;
2998 register Lisp_Object *args;
3000 register int n; /* The number of the next arg to substitute */
3001 register int total; /* An estimate of the final length */
3002 char *buf, *p;
3003 register unsigned char *format, *end;
3004 int nchars;
3005 /* Nonzero if the output should be a multibyte string,
3006 which is true if any of the inputs is one. */
3007 int multibyte = 0;
3008 /* When we make a multibyte string, we must pay attention to the
3009 byte combining problem, i.e., a byte may be combined with a
3010 multibyte charcter of the previous string. This flag tells if we
3011 must consider such a situation or not. */
3012 int maybe_combine_byte;
3013 unsigned char *this_format;
3014 int longest_format;
3015 Lisp_Object val;
3016 struct info
3018 int start, end;
3019 } *info = 0;
3021 extern char *index ();
3023 /* It should not be necessary to GCPRO ARGS, because
3024 the caller in the interpreter should take care of that. */
3026 /* Try to determine whether the result should be multibyte.
3027 This is not always right; sometimes the result needs to be multibyte
3028 because of an object that we will pass through prin1,
3029 and in that case, we won't know it here. */
3030 for (n = 0; n < nargs; n++)
3031 if (STRINGP (args[n]) && STRING_MULTIBYTE (args[n]))
3032 multibyte = 1;
3034 CHECK_STRING (args[0], 0);
3036 /* If we start out planning a unibyte result,
3037 and later find it has to be multibyte, we jump back to retry. */
3038 retry:
3040 format = XSTRING (args[0])->data;
3041 end = format + STRING_BYTES (XSTRING (args[0]));
3042 longest_format = 0;
3044 /* Make room in result for all the non-%-codes in the control string. */
3045 total = 5 + CONVERTED_BYTE_SIZE (multibyte, args[0]);
3047 /* Add to TOTAL enough space to hold the converted arguments. */
3049 n = 0;
3050 while (format != end)
3051 if (*format++ == '%')
3053 int minlen, thissize = 0;
3054 unsigned char *this_format_start = format - 1;
3056 /* Process a numeric arg and skip it. */
3057 minlen = atoi (format);
3058 if (minlen < 0)
3059 minlen = - minlen;
3061 while ((*format >= '0' && *format <= '9')
3062 || *format == '-' || *format == ' ' || *format == '.')
3063 format++;
3065 if (format - this_format_start + 1 > longest_format)
3066 longest_format = format - this_format_start + 1;
3068 if (format == end)
3069 error ("Format string ends in middle of format specifier");
3070 if (*format == '%')
3071 format++;
3072 else if (++n >= nargs)
3073 error ("Not enough arguments for format string");
3074 else if (*format == 'S')
3076 /* For `S', prin1 the argument and then treat like a string. */
3077 register Lisp_Object tem;
3078 tem = Fprin1_to_string (args[n], Qnil);
3079 if (STRING_MULTIBYTE (tem) && ! multibyte)
3081 multibyte = 1;
3082 goto retry;
3084 args[n] = tem;
3085 goto string;
3087 else if (SYMBOLP (args[n]))
3089 /* Use a temp var to avoid problems when ENABLE_CHECKING
3090 is turned on. */
3091 struct Lisp_String *t = XSYMBOL (args[n])->name;
3092 XSETSTRING (args[n], t);
3093 if (STRING_MULTIBYTE (args[n]) && ! multibyte)
3095 multibyte = 1;
3096 goto retry;
3098 goto string;
3100 else if (STRINGP (args[n]))
3102 string:
3103 if (*format != 's' && *format != 'S')
3104 error ("Format specifier doesn't match argument type");
3105 thissize = CONVERTED_BYTE_SIZE (multibyte, args[n]);
3107 /* Would get MPV otherwise, since Lisp_Int's `point' to low memory. */
3108 else if (INTEGERP (args[n]) && *format != 's')
3110 /* The following loop assumes the Lisp type indicates
3111 the proper way to pass the argument.
3112 So make sure we have a flonum if the argument should
3113 be a double. */
3114 if (*format == 'e' || *format == 'f' || *format == 'g')
3115 args[n] = Ffloat (args[n]);
3116 else
3117 if (*format != 'd' && *format != 'o' && *format != 'x'
3118 && *format != 'i' && *format != 'X' && *format != 'c')
3119 error ("Invalid format operation %%%c", *format);
3121 thissize = 30;
3122 if (*format == 'c'
3123 && (! SINGLE_BYTE_CHAR_P (XINT (args[n]))
3124 || XINT (args[n]) == 0))
3126 if (! multibyte)
3128 multibyte = 1;
3129 goto retry;
3131 args[n] = Fchar_to_string (args[n]);
3132 thissize = STRING_BYTES (XSTRING (args[n]));
3135 else if (FLOATP (args[n]) && *format != 's')
3137 if (! (*format == 'e' || *format == 'f' || *format == 'g'))
3138 args[n] = Ftruncate (args[n], Qnil);
3139 thissize = 200;
3141 else
3143 /* Anything but a string, convert to a string using princ. */
3144 register Lisp_Object tem;
3145 tem = Fprin1_to_string (args[n], Qt);
3146 if (STRING_MULTIBYTE (tem) & ! multibyte)
3148 multibyte = 1;
3149 goto retry;
3151 args[n] = tem;
3152 goto string;
3155 if (thissize < minlen)
3156 thissize = minlen;
3158 total += thissize + 4;
3161 /* Now we can no longer jump to retry.
3162 TOTAL and LONGEST_FORMAT are known for certain. */
3164 this_format = (unsigned char *) alloca (longest_format + 1);
3166 /* Allocate the space for the result.
3167 Note that TOTAL is an overestimate. */
3168 if (total < 1000)
3169 buf = (char *) alloca (total + 1);
3170 else
3171 buf = (char *) xmalloc (total + 1);
3173 p = buf;
3174 nchars = 0;
3175 n = 0;
3177 /* Scan the format and store result in BUF. */
3178 format = XSTRING (args[0])->data;
3179 maybe_combine_byte = 0;
3180 while (format != end)
3182 if (*format == '%')
3184 int minlen;
3185 int negative = 0;
3186 unsigned char *this_format_start = format;
3188 format++;
3190 /* Process a numeric arg and skip it. */
3191 minlen = atoi (format);
3192 if (minlen < 0)
3193 minlen = - minlen, negative = 1;
3195 while ((*format >= '0' && *format <= '9')
3196 || *format == '-' || *format == ' ' || *format == '.')
3197 format++;
3199 if (*format++ == '%')
3201 *p++ = '%';
3202 nchars++;
3203 continue;
3206 ++n;
3208 if (STRINGP (args[n]))
3210 int padding, nbytes;
3211 int width = strwidth (XSTRING (args[n])->data,
3212 STRING_BYTES (XSTRING (args[n])));
3213 int start = nchars;
3215 /* If spec requires it, pad on right with spaces. */
3216 padding = minlen - width;
3217 if (! negative)
3218 while (padding-- > 0)
3220 *p++ = ' ';
3221 nchars++;
3224 if (p > buf
3225 && multibyte
3226 && !ASCII_BYTE_P (*((unsigned char *) p - 1))
3227 && STRING_MULTIBYTE (args[n])
3228 && !CHAR_HEAD_P (XSTRING (args[n])->data[0]))
3229 maybe_combine_byte = 1;
3230 nbytes = copy_text (XSTRING (args[n])->data, p,
3231 STRING_BYTES (XSTRING (args[n])),
3232 STRING_MULTIBYTE (args[n]), multibyte);
3233 p += nbytes;
3234 nchars += XSTRING (args[n])->size;
3236 if (negative)
3237 while (padding-- > 0)
3239 *p++ = ' ';
3240 nchars++;
3243 /* If this argument has text properties, record where
3244 in the result string it appears. */
3245 if (XSTRING (args[n])->intervals)
3247 if (!info)
3249 int nbytes = nargs * sizeof *info;
3250 info = (struct info *) alloca (nbytes);
3251 bzero (info, nbytes);
3254 info[n].start = start;
3255 info[n].end = nchars;
3258 else if (INTEGERP (args[n]) || FLOATP (args[n]))
3260 int this_nchars;
3262 bcopy (this_format_start, this_format,
3263 format - this_format_start);
3264 this_format[format - this_format_start] = 0;
3266 if (INTEGERP (args[n]))
3267 sprintf (p, this_format, XINT (args[n]));
3268 else
3269 sprintf (p, this_format, XFLOAT_DATA (args[n]));
3271 if (p > buf
3272 && multibyte
3273 && !ASCII_BYTE_P (*((unsigned char *) p - 1))
3274 && !CHAR_HEAD_P (*((unsigned char *) p)))
3275 maybe_combine_byte = 1;
3276 this_nchars = strlen (p);
3277 if (multibyte)
3278 p += str_to_multibyte (p, buf + total - p, this_nchars);
3279 else
3280 p += this_nchars;
3281 nchars += this_nchars;
3284 else if (STRING_MULTIBYTE (args[0]))
3286 /* Copy a whole multibyte character. */
3287 if (p > buf
3288 && multibyte
3289 && !ASCII_BYTE_P (*((unsigned char *) p - 1))
3290 && !CHAR_HEAD_P (*format))
3291 maybe_combine_byte = 1;
3292 *p++ = *format++;
3293 while (! CHAR_HEAD_P (*format)) *p++ = *format++;
3294 nchars++;
3296 else if (multibyte)
3298 /* Convert a single-byte character to multibyte. */
3299 int len = copy_text (format, p, 1, 0, 1);
3301 p += len;
3302 format++;
3303 nchars++;
3305 else
3306 *p++ = *format++, nchars++;
3309 if (maybe_combine_byte)
3310 nchars = multibyte_chars_in_text (buf, p - buf);
3311 val = make_specified_string (buf, nchars, p - buf, multibyte);
3313 /* If we allocated BUF with malloc, free it too. */
3314 if (total >= 1000)
3315 xfree (buf);
3317 /* If the format string has text properties, or any of the string
3318 arguments has text properties, set up text properties of the
3319 result string. */
3321 if (XSTRING (args[0])->intervals || info)
3323 Lisp_Object len, new_len, props;
3324 struct gcpro gcpro1;
3326 /* Add text properties from the format string. */
3327 len = make_number (XSTRING (args[0])->size);
3328 props = text_property_list (args[0], make_number (0), len, Qnil);
3329 GCPRO1 (props);
3331 if (CONSP (props))
3333 new_len = make_number (XSTRING (val)->size);
3334 extend_property_ranges (props, len, new_len);
3335 add_text_properties_from_list (val, props, make_number (0));
3338 /* Add text properties from arguments. */
3339 if (info)
3340 for (n = 1; n < nargs; ++n)
3341 if (info[n].end)
3343 len = make_number (XSTRING (args[n])->size);
3344 new_len = make_number (info[n].end - info[n].start);
3345 props = text_property_list (args[n], make_number (0), len, Qnil);
3346 extend_property_ranges (props, len, new_len);
3347 /* If successive arguments have properites, be sure that
3348 the value of `composition' property be the copy. */
3349 if (n > 1 && info[n - 1].end)
3350 make_composition_value_copy (props);
3351 add_text_properties_from_list (val, props,
3352 make_number (info[n].start));
3355 UNGCPRO;
3358 return val;
3362 /* VARARGS 1 */
3363 Lisp_Object
3364 #ifdef NO_ARG_ARRAY
3365 format1 (string1, arg0, arg1, arg2, arg3, arg4)
3366 EMACS_INT arg0, arg1, arg2, arg3, arg4;
3367 #else
3368 format1 (string1)
3369 #endif
3370 char *string1;
3372 char buf[100];
3373 #ifdef NO_ARG_ARRAY
3374 EMACS_INT args[5];
3375 args[0] = arg0;
3376 args[1] = arg1;
3377 args[2] = arg2;
3378 args[3] = arg3;
3379 args[4] = arg4;
3380 doprnt (buf, sizeof buf, string1, (char *)0, 5, (char **) args);
3381 #else
3382 doprnt (buf, sizeof buf, string1, (char *)0, 5, &string1 + 1);
3383 #endif
3384 return build_string (buf);
3387 DEFUN ("char-equal", Fchar_equal, Schar_equal, 2, 2, 0,
3388 "Return t if two characters match, optionally ignoring case.\n\
3389 Both arguments must be characters (i.e. integers).\n\
3390 Case is ignored if `case-fold-search' is non-nil in the current buffer.")
3391 (c1, c2)
3392 register Lisp_Object c1, c2;
3394 int i1, i2;
3395 CHECK_NUMBER (c1, 0);
3396 CHECK_NUMBER (c2, 1);
3398 if (XINT (c1) == XINT (c2))
3399 return Qt;
3400 if (NILP (current_buffer->case_fold_search))
3401 return Qnil;
3403 /* Do these in separate statements,
3404 then compare the variables.
3405 because of the way DOWNCASE uses temp variables. */
3406 i1 = DOWNCASE (XFASTINT (c1));
3407 i2 = DOWNCASE (XFASTINT (c2));
3408 return (i1 == i2 ? Qt : Qnil);
3411 /* Transpose the markers in two regions of the current buffer, and
3412 adjust the ones between them if necessary (i.e.: if the regions
3413 differ in size).
3415 START1, END1 are the character positions of the first region.
3416 START1_BYTE, END1_BYTE are the byte positions.
3417 START2, END2 are the character positions of the second region.
3418 START2_BYTE, END2_BYTE are the byte positions.
3420 Traverses the entire marker list of the buffer to do so, adding an
3421 appropriate amount to some, subtracting from some, and leaving the
3422 rest untouched. Most of this is copied from adjust_markers in insdel.c.
3424 It's the caller's job to ensure that START1 <= END1 <= START2 <= END2. */
3426 static void
3427 transpose_markers (start1, end1, start2, end2,
3428 start1_byte, end1_byte, start2_byte, end2_byte)
3429 register int start1, end1, start2, end2;
3430 register int start1_byte, end1_byte, start2_byte, end2_byte;
3432 register int amt1, amt1_byte, amt2, amt2_byte, diff, diff_byte, mpos;
3433 register Lisp_Object marker;
3435 /* Update point as if it were a marker. */
3436 if (PT < start1)
3438 else if (PT < end1)
3439 TEMP_SET_PT_BOTH (PT + (end2 - end1),
3440 PT_BYTE + (end2_byte - end1_byte));
3441 else if (PT < start2)
3442 TEMP_SET_PT_BOTH (PT + (end2 - start2) - (end1 - start1),
3443 (PT_BYTE + (end2_byte - start2_byte)
3444 - (end1_byte - start1_byte)));
3445 else if (PT < end2)
3446 TEMP_SET_PT_BOTH (PT - (start2 - start1),
3447 PT_BYTE - (start2_byte - start1_byte));
3449 /* We used to adjust the endpoints here to account for the gap, but that
3450 isn't good enough. Even if we assume the caller has tried to move the
3451 gap out of our way, it might still be at start1 exactly, for example;
3452 and that places it `inside' the interval, for our purposes. The amount
3453 of adjustment is nontrivial if there's a `denormalized' marker whose
3454 position is between GPT and GPT + GAP_SIZE, so it's simpler to leave
3455 the dirty work to Fmarker_position, below. */
3457 /* The difference between the region's lengths */
3458 diff = (end2 - start2) - (end1 - start1);
3459 diff_byte = (end2_byte - start2_byte) - (end1_byte - start1_byte);
3461 /* For shifting each marker in a region by the length of the other
3462 region plus the distance between the regions. */
3463 amt1 = (end2 - start2) + (start2 - end1);
3464 amt2 = (end1 - start1) + (start2 - end1);
3465 amt1_byte = (end2_byte - start2_byte) + (start2_byte - end1_byte);
3466 amt2_byte = (end1_byte - start1_byte) + (start2_byte - end1_byte);
3468 for (marker = BUF_MARKERS (current_buffer); !NILP (marker);
3469 marker = XMARKER (marker)->chain)
3471 mpos = marker_byte_position (marker);
3472 if (mpos >= start1_byte && mpos < end2_byte)
3474 if (mpos < end1_byte)
3475 mpos += amt1_byte;
3476 else if (mpos < start2_byte)
3477 mpos += diff_byte;
3478 else
3479 mpos -= amt2_byte;
3480 XMARKER (marker)->bytepos = mpos;
3482 mpos = XMARKER (marker)->charpos;
3483 if (mpos >= start1 && mpos < end2)
3485 if (mpos < end1)
3486 mpos += amt1;
3487 else if (mpos < start2)
3488 mpos += diff;
3489 else
3490 mpos -= amt2;
3492 XMARKER (marker)->charpos = mpos;
3496 DEFUN ("transpose-regions", Ftranspose_regions, Stranspose_regions, 4, 5, 0,
3497 "Transpose region START1 to END1 with START2 to END2.\n\
3498 The regions may not be overlapping, because the size of the buffer is\n\
3499 never changed in a transposition.\n\
3501 Optional fifth arg LEAVE_MARKERS, if non-nil, means don't update\n\
3502 any markers that happen to be located in the regions.\n\
3504 Transposing beyond buffer boundaries is an error.")
3505 (startr1, endr1, startr2, endr2, leave_markers)
3506 Lisp_Object startr1, endr1, startr2, endr2, leave_markers;
3508 register int start1, end1, start2, end2;
3509 int start1_byte, start2_byte, len1_byte, len2_byte;
3510 int gap, len1, len_mid, len2;
3511 unsigned char *start1_addr, *start2_addr, *temp;
3512 struct gcpro gcpro1, gcpro2;
3514 INTERVAL cur_intv, tmp_interval1, tmp_interval_mid, tmp_interval2;
3515 cur_intv = BUF_INTERVALS (current_buffer);
3517 validate_region (&startr1, &endr1);
3518 validate_region (&startr2, &endr2);
3520 start1 = XFASTINT (startr1);
3521 end1 = XFASTINT (endr1);
3522 start2 = XFASTINT (startr2);
3523 end2 = XFASTINT (endr2);
3524 gap = GPT;
3526 /* Swap the regions if they're reversed. */
3527 if (start2 < end1)
3529 register int glumph = start1;
3530 start1 = start2;
3531 start2 = glumph;
3532 glumph = end1;
3533 end1 = end2;
3534 end2 = glumph;
3537 len1 = end1 - start1;
3538 len2 = end2 - start2;
3540 if (start2 < end1)
3541 error ("Transposed regions overlap");
3542 else if (start1 == end1 || start2 == end2)
3543 error ("Transposed region has length 0");
3545 /* The possibilities are:
3546 1. Adjacent (contiguous) regions, or separate but equal regions
3547 (no, really equal, in this case!), or
3548 2. Separate regions of unequal size.
3550 The worst case is usually No. 2. It means that (aside from
3551 potential need for getting the gap out of the way), there also
3552 needs to be a shifting of the text between the two regions. So
3553 if they are spread far apart, we are that much slower... sigh. */
3555 /* It must be pointed out that the really studly thing to do would
3556 be not to move the gap at all, but to leave it in place and work
3557 around it if necessary. This would be extremely efficient,
3558 especially considering that people are likely to do
3559 transpositions near where they are working interactively, which
3560 is exactly where the gap would be found. However, such code
3561 would be much harder to write and to read. So, if you are
3562 reading this comment and are feeling squirrely, by all means have
3563 a go! I just didn't feel like doing it, so I will simply move
3564 the gap the minimum distance to get it out of the way, and then
3565 deal with an unbroken array. */
3567 /* Make sure the gap won't interfere, by moving it out of the text
3568 we will operate on. */
3569 if (start1 < gap && gap < end2)
3571 if (gap - start1 < end2 - gap)
3572 move_gap (start1);
3573 else
3574 move_gap (end2);
3577 start1_byte = CHAR_TO_BYTE (start1);
3578 start2_byte = CHAR_TO_BYTE (start2);
3579 len1_byte = CHAR_TO_BYTE (end1) - start1_byte;
3580 len2_byte = CHAR_TO_BYTE (end2) - start2_byte;
3582 #ifdef BYTE_COMBINING_DEBUG
3583 if (end1 == start2)
3585 if (count_combining_before (BYTE_POS_ADDR (start2_byte),
3586 len2_byte, start1, start1_byte)
3587 || count_combining_before (BYTE_POS_ADDR (start1_byte),
3588 len1_byte, end2, start2_byte + len2_byte)
3589 || count_combining_after (BYTE_POS_ADDR (start1_byte),
3590 len1_byte, end2, start2_byte + len2_byte))
3591 abort ();
3593 else
3595 if (count_combining_before (BYTE_POS_ADDR (start2_byte),
3596 len2_byte, start1, start1_byte)
3597 || count_combining_before (BYTE_POS_ADDR (start1_byte),
3598 len1_byte, start2, start2_byte)
3599 || count_combining_after (BYTE_POS_ADDR (start2_byte),
3600 len2_byte, end1, start1_byte + len1_byte)
3601 || count_combining_after (BYTE_POS_ADDR (start1_byte),
3602 len1_byte, end2, start2_byte + len2_byte))
3603 abort ();
3605 #endif
3607 /* Hmmm... how about checking to see if the gap is large
3608 enough to use as the temporary storage? That would avoid an
3609 allocation... interesting. Later, don't fool with it now. */
3611 /* Working without memmove, for portability (sigh), so must be
3612 careful of overlapping subsections of the array... */
3614 if (end1 == start2) /* adjacent regions */
3616 modify_region (current_buffer, start1, end2);
3617 record_change (start1, len1 + len2);
3619 tmp_interval1 = copy_intervals (cur_intv, start1, len1);
3620 tmp_interval2 = copy_intervals (cur_intv, start2, len2);
3621 Fset_text_properties (make_number (start1), make_number (end2),
3622 Qnil, Qnil);
3624 /* First region smaller than second. */
3625 if (len1_byte < len2_byte)
3627 /* We use alloca only if it is small,
3628 because we want to avoid stack overflow. */
3629 if (len2_byte > 20000)
3630 temp = (unsigned char *) xmalloc (len2_byte);
3631 else
3632 temp = (unsigned char *) alloca (len2_byte);
3634 /* Don't precompute these addresses. We have to compute them
3635 at the last minute, because the relocating allocator might
3636 have moved the buffer around during the xmalloc. */
3637 start1_addr = BYTE_POS_ADDR (start1_byte);
3638 start2_addr = BYTE_POS_ADDR (start2_byte);
3640 bcopy (start2_addr, temp, len2_byte);
3641 bcopy (start1_addr, start1_addr + len2_byte, len1_byte);
3642 bcopy (temp, start1_addr, len2_byte);
3643 if (len2_byte > 20000)
3644 xfree (temp);
3646 else
3647 /* First region not smaller than second. */
3649 if (len1_byte > 20000)
3650 temp = (unsigned char *) xmalloc (len1_byte);
3651 else
3652 temp = (unsigned char *) alloca (len1_byte);
3653 start1_addr = BYTE_POS_ADDR (start1_byte);
3654 start2_addr = BYTE_POS_ADDR (start2_byte);
3655 bcopy (start1_addr, temp, len1_byte);
3656 bcopy (start2_addr, start1_addr, len2_byte);
3657 bcopy (temp, start1_addr + len2_byte, len1_byte);
3658 if (len1_byte > 20000)
3659 xfree (temp);
3661 graft_intervals_into_buffer (tmp_interval1, start1 + len2,
3662 len1, current_buffer, 0);
3663 graft_intervals_into_buffer (tmp_interval2, start1,
3664 len2, current_buffer, 0);
3665 update_compositions (start1, start1 + len2, CHECK_BORDER);
3666 update_compositions (start1 + len2, end2, CHECK_TAIL);
3668 /* Non-adjacent regions, because end1 != start2, bleagh... */
3669 else
3671 len_mid = start2_byte - (start1_byte + len1_byte);
3673 if (len1_byte == len2_byte)
3674 /* Regions are same size, though, how nice. */
3676 modify_region (current_buffer, start1, end1);
3677 modify_region (current_buffer, start2, end2);
3678 record_change (start1, len1);
3679 record_change (start2, len2);
3680 tmp_interval1 = copy_intervals (cur_intv, start1, len1);
3681 tmp_interval2 = copy_intervals (cur_intv, start2, len2);
3682 Fset_text_properties (make_number (start1), make_number (end1),
3683 Qnil, Qnil);
3684 Fset_text_properties (make_number (start2), make_number (end2),
3685 Qnil, Qnil);
3687 if (len1_byte > 20000)
3688 temp = (unsigned char *) xmalloc (len1_byte);
3689 else
3690 temp = (unsigned char *) alloca (len1_byte);
3691 start1_addr = BYTE_POS_ADDR (start1_byte);
3692 start2_addr = BYTE_POS_ADDR (start2_byte);
3693 bcopy (start1_addr, temp, len1_byte);
3694 bcopy (start2_addr, start1_addr, len2_byte);
3695 bcopy (temp, start2_addr, len1_byte);
3696 if (len1_byte > 20000)
3697 xfree (temp);
3698 graft_intervals_into_buffer (tmp_interval1, start2,
3699 len1, current_buffer, 0);
3700 graft_intervals_into_buffer (tmp_interval2, start1,
3701 len2, current_buffer, 0);
3704 else if (len1_byte < len2_byte) /* Second region larger than first */
3705 /* Non-adjacent & unequal size, area between must also be shifted. */
3707 modify_region (current_buffer, start1, end2);
3708 record_change (start1, (end2 - start1));
3709 tmp_interval1 = copy_intervals (cur_intv, start1, len1);
3710 tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid);
3711 tmp_interval2 = copy_intervals (cur_intv, start2, len2);
3712 Fset_text_properties (make_number (start1), make_number (end2),
3713 Qnil, Qnil);
3715 /* holds region 2 */
3716 if (len2_byte > 20000)
3717 temp = (unsigned char *) xmalloc (len2_byte);
3718 else
3719 temp = (unsigned char *) alloca (len2_byte);
3720 start1_addr = BYTE_POS_ADDR (start1_byte);
3721 start2_addr = BYTE_POS_ADDR (start2_byte);
3722 bcopy (start2_addr, temp, len2_byte);
3723 bcopy (start1_addr, start1_addr + len_mid + len2_byte, len1_byte);
3724 safe_bcopy (start1_addr + len1_byte, start1_addr + len2_byte, len_mid);
3725 bcopy (temp, start1_addr, len2_byte);
3726 if (len2_byte > 20000)
3727 xfree (temp);
3728 graft_intervals_into_buffer (tmp_interval1, end2 - len1,
3729 len1, current_buffer, 0);
3730 graft_intervals_into_buffer (tmp_interval_mid, start1 + len2,
3731 len_mid, current_buffer, 0);
3732 graft_intervals_into_buffer (tmp_interval2, start1,
3733 len2, current_buffer, 0);
3735 else
3736 /* Second region smaller than first. */
3738 record_change (start1, (end2 - start1));
3739 modify_region (current_buffer, start1, end2);
3741 tmp_interval1 = copy_intervals (cur_intv, start1, len1);
3742 tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid);
3743 tmp_interval2 = copy_intervals (cur_intv, start2, len2);
3744 Fset_text_properties (make_number (start1), make_number (end2),
3745 Qnil, Qnil);
3747 /* holds region 1 */
3748 if (len1_byte > 20000)
3749 temp = (unsigned char *) xmalloc (len1_byte);
3750 else
3751 temp = (unsigned char *) alloca (len1_byte);
3752 start1_addr = BYTE_POS_ADDR (start1_byte);
3753 start2_addr = BYTE_POS_ADDR (start2_byte);
3754 bcopy (start1_addr, temp, len1_byte);
3755 bcopy (start2_addr, start1_addr, len2_byte);
3756 bcopy (start1_addr + len1_byte, start1_addr + len2_byte, len_mid);
3757 bcopy (temp, start1_addr + len2_byte + len_mid, len1_byte);
3758 if (len1_byte > 20000)
3759 xfree (temp);
3760 graft_intervals_into_buffer (tmp_interval1, end2 - len1,
3761 len1, current_buffer, 0);
3762 graft_intervals_into_buffer (tmp_interval_mid, start1 + len2,
3763 len_mid, current_buffer, 0);
3764 graft_intervals_into_buffer (tmp_interval2, start1,
3765 len2, current_buffer, 0);
3768 update_compositions (start1, start1 + len2, CHECK_BORDER);
3769 update_compositions (end2 - len1, end2, CHECK_BORDER);
3772 /* When doing multiple transpositions, it might be nice
3773 to optimize this. Perhaps the markers in any one buffer
3774 should be organized in some sorted data tree. */
3775 if (NILP (leave_markers))
3777 transpose_markers (start1, end1, start2, end2,
3778 start1_byte, start1_byte + len1_byte,
3779 start2_byte, start2_byte + len2_byte);
3780 fix_overlays_in_range (start1, end2);
3783 return Qnil;
3787 void
3788 syms_of_editfns ()
3790 environbuf = 0;
3792 Qbuffer_access_fontify_functions
3793 = intern ("buffer-access-fontify-functions");
3794 staticpro (&Qbuffer_access_fontify_functions);
3796 DEFVAR_LISP ("inhibit-field-text-motion", &Vinhibit_field_text_motion,
3797 "Non-nil means.text motion commands don't notice fields.");
3798 Vinhibit_field_text_motion = Qnil;
3800 DEFVAR_LISP ("buffer-access-fontify-functions",
3801 &Vbuffer_access_fontify_functions,
3802 "List of functions called by `buffer-substring' to fontify if necessary.\n\
3803 Each function is called with two arguments which specify the range\n\
3804 of the buffer being accessed.");
3805 Vbuffer_access_fontify_functions = Qnil;
3808 Lisp_Object obuf;
3809 extern Lisp_Object Vprin1_to_string_buffer;
3810 obuf = Fcurrent_buffer ();
3811 /* Do this here, because init_buffer_once is too early--it won't work. */
3812 Fset_buffer (Vprin1_to_string_buffer);
3813 /* Make sure buffer-access-fontify-functions is nil in this buffer. */
3814 Fset (Fmake_local_variable (intern ("buffer-access-fontify-functions")),
3815 Qnil);
3816 Fset_buffer (obuf);
3819 DEFVAR_LISP ("buffer-access-fontified-property",
3820 &Vbuffer_access_fontified_property,
3821 "Property which (if non-nil) indicates text has been fontified.\n\
3822 `buffer-substring' need not call the `buffer-access-fontify-functions'\n\
3823 functions if all the text being accessed has this property.");
3824 Vbuffer_access_fontified_property = Qnil;
3826 DEFVAR_LISP ("system-name", &Vsystem_name,
3827 "The name of the machine Emacs is running on.");
3829 DEFVAR_LISP ("user-full-name", &Vuser_full_name,
3830 "The full name of the user logged in.");
3832 DEFVAR_LISP ("user-login-name", &Vuser_login_name,
3833 "The user's name, taken from environment variables if possible.");
3835 DEFVAR_LISP ("user-real-login-name", &Vuser_real_login_name,
3836 "The user's name, based upon the real uid only.");
3838 defsubr (&Spropertize);
3839 defsubr (&Schar_equal);
3840 defsubr (&Sgoto_char);
3841 defsubr (&Sstring_to_char);
3842 defsubr (&Schar_to_string);
3843 defsubr (&Sbuffer_substring);
3844 defsubr (&Sbuffer_substring_no_properties);
3845 defsubr (&Sbuffer_string);
3847 defsubr (&Spoint_marker);
3848 defsubr (&Smark_marker);
3849 defsubr (&Spoint);
3850 defsubr (&Sregion_beginning);
3851 defsubr (&Sregion_end);
3853 staticpro (&Qfield);
3854 Qfield = intern ("field");
3855 staticpro (&Qboundary);
3856 Qboundary = intern ("boundary");
3857 defsubr (&Sfield_beginning);
3858 defsubr (&Sfield_end);
3859 defsubr (&Sfield_string);
3860 defsubr (&Sfield_string_no_properties);
3861 defsubr (&Sdelete_field);
3862 defsubr (&Sconstrain_to_field);
3864 defsubr (&Sline_beginning_position);
3865 defsubr (&Sline_end_position);
3867 /* defsubr (&Smark); */
3868 /* defsubr (&Sset_mark); */
3869 defsubr (&Ssave_excursion);
3870 defsubr (&Ssave_current_buffer);
3872 defsubr (&Sbufsize);
3873 defsubr (&Spoint_max);
3874 defsubr (&Spoint_min);
3875 defsubr (&Spoint_min_marker);
3876 defsubr (&Spoint_max_marker);
3877 defsubr (&Sgap_position);
3878 defsubr (&Sgap_size);
3879 defsubr (&Sposition_bytes);
3880 defsubr (&Sbyte_to_position);
3882 defsubr (&Sbobp);
3883 defsubr (&Seobp);
3884 defsubr (&Sbolp);
3885 defsubr (&Seolp);
3886 defsubr (&Sfollowing_char);
3887 defsubr (&Sprevious_char);
3888 defsubr (&Schar_after);
3889 defsubr (&Schar_before);
3890 defsubr (&Sinsert);
3891 defsubr (&Sinsert_before_markers);
3892 defsubr (&Sinsert_and_inherit);
3893 defsubr (&Sinsert_and_inherit_before_markers);
3894 defsubr (&Sinsert_char);
3896 defsubr (&Suser_login_name);
3897 defsubr (&Suser_real_login_name);
3898 defsubr (&Suser_uid);
3899 defsubr (&Suser_real_uid);
3900 defsubr (&Suser_full_name);
3901 defsubr (&Semacs_pid);
3902 defsubr (&Scurrent_time);
3903 defsubr (&Sformat_time_string);
3904 defsubr (&Sfloat_time);
3905 defsubr (&Sdecode_time);
3906 defsubr (&Sencode_time);
3907 defsubr (&Scurrent_time_string);
3908 defsubr (&Scurrent_time_zone);
3909 defsubr (&Sset_time_zone_rule);
3910 defsubr (&Ssystem_name);
3911 defsubr (&Smessage);
3912 defsubr (&Smessage_box);
3913 defsubr (&Smessage_or_box);
3914 defsubr (&Scurrent_message);
3915 defsubr (&Sformat);
3917 defsubr (&Sinsert_buffer_substring);
3918 defsubr (&Scompare_buffer_substrings);
3919 defsubr (&Ssubst_char_in_region);
3920 defsubr (&Stranslate_region);
3921 defsubr (&Sdelete_region);
3922 defsubr (&Sdelete_and_extract_region);
3923 defsubr (&Swiden);
3924 defsubr (&Snarrow_to_region);
3925 defsubr (&Ssave_restriction);
3926 defsubr (&Stranspose_regions);