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)
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. */
24 #include <sys/types.h>
37 #include "intervals.h"
45 #define min(a, b) ((a) < (b) ? (a) : (b))
46 #define max(a, b) ((a) > (b) ? (a) : (b))
53 extern char **environ
;
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,
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. */
95 /* A special value for Qfield properties. */
97 Lisp_Object Qboundary
;
104 register unsigned char *p
;
105 struct passwd
*pw
; /* password entry for the current user */
108 /* Set up system_name even when dumping. */
112 /* Don't bother with this on initial start when just dumping out */
115 #endif /* not CANNOT_DUMP */
117 pw
= (struct passwd
*) getpwuid (getuid ());
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");
124 Vuser_real_login_name
= build_string (pw
? pw
->pw_name
: "unknown");
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");
132 user_name
= (char *) getenv ("USERNAME"); /* it's USERNAME on NT */
133 #else /* WINDOWSNT */
134 user_name
= (char *) getenv ("USER");
135 #endif /* WINDOWSNT */
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())
149 p
= (unsigned char *) getenv ("NAME");
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.")
159 Lisp_Object character
;
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.")
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
);
182 if (STRING_MULTIBYTE (string
))
183 XSETFASTINT (val
, STRING_CHAR (p
->data
, STRING_BYTES (p
)));
185 XSETFASTINT (val
, p
->data
[0]);
188 XSETFASTINT (val
, 0);
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
);
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)")
208 XSETFASTINT (temp
, PT
);
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
;
225 else if (num
> upper
)
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.")
238 register Lisp_Object position
;
242 if (MARKERP (position
)
243 && current_buffer
== XMARKER (position
)->buffer
)
245 pos
= marker_position (position
);
247 SET_PT_BOTH (BEGV
, BEGV_BYTE
);
249 SET_PT_BOTH (ZV
, ZV_BYTE
);
251 SET_PT_BOTH (pos
, marker_byte_position (position
));
256 CHECK_NUMBER_COERCE_MARKER (position
, 0);
258 pos
= clip_to_bounds (BEGV
, XINT (position
), ZV
);
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. */
269 region_limit (beginningp
)
272 extern Lisp_Object Vmark_even_if_inactive
; /* Defined in callint.c. */
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
);
282 error ("There is no region now");
284 if ((PT
< XFASTINT (m
)) == beginningp
)
285 m
= make_number (PT
);
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. */
317 char_property_eq (prop
, pos1
, pos2
)
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. */
335 char_property_stickiness (prop
, 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. */
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. */
366 /* PROP is not inherited from either side. */
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
389 find_field (pos
, merge_at_boundary
, beg
, end
)
391 Lisp_Object merge_at_boundary
;
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;
402 XSETFASTINT (pos
, PT
);
404 CHECK_NUMBER_COERCE_MARKER (pos
, 0);
407 = Fget_char_property (pos
, Qfield
, Qnil
);
409 = (XFASTINT (pos
) > BEGV
410 ? Fget_char_property (make_number (XINT (pos
) - 1), Qfield
, 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
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
);
427 else if (stickiness
< 0)
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':
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:
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. */
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
);
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
);
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
);
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.")
510 find_field (pos
, Qnil
, &beg
, &end
);
512 del_range (beg
, end
);
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.")
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.")
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
;
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
;
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. */
603 /* Use the current point, and afterwards, set it. */
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. */
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
));
626 field_bound
= Ffield_end (old_pos
, escape_from_edge
);
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
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),
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
));
659 DEFUN ("line-beginning-position", Fline_beginning_position
, Sline_beginning_position
,
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.")
673 int orig
, orig_byte
, end
;
682 Fforward_line (make_number (XINT (n
) - 1));
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
,
693 DEFUN ("line-end-position", Fline_end_position
, Sline_end_position
,
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.")
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
),
718 save_excursion_save ()
720 int visible
= (XBUFFER (XWINDOW (selected_window
)->buffer
)
723 return Fcons (Fpoint_marker (),
724 Fcons (Fcopy_marker (current_buffer
->mark
, Qnil
),
725 Fcons (visible
? Qt
: Qnil
,
726 current_buffer
->mark_active
)));
730 save_excursion_restore (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
740 /* In that case, Fmarker_buffer returns nil now. */
744 omark
= nmark
= Qnil
;
745 GCPRO3 (info
, omark
, nmark
);
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. */
763 && current_buffer
!= XBUFFER (XWINDOW (selected_window
)->buffer
))
764 Fswitch_to_buffer (Fcurrent_buffer (), Qnil
);
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"));
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'.")
800 register Lisp_Object val
;
801 int count
= specpdl_ptr
- specpdl
;
803 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
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'.")
816 int count
= specpdl_ptr
- specpdl
;
818 record_unwind_protect (set_buffer_if_live
, Fcurrent_buffer ());
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.")
831 return make_number (Z
- BEG
);
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.")
846 XSETFASTINT (temp
, BEGV
);
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.")
865 XSETFASTINT (temp
, ZV
);
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'.")
884 XSETFASTINT (temp
, GPT
);
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'.")
894 XSETFASTINT (temp
, GAP_SIZE
);
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.")
902 Lisp_Object position
;
904 CHECK_NUMBER_COERCE_MARKER (position
, 1);
905 if (XINT (position
) < BEG
|| XINT (position
) > Z
)
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.")
916 CHECK_NUMBER (bytepos
, 1);
917 if (XINT (bytepos
) < BEG_BYTE
|| XINT (bytepos
) > Z_BYTE
)
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.")
929 XSETFASTINT (temp
, 0);
931 XSETFASTINT (temp
, FETCH_CHAR (PT_BYTE
));
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.")
942 XSETFASTINT (temp
, 0);
943 else if (!NILP (current_buffer
->enable_multibyte_characters
))
947 XSETFASTINT (temp
, FETCH_CHAR (pos
));
950 XSETFASTINT (temp
, FETCH_BYTE (PT_BYTE
- 1));
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.")
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.")
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')
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')
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.")
1000 register int pos_byte
;
1005 XSETFASTINT (pos
, PT
);
1010 pos_byte
= marker_byte_position (pos
);
1011 if (pos_byte
< BEGV_BYTE
|| pos_byte
>= ZV_BYTE
)
1016 CHECK_NUMBER_COERCE_MARKER (pos
, 0);
1017 if (XINT (pos
) < BEGV
|| XINT (pos
) >= ZV
)
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.")
1033 register Lisp_Object val
;
1034 register int pos_byte
;
1039 XSETFASTINT (pos
, PT
);
1044 pos_byte
= marker_byte_position (pos
);
1046 if (pos_byte
<= BEGV_BYTE
|| pos_byte
> ZV_BYTE
)
1051 CHECK_NUMBER_COERCE_MARKER (pos
, 0);
1053 if (XINT (pos
) <= BEGV
|| XINT (pos
) > ZV
)
1056 pos_byte
= CHAR_TO_BYTE (XINT (pos
));
1059 if (!NILP (current_buffer
->enable_multibyte_characters
))
1062 XSETFASTINT (val
, FETCH_CHAR (pos_byte
));
1067 XSETFASTINT (val
, FETCH_BYTE (pos_byte
));
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.")
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
))
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
,
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
))
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.")
1140 register unsigned char *p
, *q
;
1141 extern char *index ();
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
);
1151 error ("Invalid UID specification");
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. */
1167 register unsigned char *r
;
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
);
1174 strcat (r
, XSTRING (login
)->data
);
1175 r
[q
- p
] = UPCASE (r
[q
- p
]);
1177 full
= build_string (r
);
1179 #endif /* AMPERSAND_FULL_NAME */
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 */
1196 if (STRINGP (Vsystem_name
))
1197 return (char *) XSTRING (Vsystem_name
)->data
;
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\
1216 The microsecond count is zero on systems that do not provide\n\
1217 resolution finer than a second.")
1221 Lisp_Object result
[3];
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
);
1233 lisp_time_argument (specified_time
, result
, usec
)
1234 Lisp_Object specified_time
;
1238 if (NILP (specified_time
))
1245 *usec
= EMACS_USECS (t
);
1246 *result
= EMACS_SECS (t
);
1250 return time (result
) != -1;
1254 Lisp_Object high
, low
;
1255 high
= Fcar (specified_time
);
1256 CHECK_NUMBER (high
, 0);
1257 low
= Fcdr (specified_time
);
1262 Lisp_Object usec_l
= Fcdr (low
);
1264 usec_l
= Fcar (usec_l
);
1269 CHECK_NUMBER (usec_l
, 0);
1270 *usec
= XINT (usec_l
);
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'.")
1291 Lisp_Object specified_time
;
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
1313 emacs_memftimeu (s
, maxsize
, format
, format_len
, tp
, ut
)
1318 const struct tm
*tp
;
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. */
1336 result
= emacs_strftimeu (s
, maxsize
, format
, tp
, ut
);
1340 if (result
== 0 && s
[0] != '\0')
1345 maxsize
-= result
+ 1;
1347 len
= strlen (format
);
1348 if (len
== format_len
)
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
;
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
);
1430 error ("Specified time is not representable");
1432 synchronize_system_time_locale ();
1436 char *buf
= (char *) alloca (size
+ 1);
1440 result
= emacs_memftimeu (buf
, size
, XSTRING (format_string
)->data
,
1441 STRING_BYTES (XSTRING (format_string
)),
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
)),
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.)")
1470 Lisp_Object specified_time
;
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
);
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
;
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.")
1521 register Lisp_Object
*args
;
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;
1545 time
= mktime (&tm
);
1550 char **oldenv
= environ
, **newenv
;
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);
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. */
1576 #ifdef LOCALTIME_CACHE
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\
1599 (HIGH LOW . IGNORED).\n\
1600 Thus, you can use times obtained from `current-time'\n\
1601 and from `file-attributes'.")
1603 Lisp_Object specified_time
;
1609 if (! lisp_time_argument (specified_time
, &value
, NULL
))
1611 tem
= (char *) ctime (&value
);
1613 strncpy (buf
, tem
, 24);
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. */
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\
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.")
1663 Lisp_Object specified_time
;
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
);
1678 s
= (char *)t
->tm_zone
;
1679 #else /* not HAVE_TM_ZONE */
1681 if (t
->tm_isdst
== 0 || t
->tm_isdst
== 1)
1682 s
= tzname
[t
->tm_isdst
];
1684 #endif /* not HAVE_TM_ZONE */
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);
1692 return Fcons (make_number (offset
), Fcons (build_string (s
), Qnil
));
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.")
1714 else if (EQ (tz
, Qt
))
1718 CHECK_STRING (tz
, 0);
1719 tzstring
= (char *) XSTRING (tz
)->data
;
1722 set_time_zone_rule (tzstring
);
1725 environbuf
= environ
;
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";
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. */
1751 set_time_zone_rule (tzstring
)
1755 char **from
, **to
, **newenv
;
1757 /* Make the ENVIRON vector longer with room for TZSTRING. */
1758 for (from
= environ
; *from
; from
++)
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. */
1767 char *t
= (char *) (to
+ envptrs
);
1769 strcat (t
, tzstring
);
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)
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. */
1799 /* Temporarily set TZ to a value that loads a tz file
1800 and that differs from tzstring. */
1802 *newenv
= (strcmp (tzstring
, set_time_zone_rule_tz1
+ 3) == 0
1803 ? set_time_zone_rule_tz2
: set_time_zone_rule_tz1
);
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
;
1814 *to
= set_time_zone_rule_tz2
;
1819 /* Now TZ has the desired value, and tzset can be invoked safely. */
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. */
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));
1837 register Lisp_Object
*args
;
1839 register int argnum
;
1840 register Lisp_Object val
;
1842 for (argnum
= 0; argnum
< nargs
; argnum
++)
1848 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
1851 if (!NILP (current_buffer
->enable_multibyte_characters
))
1852 len
= CHAR_STRING (XFASTINT (val
), str
);
1855 str
[0] = (SINGLE_BYTE_CHAR_P (XINT (val
))
1857 : multibyte_char_to_unibyte (XINT (val
), Qnil
));
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
)),
1871 val
= wrong_type_argument (Qchar_or_string_p
, val
);
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.")
1902 register Lisp_Object
*args
;
1904 general_insert_function (insert
, insert_from_string
, 0, nargs
, args
);
1908 DEFUN ("insert-and-inherit", Finsert_and_inherit
, Sinsert_and_inherit
,
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.")
1921 register Lisp_Object
*args
;
1923 general_insert_function (insert_and_inherit
, insert_from_string
, 1,
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.")
1938 register Lisp_Object
*args
;
1940 general_insert_function (insert_before_markers
,
1941 insert_from_string_before_markers
, 0,
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.")
1957 register Lisp_Object
*args
;
1959 general_insert_function (insert_before_markers_and_inherit
,
1960 insert_from_string_before_markers
, 1,
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
;
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
);
1986 str
[0] = XFASTINT (character
), len
= 1;
1987 n
= XINT (count
) * len
;
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
];
1997 if (!NILP (inherit
))
1998 insert_and_inherit (string
, strlen
);
2000 insert (string
, strlen
);
2005 if (!NILP (inherit
))
2006 insert_and_inherit (string
, n
);
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. */
2030 make_buffer_string (start
, end
, 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. */
2056 make_buffer_string_both (start
, start_byte
, end
, end_byte
, props
)
2057 int start
, start_byte
, end
, end_byte
;
2060 Lisp_Object result
, tem
, tem1
;
2062 if (start
< GPT
&& GPT
< end
)
2065 if (! NILP (current_buffer
->enable_multibyte_characters
))
2066 result
= make_uninit_multibyte_string (end
- start
, end_byte
- start_byte
);
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. */
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
,
2088 /* Call Vbuffer_access_fontify_functions for the range START ... END
2089 in the current buffer, if necessary. */
2092 update_buffer_properties (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];
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
,
2114 Frun_hook_with_args (3, args
);
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.")
2127 Lisp_Object start
, end
;
2131 validate_region (&start
, &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.")
2144 Lisp_Object start
, end
;
2148 validate_region (&start
, &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\
2162 return make_buffer_string (BEGV
, ZV
, 1);
2165 DEFUN ("insert-buffer-substring", Finsert_buffer_substring
, Sinsert_buffer_substring
,
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.")
2172 Lisp_Object buf
, start
, end
;
2174 register int b
, e
, temp
;
2175 register struct buffer
*bp
, *obuf
;
2178 buffer
= Fget_buffer (buf
);
2181 bp
= XBUFFER (buffer
);
2182 if (NILP (bp
->name
))
2183 error ("Selecting deleted buffer");
2189 CHECK_NUMBER_COERCE_MARKER (start
, 0);
2196 CHECK_NUMBER_COERCE_MARKER (end
, 1);
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);
2215 DEFUN ("compare-buffer-substrings", Fcompare_buffer_substrings
, Scompare_buffer_substrings
,
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);
2233 int i1
, i2
, i1_byte
, i2_byte
;
2235 /* Find the first buffer and its substring. */
2238 bp1
= current_buffer
;
2242 buf1
= Fget_buffer (buffer1
);
2245 bp1
= XBUFFER (buf1
);
2246 if (NILP (bp1
->name
))
2247 error ("Selecting deleted buffer");
2251 begp1
= BUF_BEGV (bp1
);
2254 CHECK_NUMBER_COERCE_MARKER (start1
, 1);
2255 begp1
= XINT (start1
);
2258 endp1
= BUF_ZV (bp1
);
2261 CHECK_NUMBER_COERCE_MARKER (end1
, 2);
2262 endp1
= XINT (end1
);
2266 temp
= begp1
, begp1
= endp1
, endp1
= temp
;
2268 if (!(BUF_BEGV (bp1
) <= begp1
2270 && endp1
<= BUF_ZV (bp1
)))
2271 args_out_of_range (start1
, end1
);
2273 /* Likewise for second substring. */
2276 bp2
= current_buffer
;
2280 buf2
= Fget_buffer (buffer2
);
2283 bp2
= XBUFFER (buf2
);
2284 if (NILP (bp2
->name
))
2285 error ("Selecting deleted buffer");
2289 begp2
= BUF_BEGV (bp2
);
2292 CHECK_NUMBER_COERCE_MARKER (start2
, 4);
2293 begp2
= XINT (start2
);
2296 endp2
= BUF_ZV (bp2
);
2299 CHECK_NUMBER_COERCE_MARKER (end2
, 5);
2300 endp2
= XINT (end2
);
2304 temp
= begp2
, begp2
= endp2
, endp2
= temp
;
2306 if (!(BUF_BEGV (bp2
) <= begp2
2308 && endp2
<= BUF_ZV (bp2
)))
2309 args_out_of_range (start2
, end2
);
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. */
2322 if (! NILP (bp1
->enable_multibyte_characters
))
2324 c1
= BUF_FETCH_MULTIBYTE_CHAR (bp1
, i1_byte
);
2325 BUF_INC_POS (bp1
, i1_byte
);
2330 c1
= BUF_FETCH_BYTE (bp1
, i1
);
2331 c1
= unibyte_char_to_multibyte (c1
);
2335 if (! NILP (bp2
->enable_multibyte_characters
))
2337 c2
= BUF_FETCH_MULTIBYTE_CHAR (bp2
, i2_byte
);
2338 BUF_INC_POS (bp2
, i2_byte
);
2343 c2
= BUF_FETCH_BYTE (bp2
, i2
);
2344 c2
= unibyte_char_to_multibyte (c2
);
2350 c1
= XINT (trt
[c1
]);
2351 c2
= XINT (trt
[c2
]);
2354 return make_number (- 1 - chars
);
2356 return make_number (chars
+ 1);
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);
2373 subst_char_in_region_unwind (arg
)
2376 return current_buffer
->undo_list
= arg
;
2380 subst_char_in_region_unwind_1 (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
;
2397 unsigned char fromstr
[MAX_MULTIBYTE_LENGTH
], tostr
[MAX_MULTIBYTE_LENGTH
];
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
;
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);
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
;
2432 fromstr
[0] = XFASTINT (fromchar
);
2433 tostr
[0] = XFASTINT (tochar
);
2437 pos_byte
= CHAR_TO_BYTE (pos
);
2438 stop
= CHAR_TO_BYTE (XINT (end
));
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. */
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
);
2460 int pos_byte_next
= pos_byte
;
2462 if (pos_byte
>= stop
)
2464 if (pos_byte
>= end_byte
) break;
2467 p
= BYTE_POS_ADDR (pos_byte
);
2469 INC_POS (pos_byte_next
);
2472 if (pos_byte_next
- pos_byte
== len
2473 && p
[0] == fromstr
[0]
2475 || (p
[1] == fromstr
[1]
2476 && (len
== 2 || (p
[2] == fromstr
[2]
2477 && (len
== 3 || p
[3] == fromstr
[3]))))))
2482 modify_region (current_buffer
, changed
, XINT (end
));
2484 if (! NILP (noundo
))
2486 if (MODIFF
- 1 == 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
;
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
,
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,
2524 INC_POS (pos_byte_next
);
2526 if (! NILP (noundo
))
2527 current_buffer
->undo_list
= tem
;
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
;
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
);
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.")
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. */
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
));
2585 for (; pos_byte
< stop
; )
2587 register unsigned char *p
= BYTE_POS_ADDR (pos_byte
);
2593 oc
= STRING_CHAR_AND_LENGTH (p
, stop
- pos_byte
, len
);
2596 pos_byte_next
= pos_byte
+ len
;
2597 if (oc
< size
&& len
== 1)
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)))))
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
,
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. */
2624 INC_POS (pos_byte_next
);
2628 record_change (pos
, 1);
2630 signal_after_change (pos
, 1, 1);
2631 update_compositions (pos
, pos
+ 1, CHECK_BORDER
);
2636 pos_byte
= pos_byte_next
;
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.")
2648 Lisp_Object start
, end
;
2650 validate_region (&start
, &end
);
2651 del_range (XINT (start
), XINT (end
));
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.")
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;
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 ();
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.")
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
))
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 ();
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 ();
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
);
2743 save_restriction_restore (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
),
2769 buf
->clip_changed
= 1; /* Remember that the narrowing changed. */
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. */
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 ...))")
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
);
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.")
2844 register Lisp_Object val
;
2845 val
= Fformat (nargs
, args
);
2846 message3 (val
, STRING_BYTES (XSTRING (val
)), STRING_MULTIBYTE (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.")
2870 register Lisp_Object val
;
2871 val
= Fformat (nargs
, args
);
2874 Lisp_Object pane
, menu
, obj
;
2875 struct gcpro gcpro1
;
2876 pane
= Fcons (Fcons (build_string ("OK"), Qt
), Qnil
);
2878 menu
= Fcons (val
, pane
);
2879 obj
= Fx_popup_dialog (Qt
, menu
);
2883 #else /* not HAVE_MENUS */
2884 /* Copy the data so that it won't move when we GC. */
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
));
2899 #endif /* not HAVE_MENUS */
2903 extern Lisp_Object last_nonmenu_event
;
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.")
2920 if ((NILP (last_nonmenu_event
) || CONSP (last_nonmenu_event
))
2922 return Fmessage_box (nargs
, args
);
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 ")
2944 Lisp_Object properties
, string
;
2945 struct gcpro gcpro1
, gcpro2
;
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.")
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 */
3003 register unsigned char *format
, *end
;
3005 /* Nonzero if the output should be a multibyte string,
3006 which is true if any of the inputs is one. */
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
;
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
]))
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. */
3040 format
= XSTRING (args
[0])->data
;
3041 end
= format
+ STRING_BYTES (XSTRING (args
[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. */
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
);
3061 while ((*format
>= '0' && *format
<= '9')
3062 || *format
== '-' || *format
== ' ' || *format
== '.')
3065 if (format
- this_format_start
+ 1 > longest_format
)
3066 longest_format
= format
- this_format_start
+ 1;
3069 error ("Format string ends in middle of format specifier");
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
)
3087 else if (SYMBOLP (args
[n
]))
3089 /* Use a temp var to avoid problems when ENABLE_CHECKING
3091 struct Lisp_String
*t
= XSYMBOL (args
[n
])->name
;
3092 XSETSTRING (args
[n
], t
);
3093 if (STRING_MULTIBYTE (args
[n
]) && ! multibyte
)
3100 else if (STRINGP (args
[n
]))
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
3114 if (*format
== 'e' || *format
== 'f' || *format
== 'g')
3115 args
[n
] = Ffloat (args
[n
]);
3117 if (*format
!= 'd' && *format
!= 'o' && *format
!= 'x'
3118 && *format
!= 'i' && *format
!= 'X' && *format
!= 'c')
3119 error ("Invalid format operation %%%c", *format
);
3123 && (! SINGLE_BYTE_CHAR_P (XINT (args
[n
]))
3124 || XINT (args
[n
]) == 0))
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
);
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
)
3155 if (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. */
3169 buf
= (char *) alloca (total
+ 1);
3171 buf
= (char *) xmalloc (total
+ 1);
3177 /* Scan the format and store result in BUF. */
3178 format
= XSTRING (args
[0])->data
;
3179 maybe_combine_byte
= 0;
3180 while (format
!= end
)
3186 unsigned char *this_format_start
= format
;
3190 /* Process a numeric arg and skip it. */
3191 minlen
= atoi (format
);
3193 minlen
= - minlen
, negative
= 1;
3195 while ((*format
>= '0' && *format
<= '9')
3196 || *format
== '-' || *format
== ' ' || *format
== '.')
3199 if (*format
++ == '%')
3208 if (STRINGP (args
[n
]))
3210 int padding
, nbytes
;
3211 int width
= strwidth (XSTRING (args
[n
])->data
,
3212 STRING_BYTES (XSTRING (args
[n
])));
3215 /* If spec requires it, pad on right with spaces. */
3216 padding
= minlen
- width
;
3218 while (padding
-- > 0)
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
);
3234 nchars
+= XSTRING (args
[n
])->size
;
3237 while (padding
-- > 0)
3243 /* If this argument has text properties, record where
3244 in the result string it appears. */
3245 if (XSTRING (args
[n
])->intervals
)
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
]))
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
]));
3269 sprintf (p
, this_format
, XFLOAT_DATA (args
[n
]));
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
);
3278 p
+= str_to_multibyte (p
, buf
+ total
- p
, this_nchars
);
3281 nchars
+= this_nchars
;
3284 else if (STRING_MULTIBYTE (args
[0]))
3286 /* Copy a whole multibyte character. */
3289 && !ASCII_BYTE_P (*((unsigned char *) p
- 1))
3290 && !CHAR_HEAD_P (*format
))
3291 maybe_combine_byte
= 1;
3293 while (! CHAR_HEAD_P (*format
)) *p
++ = *format
++;
3298 /* Convert a single-byte character to multibyte. */
3299 int len
= copy_text (format
, p
, 1, 0, 1);
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. */
3317 /* If the format string has text properties, or any of the string
3318 arguments has text properties, set up text properties of the
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
);
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. */
3340 for (n
= 1; n
< nargs
; ++n
)
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
));
3365 format1 (string1
, arg0
, arg1
, arg2
, arg3
, arg4
)
3366 EMACS_INT arg0
, arg1
, arg2
, arg3
, arg4
;
3380 doprnt (buf
, sizeof buf
, string1
, (char *)0, 5, (char **) args
);
3382 doprnt (buf
, sizeof buf
, string1
, (char *)0, 5, &string1
+ 1);
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.")
3392 register Lisp_Object c1
, c2
;
3395 CHECK_NUMBER (c1
, 0);
3396 CHECK_NUMBER (c2
, 1);
3398 if (XINT (c1
) == XINT (c2
))
3400 if (NILP (current_buffer
->case_fold_search
))
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
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. */
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. */
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
)));
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
)
3476 else if (mpos
< start2_byte
)
3480 XMARKER (marker
)->bytepos
= mpos
;
3482 mpos
= XMARKER (marker
)->charpos
;
3483 if (mpos
>= start1
&& mpos
< end2
)
3487 else if (mpos
< start2
)
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
);
3526 /* Swap the regions if they're reversed. */
3529 register int glumph
= start1
;
3537 len1
= end1
- start1
;
3538 len2
= end2
- start2
;
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
)
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
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
))
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
))
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
),
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
);
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)
3647 /* First region not smaller than second. */
3649 if (len1_byte
> 20000)
3650 temp
= (unsigned char *) xmalloc (len1_byte
);
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)
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... */
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
),
3684 Fset_text_properties (make_number (start2
), make_number (end2
),
3687 if (len1_byte
> 20000)
3688 temp
= (unsigned char *) xmalloc (len1_byte
);
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)
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
),
3715 /* holds region 2 */
3716 if (len2_byte
> 20000)
3717 temp
= (unsigned char *) xmalloc (len2_byte
);
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)
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);
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
),
3747 /* holds region 1 */
3748 if (len1_byte
> 20000)
3749 temp
= (unsigned char *) xmalloc (len1_byte
);
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)
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
);
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
;
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")),
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
);
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
);
3886 defsubr (&Sfollowing_char
);
3887 defsubr (&Sprevious_char
);
3888 defsubr (&Schar_after
);
3889 defsubr (&Schar_before
);
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
);
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
);
3924 defsubr (&Snarrow_to_region
);
3925 defsubr (&Ssave_restriction
);
3926 defsubr (&Stranspose_regions
);