(struct rcsoc_state): New type.
[bpt/emacs.git] / src / editfns.c
... / ...
CommitLineData
1/* Lisp functions pertaining to editing.
2 Copyright (C) 1985,86,87,89,93,94,95,96,97,98, 1999, 2000, 2001
3 Free Software Foundation, Inc.
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs; see the file COPYING. If not, write to
19the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
21
22
23#include <config.h>
24#include <ctype.h>
25#include <sys/types.h>
26
27#ifdef VMS
28#include "vms-pwd.h"
29#else
30#include <pwd.h>
31#endif
32
33#ifdef HAVE_UNISTD_H
34#include <unistd.h>
35#endif
36
37#include "lisp.h"
38#include "intervals.h"
39#include "buffer.h"
40#include "charset.h"
41#include "coding.h"
42#include "frame.h"
43#include "window.h"
44
45#include "systime.h"
46
47#ifdef STDC_HEADERS
48#include <float.h>
49#define MAX_10_EXP DBL_MAX_10_EXP
50#else
51#define MAX_10_EXP 310
52#endif
53
54#ifndef NULL
55#define NULL 0
56#endif
57
58#ifndef USE_CRT_DLL
59extern char **environ;
60#endif
61
62extern Lisp_Object make_time P_ ((time_t));
63extern size_t emacs_strftimeu P_ ((char *, size_t, const char *,
64 const struct tm *, int));
65static int tm_diff P_ ((struct tm *, struct tm *));
66static void find_field P_ ((Lisp_Object, Lisp_Object, int *, int *));
67static void update_buffer_properties P_ ((int, int));
68static Lisp_Object region_limit P_ ((int));
69static int lisp_time_argument P_ ((Lisp_Object, time_t *, int *));
70static size_t emacs_memftimeu P_ ((char *, size_t, const char *,
71 size_t, const struct tm *, int));
72static void general_insert_function P_ ((void (*) (unsigned char *, int),
73 void (*) (Lisp_Object, int, int, int,
74 int, int),
75 int, int, Lisp_Object *));
76static Lisp_Object subst_char_in_region_unwind P_ ((Lisp_Object));
77static Lisp_Object subst_char_in_region_unwind_1 P_ ((Lisp_Object));
78static void transpose_markers P_ ((int, int, int, int, int, int, int, int));
79
80#ifdef HAVE_INDEX
81extern char *index P_ ((const char *, int));
82#endif
83
84Lisp_Object Vbuffer_access_fontify_functions;
85Lisp_Object Qbuffer_access_fontify_functions;
86Lisp_Object Vbuffer_access_fontified_property;
87
88Lisp_Object Fuser_full_name P_ ((Lisp_Object));
89
90/* Non-nil means don't stop at field boundary in text motion commands. */
91
92Lisp_Object Vinhibit_field_text_motion;
93
94/* Some static data, and a function to initialize it for each run */
95
96Lisp_Object Vsystem_name;
97Lisp_Object Vuser_real_login_name; /* login name of current user ID */
98Lisp_Object Vuser_full_name; /* full name of current user */
99Lisp_Object Vuser_login_name; /* user name from LOGNAME or USER */
100
101/* Symbol for the text property used to mark fields. */
102
103Lisp_Object Qfield;
104
105/* A special value for Qfield properties. */
106
107Lisp_Object Qboundary;
108
109
110void
111init_editfns ()
112{
113 char *user_name;
114 register unsigned char *p;
115 struct passwd *pw; /* password entry for the current user */
116 Lisp_Object tem;
117
118 /* Set up system_name even when dumping. */
119 init_system_name ();
120
121#ifndef CANNOT_DUMP
122 /* Don't bother with this on initial start when just dumping out */
123 if (!initialized)
124 return;
125#endif /* not CANNOT_DUMP */
126
127 pw = (struct passwd *) getpwuid (getuid ());
128#ifdef MSDOS
129 /* We let the real user name default to "root" because that's quite
130 accurate on MSDOG and because it lets Emacs find the init file.
131 (The DVX libraries override the Djgpp libraries here.) */
132 Vuser_real_login_name = build_string (pw ? pw->pw_name : "root");
133#else
134 Vuser_real_login_name = build_string (pw ? pw->pw_name : "unknown");
135#endif
136
137 /* Get the effective user name, by consulting environment variables,
138 or the effective uid if those are unset. */
139 user_name = (char *) getenv ("LOGNAME");
140 if (!user_name)
141#ifdef WINDOWSNT
142 user_name = (char *) getenv ("USERNAME"); /* it's USERNAME on NT */
143#else /* WINDOWSNT */
144 user_name = (char *) getenv ("USER");
145#endif /* WINDOWSNT */
146 if (!user_name)
147 {
148 pw = (struct passwd *) getpwuid (geteuid ());
149 user_name = (char *) (pw ? pw->pw_name : "unknown");
150 }
151 Vuser_login_name = build_string (user_name);
152
153 /* If the user name claimed in the environment vars differs from
154 the real uid, use the claimed name to find the full name. */
155 tem = Fstring_equal (Vuser_login_name, Vuser_real_login_name);
156 Vuser_full_name = Fuser_full_name (NILP (tem)? make_number (geteuid())
157 : Vuser_login_name);
158
159 p = (unsigned char *) getenv ("NAME");
160 if (p)
161 Vuser_full_name = build_string (p);
162 else if (NILP (Vuser_full_name))
163 Vuser_full_name = build_string ("unknown");
164}
165\f
166DEFUN ("char-to-string", Fchar_to_string, Schar_to_string, 1, 1, 0,
167 doc: /* Convert arg CHARACTER to a string containing that character. */)
168 (character)
169 Lisp_Object character;
170{
171 int len;
172 unsigned char str[MAX_MULTIBYTE_LENGTH];
173
174 CHECK_NUMBER (character, 0);
175
176 len = (SINGLE_BYTE_CHAR_P (XFASTINT (character))
177 ? (*str = (unsigned char)(XFASTINT (character)), 1)
178 : char_to_string (XFASTINT (character), str));
179 return make_string_from_bytes (str, 1, len);
180}
181
182DEFUN ("string-to-char", Fstring_to_char, Sstring_to_char, 1, 1, 0,
183 doc: /* Convert arg STRING to a character, the first character of that string.
184A multibyte character is handled correctly. */)
185 (string)
186 register Lisp_Object string;
187{
188 register Lisp_Object val;
189 register struct Lisp_String *p;
190 CHECK_STRING (string, 0);
191 p = XSTRING (string);
192 if (p->size)
193 {
194 if (STRING_MULTIBYTE (string))
195 XSETFASTINT (val, STRING_CHAR (p->data, STRING_BYTES (p)));
196 else
197 XSETFASTINT (val, p->data[0]);
198 }
199 else
200 XSETFASTINT (val, 0);
201 return val;
202}
203\f
204static Lisp_Object
205buildmark (charpos, bytepos)
206 int charpos, bytepos;
207{
208 register Lisp_Object mark;
209 mark = Fmake_marker ();
210 set_marker_both (mark, Qnil, charpos, bytepos);
211 return mark;
212}
213
214DEFUN ("point", Fpoint, Spoint, 0, 0, 0,
215 doc: /* Return value of point, as an integer.
216Beginning of buffer is position (point-min). */)
217 ()
218{
219 Lisp_Object temp;
220 XSETFASTINT (temp, PT);
221 return temp;
222}
223
224DEFUN ("point-marker", Fpoint_marker, Spoint_marker, 0, 0, 0,
225 doc: /* Return value of point, as a marker object. */)
226 ()
227{
228 return buildmark (PT, PT_BYTE);
229}
230
231int
232clip_to_bounds (lower, num, upper)
233 int lower, num, upper;
234{
235 if (num < lower)
236 return lower;
237 else if (num > upper)
238 return upper;
239 else
240 return num;
241}
242
243DEFUN ("goto-char", Fgoto_char, Sgoto_char, 1, 1, "NGoto char: ",
244 doc: /* Set point to POSITION, a number or marker.
245Beginning of buffer is position (point-min), end is (point-max).
246If the position is in the middle of a multibyte form,
247the actual point is set at the head of the multibyte form
248except in the case that `enable-multibyte-characters' is nil. */)
249 (position)
250 register Lisp_Object position;
251{
252 int pos;
253
254 if (MARKERP (position)
255 && current_buffer == XMARKER (position)->buffer)
256 {
257 pos = marker_position (position);
258 if (pos < BEGV)
259 SET_PT_BOTH (BEGV, BEGV_BYTE);
260 else if (pos > ZV)
261 SET_PT_BOTH (ZV, ZV_BYTE);
262 else
263 SET_PT_BOTH (pos, marker_byte_position (position));
264
265 return position;
266 }
267
268 CHECK_NUMBER_COERCE_MARKER (position, 0);
269
270 pos = clip_to_bounds (BEGV, XINT (position), ZV);
271 SET_PT (pos);
272 return position;
273}
274
275
276/* Return the start or end position of the region.
277 BEGINNINGP non-zero means return the start.
278 If there is no region active, signal an error. */
279
280static Lisp_Object
281region_limit (beginningp)
282 int beginningp;
283{
284 extern Lisp_Object Vmark_even_if_inactive; /* Defined in callint.c. */
285 Lisp_Object m;
286
287 if (!NILP (Vtransient_mark_mode)
288 && NILP (Vmark_even_if_inactive)
289 && NILP (current_buffer->mark_active))
290 Fsignal (Qmark_inactive, Qnil);
291
292 m = Fmarker_position (current_buffer->mark);
293 if (NILP (m))
294 error ("There is no region now");
295
296 if ((PT < XFASTINT (m)) == beginningp)
297 m = make_number (PT);
298 return m;
299}
300
301DEFUN ("region-beginning", Fregion_beginning, Sregion_beginning, 0, 0, 0,
302 doc: /* Return position of beginning of region, as an integer. */)
303 ()
304{
305 return region_limit (1);
306}
307
308DEFUN ("region-end", Fregion_end, Sregion_end, 0, 0, 0,
309 doc: /* Return position of end of region, as an integer. */)
310 ()
311{
312 return region_limit (0);
313}
314
315DEFUN ("mark-marker", Fmark_marker, Smark_marker, 0, 0, 0,
316 doc: /* Return this buffer's mark, as a marker object.
317Watch out! Moving this marker changes the mark position.
318If you set the marker not to point anywhere, the buffer will have no mark. */)
319 ()
320{
321 return current_buffer->mark;
322}
323
324\f
325#if 0 /* Not used. */
326
327/* Return nonzero if POS1 and POS2 have the same value
328 for the text property PROP. */
329
330static int
331char_property_eq (prop, pos1, pos2)
332 Lisp_Object prop;
333 Lisp_Object pos1, pos2;
334{
335 Lisp_Object pval1, pval2;
336
337 pval1 = Fget_char_property (pos1, prop, Qnil);
338 pval2 = Fget_char_property (pos2, prop, Qnil);
339
340 return EQ (pval1, pval2);
341}
342
343#endif /* 0 */
344
345/* Return the direction from which the text-property PROP would be
346 inherited by any new text inserted at POS: 1 if it would be
347 inherited from the char after POS, -1 if it would be inherited from
348 the char before POS, and 0 if from neither. */
349
350static int
351text_property_stickiness (prop, pos)
352 Lisp_Object prop;
353 Lisp_Object pos;
354{
355 Lisp_Object prev_pos, front_sticky;
356 int is_rear_sticky = 1, is_front_sticky = 0; /* defaults */
357
358 if (XINT (pos) > BEGV)
359 /* Consider previous character. */
360 {
361 Lisp_Object rear_non_sticky;
362
363 prev_pos = make_number (XINT (pos) - 1);
364 rear_non_sticky = Fget_text_property (prev_pos, Qrear_nonsticky, Qnil);
365
366 if (CONSP (rear_non_sticky)
367 ? Fmemq (prop, rear_non_sticky)
368 : !NILP (rear_non_sticky))
369 /* PROP is rear-non-sticky. */
370 is_rear_sticky = 0;
371 }
372
373 /* Consider following character. */
374 front_sticky = Fget_text_property (pos, Qfront_sticky, Qnil);
375
376 if (EQ (front_sticky, Qt)
377 || (CONSP (front_sticky)
378 && !NILP (Fmemq (prop, front_sticky))))
379 /* PROP is inherited from after. */
380 is_front_sticky = 1;
381
382 /* Simple cases, where the properties are consistent. */
383 if (is_rear_sticky && !is_front_sticky)
384 return -1;
385 else if (!is_rear_sticky && is_front_sticky)
386 return 1;
387 else if (!is_rear_sticky && !is_front_sticky)
388 return 0;
389
390 /* The stickiness properties are inconsistent, so we have to
391 disambiguate. Basically, rear-sticky wins, _except_ if the
392 property that would be inherited has a value of nil, in which case
393 front-sticky wins. */
394 if (XINT (pos) == BEGV || NILP (Fget_text_property (prev_pos, prop, Qnil)))
395 return 1;
396 else
397 return -1;
398}
399
400\f
401/* Find the field surrounding POS in *BEG and *END. If POS is nil,
402 the value of point is used instead. If BEG or END null,
403 means don't store the beginning or end of the field.
404
405 If MERGE_AT_BOUNDARY is nonzero, then if POS is at the very first
406 position of a field, then the beginning of the previous field is
407 returned instead of the beginning of POS's field (since the end of a
408 field is actually also the beginning of the next input field, this
409 behavior is sometimes useful). Additionally in the MERGE_AT_BOUNDARY
410 true case, if two fields are separated by a field with the special
411 value `boundary', and POS lies within it, then the two separated
412 fields are considered to be adjacent, and POS between them, when
413 finding the beginning and ending of the "merged" field.
414
415 Either BEG or END may be 0, in which case the corresponding value
416 is not stored. */
417
418static void
419find_field (pos, merge_at_boundary, beg, end)
420 Lisp_Object pos;
421 Lisp_Object merge_at_boundary;
422 int *beg, *end;
423{
424 /* Fields right before and after the point. */
425 Lisp_Object before_field, after_field;
426 /* If the fields came from overlays, the associated overlays.
427 Qnil means they came from text-properties. */
428 Lisp_Object before_overlay = Qnil, after_overlay = Qnil;
429 /* 1 if POS counts as the start of a field. */
430 int at_field_start = 0;
431 /* 1 if POS counts as the end of a field. */
432 int at_field_end = 0;
433
434 if (NILP (pos))
435 XSETFASTINT (pos, PT);
436 else
437 CHECK_NUMBER_COERCE_MARKER (pos, 0);
438
439 after_field
440 = get_char_property_and_overlay (pos, Qfield, Qnil, &after_overlay);
441 before_field
442 = (XFASTINT (pos) > BEGV
443 ? get_char_property_and_overlay (make_number (XINT (pos) - 1),
444 Qfield, Qnil,
445 &before_overlay)
446 : Qnil);
447
448 /* See if we need to handle the case where MERGE_AT_BOUNDARY is nil
449 and POS is at beginning of a field, which can also be interpreted
450 as the end of the previous field. Note that the case where if
451 MERGE_AT_BOUNDARY is non-nil (see function comment) is actually the
452 more natural one; then we avoid treating the beginning of a field
453 specially. */
454 if (NILP (merge_at_boundary) && !EQ (after_field, before_field))
455 /* We are at a boundary, see which direction is inclusive. We
456 decide by seeing which field the `field' property sticks to. */
457 {
458 /* -1 means insertions go into before_field, 1 means they go
459 into after_field, 0 means neither. */
460 int stickiness;
461 /* Whether the before/after_field come from overlays. */
462 int bop = !NILP (before_overlay);
463 int aop = !NILP (after_overlay);
464
465 if (bop && XMARKER (OVERLAY_END (before_overlay))->insertion_type == 1)
466 /* before_field is from an overlay, which expands upon
467 end-insertions. Note that it's possible for after_overlay to
468 also eat insertions here, but then they will overlap, and
469 there's not much we can do. */
470 stickiness = -1;
471 else if (aop
472 && XMARKER (OVERLAY_START (after_overlay))->insertion_type == 0)
473 /* after_field is from an overlay, which expand to contain
474 start-insertions. */
475 stickiness = 1;
476 else if (bop && aop)
477 /* Both fields come from overlays, but neither will contain any
478 insertion here. */
479 stickiness = 0;
480 else if (bop)
481 /* before_field is an overlay that won't eat any insertion, but
482 after_field is from a text-property. Assume that the
483 text-property continues underneath the overlay, and so will
484 be inherited by any insertion, regardless of any stickiness
485 settings. */
486 stickiness = 1;
487 else if (aop)
488 /* Similarly, when after_field is the overlay. */
489 stickiness = -1;
490 else
491 /* Both fields come from text-properties. Look for explicit
492 stickiness properties. */
493 stickiness = text_property_stickiness (Qfield, pos);
494
495 if (stickiness > 0)
496 at_field_start = 1;
497 else if (stickiness < 0)
498 at_field_end = 1;
499 else
500 /* STICKINESS == 0 means that any inserted text will get a
501 `field' char-property of nil, so check to see if that
502 matches either of the adjacent characters (this being a
503 kind of "stickiness by default"). */
504 {
505 if (NILP (before_field))
506 at_field_end = 1; /* Sticks to the left. */
507 else if (NILP (after_field))
508 at_field_start = 1; /* Sticks to the right. */
509 }
510 }
511
512 /* Note about special `boundary' fields:
513
514 Consider the case where the point (`.') is between the fields `x' and `y':
515
516 xxxx.yyyy
517
518 In this situation, if merge_at_boundary is true, we consider the
519 `x' and `y' fields as forming one big merged field, and so the end
520 of the field is the end of `y'.
521
522 However, if `x' and `y' are separated by a special `boundary' field
523 (a field with a `field' char-property of 'boundary), then we ignore
524 this special field when merging adjacent fields. Here's the same
525 situation, but with a `boundary' field between the `x' and `y' fields:
526
527 xxx.BBBByyyy
528
529 Here, if point is at the end of `x', the beginning of `y', or
530 anywhere in-between (within the `boundary' field), we merge all
531 three fields and consider the beginning as being the beginning of
532 the `x' field, and the end as being the end of the `y' field. */
533
534 if (beg)
535 {
536 if (at_field_start)
537 /* POS is at the edge of a field, and we should consider it as
538 the beginning of the following field. */
539 *beg = XFASTINT (pos);
540 else
541 /* Find the previous field boundary. */
542 {
543 if (!NILP (merge_at_boundary) && EQ (before_field, Qboundary))
544 /* Skip a `boundary' field. */
545 pos = Fprevious_single_char_property_change (pos, Qfield, Qnil,Qnil);
546
547 pos = Fprevious_single_char_property_change (pos, Qfield, Qnil, Qnil);
548 *beg = NILP (pos) ? BEGV : XFASTINT (pos);
549 }
550 }
551
552 if (end)
553 {
554 if (at_field_end)
555 /* POS is at the edge of a field, and we should consider it as
556 the end of the previous field. */
557 *end = XFASTINT (pos);
558 else
559 /* Find the next field boundary. */
560 {
561 if (!NILP (merge_at_boundary) && EQ (after_field, Qboundary))
562 /* Skip a `boundary' field. */
563 pos = Fnext_single_char_property_change (pos, Qfield, Qnil, Qnil);
564
565 pos = Fnext_single_char_property_change (pos, Qfield, Qnil, Qnil);
566 *end = NILP (pos) ? ZV : XFASTINT (pos);
567 }
568 }
569}
570
571\f
572DEFUN ("delete-field", Fdelete_field, Sdelete_field, 0, 1, 0,
573 doc: /* Delete the field surrounding POS.
574A field is a region of text with the same `field' property.
575If POS is nil, the value of point is used for POS. */)
576 (pos)
577 Lisp_Object pos;
578{
579 int beg, end;
580 find_field (pos, Qnil, &beg, &end);
581 if (beg != end)
582 del_range (beg, end);
583 return Qnil;
584}
585
586DEFUN ("field-string", Ffield_string, Sfield_string, 0, 1, 0,
587 doc: /* Return the contents of the field surrounding POS as a string.
588A field is a region of text with the same `field' property.
589If POS is nil, the value of point is used for POS. */)
590 (pos)
591 Lisp_Object pos;
592{
593 int beg, end;
594 find_field (pos, Qnil, &beg, &end);
595 return make_buffer_string (beg, end, 1);
596}
597
598DEFUN ("field-string-no-properties", Ffield_string_no_properties, Sfield_string_no_properties, 0, 1, 0,
599 doc: /* Return the contents of the field around POS, without text-properties.
600A field is a region of text with the same `field' property.
601If POS is nil, the value of point is used for POS. */)
602 (pos)
603 Lisp_Object pos;
604{
605 int beg, end;
606 find_field (pos, Qnil, &beg, &end);
607 return make_buffer_string (beg, end, 0);
608}
609
610DEFUN ("field-beginning", Ffield_beginning, Sfield_beginning, 0, 2, 0,
611 doc: /* Return the beginning of the field surrounding POS.
612A field is a region of text with the same `field' property.
613If POS is nil, the value of point is used for POS.
614If ESCAPE-FROM-EDGE is non-nil and POS is at the beginning of its
615field, then the beginning of the *previous* field is returned. */)
616 (pos, escape_from_edge)
617 Lisp_Object pos, escape_from_edge;
618{
619 int beg;
620 find_field (pos, escape_from_edge, &beg, 0);
621 return make_number (beg);
622}
623
624DEFUN ("field-end", Ffield_end, Sfield_end, 0, 2, 0,
625 doc: /* Return the end of the field surrounding POS.
626A field is a region of text with the same `field' property.
627If POS is nil, the value of point is used for POS.
628If ESCAPE-FROM-EDGE is non-nil and POS is at the end of its field,
629then the end of the *following* field is returned. */)
630 (pos, escape_from_edge)
631 Lisp_Object pos, escape_from_edge;
632{
633 int end;
634 find_field (pos, escape_from_edge, 0, &end);
635 return make_number (end);
636}
637
638DEFUN ("constrain-to-field", Fconstrain_to_field, Sconstrain_to_field, 2, 5, 0,
639 doc: /* Return the position closest to NEW-POS that is in the same field as OLD-POS.
640
641A field is a region of text with the same `field' property.
642If NEW-POS is nil, then the current point is used instead, and set to the
643constrained position if that is different.
644
645If OLD-POS is at the boundary of two fields, then the allowable
646positions for NEW-POS depends on the value of the optional argument
647ESCAPE-FROM-EDGE: If ESCAPE-FROM-EDGE is nil, then NEW-POS is
648constrained to the field that has the same `field' char-property
649as any new characters inserted at OLD-POS, whereas if ESCAPE-FROM-EDGE
650is non-nil, NEW-POS is constrained to the union of the two adjacent
651fields. Additionally, if two fields are separated by another field with
652the special value `boundary', then any point within this special field is
653also considered to be `on the boundary'.
654
655If the optional argument ONLY-IN-LINE is non-nil and constraining
656NEW-POS would move it to a different line, NEW-POS is returned
657unconstrained. This useful for commands that move by line, like
658\\[next-line] or \\[beginning-of-line], which should generally respect field boundaries
659only in the case where they can still move to the right line.
660
661If the optional argument INHIBIT-CAPTURE-PROPERTY is non-nil, and OLD-POS has
662a non-nil property of that name, then any field boundaries are ignored.
663
664Field boundaries are not noticed if `inhibit-field-text-motion' is non-nil. */)
665 (new_pos, old_pos, escape_from_edge, only_in_line, inhibit_capture_property)
666 Lisp_Object new_pos, old_pos;
667 Lisp_Object escape_from_edge, only_in_line, inhibit_capture_property;
668{
669 /* If non-zero, then the original point, before re-positioning. */
670 int orig_point = 0;
671
672 if (NILP (new_pos))
673 /* Use the current point, and afterwards, set it. */
674 {
675 orig_point = PT;
676 XSETFASTINT (new_pos, PT);
677 }
678
679 if (NILP (Vinhibit_field_text_motion)
680 && !EQ (new_pos, old_pos)
681 && (!NILP (Fget_char_property (new_pos, Qfield, Qnil))
682 || !NILP (Fget_char_property (old_pos, Qfield, Qnil)))
683 && (NILP (inhibit_capture_property)
684 || NILP (Fget_char_property(old_pos, inhibit_capture_property, Qnil))))
685 /* NEW_POS is not within the same field as OLD_POS; try to
686 move NEW_POS so that it is. */
687 {
688 int fwd, shortage;
689 Lisp_Object field_bound;
690
691 CHECK_NUMBER_COERCE_MARKER (new_pos, 0);
692 CHECK_NUMBER_COERCE_MARKER (old_pos, 0);
693
694 fwd = (XFASTINT (new_pos) > XFASTINT (old_pos));
695
696 if (fwd)
697 field_bound = Ffield_end (old_pos, escape_from_edge);
698 else
699 field_bound = Ffield_beginning (old_pos, escape_from_edge);
700
701 if (/* See if ESCAPE_FROM_EDGE caused FIELD_BOUND to jump to the
702 other side of NEW_POS, which would mean that NEW_POS is
703 already acceptable, and it's not necessary to constrain it
704 to FIELD_BOUND. */
705 ((XFASTINT (field_bound) < XFASTINT (new_pos)) ? fwd : !fwd)
706 /* NEW_POS should be constrained, but only if either
707 ONLY_IN_LINE is nil (in which case any constraint is OK),
708 or NEW_POS and FIELD_BOUND are on the same line (in which
709 case the constraint is OK even if ONLY_IN_LINE is non-nil). */
710 && (NILP (only_in_line)
711 /* This is the ONLY_IN_LINE case, check that NEW_POS and
712 FIELD_BOUND are on the same line by seeing whether
713 there's an intervening newline or not. */
714 || (scan_buffer ('\n',
715 XFASTINT (new_pos), XFASTINT (field_bound),
716 fwd ? -1 : 1, &shortage, 1),
717 shortage != 0)))
718 /* Constrain NEW_POS to FIELD_BOUND. */
719 new_pos = field_bound;
720
721 if (orig_point && XFASTINT (new_pos) != orig_point)
722 /* The NEW_POS argument was originally nil, so automatically set PT. */
723 SET_PT (XFASTINT (new_pos));
724 }
725
726 return new_pos;
727}
728
729\f
730DEFUN ("line-beginning-position",
731 Fline_beginning_position, Sline_beginning_position, 0, 1, 0,
732 doc: /* Return the character position of the first character on the current line.
733With argument N not nil or 1, move forward N - 1 lines first.
734If scan reaches end of buffer, return that position.
735
736The scan does not cross a field boundary unless doing so would move
737beyond there to a different line; if N is nil or 1, and scan starts at a
738field boundary, the scan stops as soon as it starts. To ignore field
739boundaries bind `inhibit-field-text-motion' to t.
740
741This function does not move point. */)
742 (n)
743 Lisp_Object n;
744{
745 int orig, orig_byte, end;
746
747 if (NILP (n))
748 XSETFASTINT (n, 1);
749 else
750 CHECK_NUMBER (n, 0);
751
752 orig = PT;
753 orig_byte = PT_BYTE;
754 Fforward_line (make_number (XINT (n) - 1));
755 end = PT;
756
757 SET_PT_BOTH (orig, orig_byte);
758
759 /* Return END constrained to the current input field. */
760 return Fconstrain_to_field (make_number (end), make_number (orig),
761 XINT (n) != 1 ? Qt : Qnil,
762 Qt, Qnil);
763}
764
765DEFUN ("line-end-position", Fline_end_position, Sline_end_position, 0, 1, 0,
766 doc: /* Return the character position of the last character on the current line.
767With argument N not nil or 1, move forward N - 1 lines first.
768If scan reaches end of buffer, return that position.
769
770The scan does not cross a field boundary unless doing so would move
771beyond there to a different line; if N is nil or 1, and scan starts at a
772field boundary, the scan stops as soon as it starts. To ignore field
773boundaries bind `inhibit-field-text-motion' to t.
774
775This function does not move point. */)
776 (n)
777 Lisp_Object n;
778{
779 int end_pos;
780 int orig = PT;
781
782 if (NILP (n))
783 XSETFASTINT (n, 1);
784 else
785 CHECK_NUMBER (n, 0);
786
787 end_pos = find_before_next_newline (orig, 0, XINT (n) - (XINT (n) <= 0));
788
789 /* Return END_POS constrained to the current input field. */
790 return Fconstrain_to_field (make_number (end_pos), make_number (orig),
791 Qnil, Qt, Qnil);
792}
793
794\f
795Lisp_Object
796save_excursion_save ()
797{
798 int visible = (XBUFFER (XWINDOW (selected_window)->buffer)
799 == current_buffer);
800
801 return Fcons (Fpoint_marker (),
802 Fcons (Fcopy_marker (current_buffer->mark, Qnil),
803 Fcons (visible ? Qt : Qnil,
804 Fcons (current_buffer->mark_active,
805 selected_window))));
806}
807
808Lisp_Object
809save_excursion_restore (info)
810 Lisp_Object info;
811{
812 Lisp_Object tem, tem1, omark, nmark;
813 struct gcpro gcpro1, gcpro2, gcpro3;
814 int visible_p;
815
816 tem = Fmarker_buffer (XCAR (info));
817 /* If buffer being returned to is now deleted, avoid error */
818 /* Otherwise could get error here while unwinding to top level
819 and crash */
820 /* In that case, Fmarker_buffer returns nil now. */
821 if (NILP (tem))
822 return Qnil;
823
824 omark = nmark = Qnil;
825 GCPRO3 (info, omark, nmark);
826
827 Fset_buffer (tem);
828
829 /* Point marker. */
830 tem = XCAR (info);
831 Fgoto_char (tem);
832 unchain_marker (tem);
833
834 /* Mark marker. */
835 info = XCDR (info);
836 tem = XCAR (info);
837 omark = Fmarker_position (current_buffer->mark);
838 Fset_marker (current_buffer->mark, tem, Fcurrent_buffer ());
839 nmark = Fmarker_position (tem);
840 unchain_marker (tem);
841
842 /* visible */
843 info = XCDR (info);
844 visible_p = !NILP (XCAR (info));
845
846#if 0 /* We used to make the current buffer visible in the selected window
847 if that was true previously. That avoids some anomalies.
848 But it creates others, and it wasn't documented, and it is simpler
849 and cleaner never to alter the window/buffer connections. */
850 tem1 = Fcar (tem);
851 if (!NILP (tem1)
852 && current_buffer != XBUFFER (XWINDOW (selected_window)->buffer))
853 Fswitch_to_buffer (Fcurrent_buffer (), Qnil);
854#endif /* 0 */
855
856 /* Mark active */
857 info = XCDR (info);
858 tem = XCAR (info);
859 tem1 = current_buffer->mark_active;
860 current_buffer->mark_active = tem;
861
862 if (!NILP (Vrun_hooks))
863 {
864 /* If mark is active now, and either was not active
865 or was at a different place, run the activate hook. */
866 if (! NILP (current_buffer->mark_active))
867 {
868 if (! EQ (omark, nmark))
869 call1 (Vrun_hooks, intern ("activate-mark-hook"));
870 }
871 /* If mark has ceased to be active, run deactivate hook. */
872 else if (! NILP (tem1))
873 call1 (Vrun_hooks, intern ("deactivate-mark-hook"));
874 }
875
876 /* If buffer was visible in a window, and a different window was
877 selected, and the old selected window is still showing this
878 buffer, restore point in that window. */
879 tem = XCDR (info);
880 if (visible_p
881 && !EQ (tem, selected_window)
882 && (tem1 = XWINDOW (tem)->buffer,
883 (/* Window is live... */
884 BUFFERP (tem1)
885 /* ...and it shows the current buffer. */
886 && XBUFFER (tem1) == current_buffer)))
887 Fset_window_point (tem, make_number (PT));
888
889 UNGCPRO;
890 return Qnil;
891}
892
893DEFUN ("save-excursion", Fsave_excursion, Ssave_excursion, 0, UNEVALLED, 0,
894 doc: /* Save point, mark, and current buffer; execute BODY; restore those things.
895Executes BODY just like `progn'.
896The values of point, mark and the current buffer are restored
897even in case of abnormal exit (throw or error).
898The state of activation of the mark is also restored.
899
900This construct does not save `deactivate-mark', and therefore
901functions that change the buffer will still cause deactivation
902of the mark at the end of the command. To prevent that, bind
903`deactivate-mark' with `let'. */)
904 (args)
905 Lisp_Object args;
906{
907 register Lisp_Object val;
908 int count = specpdl_ptr - specpdl;
909
910 record_unwind_protect (save_excursion_restore, save_excursion_save ());
911
912 val = Fprogn (args);
913 return unbind_to (count, val);
914}
915
916DEFUN ("save-current-buffer", Fsave_current_buffer, Ssave_current_buffer, 0, UNEVALLED, 0,
917 doc: /* Save the current buffer; execute BODY; restore the current buffer.
918Executes BODY just like `progn'. */)
919 (args)
920 Lisp_Object args;
921{
922 Lisp_Object val;
923 int count = specpdl_ptr - specpdl;
924
925 record_unwind_protect (set_buffer_if_live, Fcurrent_buffer ());
926
927 val = Fprogn (args);
928 return unbind_to (count, val);
929}
930\f
931DEFUN ("buffer-size", Fbufsize, Sbufsize, 0, 1, 0,
932 doc: /* Return the number of characters in the current buffer.
933If BUFFER, return the number of characters in that buffer instead. */)
934 (buffer)
935 Lisp_Object buffer;
936{
937 if (NILP (buffer))
938 return make_number (Z - BEG);
939 else
940 {
941 CHECK_BUFFER (buffer, 1);
942 return make_number (BUF_Z (XBUFFER (buffer))
943 - BUF_BEG (XBUFFER (buffer)));
944 }
945}
946
947DEFUN ("point-min", Fpoint_min, Spoint_min, 0, 0, 0,
948 doc: /* Return the minimum permissible value of point in the current buffer.
949This is 1, unless narrowing (a buffer restriction) is in effect. */)
950 ()
951{
952 Lisp_Object temp;
953 XSETFASTINT (temp, BEGV);
954 return temp;
955}
956
957DEFUN ("point-min-marker", Fpoint_min_marker, Spoint_min_marker, 0, 0, 0,
958 doc: /* Return a marker to the minimum permissible value of point in this buffer.
959This is the beginning, unless narrowing (a buffer restriction) is in effect. */)
960 ()
961{
962 return buildmark (BEGV, BEGV_BYTE);
963}
964
965DEFUN ("point-max", Fpoint_max, Spoint_max, 0, 0, 0,
966 doc: /* Return the maximum permissible value of point in the current buffer.
967This is (1+ (buffer-size)), unless narrowing (a buffer restriction)
968is in effect, in which case it is less. */)
969 ()
970{
971 Lisp_Object temp;
972 XSETFASTINT (temp, ZV);
973 return temp;
974}
975
976DEFUN ("point-max-marker", Fpoint_max_marker, Spoint_max_marker, 0, 0, 0,
977 doc: /* Return a marker to the maximum permissible value of point in this buffer.
978This is (1+ (buffer-size)), unless narrowing (a buffer restriction)
979is in effect, in which case it is less. */)
980 ()
981{
982 return buildmark (ZV, ZV_BYTE);
983}
984
985DEFUN ("gap-position", Fgap_position, Sgap_position, 0, 0, 0,
986 doc: /* Return the position of the gap, in the current buffer.
987See also `gap-size'. */)
988 ()
989{
990 Lisp_Object temp;
991 XSETFASTINT (temp, GPT);
992 return temp;
993}
994
995DEFUN ("gap-size", Fgap_size, Sgap_size, 0, 0, 0,
996 doc: /* Return the size of the current buffer's gap.
997See also `gap-position'. */)
998 ()
999{
1000 Lisp_Object temp;
1001 XSETFASTINT (temp, GAP_SIZE);
1002 return temp;
1003}
1004
1005DEFUN ("position-bytes", Fposition_bytes, Sposition_bytes, 1, 1, 0,
1006 doc: /* Return the byte position for character position POSITION.
1007If POSITION is out of range, the value is nil. */)
1008 (position)
1009 Lisp_Object position;
1010{
1011 CHECK_NUMBER_COERCE_MARKER (position, 1);
1012 if (XINT (position) < BEG || XINT (position) > Z)
1013 return Qnil;
1014 return make_number (CHAR_TO_BYTE (XINT (position)));
1015}
1016
1017DEFUN ("byte-to-position", Fbyte_to_position, Sbyte_to_position, 1, 1, 0,
1018 doc: /* Return the character position for byte position BYTEPOS.
1019If BYTEPOS is out of range, the value is nil. */)
1020 (bytepos)
1021 Lisp_Object bytepos;
1022{
1023 CHECK_NUMBER (bytepos, 1);
1024 if (XINT (bytepos) < BEG_BYTE || XINT (bytepos) > Z_BYTE)
1025 return Qnil;
1026 return make_number (BYTE_TO_CHAR (XINT (bytepos)));
1027}
1028\f
1029DEFUN ("following-char", Ffollowing_char, Sfollowing_char, 0, 0, 0,
1030 doc: /* Return the character following point, as a number.
1031At the end of the buffer or accessible region, return 0. */)
1032 ()
1033{
1034 Lisp_Object temp;
1035 if (PT >= ZV)
1036 XSETFASTINT (temp, 0);
1037 else
1038 XSETFASTINT (temp, FETCH_CHAR (PT_BYTE));
1039 return temp;
1040}
1041
1042DEFUN ("preceding-char", Fprevious_char, Sprevious_char, 0, 0, 0,
1043 doc: /* Return the character preceding point, as a number.
1044At the beginning of the buffer or accessible region, return 0. */)
1045 ()
1046{
1047 Lisp_Object temp;
1048 if (PT <= BEGV)
1049 XSETFASTINT (temp, 0);
1050 else if (!NILP (current_buffer->enable_multibyte_characters))
1051 {
1052 int pos = PT_BYTE;
1053 DEC_POS (pos);
1054 XSETFASTINT (temp, FETCH_CHAR (pos));
1055 }
1056 else
1057 XSETFASTINT (temp, FETCH_BYTE (PT_BYTE - 1));
1058 return temp;
1059}
1060
1061DEFUN ("bobp", Fbobp, Sbobp, 0, 0, 0,
1062 doc: /* Return t if point is at the beginning of the buffer.
1063If the buffer is narrowed, this means the beginning of the narrowed part. */)
1064 ()
1065{
1066 if (PT == BEGV)
1067 return Qt;
1068 return Qnil;
1069}
1070
1071DEFUN ("eobp", Feobp, Seobp, 0, 0, 0,
1072 doc: /* Return t if point is at the end of the buffer.
1073If the buffer is narrowed, this means the end of the narrowed part. */)
1074 ()
1075{
1076 if (PT == ZV)
1077 return Qt;
1078 return Qnil;
1079}
1080
1081DEFUN ("bolp", Fbolp, Sbolp, 0, 0, 0,
1082 doc: /* Return t if point is at the beginning of a line. */)
1083 ()
1084{
1085 if (PT == BEGV || FETCH_BYTE (PT_BYTE - 1) == '\n')
1086 return Qt;
1087 return Qnil;
1088}
1089
1090DEFUN ("eolp", Feolp, Seolp, 0, 0, 0,
1091 doc: /* Return t if point is at the end of a line.
1092`End of a line' includes point being at the end of the buffer. */)
1093 ()
1094{
1095 if (PT == ZV || FETCH_BYTE (PT_BYTE) == '\n')
1096 return Qt;
1097 return Qnil;
1098}
1099
1100DEFUN ("char-after", Fchar_after, Schar_after, 0, 1, 0,
1101 doc: /* Return character in current buffer at position POS.
1102POS is an integer or a marker.
1103If POS is out of range, the value is nil. */)
1104 (pos)
1105 Lisp_Object pos;
1106{
1107 register int pos_byte;
1108
1109 if (NILP (pos))
1110 {
1111 pos_byte = PT_BYTE;
1112 XSETFASTINT (pos, PT);
1113 }
1114
1115 if (MARKERP (pos))
1116 {
1117 pos_byte = marker_byte_position (pos);
1118 if (pos_byte < BEGV_BYTE || pos_byte >= ZV_BYTE)
1119 return Qnil;
1120 }
1121 else
1122 {
1123 CHECK_NUMBER_COERCE_MARKER (pos, 0);
1124 if (XINT (pos) < BEGV || XINT (pos) >= ZV)
1125 return Qnil;
1126
1127 pos_byte = CHAR_TO_BYTE (XINT (pos));
1128 }
1129
1130 return make_number (FETCH_CHAR (pos_byte));
1131}
1132
1133DEFUN ("char-before", Fchar_before, Schar_before, 0, 1, 0,
1134 doc: /* Return character in current buffer preceding position POS.
1135POS is an integer or a marker.
1136If POS is out of range, the value is nil. */)
1137 (pos)
1138 Lisp_Object pos;
1139{
1140 register Lisp_Object val;
1141 register int pos_byte;
1142
1143 if (NILP (pos))
1144 {
1145 pos_byte = PT_BYTE;
1146 XSETFASTINT (pos, PT);
1147 }
1148
1149 if (MARKERP (pos))
1150 {
1151 pos_byte = marker_byte_position (pos);
1152
1153 if (pos_byte <= BEGV_BYTE || pos_byte > ZV_BYTE)
1154 return Qnil;
1155 }
1156 else
1157 {
1158 CHECK_NUMBER_COERCE_MARKER (pos, 0);
1159
1160 if (XINT (pos) <= BEGV || XINT (pos) > ZV)
1161 return Qnil;
1162
1163 pos_byte = CHAR_TO_BYTE (XINT (pos));
1164 }
1165
1166 if (!NILP (current_buffer->enable_multibyte_characters))
1167 {
1168 DEC_POS (pos_byte);
1169 XSETFASTINT (val, FETCH_CHAR (pos_byte));
1170 }
1171 else
1172 {
1173 pos_byte--;
1174 XSETFASTINT (val, FETCH_BYTE (pos_byte));
1175 }
1176 return val;
1177}
1178\f
1179DEFUN ("user-login-name", Fuser_login_name, Suser_login_name, 0, 1, 0,
1180 doc: /* Return the name under which the user logged in, as a string.
1181This is based on the effective uid, not the real uid.
1182Also, if the environment variable LOGNAME or USER is set,
1183that determines the value of this function.
1184
1185If optional argument UID is an integer, return the login name of the user
1186with that uid, or nil if there is no such user. */)
1187 (uid)
1188 Lisp_Object uid;
1189{
1190 struct passwd *pw;
1191
1192 /* Set up the user name info if we didn't do it before.
1193 (That can happen if Emacs is dumpable
1194 but you decide to run `temacs -l loadup' and not dump. */
1195 if (INTEGERP (Vuser_login_name))
1196 init_editfns ();
1197
1198 if (NILP (uid))
1199 return Vuser_login_name;
1200
1201 CHECK_NUMBER (uid, 0);
1202 pw = (struct passwd *) getpwuid (XINT (uid));
1203 return (pw ? build_string (pw->pw_name) : Qnil);
1204}
1205
1206DEFUN ("user-real-login-name", Fuser_real_login_name, Suser_real_login_name,
1207 0, 0, 0,
1208 doc: /* Return the name of the user's real uid, as a string.
1209This ignores the environment variables LOGNAME and USER, so it differs from
1210`user-login-name' when running under `su'. */)
1211 ()
1212{
1213 /* Set up the user name info if we didn't do it before.
1214 (That can happen if Emacs is dumpable
1215 but you decide to run `temacs -l loadup' and not dump. */
1216 if (INTEGERP (Vuser_login_name))
1217 init_editfns ();
1218 return Vuser_real_login_name;
1219}
1220
1221DEFUN ("user-uid", Fuser_uid, Suser_uid, 0, 0, 0,
1222 doc: /* Return the effective uid of Emacs.
1223Value is an integer or float, depending on the value. */)
1224 ()
1225{
1226 return make_fixnum_or_float (geteuid ());
1227}
1228
1229DEFUN ("user-real-uid", Fuser_real_uid, Suser_real_uid, 0, 0, 0,
1230 doc: /* Return the real uid of Emacs.
1231Value is an integer or float, depending on the value. */)
1232 ()
1233{
1234 return make_fixnum_or_float (getuid ());
1235}
1236
1237DEFUN ("user-full-name", Fuser_full_name, Suser_full_name, 0, 1, 0,
1238 doc: /* Return the full name of the user logged in, as a string.
1239If the full name corresponding to Emacs's userid is not known,
1240return "unknown".
1241
1242If optional argument UID is an integer or float, return the full name
1243of the user with that uid, or nil if there is no such user.
1244If UID is a string, return the full name of the user with that login
1245name, or nil if there is no such user. */)
1246 (uid)
1247 Lisp_Object uid;
1248{
1249 struct passwd *pw;
1250 register unsigned char *p, *q;
1251 Lisp_Object full;
1252
1253 if (NILP (uid))
1254 return Vuser_full_name;
1255 else if (NUMBERP (uid))
1256 pw = (struct passwd *) getpwuid ((uid_t) XFLOATINT (uid));
1257 else if (STRINGP (uid))
1258 pw = (struct passwd *) getpwnam (XSTRING (uid)->data);
1259 else
1260 error ("Invalid UID specification");
1261
1262 if (!pw)
1263 return Qnil;
1264
1265 p = (unsigned char *) USER_FULL_NAME;
1266 /* Chop off everything after the first comma. */
1267 q = (unsigned char *) index (p, ',');
1268 full = make_string (p, q ? q - p : strlen (p));
1269
1270#ifdef AMPERSAND_FULL_NAME
1271 p = XSTRING (full)->data;
1272 q = (unsigned char *) index (p, '&');
1273 /* Substitute the login name for the &, upcasing the first character. */
1274 if (q)
1275 {
1276 register unsigned char *r;
1277 Lisp_Object login;
1278
1279 login = Fuser_login_name (make_number (pw->pw_uid));
1280 r = (unsigned char *) alloca (strlen (p) + XSTRING (login)->size + 1);
1281 bcopy (p, r, q - p);
1282 r[q - p] = 0;
1283 strcat (r, XSTRING (login)->data);
1284 r[q - p] = UPCASE (r[q - p]);
1285 strcat (r, q + 1);
1286 full = build_string (r);
1287 }
1288#endif /* AMPERSAND_FULL_NAME */
1289
1290 return full;
1291}
1292
1293DEFUN ("system-name", Fsystem_name, Ssystem_name, 0, 0, 0,
1294 doc: /* Return the name of the machine you are running on, as a string. */)
1295 ()
1296{
1297 return Vsystem_name;
1298}
1299
1300/* For the benefit of callers who don't want to include lisp.h */
1301
1302char *
1303get_system_name ()
1304{
1305 if (STRINGP (Vsystem_name))
1306 return (char *) XSTRING (Vsystem_name)->data;
1307 else
1308 return "";
1309}
1310
1311DEFUN ("emacs-pid", Femacs_pid, Semacs_pid, 0, 0, 0,
1312 doc: /* Return the process ID of Emacs, as an integer. */)
1313 ()
1314{
1315 return make_number (getpid ());
1316}
1317
1318DEFUN ("current-time", Fcurrent_time, Scurrent_time, 0, 0, 0,
1319 doc: /* Return the current time, as the number of seconds since 1970-01-01 00:00:00.
1320The time is returned as a list of three integers. The first has the
1321most significant 16 bits of the seconds, while the second has the
1322least significant 16 bits. The third integer gives the microsecond
1323count.
1324
1325The microsecond count is zero on systems that do not provide
1326resolution finer than a second. */)
1327 ()
1328{
1329 EMACS_TIME t;
1330 Lisp_Object result[3];
1331
1332 EMACS_GET_TIME (t);
1333 XSETINT (result[0], (EMACS_SECS (t) >> 16) & 0xffff);
1334 XSETINT (result[1], (EMACS_SECS (t) >> 0) & 0xffff);
1335 XSETINT (result[2], EMACS_USECS (t));
1336
1337 return Flist (3, result);
1338}
1339\f
1340
1341static int
1342lisp_time_argument (specified_time, result, usec)
1343 Lisp_Object specified_time;
1344 time_t *result;
1345 int *usec;
1346{
1347 if (NILP (specified_time))
1348 {
1349 if (usec)
1350 {
1351 EMACS_TIME t;
1352
1353 EMACS_GET_TIME (t);
1354 *usec = EMACS_USECS (t);
1355 *result = EMACS_SECS (t);
1356 return 1;
1357 }
1358 else
1359 return time (result) != -1;
1360 }
1361 else
1362 {
1363 Lisp_Object high, low;
1364 high = Fcar (specified_time);
1365 CHECK_NUMBER (high, 0);
1366 low = Fcdr (specified_time);
1367 if (CONSP (low))
1368 {
1369 if (usec)
1370 {
1371 Lisp_Object usec_l = Fcdr (low);
1372 if (CONSP (usec_l))
1373 usec_l = Fcar (usec_l);
1374 if (NILP (usec_l))
1375 *usec = 0;
1376 else
1377 {
1378 CHECK_NUMBER (usec_l, 0);
1379 *usec = XINT (usec_l);
1380 }
1381 }
1382 low = Fcar (low);
1383 }
1384 else if (usec)
1385 *usec = 0;
1386 CHECK_NUMBER (low, 0);
1387 *result = (XINT (high) << 16) + (XINT (low) & 0xffff);
1388 return *result >> 16 == XINT (high);
1389 }
1390}
1391
1392DEFUN ("float-time", Ffloat_time, Sfloat_time, 0, 1, 0,
1393 doc: /* Return the current time, as a float number of seconds since the epoch.
1394If an argument is given, it specifies a time to convert to float
1395instead of the current time. The argument should have the forms:
1396 (HIGH . LOW) or (HIGH LOW USEC) or (HIGH LOW . USEC).
1397Thus, you can use times obtained from `current-time'
1398and from `file-attributes'.
1399
1400WARNING: Since the result is floating point, it may not be exact.
1401Do not use this function if precise time stamps are required. */)
1402 (specified_time)
1403 Lisp_Object specified_time;
1404{
1405 time_t sec;
1406 int usec;
1407
1408 if (! lisp_time_argument (specified_time, &sec, &usec))
1409 error ("Invalid time specification");
1410
1411 return make_float ((sec * 1e6 + usec) / 1e6);
1412}
1413
1414/* Write information into buffer S of size MAXSIZE, according to the
1415 FORMAT of length FORMAT_LEN, using time information taken from *TP.
1416 Default to Universal Time if UT is nonzero, local time otherwise.
1417 Return the number of bytes written, not including the terminating
1418 '\0'. If S is NULL, nothing will be written anywhere; so to
1419 determine how many bytes would be written, use NULL for S and
1420 ((size_t) -1) for MAXSIZE.
1421
1422 This function behaves like emacs_strftimeu, except it allows null
1423 bytes in FORMAT. */
1424static size_t
1425emacs_memftimeu (s, maxsize, format, format_len, tp, ut)
1426 char *s;
1427 size_t maxsize;
1428 const char *format;
1429 size_t format_len;
1430 const struct tm *tp;
1431 int ut;
1432{
1433 size_t total = 0;
1434
1435 /* Loop through all the null-terminated strings in the format
1436 argument. Normally there's just one null-terminated string, but
1437 there can be arbitrarily many, concatenated together, if the
1438 format contains '\0' bytes. emacs_strftimeu stops at the first
1439 '\0' byte so we must invoke it separately for each such string. */
1440 for (;;)
1441 {
1442 size_t len;
1443 size_t result;
1444
1445 if (s)
1446 s[0] = '\1';
1447
1448 result = emacs_strftimeu (s, maxsize, format, tp, ut);
1449
1450 if (s)
1451 {
1452 if (result == 0 && s[0] != '\0')
1453 return 0;
1454 s += result + 1;
1455 }
1456
1457 maxsize -= result + 1;
1458 total += result;
1459 len = strlen (format);
1460 if (len == format_len)
1461 return total;
1462 total++;
1463 format += len + 1;
1464 format_len -= len + 1;
1465 }
1466}
1467
1468DEFUN ("format-time-string", Fformat_time_string, Sformat_time_string, 1, 3, 0,
1469 doc: /* Use FORMAT-STRING to format the time TIME, or now if omitted.
1470TIME is specified as (HIGH LOW . IGNORED) or (HIGH . LOW), as returned by
1471`current-time' or `file-attributes'.
1472The third, optional, argument UNIVERSAL, if non-nil, means describe TIME
1473as Universal Time; nil means describe TIME in the local time zone.
1474The value is a copy of FORMAT-STRING, but with certain constructs replaced
1475by text that describes the specified date and time in TIME:
1476
1477%Y is the year, %y within the century, %C the century.
1478%G is the year corresponding to the ISO week, %g within the century.
1479%m is the numeric month.
1480%b and %h are the locale's abbreviated month name, %B the full name.
1481%d is the day of the month, zero-padded, %e is blank-padded.
1482%u is the numeric day of week from 1 (Monday) to 7, %w from 0 (Sunday) to 6.
1483%a is the locale's abbreviated name of the day of week, %A the full name.
1484%U is the week number starting on Sunday, %W starting on Monday,
1485 %V according to ISO 8601.
1486%j is the day of the year.
1487
1488%H is the hour on a 24-hour clock, %I is on a 12-hour clock, %k is like %H
1489 only blank-padded, %l is like %I blank-padded.
1490%p is the locale's equivalent of either AM or PM.
1491%M is the minute.
1492%S is the second.
1493%Z is the time zone name, %z is the numeric form.
1494%s is the number of seconds since 1970-01-01 00:00:00 +0000.
1495
1496%c is the locale's date and time format.
1497%x is the locale's "preferred" date format.
1498%D is like "%m/%d/%y".
1499
1500%R is like "%H:%M", %T is like "%H:%M:%S", %r is like "%I:%M:%S %p".
1501%X is the locale's "preferred" time format.
1502
1503Finally, %n is a newline, %t is a tab, %% is a literal %.
1504
1505Certain flags and modifiers are available with some format controls.
1506The flags are `_', `-', `^' and `#'. For certain characters X,
1507%_X is like %X, but padded with blanks; %-X is like %X,
1508ut without padding. %^X is like %X but with all textual
1509characters up-cased; %#X is like %X but with letter-case of
1510all textual characters reversed.
1511%NX (where N stands for an integer) is like %X,
1512but takes up at least N (a number) positions.
1513The modifiers are `E' and `O'. For certain characters X,
1514%EX is a locale's alternative version of %X;
1515%OX is like %X, but uses the locale's number symbols.
1516
1517For example, to produce full ISO 8601 format, use "%Y-%m-%dT%T%z". */)
1518 (format_string, time, universal)
1519 Lisp_Object format_string, time, universal;
1520{
1521 time_t value;
1522 int size;
1523 struct tm *tm;
1524 int ut = ! NILP (universal);
1525
1526 CHECK_STRING (format_string, 1);
1527
1528 if (! lisp_time_argument (time, &value, NULL))
1529 error ("Invalid time specification");
1530
1531 format_string = code_convert_string_norecord (format_string,
1532 Vlocale_coding_system, 1);
1533
1534 /* This is probably enough. */
1535 size = STRING_BYTES (XSTRING (format_string)) * 6 + 50;
1536
1537 tm = ut ? gmtime (&value) : localtime (&value);
1538 if (! tm)
1539 error ("Specified time is not representable");
1540
1541 synchronize_system_time_locale ();
1542
1543 while (1)
1544 {
1545 char *buf = (char *) alloca (size + 1);
1546 int result;
1547
1548 buf[0] = '\1';
1549 result = emacs_memftimeu (buf, size, XSTRING (format_string)->data,
1550 STRING_BYTES (XSTRING (format_string)),
1551 tm, ut);
1552 if ((result > 0 && result < size) || (result == 0 && buf[0] == '\0'))
1553 return code_convert_string_norecord (make_string (buf, result),
1554 Vlocale_coding_system, 0);
1555
1556 /* If buffer was too small, make it bigger and try again. */
1557 result = emacs_memftimeu (NULL, (size_t) -1,
1558 XSTRING (format_string)->data,
1559 STRING_BYTES (XSTRING (format_string)),
1560 tm, ut);
1561 size = result + 1;
1562 }
1563}
1564
1565DEFUN ("decode-time", Fdecode_time, Sdecode_time, 0, 1, 0,
1566 doc: /* Decode a time value as (SEC MINUTE HOUR DAY MONTH YEAR DOW DST ZONE).
1567The optional SPECIFIED-TIME should be a list of (HIGH LOW . IGNORED)
1568or (HIGH . LOW), as from `current-time' and `file-attributes', or `nil'
1569to use the current time. The list has the following nine members:
1570SEC is an integer between 0 and 60; SEC is 60 for a leap second, which
1571only some operating systems support. MINUTE is an integer between 0 and 59.
1572HOUR is an integer between 0 and 23. DAY is an integer between 1 and 31.
1573MONTH is an integer between 1 and 12. YEAR is an integer indicating the
1574four-digit year. DOW is the day of week, an integer between 0 and 6, where
15750 is Sunday. DST is t if daylight savings time is effect, otherwise nil.
1576ZONE is an integer indicating the number of seconds east of Greenwich.
1577(Note that Common Lisp has different meanings for DOW and ZONE.) */)
1578 (specified_time)
1579 Lisp_Object specified_time;
1580{
1581 time_t time_spec;
1582 struct tm save_tm;
1583 struct tm *decoded_time;
1584 Lisp_Object list_args[9];
1585
1586 if (! lisp_time_argument (specified_time, &time_spec, NULL))
1587 error ("Invalid time specification");
1588
1589 decoded_time = localtime (&time_spec);
1590 if (! decoded_time)
1591 error ("Specified time is not representable");
1592 XSETFASTINT (list_args[0], decoded_time->tm_sec);
1593 XSETFASTINT (list_args[1], decoded_time->tm_min);
1594 XSETFASTINT (list_args[2], decoded_time->tm_hour);
1595 XSETFASTINT (list_args[3], decoded_time->tm_mday);
1596 XSETFASTINT (list_args[4], decoded_time->tm_mon + 1);
1597 XSETINT (list_args[5], decoded_time->tm_year + 1900);
1598 XSETFASTINT (list_args[6], decoded_time->tm_wday);
1599 list_args[7] = (decoded_time->tm_isdst)? Qt : Qnil;
1600
1601 /* Make a copy, in case gmtime modifies the struct. */
1602 save_tm = *decoded_time;
1603 decoded_time = gmtime (&time_spec);
1604 if (decoded_time == 0)
1605 list_args[8] = Qnil;
1606 else
1607 XSETINT (list_args[8], tm_diff (&save_tm, decoded_time));
1608 return Flist (9, list_args);
1609}
1610
1611DEFUN ("encode-time", Fencode_time, Sencode_time, 6, MANY, 0,
1612 doc: /* Convert SECOND, MINUTE, HOUR, DAY, MONTH, YEAR and ZONE to internal time.
1613This is the reverse operation of `decode-time', which see.
1614ZONE defaults to the current time zone rule. This can
1615be a string or t (as from `set-time-zone-rule'), or it can be a list
1616\(as from `current-time-zone') or an integer (as from `decode-time')
1617applied without consideration for daylight savings time.
1618
1619You can pass more than 7 arguments; then the first six arguments
1620are used as SECOND through YEAR, and the *last* argument is used as ZONE.
1621The intervening arguments are ignored.
1622This feature lets (apply 'encode-time (decode-time ...)) work.
1623
1624Out-of-range values for SEC, MINUTE, HOUR, DAY, or MONTH are allowed;
1625for example, a DAY of 0 means the day preceding the given month.
1626Year numbers less than 100 are treated just like other year numbers.
1627If you want them to stand for years in this century, you must do that yourself. */)
1628 (nargs, args)
1629 int nargs;
1630 register Lisp_Object *args;
1631{
1632 time_t time;
1633 struct tm tm;
1634 Lisp_Object zone = (nargs > 6 ? args[nargs - 1] : Qnil);
1635
1636 CHECK_NUMBER (args[0], 0); /* second */
1637 CHECK_NUMBER (args[1], 1); /* minute */
1638 CHECK_NUMBER (args[2], 2); /* hour */
1639 CHECK_NUMBER (args[3], 3); /* day */
1640 CHECK_NUMBER (args[4], 4); /* month */
1641 CHECK_NUMBER (args[5], 5); /* year */
1642
1643 tm.tm_sec = XINT (args[0]);
1644 tm.tm_min = XINT (args[1]);
1645 tm.tm_hour = XINT (args[2]);
1646 tm.tm_mday = XINT (args[3]);
1647 tm.tm_mon = XINT (args[4]) - 1;
1648 tm.tm_year = XINT (args[5]) - 1900;
1649 tm.tm_isdst = -1;
1650
1651 if (CONSP (zone))
1652 zone = Fcar (zone);
1653 if (NILP (zone))
1654 time = mktime (&tm);
1655 else
1656 {
1657 char tzbuf[100];
1658 char *tzstring;
1659 char **oldenv = environ, **newenv;
1660
1661 if (EQ (zone, Qt))
1662 tzstring = "UTC0";
1663 else if (STRINGP (zone))
1664 tzstring = (char *) XSTRING (zone)->data;
1665 else if (INTEGERP (zone))
1666 {
1667 int abszone = abs (XINT (zone));
1668 sprintf (tzbuf, "XXX%s%d:%02d:%02d", "-" + (XINT (zone) < 0),
1669 abszone / (60*60), (abszone/60) % 60, abszone % 60);
1670 tzstring = tzbuf;
1671 }
1672 else
1673 error ("Invalid time zone specification");
1674
1675 /* Set TZ before calling mktime; merely adjusting mktime's returned
1676 value doesn't suffice, since that would mishandle leap seconds. */
1677 set_time_zone_rule (tzstring);
1678
1679 time = mktime (&tm);
1680
1681 /* Restore TZ to previous value. */
1682 newenv = environ;
1683 environ = oldenv;
1684 xfree (newenv);
1685#ifdef LOCALTIME_CACHE
1686 tzset ();
1687#endif
1688 }
1689
1690 if (time == (time_t) -1)
1691 error ("Specified time is not representable");
1692
1693 return make_time (time);
1694}
1695
1696DEFUN ("current-time-string", Fcurrent_time_string, Scurrent_time_string, 0, 1, 0,
1697 doc: /* Return the current time, as a human-readable string.
1698Programs can use this function to decode a time,
1699since the number of columns in each field is fixed.
1700The format is `Sun Sep 16 01:03:52 1973'.
1701However, see also the functions `decode-time' and `format-time-string'
1702which provide a much more powerful and general facility.
1703
1704If an argument is given, it specifies a time to format
1705instead of the current time. The argument should have the form:
1706 (HIGH . LOW)
1707or the form:
1708 (HIGH LOW . IGNORED).
1709Thus, you can use times obtained from `current-time'
1710and from `file-attributes'. */)
1711 (specified_time)
1712 Lisp_Object specified_time;
1713{
1714 time_t value;
1715 char buf[30];
1716 register char *tem;
1717
1718 if (! lisp_time_argument (specified_time, &value, NULL))
1719 value = -1;
1720 tem = (char *) ctime (&value);
1721
1722 strncpy (buf, tem, 24);
1723 buf[24] = 0;
1724
1725 return build_string (buf);
1726}
1727
1728#define TM_YEAR_BASE 1900
1729
1730/* Yield A - B, measured in seconds.
1731 This function is copied from the GNU C Library. */
1732static int
1733tm_diff (a, b)
1734 struct tm *a, *b;
1735{
1736 /* Compute intervening leap days correctly even if year is negative.
1737 Take care to avoid int overflow in leap day calculations,
1738 but it's OK to assume that A and B are close to each other. */
1739 int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
1740 int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
1741 int a100 = a4 / 25 - (a4 % 25 < 0);
1742 int b100 = b4 / 25 - (b4 % 25 < 0);
1743 int a400 = a100 >> 2;
1744 int b400 = b100 >> 2;
1745 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
1746 int years = a->tm_year - b->tm_year;
1747 int days = (365 * years + intervening_leap_days
1748 + (a->tm_yday - b->tm_yday));
1749 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
1750 + (a->tm_min - b->tm_min))
1751 + (a->tm_sec - b->tm_sec));
1752}
1753
1754DEFUN ("current-time-zone", Fcurrent_time_zone, Scurrent_time_zone, 0, 1, 0,
1755 doc: /* Return the offset and name for the local time zone.
1756This returns a list of the form (OFFSET NAME).
1757OFFSET is an integer number of seconds ahead of UTC (east of Greenwich).
1758 A negative value means west of Greenwich.
1759NAME is a string giving the name of the time zone.
1760If an argument is given, it specifies when the time zone offset is determined
1761instead of using the current time. The argument should have the form:
1762 (HIGH . LOW)
1763or the form:
1764 (HIGH LOW . IGNORED).
1765Thus, you can use times obtained from `current-time'
1766and from `file-attributes'.
1767
1768Some operating systems cannot provide all this information to Emacs;
1769in this case, `current-time-zone' returns a list containing nil for
1770the data it can't find. */)
1771 (specified_time)
1772 Lisp_Object specified_time;
1773{
1774 time_t value;
1775 struct tm *t;
1776 struct tm gmt;
1777
1778 if (lisp_time_argument (specified_time, &value, NULL)
1779 && (t = gmtime (&value)) != 0
1780 && (gmt = *t, t = localtime (&value)) != 0)
1781 {
1782 int offset = tm_diff (t, &gmt);
1783 char *s = 0;
1784 char buf[6];
1785#ifdef HAVE_TM_ZONE
1786 if (t->tm_zone)
1787 s = (char *)t->tm_zone;
1788#else /* not HAVE_TM_ZONE */
1789#ifdef HAVE_TZNAME
1790 if (t->tm_isdst == 0 || t->tm_isdst == 1)
1791 s = tzname[t->tm_isdst];
1792#endif
1793#endif /* not HAVE_TM_ZONE */
1794
1795#if defined HAVE_TM_ZONE || defined HAVE_TZNAME
1796 if (s)
1797 {
1798 /* On Japanese w32, we can get a Japanese string as time
1799 zone name. Don't accept that. */
1800 char *p;
1801 for (p = s; *p && (isalnum ((unsigned char)*p) || *p == ' '); ++p)
1802 ;
1803 if (p == s || *p)
1804 s = NULL;
1805 }
1806#endif
1807
1808 if (!s)
1809 {
1810 /* No local time zone name is available; use "+-NNNN" instead. */
1811 int am = (offset < 0 ? -offset : offset) / 60;
1812 sprintf (buf, "%c%02d%02d", (offset < 0 ? '-' : '+'), am/60, am%60);
1813 s = buf;
1814 }
1815 return Fcons (make_number (offset), Fcons (build_string (s), Qnil));
1816 }
1817 else
1818 return Fmake_list (make_number (2), Qnil);
1819}
1820
1821/* This holds the value of `environ' produced by the previous
1822 call to Fset_time_zone_rule, or 0 if Fset_time_zone_rule
1823 has never been called. */
1824static char **environbuf;
1825
1826DEFUN ("set-time-zone-rule", Fset_time_zone_rule, Sset_time_zone_rule, 1, 1, 0,
1827 doc: /* Set the local time zone using TZ, a string specifying a time zone rule.
1828If TZ is nil, use implementation-defined default time zone information.
1829If TZ is t, use Universal Time. */)
1830 (tz)
1831 Lisp_Object tz;
1832{
1833 char *tzstring;
1834
1835 if (NILP (tz))
1836 tzstring = 0;
1837 else if (EQ (tz, Qt))
1838 tzstring = "UTC0";
1839 else
1840 {
1841 CHECK_STRING (tz, 0);
1842 tzstring = (char *) XSTRING (tz)->data;
1843 }
1844
1845 set_time_zone_rule (tzstring);
1846 if (environbuf)
1847 free (environbuf);
1848 environbuf = environ;
1849
1850 return Qnil;
1851}
1852
1853#ifdef LOCALTIME_CACHE
1854
1855/* These two values are known to load tz files in buggy implementations,
1856 i.e. Solaris 1 executables running under either Solaris 1 or Solaris 2.
1857 Their values shouldn't matter in non-buggy implementations.
1858 We don't use string literals for these strings,
1859 since if a string in the environment is in readonly
1860 storage, it runs afoul of bugs in SVR4 and Solaris 2.3.
1861 See Sun bugs 1113095 and 1114114, ``Timezone routines
1862 improperly modify environment''. */
1863
1864static char set_time_zone_rule_tz1[] = "TZ=GMT+0";
1865static char set_time_zone_rule_tz2[] = "TZ=GMT+1";
1866
1867#endif
1868
1869/* Set the local time zone rule to TZSTRING.
1870 This allocates memory into `environ', which it is the caller's
1871 responsibility to free. */
1872
1873void
1874set_time_zone_rule (tzstring)
1875 char *tzstring;
1876{
1877 int envptrs;
1878 char **from, **to, **newenv;
1879
1880 /* Make the ENVIRON vector longer with room for TZSTRING. */
1881 for (from = environ; *from; from++)
1882 continue;
1883 envptrs = from - environ + 2;
1884 newenv = to = (char **) xmalloc (envptrs * sizeof (char *)
1885 + (tzstring ? strlen (tzstring) + 4 : 0));
1886
1887 /* Add TZSTRING to the end of environ, as a value for TZ. */
1888 if (tzstring)
1889 {
1890 char *t = (char *) (to + envptrs);
1891 strcpy (t, "TZ=");
1892 strcat (t, tzstring);
1893 *to++ = t;
1894 }
1895
1896 /* Copy the old environ vector elements into NEWENV,
1897 but don't copy the TZ variable.
1898 So we have only one definition of TZ, which came from TZSTRING. */
1899 for (from = environ; *from; from++)
1900 if (strncmp (*from, "TZ=", 3) != 0)
1901 *to++ = *from;
1902 *to = 0;
1903
1904 environ = newenv;
1905
1906 /* If we do have a TZSTRING, NEWENV points to the vector slot where
1907 the TZ variable is stored. If we do not have a TZSTRING,
1908 TO points to the vector slot which has the terminating null. */
1909
1910#ifdef LOCALTIME_CACHE
1911 {
1912 /* In SunOS 4.1.3_U1 and 4.1.4, if TZ has a value like
1913 "US/Pacific" that loads a tz file, then changes to a value like
1914 "XXX0" that does not load a tz file, and then changes back to
1915 its original value, the last change is (incorrectly) ignored.
1916 Also, if TZ changes twice in succession to values that do
1917 not load a tz file, tzset can dump core (see Sun bug#1225179).
1918 The following code works around these bugs. */
1919
1920 if (tzstring)
1921 {
1922 /* Temporarily set TZ to a value that loads a tz file
1923 and that differs from tzstring. */
1924 char *tz = *newenv;
1925 *newenv = (strcmp (tzstring, set_time_zone_rule_tz1 + 3) == 0
1926 ? set_time_zone_rule_tz2 : set_time_zone_rule_tz1);
1927 tzset ();
1928 *newenv = tz;
1929 }
1930 else
1931 {
1932 /* The implied tzstring is unknown, so temporarily set TZ to
1933 two different values that each load a tz file. */
1934 *to = set_time_zone_rule_tz1;
1935 to[1] = 0;
1936 tzset ();
1937 *to = set_time_zone_rule_tz2;
1938 tzset ();
1939 *to = 0;
1940 }
1941
1942 /* Now TZ has the desired value, and tzset can be invoked safely. */
1943 }
1944
1945 tzset ();
1946#endif
1947}
1948\f
1949/* Insert NARGS Lisp objects in the array ARGS by calling INSERT_FUNC
1950 (if a type of object is Lisp_Int) or INSERT_FROM_STRING_FUNC (if a
1951 type of object is Lisp_String). INHERIT is passed to
1952 INSERT_FROM_STRING_FUNC as the last argument. */
1953
1954static void
1955general_insert_function (insert_func, insert_from_string_func,
1956 inherit, nargs, args)
1957 void (*insert_func) P_ ((unsigned char *, int));
1958 void (*insert_from_string_func) P_ ((Lisp_Object, int, int, int, int, int));
1959 int inherit, nargs;
1960 register Lisp_Object *args;
1961{
1962 register int argnum;
1963 register Lisp_Object val;
1964
1965 for (argnum = 0; argnum < nargs; argnum++)
1966 {
1967 val = args[argnum];
1968 retry:
1969 if (INTEGERP (val))
1970 {
1971 unsigned char str[MAX_MULTIBYTE_LENGTH];
1972 int len;
1973
1974 if (!NILP (current_buffer->enable_multibyte_characters))
1975 len = CHAR_STRING (XFASTINT (val), str);
1976 else
1977 {
1978 str[0] = (SINGLE_BYTE_CHAR_P (XINT (val))
1979 ? XINT (val)
1980 : multibyte_char_to_unibyte (XINT (val), Qnil));
1981 len = 1;
1982 }
1983 (*insert_func) (str, len);
1984 }
1985 else if (STRINGP (val))
1986 {
1987 (*insert_from_string_func) (val, 0, 0,
1988 XSTRING (val)->size,
1989 STRING_BYTES (XSTRING (val)),
1990 inherit);
1991 }
1992 else
1993 {
1994 val = wrong_type_argument (Qchar_or_string_p, val);
1995 goto retry;
1996 }
1997 }
1998}
1999
2000void
2001insert1 (arg)
2002 Lisp_Object arg;
2003{
2004 Finsert (1, &arg);
2005}
2006
2007
2008/* Callers passing one argument to Finsert need not gcpro the
2009 argument "array", since the only element of the array will
2010 not be used after calling insert or insert_from_string, so
2011 we don't care if it gets trashed. */
2012
2013DEFUN ("insert", Finsert, Sinsert, 0, MANY, 0,
2014 doc: /* Insert the arguments, either strings or characters, at point.
2015Point and before-insertion markers move forward to end up
2016 after the inserted text.
2017Any other markers at the point of insertion remain before the text.
2018
2019If the current buffer is multibyte, unibyte strings are converted
2020to multibyte for insertion (see `unibyte-char-to-multibyte').
2021If the current buffer is unibyte, multibyte strings are converted
2022to unibyte for insertion. */)
2023 (nargs, args)
2024 int nargs;
2025 register Lisp_Object *args;
2026{
2027 general_insert_function (insert, insert_from_string, 0, nargs, args);
2028 return Qnil;
2029}
2030
2031DEFUN ("insert-and-inherit", Finsert_and_inherit, Sinsert_and_inherit,
2032 0, MANY, 0,
2033 doc: /* Insert the arguments at point, inheriting properties from adjoining text.
2034Point and before-insertion markers move forward to end up
2035 after the inserted text.
2036Any other markers at the point of insertion remain before the text.
2037
2038If the current buffer is multibyte, unibyte strings are converted
2039to multibyte for insertion (see `unibyte-char-to-multibyte').
2040If the current buffer is unibyte, multibyte strings are converted
2041to unibyte for insertion. */)
2042 (nargs, args)
2043 int nargs;
2044 register Lisp_Object *args;
2045{
2046 general_insert_function (insert_and_inherit, insert_from_string, 1,
2047 nargs, args);
2048 return Qnil;
2049}
2050
2051DEFUN ("insert-before-markers", Finsert_before_markers, Sinsert_before_markers, 0, MANY, 0,
2052 doc: /* Insert strings or characters at point, relocating markers after the text.
2053Point and markers move forward to end up after the inserted text.
2054
2055If the current buffer is multibyte, unibyte strings are converted
2056to multibyte for insertion (see `unibyte-char-to-multibyte').
2057If the current buffer is unibyte, multibyte strings are converted
2058to unibyte for insertion. */)
2059 (nargs, args)
2060 int nargs;
2061 register Lisp_Object *args;
2062{
2063 general_insert_function (insert_before_markers,
2064 insert_from_string_before_markers, 0,
2065 nargs, args);
2066 return Qnil;
2067}
2068
2069DEFUN ("insert-before-markers-and-inherit", Finsert_and_inherit_before_markers,
2070 Sinsert_and_inherit_before_markers, 0, MANY, 0,
2071 doc: /* Insert text at point, relocating markers and inheriting properties.
2072Point and markers move forward to end up after the inserted text.
2073
2074If the current buffer is multibyte, unibyte strings are converted
2075to multibyte for insertion (see `unibyte-char-to-multibyte').
2076If the current buffer is unibyte, multibyte strings are converted
2077to unibyte for insertion. */)
2078 (nargs, args)
2079 int nargs;
2080 register Lisp_Object *args;
2081{
2082 general_insert_function (insert_before_markers_and_inherit,
2083 insert_from_string_before_markers, 1,
2084 nargs, args);
2085 return Qnil;
2086}
2087\f
2088DEFUN ("insert-char", Finsert_char, Sinsert_char, 2, 3, 0,
2089 doc: /* Insert COUNT (second arg) copies of CHARACTER (first arg).
2090Both arguments are required.
2091Point, and before-insertion markers, are relocated as in the function `insert'.
2092The optional third arg INHERIT, if non-nil, says to inherit text properties
2093from adjoining text, if those properties are sticky. */)
2094 (character, count, inherit)
2095 Lisp_Object character, count, inherit;
2096{
2097 register unsigned char *string;
2098 register int strlen;
2099 register int i, n;
2100 int len;
2101 unsigned char str[MAX_MULTIBYTE_LENGTH];
2102
2103 CHECK_NUMBER (character, 0);
2104 CHECK_NUMBER (count, 1);
2105
2106 if (!NILP (current_buffer->enable_multibyte_characters))
2107 len = CHAR_STRING (XFASTINT (character), str);
2108 else
2109 str[0] = XFASTINT (character), len = 1;
2110 n = XINT (count) * len;
2111 if (n <= 0)
2112 return Qnil;
2113 strlen = min (n, 256 * len);
2114 string = (unsigned char *) alloca (strlen);
2115 for (i = 0; i < strlen; i++)
2116 string[i] = str[i % len];
2117 while (n >= strlen)
2118 {
2119 QUIT;
2120 if (!NILP (inherit))
2121 insert_and_inherit (string, strlen);
2122 else
2123 insert (string, strlen);
2124 n -= strlen;
2125 }
2126 if (n > 0)
2127 {
2128 if (!NILP (inherit))
2129 insert_and_inherit (string, n);
2130 else
2131 insert (string, n);
2132 }
2133 return Qnil;
2134}
2135
2136\f
2137/* Making strings from buffer contents. */
2138
2139/* Return a Lisp_String containing the text of the current buffer from
2140 START to END. If text properties are in use and the current buffer
2141 has properties in the range specified, the resulting string will also
2142 have them, if PROPS is nonzero.
2143
2144 We don't want to use plain old make_string here, because it calls
2145 make_uninit_string, which can cause the buffer arena to be
2146 compacted. make_string has no way of knowing that the data has
2147 been moved, and thus copies the wrong data into the string. This
2148 doesn't effect most of the other users of make_string, so it should
2149 be left as is. But we should use this function when conjuring
2150 buffer substrings. */
2151
2152Lisp_Object
2153make_buffer_string (start, end, props)
2154 int start, end;
2155 int props;
2156{
2157 int start_byte = CHAR_TO_BYTE (start);
2158 int end_byte = CHAR_TO_BYTE (end);
2159
2160 return make_buffer_string_both (start, start_byte, end, end_byte, props);
2161}
2162
2163/* Return a Lisp_String containing the text of the current buffer from
2164 START / START_BYTE to END / END_BYTE.
2165
2166 If text properties are in use and the current buffer
2167 has properties in the range specified, the resulting string will also
2168 have them, if PROPS is nonzero.
2169
2170 We don't want to use plain old make_string here, because it calls
2171 make_uninit_string, which can cause the buffer arena to be
2172 compacted. make_string has no way of knowing that the data has
2173 been moved, and thus copies the wrong data into the string. This
2174 doesn't effect most of the other users of make_string, so it should
2175 be left as is. But we should use this function when conjuring
2176 buffer substrings. */
2177
2178Lisp_Object
2179make_buffer_string_both (start, start_byte, end, end_byte, props)
2180 int start, start_byte, end, end_byte;
2181 int props;
2182{
2183 Lisp_Object result, tem, tem1;
2184
2185 if (start < GPT && GPT < end)
2186 move_gap (start);
2187
2188 if (! NILP (current_buffer->enable_multibyte_characters))
2189 result = make_uninit_multibyte_string (end - start, end_byte - start_byte);
2190 else
2191 result = make_uninit_string (end - start);
2192 bcopy (BYTE_POS_ADDR (start_byte), XSTRING (result)->data,
2193 end_byte - start_byte);
2194
2195 /* If desired, update and copy the text properties. */
2196 if (props)
2197 {
2198 update_buffer_properties (start, end);
2199
2200 tem = Fnext_property_change (make_number (start), Qnil, make_number (end));
2201 tem1 = Ftext_properties_at (make_number (start), Qnil);
2202
2203 if (XINT (tem) != end || !NILP (tem1))
2204 copy_intervals_to_string (result, current_buffer, start,
2205 end - start);
2206 }
2207
2208 return result;
2209}
2210
2211/* Call Vbuffer_access_fontify_functions for the range START ... END
2212 in the current buffer, if necessary. */
2213
2214static void
2215update_buffer_properties (start, end)
2216 int start, end;
2217{
2218 /* If this buffer has some access functions,
2219 call them, specifying the range of the buffer being accessed. */
2220 if (!NILP (Vbuffer_access_fontify_functions))
2221 {
2222 Lisp_Object args[3];
2223 Lisp_Object tem;
2224
2225 args[0] = Qbuffer_access_fontify_functions;
2226 XSETINT (args[1], start);
2227 XSETINT (args[2], end);
2228
2229 /* But don't call them if we can tell that the work
2230 has already been done. */
2231 if (!NILP (Vbuffer_access_fontified_property))
2232 {
2233 tem = Ftext_property_any (args[1], args[2],
2234 Vbuffer_access_fontified_property,
2235 Qnil, Qnil);
2236 if (! NILP (tem))
2237 Frun_hook_with_args (3, args);
2238 }
2239 else
2240 Frun_hook_with_args (3, args);
2241 }
2242}
2243
2244DEFUN ("buffer-substring", Fbuffer_substring, Sbuffer_substring, 2, 2, 0,
2245 doc: /* Return the contents of part of the current buffer as a string.
2246The two arguments START and END are character positions;
2247they can be in either order.
2248The string returned is multibyte if the buffer is multibyte.
2249
2250This function copies the text properties of that part of the buffer
2251into the result string; if you don't want the text properties,
2252use `buffer-substring-no-properties' instead. */)
2253 (start, end)
2254 Lisp_Object start, end;
2255{
2256 register int b, e;
2257
2258 validate_region (&start, &end);
2259 b = XINT (start);
2260 e = XINT (end);
2261
2262 return make_buffer_string (b, e, 1);
2263}
2264
2265DEFUN ("buffer-substring-no-properties", Fbuffer_substring_no_properties,
2266 Sbuffer_substring_no_properties, 2, 2, 0,
2267 doc: /* Return the characters of part of the buffer, without the text properties.
2268The two arguments START and END are character positions;
2269they can be in either order. */)
2270 (start, end)
2271 Lisp_Object start, end;
2272{
2273 register int b, e;
2274
2275 validate_region (&start, &end);
2276 b = XINT (start);
2277 e = XINT (end);
2278
2279 return make_buffer_string (b, e, 0);
2280}
2281
2282DEFUN ("buffer-string", Fbuffer_string, Sbuffer_string, 0, 0, 0,
2283 doc: /* Return the contents of the current buffer as a string.
2284If narrowing is in effect, this function returns only the visible part
2285of the buffer. */)
2286 ()
2287{
2288 return make_buffer_string (BEGV, ZV, 1);
2289}
2290
2291DEFUN ("insert-buffer-substring", Finsert_buffer_substring, Sinsert_buffer_substring,
2292 1, 3, 0,
2293 doc: /* Insert before point a substring of the contents of buffer BUFFER.
2294BUFFER may be a buffer or a buffer name.
2295Arguments START and END are character numbers specifying the substring.
2296They default to the beginning and the end of BUFFER. */)
2297 (buf, start, end)
2298 Lisp_Object buf, start, end;
2299{
2300 register int b, e, temp;
2301 register struct buffer *bp, *obuf;
2302 Lisp_Object buffer;
2303
2304 buffer = Fget_buffer (buf);
2305 if (NILP (buffer))
2306 nsberror (buf);
2307 bp = XBUFFER (buffer);
2308 if (NILP (bp->name))
2309 error ("Selecting deleted buffer");
2310
2311 if (NILP (start))
2312 b = BUF_BEGV (bp);
2313 else
2314 {
2315 CHECK_NUMBER_COERCE_MARKER (start, 0);
2316 b = XINT (start);
2317 }
2318 if (NILP (end))
2319 e = BUF_ZV (bp);
2320 else
2321 {
2322 CHECK_NUMBER_COERCE_MARKER (end, 1);
2323 e = XINT (end);
2324 }
2325
2326 if (b > e)
2327 temp = b, b = e, e = temp;
2328
2329 if (!(BUF_BEGV (bp) <= b && e <= BUF_ZV (bp)))
2330 args_out_of_range (start, end);
2331
2332 obuf = current_buffer;
2333 set_buffer_internal_1 (bp);
2334 update_buffer_properties (b, e);
2335 set_buffer_internal_1 (obuf);
2336
2337 insert_from_buffer (bp, b, e - b, 0);
2338 return Qnil;
2339}
2340
2341DEFUN ("compare-buffer-substrings", Fcompare_buffer_substrings, Scompare_buffer_substrings,
2342 6, 6, 0,
2343 doc: /* Compare two substrings of two buffers; return result as number.
2344the value is -N if first string is less after N-1 chars,
2345+N if first string is greater after N-1 chars, or 0 if strings match.
2346Each substring is represented as three arguments: BUFFER, START and END.
2347That makes six args in all, three for each substring.
2348
2349The value of `case-fold-search' in the current buffer
2350determines whether case is significant or ignored. */)
2351 (buffer1, start1, end1, buffer2, start2, end2)
2352 Lisp_Object buffer1, start1, end1, buffer2, start2, end2;
2353{
2354 register int begp1, endp1, begp2, endp2, temp;
2355 register struct buffer *bp1, *bp2;
2356 register Lisp_Object *trt
2357 = (!NILP (current_buffer->case_fold_search)
2358 ? XCHAR_TABLE (current_buffer->case_canon_table)->contents : 0);
2359 int chars = 0;
2360 int i1, i2, i1_byte, i2_byte;
2361
2362 /* Find the first buffer and its substring. */
2363
2364 if (NILP (buffer1))
2365 bp1 = current_buffer;
2366 else
2367 {
2368 Lisp_Object buf1;
2369 buf1 = Fget_buffer (buffer1);
2370 if (NILP (buf1))
2371 nsberror (buffer1);
2372 bp1 = XBUFFER (buf1);
2373 if (NILP (bp1->name))
2374 error ("Selecting deleted buffer");
2375 }
2376
2377 if (NILP (start1))
2378 begp1 = BUF_BEGV (bp1);
2379 else
2380 {
2381 CHECK_NUMBER_COERCE_MARKER (start1, 1);
2382 begp1 = XINT (start1);
2383 }
2384 if (NILP (end1))
2385 endp1 = BUF_ZV (bp1);
2386 else
2387 {
2388 CHECK_NUMBER_COERCE_MARKER (end1, 2);
2389 endp1 = XINT (end1);
2390 }
2391
2392 if (begp1 > endp1)
2393 temp = begp1, begp1 = endp1, endp1 = temp;
2394
2395 if (!(BUF_BEGV (bp1) <= begp1
2396 && begp1 <= endp1
2397 && endp1 <= BUF_ZV (bp1)))
2398 args_out_of_range (start1, end1);
2399
2400 /* Likewise for second substring. */
2401
2402 if (NILP (buffer2))
2403 bp2 = current_buffer;
2404 else
2405 {
2406 Lisp_Object buf2;
2407 buf2 = Fget_buffer (buffer2);
2408 if (NILP (buf2))
2409 nsberror (buffer2);
2410 bp2 = XBUFFER (buf2);
2411 if (NILP (bp2->name))
2412 error ("Selecting deleted buffer");
2413 }
2414
2415 if (NILP (start2))
2416 begp2 = BUF_BEGV (bp2);
2417 else
2418 {
2419 CHECK_NUMBER_COERCE_MARKER (start2, 4);
2420 begp2 = XINT (start2);
2421 }
2422 if (NILP (end2))
2423 endp2 = BUF_ZV (bp2);
2424 else
2425 {
2426 CHECK_NUMBER_COERCE_MARKER (end2, 5);
2427 endp2 = XINT (end2);
2428 }
2429
2430 if (begp2 > endp2)
2431 temp = begp2, begp2 = endp2, endp2 = temp;
2432
2433 if (!(BUF_BEGV (bp2) <= begp2
2434 && begp2 <= endp2
2435 && endp2 <= BUF_ZV (bp2)))
2436 args_out_of_range (start2, end2);
2437
2438 i1 = begp1;
2439 i2 = begp2;
2440 i1_byte = buf_charpos_to_bytepos (bp1, i1);
2441 i2_byte = buf_charpos_to_bytepos (bp2, i2);
2442
2443 while (i1 < endp1 && i2 < endp2)
2444 {
2445 /* When we find a mismatch, we must compare the
2446 characters, not just the bytes. */
2447 int c1, c2;
2448
2449 if (! NILP (bp1->enable_multibyte_characters))
2450 {
2451 c1 = BUF_FETCH_MULTIBYTE_CHAR (bp1, i1_byte);
2452 BUF_INC_POS (bp1, i1_byte);
2453 i1++;
2454 }
2455 else
2456 {
2457 c1 = BUF_FETCH_BYTE (bp1, i1);
2458 c1 = unibyte_char_to_multibyte (c1);
2459 i1++;
2460 }
2461
2462 if (! NILP (bp2->enable_multibyte_characters))
2463 {
2464 c2 = BUF_FETCH_MULTIBYTE_CHAR (bp2, i2_byte);
2465 BUF_INC_POS (bp2, i2_byte);
2466 i2++;
2467 }
2468 else
2469 {
2470 c2 = BUF_FETCH_BYTE (bp2, i2);
2471 c2 = unibyte_char_to_multibyte (c2);
2472 i2++;
2473 }
2474
2475 if (trt)
2476 {
2477 c1 = XINT (trt[c1]);
2478 c2 = XINT (trt[c2]);
2479 }
2480 if (c1 < c2)
2481 return make_number (- 1 - chars);
2482 if (c1 > c2)
2483 return make_number (chars + 1);
2484
2485 chars++;
2486 }
2487
2488 /* The strings match as far as they go.
2489 If one is shorter, that one is less. */
2490 if (chars < endp1 - begp1)
2491 return make_number (chars + 1);
2492 else if (chars < endp2 - begp2)
2493 return make_number (- chars - 1);
2494
2495 /* Same length too => they are equal. */
2496 return make_number (0);
2497}
2498\f
2499static Lisp_Object
2500subst_char_in_region_unwind (arg)
2501 Lisp_Object arg;
2502{
2503 return current_buffer->undo_list = arg;
2504}
2505
2506static Lisp_Object
2507subst_char_in_region_unwind_1 (arg)
2508 Lisp_Object arg;
2509{
2510 return current_buffer->filename = arg;
2511}
2512
2513DEFUN ("subst-char-in-region", Fsubst_char_in_region,
2514 Ssubst_char_in_region, 4, 5, 0,
2515 doc: /* From START to END, replace FROMCHAR with TOCHAR each time it occurs.
2516If optional arg NOUNDO is non-nil, don't record this change for undo
2517and don't mark the buffer as really changed.
2518Both characters must have the same length of multi-byte form. */)
2519 (start, end, fromchar, tochar, noundo)
2520 Lisp_Object start, end, fromchar, tochar, noundo;
2521{
2522 register int pos, pos_byte, stop, i, len, end_byte;
2523 int changed = 0;
2524 unsigned char fromstr[MAX_MULTIBYTE_LENGTH], tostr[MAX_MULTIBYTE_LENGTH];
2525 unsigned char *p;
2526 int count = specpdl_ptr - specpdl;
2527#define COMBINING_NO 0
2528#define COMBINING_BEFORE 1
2529#define COMBINING_AFTER 2
2530#define COMBINING_BOTH (COMBINING_BEFORE | COMBINING_AFTER)
2531 int maybe_byte_combining = COMBINING_NO;
2532 int last_changed = 0;
2533 int multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2534
2535 validate_region (&start, &end);
2536 CHECK_NUMBER (fromchar, 2);
2537 CHECK_NUMBER (tochar, 3);
2538
2539 if (multibyte_p)
2540 {
2541 len = CHAR_STRING (XFASTINT (fromchar), fromstr);
2542 if (CHAR_STRING (XFASTINT (tochar), tostr) != len)
2543 error ("Characters in subst-char-in-region have different byte-lengths");
2544 if (!ASCII_BYTE_P (*tostr))
2545 {
2546 /* If *TOSTR is in the range 0x80..0x9F and TOCHAR is not a
2547 complete multibyte character, it may be combined with the
2548 after bytes. If it is in the range 0xA0..0xFF, it may be
2549 combined with the before and after bytes. */
2550 if (!CHAR_HEAD_P (*tostr))
2551 maybe_byte_combining = COMBINING_BOTH;
2552 else if (BYTES_BY_CHAR_HEAD (*tostr) > len)
2553 maybe_byte_combining = COMBINING_AFTER;
2554 }
2555 }
2556 else
2557 {
2558 len = 1;
2559 fromstr[0] = XFASTINT (fromchar);
2560 tostr[0] = XFASTINT (tochar);
2561 }
2562
2563 pos = XINT (start);
2564 pos_byte = CHAR_TO_BYTE (pos);
2565 stop = CHAR_TO_BYTE (XINT (end));
2566 end_byte = stop;
2567
2568 /* If we don't want undo, turn off putting stuff on the list.
2569 That's faster than getting rid of things,
2570 and it prevents even the entry for a first change.
2571 Also inhibit locking the file. */
2572 if (!NILP (noundo))
2573 {
2574 record_unwind_protect (subst_char_in_region_unwind,
2575 current_buffer->undo_list);
2576 current_buffer->undo_list = Qt;
2577 /* Don't do file-locking. */
2578 record_unwind_protect (subst_char_in_region_unwind_1,
2579 current_buffer->filename);
2580 current_buffer->filename = Qnil;
2581 }
2582
2583 if (pos_byte < GPT_BYTE)
2584 stop = min (stop, GPT_BYTE);
2585 while (1)
2586 {
2587 int pos_byte_next = pos_byte;
2588
2589 if (pos_byte >= stop)
2590 {
2591 if (pos_byte >= end_byte) break;
2592 stop = end_byte;
2593 }
2594 p = BYTE_POS_ADDR (pos_byte);
2595 if (multibyte_p)
2596 INC_POS (pos_byte_next);
2597 else
2598 ++pos_byte_next;
2599 if (pos_byte_next - pos_byte == len
2600 && p[0] == fromstr[0]
2601 && (len == 1
2602 || (p[1] == fromstr[1]
2603 && (len == 2 || (p[2] == fromstr[2]
2604 && (len == 3 || p[3] == fromstr[3]))))))
2605 {
2606 if (! changed)
2607 {
2608 changed = pos;
2609 modify_region (current_buffer, changed, XINT (end));
2610
2611 if (! NILP (noundo))
2612 {
2613 if (MODIFF - 1 == SAVE_MODIFF)
2614 SAVE_MODIFF++;
2615 if (MODIFF - 1 == current_buffer->auto_save_modified)
2616 current_buffer->auto_save_modified++;
2617 }
2618 }
2619
2620 /* Take care of the case where the new character
2621 combines with neighboring bytes. */
2622 if (maybe_byte_combining
2623 && (maybe_byte_combining == COMBINING_AFTER
2624 ? (pos_byte_next < Z_BYTE
2625 && ! CHAR_HEAD_P (FETCH_BYTE (pos_byte_next)))
2626 : ((pos_byte_next < Z_BYTE
2627 && ! CHAR_HEAD_P (FETCH_BYTE (pos_byte_next)))
2628 || (pos_byte > BEG_BYTE
2629 && ! ASCII_BYTE_P (FETCH_BYTE (pos_byte - 1))))))
2630 {
2631 Lisp_Object tem, string;
2632
2633 struct gcpro gcpro1;
2634
2635 tem = current_buffer->undo_list;
2636 GCPRO1 (tem);
2637
2638 /* Make a multibyte string containing this single character. */
2639 string = make_multibyte_string (tostr, 1, len);
2640 /* replace_range is less efficient, because it moves the gap,
2641 but it handles combining correctly. */
2642 replace_range (pos, pos + 1, string,
2643 0, 0, 1);
2644 pos_byte_next = CHAR_TO_BYTE (pos);
2645 if (pos_byte_next > pos_byte)
2646 /* Before combining happened. We should not increment
2647 POS. So, to cancel the later increment of POS,
2648 decrease it now. */
2649 pos--;
2650 else
2651 INC_POS (pos_byte_next);
2652
2653 if (! NILP (noundo))
2654 current_buffer->undo_list = tem;
2655
2656 UNGCPRO;
2657 }
2658 else
2659 {
2660 if (NILP (noundo))
2661 record_change (pos, 1);
2662 for (i = 0; i < len; i++) *p++ = tostr[i];
2663 }
2664 last_changed = pos + 1;
2665 }
2666 pos_byte = pos_byte_next;
2667 pos++;
2668 }
2669
2670 if (changed)
2671 {
2672 signal_after_change (changed,
2673 last_changed - changed, last_changed - changed);
2674 update_compositions (changed, last_changed, CHECK_ALL);
2675 }
2676
2677 unbind_to (count, Qnil);
2678 return Qnil;
2679}
2680
2681DEFUN ("translate-region", Ftranslate_region, Stranslate_region, 3, 3, 0,
2682 doc: /* From START to END, translate characters according to TABLE.
2683TABLE is a string; the Nth character in it is the mapping
2684for the character with code N.
2685This function does not alter multibyte characters.
2686It returns the number of characters changed. */)
2687 (start, end, table)
2688 Lisp_Object start;
2689 Lisp_Object end;
2690 register Lisp_Object table;
2691{
2692 register int pos_byte, stop; /* Limits of the region. */
2693 register unsigned char *tt; /* Trans table. */
2694 register int nc; /* New character. */
2695 int cnt; /* Number of changes made. */
2696 int size; /* Size of translate table. */
2697 int pos;
2698 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
2699
2700 validate_region (&start, &end);
2701 CHECK_STRING (table, 2);
2702
2703 size = STRING_BYTES (XSTRING (table));
2704 tt = XSTRING (table)->data;
2705
2706 pos_byte = CHAR_TO_BYTE (XINT (start));
2707 stop = CHAR_TO_BYTE (XINT (end));
2708 modify_region (current_buffer, XINT (start), XINT (end));
2709 pos = XINT (start);
2710
2711 cnt = 0;
2712 for (; pos_byte < stop; )
2713 {
2714 register unsigned char *p = BYTE_POS_ADDR (pos_byte);
2715 int len;
2716 int oc;
2717 int pos_byte_next;
2718
2719 if (multibyte)
2720 oc = STRING_CHAR_AND_LENGTH (p, stop - pos_byte, len);
2721 else
2722 oc = *p, len = 1;
2723 pos_byte_next = pos_byte + len;
2724 if (oc < size && len == 1)
2725 {
2726 nc = tt[oc];
2727 if (nc != oc)
2728 {
2729 /* Take care of the case where the new character
2730 combines with neighboring bytes. */
2731 if (!ASCII_BYTE_P (nc)
2732 && (CHAR_HEAD_P (nc)
2733 ? ! CHAR_HEAD_P (FETCH_BYTE (pos_byte + 1))
2734 : (pos_byte > BEG_BYTE
2735 && ! ASCII_BYTE_P (FETCH_BYTE (pos_byte - 1)))))
2736 {
2737 Lisp_Object string;
2738
2739 string = make_multibyte_string (tt + oc, 1, 1);
2740 /* This is less efficient, because it moves the gap,
2741 but it handles combining correctly. */
2742 replace_range (pos, pos + 1, string,
2743 1, 0, 1);
2744 pos_byte_next = CHAR_TO_BYTE (pos);
2745 if (pos_byte_next > pos_byte)
2746 /* Before combining happened. We should not
2747 increment POS. So, to cancel the later
2748 increment of POS, we decrease it now. */
2749 pos--;
2750 else
2751 INC_POS (pos_byte_next);
2752 }
2753 else
2754 {
2755 record_change (pos, 1);
2756 *p = nc;
2757 signal_after_change (pos, 1, 1);
2758 update_compositions (pos, pos + 1, CHECK_BORDER);
2759 }
2760 ++cnt;
2761 }
2762 }
2763 pos_byte = pos_byte_next;
2764 pos++;
2765 }
2766
2767 return make_number (cnt);
2768}
2769
2770DEFUN ("delete-region", Fdelete_region, Sdelete_region, 2, 2, "r",
2771 doc: /* Delete the text between point and mark.
2772When called from a program, expects two arguments,
2773positions (integers or markers) specifying the stretch to be deleted. */)
2774 (start, end)
2775 Lisp_Object start, end;
2776{
2777 validate_region (&start, &end);
2778 del_range (XINT (start), XINT (end));
2779 return Qnil;
2780}
2781
2782DEFUN ("delete-and-extract-region", Fdelete_and_extract_region,
2783 Sdelete_and_extract_region, 2, 2, 0,
2784 doc: /* Delete the text between START and END and return it. */)
2785 (start, end)
2786 Lisp_Object start, end;
2787{
2788 validate_region (&start, &end);
2789 return del_range_1 (XINT (start), XINT (end), 1, 1);
2790}
2791\f
2792DEFUN ("widen", Fwiden, Swiden, 0, 0, "",
2793 doc: /* Remove restrictions (narrowing) from current buffer.
2794This allows the buffer's full text to be seen and edited. */)
2795 ()
2796{
2797 if (BEG != BEGV || Z != ZV)
2798 current_buffer->clip_changed = 1;
2799 BEGV = BEG;
2800 BEGV_BYTE = BEG_BYTE;
2801 SET_BUF_ZV_BOTH (current_buffer, Z, Z_BYTE);
2802 /* Changing the buffer bounds invalidates any recorded current column. */
2803 invalidate_current_column ();
2804 return Qnil;
2805}
2806
2807DEFUN ("narrow-to-region", Fnarrow_to_region, Snarrow_to_region, 2, 2, "r",
2808 doc: /* Restrict editing in this buffer to the current region.
2809The rest of the text becomes temporarily invisible and untouchable
2810but is not deleted; if you save the buffer in a file, the invisible
2811text is included in the file. \\[widen] makes all visible again.
2812See also `save-restriction'.
2813
2814When calling from a program, pass two arguments; positions (integers
2815or markers) bounding the text that should remain visible. */)
2816 (start, end)
2817 register Lisp_Object start, end;
2818{
2819 CHECK_NUMBER_COERCE_MARKER (start, 0);
2820 CHECK_NUMBER_COERCE_MARKER (end, 1);
2821
2822 if (XINT (start) > XINT (end))
2823 {
2824 Lisp_Object tem;
2825 tem = start; start = end; end = tem;
2826 }
2827
2828 if (!(BEG <= XINT (start) && XINT (start) <= XINT (end) && XINT (end) <= Z))
2829 args_out_of_range (start, end);
2830
2831 if (BEGV != XFASTINT (start) || ZV != XFASTINT (end))
2832 current_buffer->clip_changed = 1;
2833
2834 SET_BUF_BEGV (current_buffer, XFASTINT (start));
2835 SET_BUF_ZV (current_buffer, XFASTINT (end));
2836 if (PT < XFASTINT (start))
2837 SET_PT (XFASTINT (start));
2838 if (PT > XFASTINT (end))
2839 SET_PT (XFASTINT (end));
2840 /* Changing the buffer bounds invalidates any recorded current column. */
2841 invalidate_current_column ();
2842 return Qnil;
2843}
2844
2845Lisp_Object
2846save_restriction_save ()
2847{
2848 if (BEGV == BEG && ZV == Z)
2849 /* The common case that the buffer isn't narrowed.
2850 We return just the buffer object, which save_restriction_restore
2851 recognizes as meaning `no restriction'. */
2852 return Fcurrent_buffer ();
2853 else
2854 /* We have to save a restriction, so return a pair of markers, one
2855 for the beginning and one for the end. */
2856 {
2857 Lisp_Object beg, end;
2858
2859 beg = buildmark (BEGV, BEGV_BYTE);
2860 end = buildmark (ZV, ZV_BYTE);
2861
2862 /* END must move forward if text is inserted at its exact location. */
2863 XMARKER(end)->insertion_type = 1;
2864
2865 return Fcons (beg, end);
2866 }
2867}
2868
2869Lisp_Object
2870save_restriction_restore (data)
2871 Lisp_Object data;
2872{
2873 if (CONSP (data))
2874 /* A pair of marks bounding a saved restriction. */
2875 {
2876 struct Lisp_Marker *beg = XMARKER (XCAR (data));
2877 struct Lisp_Marker *end = XMARKER (XCDR (data));
2878 struct buffer *buf = beg->buffer; /* END should have the same buffer. */
2879
2880 if (beg->charpos != BUF_BEGV(buf) || end->charpos != BUF_ZV(buf))
2881 /* The restriction has changed from the saved one, so restore
2882 the saved restriction. */
2883 {
2884 int pt = BUF_PT (buf);
2885
2886 SET_BUF_BEGV_BOTH (buf, beg->charpos, beg->bytepos);
2887 SET_BUF_ZV_BOTH (buf, end->charpos, end->bytepos);
2888
2889 if (pt < beg->charpos || pt > end->charpos)
2890 /* The point is outside the new visible range, move it inside. */
2891 SET_BUF_PT_BOTH (buf,
2892 clip_to_bounds (beg->charpos, pt, end->charpos),
2893 clip_to_bounds (beg->bytepos, BUF_PT_BYTE(buf),
2894 end->bytepos));
2895
2896 buf->clip_changed = 1; /* Remember that the narrowing changed. */
2897 }
2898 }
2899 else
2900 /* A buffer, which means that there was no old restriction. */
2901 {
2902 struct buffer *buf = XBUFFER (data);
2903
2904 if (BUF_BEGV(buf) != BUF_BEG(buf) || BUF_ZV(buf) != BUF_Z(buf))
2905 /* The buffer has been narrowed, get rid of the narrowing. */
2906 {
2907 SET_BUF_BEGV_BOTH (buf, BUF_BEG(buf), BUF_BEG_BYTE(buf));
2908 SET_BUF_ZV_BOTH (buf, BUF_Z(buf), BUF_Z_BYTE(buf));
2909
2910 buf->clip_changed = 1; /* Remember that the narrowing changed. */
2911 }
2912 }
2913
2914 return Qnil;
2915}
2916
2917DEFUN ("save-restriction", Fsave_restriction, Ssave_restriction, 0, UNEVALLED, 0,
2918 doc: /* Execute BODY, saving and restoring current buffer's restrictions.
2919The buffer's restrictions make parts of the beginning and end invisible.
2920(They are set up with `narrow-to-region' and eliminated with `widen'.)
2921This special form, `save-restriction', saves the current buffer's restrictions
2922when it is entered, and restores them when it is exited.
2923So any `narrow-to-region' within BODY lasts only until the end of the form.
2924The old restrictions settings are restored
2925even in case of abnormal exit (throw or error).
2926
2927The value returned is the value of the last form in BODY.
2928
2929Note: if you are using both `save-excursion' and `save-restriction',
2930use `save-excursion' outermost:
2931 (save-excursion (save-restriction ...)) */)
2932 (body)
2933 Lisp_Object body;
2934{
2935 register Lisp_Object val;
2936 int count = specpdl_ptr - specpdl;
2937
2938 record_unwind_protect (save_restriction_restore, save_restriction_save ());
2939 val = Fprogn (body);
2940 return unbind_to (count, val);
2941}
2942\f
2943/* Buffer for the most recent text displayed by Fmessage_box. */
2944static char *message_text;
2945
2946/* Allocated length of that buffer. */
2947static int message_length;
2948
2949DEFUN ("message", Fmessage, Smessage, 1, MANY, 0,
2950 doc: /* Print a one-line message at the bottom of the screen.
2951The first argument is a format control string, and the rest are data
2952to be formatted under control of the string. See `format' for details.
2953
2954If the first argument is nil, clear any existing message; let the
2955minibuffer contents show. */)
2956 (nargs, args)
2957 int nargs;
2958 Lisp_Object *args;
2959{
2960 if (NILP (args[0]))
2961 {
2962 message (0);
2963 return Qnil;
2964 }
2965 else
2966 {
2967 register Lisp_Object val;
2968 val = Fformat (nargs, args);
2969 message3 (val, STRING_BYTES (XSTRING (val)), STRING_MULTIBYTE (val));
2970 return val;
2971 }
2972}
2973
2974DEFUN ("message-box", Fmessage_box, Smessage_box, 1, MANY, 0,
2975 doc: /* Display a message, in a dialog box if possible.
2976If a dialog box is not available, use the echo area.
2977The first argument is a format control string, and the rest are data
2978to be formatted under control of the string. See `format' for details.
2979
2980If the first argument is nil, clear any existing message; let the
2981minibuffer contents show. */)
2982 (nargs, args)
2983 int nargs;
2984 Lisp_Object *args;
2985{
2986 if (NILP (args[0]))
2987 {
2988 message (0);
2989 return Qnil;
2990 }
2991 else
2992 {
2993 register Lisp_Object val;
2994 val = Fformat (nargs, args);
2995#ifdef HAVE_MENUS
2996 /* The MS-DOS frames support popup menus even though they are
2997 not FRAME_WINDOW_P. */
2998 if (FRAME_WINDOW_P (XFRAME (selected_frame))
2999 || FRAME_MSDOS_P (XFRAME (selected_frame)))
3000 {
3001 Lisp_Object pane, menu, obj;
3002 struct gcpro gcpro1;
3003 pane = Fcons (Fcons (build_string ("OK"), Qt), Qnil);
3004 GCPRO1 (pane);
3005 menu = Fcons (val, pane);
3006 obj = Fx_popup_dialog (Qt, menu);
3007 UNGCPRO;
3008 return val;
3009 }
3010#endif /* HAVE_MENUS */
3011 /* Copy the data so that it won't move when we GC. */
3012 if (! message_text)
3013 {
3014 message_text = (char *)xmalloc (80);
3015 message_length = 80;
3016 }
3017 if (STRING_BYTES (XSTRING (val)) > message_length)
3018 {
3019 message_length = STRING_BYTES (XSTRING (val));
3020 message_text = (char *)xrealloc (message_text, message_length);
3021 }
3022 bcopy (XSTRING (val)->data, message_text, STRING_BYTES (XSTRING (val)));
3023 message2 (message_text, STRING_BYTES (XSTRING (val)),
3024 STRING_MULTIBYTE (val));
3025 return val;
3026 }
3027}
3028#ifdef HAVE_MENUS
3029extern Lisp_Object last_nonmenu_event;
3030#endif
3031
3032DEFUN ("message-or-box", Fmessage_or_box, Smessage_or_box, 1, MANY, 0,
3033 doc: /* Display a message in a dialog box or in the echo area.
3034If this command was invoked with the mouse, use a dialog box if
3035`use-dialog-box' is non-nil.
3036Otherwise, use the echo area.
3037The first argument is a format control string, and the rest are data
3038to be formatted under control of the string. See `format' for details.
3039
3040If the first argument is nil, clear any existing message; let the
3041minibuffer contents show. */)
3042 (nargs, args)
3043 int nargs;
3044 Lisp_Object *args;
3045{
3046#ifdef HAVE_MENUS
3047 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
3048 && use_dialog_box)
3049 return Fmessage_box (nargs, args);
3050#endif
3051 return Fmessage (nargs, args);
3052}
3053
3054DEFUN ("current-message", Fcurrent_message, Scurrent_message, 0, 0, 0,
3055 doc: /* Return the string currently displayed in the echo area, or nil if none. */)
3056 ()
3057{
3058 return current_message ();
3059}
3060
3061
3062DEFUN ("propertize", Fpropertize, Spropertize, 3, MANY, 0,
3063 doc: /* Return a copy of STRING with text properties added.
3064First argument is the string to copy.
3065Remaining arguments form a sequence of PROPERTY VALUE pairs for text
3066properties to add to the result. */)
3067 (nargs, args)
3068 int nargs;
3069 Lisp_Object *args;
3070{
3071 Lisp_Object properties, string;
3072 struct gcpro gcpro1, gcpro2;
3073 int i;
3074
3075 /* Number of args must be odd. */
3076 if ((nargs & 1) == 0 || nargs < 3)
3077 error ("Wrong number of arguments");
3078
3079 properties = string = Qnil;
3080 GCPRO2 (properties, string);
3081
3082 /* First argument must be a string. */
3083 CHECK_STRING (args[0], 0);
3084 string = Fcopy_sequence (args[0]);
3085
3086 for (i = 1; i < nargs; i += 2)
3087 {
3088 CHECK_SYMBOL (args[i], i);
3089 properties = Fcons (args[i], Fcons (args[i + 1], properties));
3090 }
3091
3092 Fadd_text_properties (make_number (0),
3093 make_number (XSTRING (string)->size),
3094 properties, string);
3095 RETURN_UNGCPRO (string);
3096}
3097
3098
3099/* Number of bytes that STRING will occupy when put into the result.
3100 MULTIBYTE is nonzero if the result should be multibyte. */
3101
3102#define CONVERTED_BYTE_SIZE(MULTIBYTE, STRING) \
3103 (((MULTIBYTE) && ! STRING_MULTIBYTE (STRING)) \
3104 ? count_size_as_multibyte (XSTRING (STRING)->data, \
3105 STRING_BYTES (XSTRING (STRING))) \
3106 : STRING_BYTES (XSTRING (STRING)))
3107
3108DEFUN ("format", Fformat, Sformat, 1, MANY, 0,
3109 doc: /* Format a string out of a control-string and arguments.
3110The first argument is a control string.
3111The other arguments are substituted into it to make the result, a string.
3112It may contain %-sequences meaning to substitute the next argument.
3113%s means print a string argument. Actually, prints any object, with `princ'.
3114%d means print as number in decimal (%o octal, %x hex).
3115%X is like %x, but uses upper case.
3116%e means print a number in exponential notation.
3117%f means print a number in decimal-point notation.
3118%g means print a number in exponential notation
3119 or decimal-point notation, whichever uses fewer characters.
3120%c means print a number as a single character.
3121%S means print any object as an s-expression (using `prin1').
3122 The argument used for %d, %o, %x, %e, %f, %g or %c must be a number.
3123Use %% to put a single % into the output. */)
3124 (nargs, args)
3125 int nargs;
3126 register Lisp_Object *args;
3127{
3128 register int n; /* The number of the next arg to substitute */
3129 register int total; /* An estimate of the final length */
3130 char *buf, *p;
3131 register unsigned char *format, *end;
3132 int nchars;
3133 /* Nonzero if the output should be a multibyte string,
3134 which is true if any of the inputs is one. */
3135 int multibyte = 0;
3136 /* When we make a multibyte string, we must pay attention to the
3137 byte combining problem, i.e., a byte may be combined with a
3138 multibyte charcter of the previous string. This flag tells if we
3139 must consider such a situation or not. */
3140 int maybe_combine_byte;
3141 unsigned char *this_format;
3142 int longest_format;
3143 Lisp_Object val;
3144 struct info
3145 {
3146 int start, end;
3147 } *info = 0;
3148
3149 /* It should not be necessary to GCPRO ARGS, because
3150 the caller in the interpreter should take care of that. */
3151
3152 /* Try to determine whether the result should be multibyte.
3153 This is not always right; sometimes the result needs to be multibyte
3154 because of an object that we will pass through prin1,
3155 and in that case, we won't know it here. */
3156 for (n = 0; n < nargs; n++)
3157 if (STRINGP (args[n]) && STRING_MULTIBYTE (args[n]))
3158 multibyte = 1;
3159
3160 CHECK_STRING (args[0], 0);
3161
3162 /* If we start out planning a unibyte result,
3163 and later find it has to be multibyte, we jump back to retry. */
3164 retry:
3165
3166 format = XSTRING (args[0])->data;
3167 end = format + STRING_BYTES (XSTRING (args[0]));
3168 longest_format = 0;
3169
3170 /* Make room in result for all the non-%-codes in the control string. */
3171 total = 5 + CONVERTED_BYTE_SIZE (multibyte, args[0]);
3172
3173 /* Add to TOTAL enough space to hold the converted arguments. */
3174
3175 n = 0;
3176 while (format != end)
3177 if (*format++ == '%')
3178 {
3179 int thissize = 0;
3180 unsigned char *this_format_start = format - 1;
3181 int field_width, precision;
3182
3183 /* General format specifications look like
3184
3185 '%' [flags] [field-width] [precision] format
3186
3187 where
3188
3189 flags ::= [#-* 0]+
3190 field-width ::= [0-9]+
3191 precision ::= '.' [0-9]*
3192
3193 If a field-width is specified, it specifies to which width
3194 the output should be padded with blanks, iff the output
3195 string is shorter than field-width.
3196
3197 if precision is specified, it specifies the number of
3198 digits to print after the '.' for floats, or the max.
3199 number of chars to print from a string. */
3200
3201 precision = field_width = 0;
3202
3203 while (index ("-*# 0", *format))
3204 ++format;
3205
3206 if (*format >= '0' && *format <= '9')
3207 {
3208 for (field_width = 0; *format >= '0' && *format <= '9'; ++format)
3209 field_width = 10 * field_width + *format - '0';
3210 }
3211
3212 if (*format == '.')
3213 {
3214 ++format;
3215 for (precision = 0; *format >= '0' && *format <= '9'; ++format)
3216 precision = 10 * precision + *format - '0';
3217 }
3218
3219 if (format - this_format_start + 1 > longest_format)
3220 longest_format = format - this_format_start + 1;
3221
3222 if (format == end)
3223 error ("Format string ends in middle of format specifier");
3224 if (*format == '%')
3225 format++;
3226 else if (++n >= nargs)
3227 error ("Not enough arguments for format string");
3228 else if (*format == 'S')
3229 {
3230 /* For `S', prin1 the argument and then treat like a string. */
3231 register Lisp_Object tem;
3232 tem = Fprin1_to_string (args[n], Qnil);
3233 if (STRING_MULTIBYTE (tem) && ! multibyte)
3234 {
3235 multibyte = 1;
3236 goto retry;
3237 }
3238 args[n] = tem;
3239 goto string;
3240 }
3241 else if (SYMBOLP (args[n]))
3242 {
3243 /* Use a temp var to avoid problems when ENABLE_CHECKING
3244 is turned on. */
3245 struct Lisp_String *t = XSYMBOL (args[n])->name;
3246 XSETSTRING (args[n], t);
3247 if (STRING_MULTIBYTE (args[n]) && ! multibyte)
3248 {
3249 multibyte = 1;
3250 goto retry;
3251 }
3252 goto string;
3253 }
3254 else if (STRINGP (args[n]))
3255 {
3256 string:
3257 if (*format != 's' && *format != 'S')
3258 error ("Format specifier doesn't match argument type");
3259 thissize = CONVERTED_BYTE_SIZE (multibyte, args[n]);
3260 }
3261 /* Would get MPV otherwise, since Lisp_Int's `point' to low memory. */
3262 else if (INTEGERP (args[n]) && *format != 's')
3263 {
3264 /* The following loop assumes the Lisp type indicates
3265 the proper way to pass the argument.
3266 So make sure we have a flonum if the argument should
3267 be a double. */
3268 if (*format == 'e' || *format == 'f' || *format == 'g')
3269 args[n] = Ffloat (args[n]);
3270 else
3271 if (*format != 'd' && *format != 'o' && *format != 'x'
3272 && *format != 'i' && *format != 'X' && *format != 'c')
3273 error ("Invalid format operation %%%c", *format);
3274
3275 thissize = 30;
3276 if (*format == 'c'
3277 && (! SINGLE_BYTE_CHAR_P (XINT (args[n]))
3278 || XINT (args[n]) == 0))
3279 {
3280 if (! multibyte)
3281 {
3282 multibyte = 1;
3283 goto retry;
3284 }
3285 args[n] = Fchar_to_string (args[n]);
3286 thissize = STRING_BYTES (XSTRING (args[n]));
3287 }
3288 }
3289 else if (FLOATP (args[n]) && *format != 's')
3290 {
3291 if (! (*format == 'e' || *format == 'f' || *format == 'g'))
3292 args[n] = Ftruncate (args[n], Qnil);
3293
3294 /* Note that we're using sprintf to print floats,
3295 so we have to take into account what that function
3296 prints. */
3297 thissize = MAX_10_EXP + 100 + precision;
3298 }
3299 else
3300 {
3301 /* Anything but a string, convert to a string using princ. */
3302 register Lisp_Object tem;
3303 tem = Fprin1_to_string (args[n], Qt);
3304 if (STRING_MULTIBYTE (tem) & ! multibyte)
3305 {
3306 multibyte = 1;
3307 goto retry;
3308 }
3309 args[n] = tem;
3310 goto string;
3311 }
3312
3313 thissize = max (field_width, thissize);
3314 total += thissize + 4;
3315 }
3316
3317 /* Now we can no longer jump to retry.
3318 TOTAL and LONGEST_FORMAT are known for certain. */
3319
3320 this_format = (unsigned char *) alloca (longest_format + 1);
3321
3322 /* Allocate the space for the result.
3323 Note that TOTAL is an overestimate. */
3324 if (total < 1000)
3325 buf = (char *) alloca (total + 1);
3326 else
3327 buf = (char *) xmalloc (total + 1);
3328
3329 p = buf;
3330 nchars = 0;
3331 n = 0;
3332
3333 /* Scan the format and store result in BUF. */
3334 format = XSTRING (args[0])->data;
3335 maybe_combine_byte = 0;
3336 while (format != end)
3337 {
3338 if (*format == '%')
3339 {
3340 int minlen;
3341 int negative = 0;
3342 unsigned char *this_format_start = format;
3343
3344 format++;
3345
3346 /* Process a numeric arg and skip it. */
3347 minlen = atoi (format);
3348 if (minlen < 0)
3349 minlen = - minlen, negative = 1;
3350
3351 while ((*format >= '0' && *format <= '9')
3352 || *format == '-' || *format == ' ' || *format == '.')
3353 format++;
3354
3355 if (*format++ == '%')
3356 {
3357 *p++ = '%';
3358 nchars++;
3359 continue;
3360 }
3361
3362 ++n;
3363
3364 if (STRINGP (args[n]))
3365 {
3366 int padding, nbytes, start, end;
3367 int width = lisp_string_width (args[n], -1, NULL, NULL);
3368
3369 /* If spec requires it, pad on right with spaces. */
3370 padding = minlen - width;
3371 if (! negative)
3372 while (padding-- > 0)
3373 {
3374 *p++ = ' ';
3375 ++nchars;
3376 }
3377
3378 start = nchars;
3379
3380 if (p > buf
3381 && multibyte
3382 && !ASCII_BYTE_P (*((unsigned char *) p - 1))
3383 && STRING_MULTIBYTE (args[n])
3384 && !CHAR_HEAD_P (XSTRING (args[n])->data[0]))
3385 maybe_combine_byte = 1;
3386 nbytes = copy_text (XSTRING (args[n])->data, p,
3387 STRING_BYTES (XSTRING (args[n])),
3388 STRING_MULTIBYTE (args[n]), multibyte);
3389 p += nbytes;
3390 nchars += XSTRING (args[n])->size;
3391 end = nchars;
3392
3393 if (negative)
3394 while (padding-- > 0)
3395 {
3396 *p++ = ' ';
3397 nchars++;
3398 }
3399
3400 /* If this argument has text properties, record where
3401 in the result string it appears. */
3402 if (XSTRING (args[n])->intervals)
3403 {
3404 if (!info)
3405 {
3406 int nbytes = nargs * sizeof *info;
3407 info = (struct info *) alloca (nbytes);
3408 bzero (info, nbytes);
3409 }
3410
3411 info[n].start = start;
3412 info[n].end = end;
3413 }
3414 }
3415 else if (INTEGERP (args[n]) || FLOATP (args[n]))
3416 {
3417 int this_nchars;
3418
3419 bcopy (this_format_start, this_format,
3420 format - this_format_start);
3421 this_format[format - this_format_start] = 0;
3422
3423 if (INTEGERP (args[n]))
3424 sprintf (p, this_format, XINT (args[n]));
3425 else
3426 sprintf (p, this_format, XFLOAT_DATA (args[n]));
3427
3428 if (p > buf
3429 && multibyte
3430 && !ASCII_BYTE_P (*((unsigned char *) p - 1))
3431 && !CHAR_HEAD_P (*((unsigned char *) p)))
3432 maybe_combine_byte = 1;
3433 this_nchars = strlen (p);
3434 if (multibyte)
3435 p += str_to_multibyte (p, buf + total - p, this_nchars);
3436 else
3437 p += this_nchars;
3438 nchars += this_nchars;
3439 }
3440 }
3441 else if (STRING_MULTIBYTE (args[0]))
3442 {
3443 /* Copy a whole multibyte character. */
3444 if (p > buf
3445 && multibyte
3446 && !ASCII_BYTE_P (*((unsigned char *) p - 1))
3447 && !CHAR_HEAD_P (*format))
3448 maybe_combine_byte = 1;
3449 *p++ = *format++;
3450 while (! CHAR_HEAD_P (*format)) *p++ = *format++;
3451 nchars++;
3452 }
3453 else if (multibyte)
3454 {
3455 /* Convert a single-byte character to multibyte. */
3456 int len = copy_text (format, p, 1, 0, 1);
3457
3458 p += len;
3459 format++;
3460 nchars++;
3461 }
3462 else
3463 *p++ = *format++, nchars++;
3464 }
3465
3466 if (p > buf + total + 1)
3467 abort ();
3468
3469 if (maybe_combine_byte)
3470 nchars = multibyte_chars_in_text (buf, p - buf);
3471 val = make_specified_string (buf, nchars, p - buf, multibyte);
3472
3473 /* If we allocated BUF with malloc, free it too. */
3474 if (total >= 1000)
3475 xfree (buf);
3476
3477 /* If the format string has text properties, or any of the string
3478 arguments has text properties, set up text properties of the
3479 result string. */
3480
3481 if (XSTRING (args[0])->intervals || info)
3482 {
3483 Lisp_Object len, new_len, props;
3484 struct gcpro gcpro1;
3485
3486 /* Add text properties from the format string. */
3487 len = make_number (XSTRING (args[0])->size);
3488 props = text_property_list (args[0], make_number (0), len, Qnil);
3489 GCPRO1 (props);
3490
3491 if (CONSP (props))
3492 {
3493 new_len = make_number (XSTRING (val)->size);
3494 extend_property_ranges (props, len, new_len);
3495 add_text_properties_from_list (val, props, make_number (0));
3496 }
3497
3498 /* Add text properties from arguments. */
3499 if (info)
3500 for (n = 1; n < nargs; ++n)
3501 if (info[n].end)
3502 {
3503 len = make_number (XSTRING (args[n])->size);
3504 new_len = make_number (info[n].end - info[n].start);
3505 props = text_property_list (args[n], make_number (0), len, Qnil);
3506 extend_property_ranges (props, len, new_len);
3507 /* If successive arguments have properites, be sure that
3508 the value of `composition' property be the copy. */
3509 if (n > 1 && info[n - 1].end)
3510 make_composition_value_copy (props);
3511 add_text_properties_from_list (val, props,
3512 make_number (info[n].start));
3513 }
3514
3515 UNGCPRO;
3516 }
3517
3518 return val;
3519}
3520
3521
3522/* VARARGS 1 */
3523Lisp_Object
3524#ifdef NO_ARG_ARRAY
3525format1 (string1, arg0, arg1, arg2, arg3, arg4)
3526 EMACS_INT arg0, arg1, arg2, arg3, arg4;
3527#else
3528format1 (string1)
3529#endif
3530 char *string1;
3531{
3532 char buf[100];
3533#ifdef NO_ARG_ARRAY
3534 EMACS_INT args[5];
3535 args[0] = arg0;
3536 args[1] = arg1;
3537 args[2] = arg2;
3538 args[3] = arg3;
3539 args[4] = arg4;
3540 doprnt (buf, sizeof buf, string1, (char *)0, 5, (char **) args);
3541#else
3542 doprnt (buf, sizeof buf, string1, (char *)0, 5, &string1 + 1);
3543#endif
3544 return build_string (buf);
3545}
3546\f
3547DEFUN ("char-equal", Fchar_equal, Schar_equal, 2, 2, 0,
3548 doc: /* Return t if two characters match, optionally ignoring case.
3549Both arguments must be characters (i.e. integers).
3550Case is ignored if `case-fold-search' is non-nil in the current buffer. */)
3551 (c1, c2)
3552 register Lisp_Object c1, c2;
3553{
3554 int i1, i2;
3555 CHECK_NUMBER (c1, 0);
3556 CHECK_NUMBER (c2, 1);
3557
3558 if (XINT (c1) == XINT (c2))
3559 return Qt;
3560 if (NILP (current_buffer->case_fold_search))
3561 return Qnil;
3562
3563 /* Do these in separate statements,
3564 then compare the variables.
3565 because of the way DOWNCASE uses temp variables. */
3566 i1 = DOWNCASE (XFASTINT (c1));
3567 i2 = DOWNCASE (XFASTINT (c2));
3568 return (i1 == i2 ? Qt : Qnil);
3569}
3570\f
3571/* Transpose the markers in two regions of the current buffer, and
3572 adjust the ones between them if necessary (i.e.: if the regions
3573 differ in size).
3574
3575 START1, END1 are the character positions of the first region.
3576 START1_BYTE, END1_BYTE are the byte positions.
3577 START2, END2 are the character positions of the second region.
3578 START2_BYTE, END2_BYTE are the byte positions.
3579
3580 Traverses the entire marker list of the buffer to do so, adding an
3581 appropriate amount to some, subtracting from some, and leaving the
3582 rest untouched. Most of this is copied from adjust_markers in insdel.c.
3583
3584 It's the caller's job to ensure that START1 <= END1 <= START2 <= END2. */
3585
3586static void
3587transpose_markers (start1, end1, start2, end2,
3588 start1_byte, end1_byte, start2_byte, end2_byte)
3589 register int start1, end1, start2, end2;
3590 register int start1_byte, end1_byte, start2_byte, end2_byte;
3591{
3592 register int amt1, amt1_byte, amt2, amt2_byte, diff, diff_byte, mpos;
3593 register Lisp_Object marker;
3594
3595 /* Update point as if it were a marker. */
3596 if (PT < start1)
3597 ;
3598 else if (PT < end1)
3599 TEMP_SET_PT_BOTH (PT + (end2 - end1),
3600 PT_BYTE + (end2_byte - end1_byte));
3601 else if (PT < start2)
3602 TEMP_SET_PT_BOTH (PT + (end2 - start2) - (end1 - start1),
3603 (PT_BYTE + (end2_byte - start2_byte)
3604 - (end1_byte - start1_byte)));
3605 else if (PT < end2)
3606 TEMP_SET_PT_BOTH (PT - (start2 - start1),
3607 PT_BYTE - (start2_byte - start1_byte));
3608
3609 /* We used to adjust the endpoints here to account for the gap, but that
3610 isn't good enough. Even if we assume the caller has tried to move the
3611 gap out of our way, it might still be at start1 exactly, for example;
3612 and that places it `inside' the interval, for our purposes. The amount
3613 of adjustment is nontrivial if there's a `denormalized' marker whose
3614 position is between GPT and GPT + GAP_SIZE, so it's simpler to leave
3615 the dirty work to Fmarker_position, below. */
3616
3617 /* The difference between the region's lengths */
3618 diff = (end2 - start2) - (end1 - start1);
3619 diff_byte = (end2_byte - start2_byte) - (end1_byte - start1_byte);
3620
3621 /* For shifting each marker in a region by the length of the other
3622 region plus the distance between the regions. */
3623 amt1 = (end2 - start2) + (start2 - end1);
3624 amt2 = (end1 - start1) + (start2 - end1);
3625 amt1_byte = (end2_byte - start2_byte) + (start2_byte - end1_byte);
3626 amt2_byte = (end1_byte - start1_byte) + (start2_byte - end1_byte);
3627
3628 for (marker = BUF_MARKERS (current_buffer); !NILP (marker);
3629 marker = XMARKER (marker)->chain)
3630 {
3631 mpos = marker_byte_position (marker);
3632 if (mpos >= start1_byte && mpos < end2_byte)
3633 {
3634 if (mpos < end1_byte)
3635 mpos += amt1_byte;
3636 else if (mpos < start2_byte)
3637 mpos += diff_byte;
3638 else
3639 mpos -= amt2_byte;
3640 XMARKER (marker)->bytepos = mpos;
3641 }
3642 mpos = XMARKER (marker)->charpos;
3643 if (mpos >= start1 && mpos < end2)
3644 {
3645 if (mpos < end1)
3646 mpos += amt1;
3647 else if (mpos < start2)
3648 mpos += diff;
3649 else
3650 mpos -= amt2;
3651 }
3652 XMARKER (marker)->charpos = mpos;
3653 }
3654}
3655
3656DEFUN ("transpose-regions", Ftranspose_regions, Stranspose_regions, 4, 5, 0,
3657 doc: /* Transpose region START1 to END1 with START2 to END2.
3658The regions may not be overlapping, because the size of the buffer is
3659never changed in a transposition.
3660
3661Optional fifth arg LEAVE_MARKERS, if non-nil, means don't update
3662any markers that happen to be located in the regions.
3663
3664Transposing beyond buffer boundaries is an error. */)
3665 (startr1, endr1, startr2, endr2, leave_markers)
3666 Lisp_Object startr1, endr1, startr2, endr2, leave_markers;
3667{
3668 register int start1, end1, start2, end2;
3669 int start1_byte, start2_byte, len1_byte, len2_byte;
3670 int gap, len1, len_mid, len2;
3671 unsigned char *start1_addr, *start2_addr, *temp;
3672
3673 INTERVAL cur_intv, tmp_interval1, tmp_interval_mid, tmp_interval2;
3674 cur_intv = BUF_INTERVALS (current_buffer);
3675
3676 validate_region (&startr1, &endr1);
3677 validate_region (&startr2, &endr2);
3678
3679 start1 = XFASTINT (startr1);
3680 end1 = XFASTINT (endr1);
3681 start2 = XFASTINT (startr2);
3682 end2 = XFASTINT (endr2);
3683 gap = GPT;
3684
3685 /* Swap the regions if they're reversed. */
3686 if (start2 < end1)
3687 {
3688 register int glumph = start1;
3689 start1 = start2;
3690 start2 = glumph;
3691 glumph = end1;
3692 end1 = end2;
3693 end2 = glumph;
3694 }
3695
3696 len1 = end1 - start1;
3697 len2 = end2 - start2;
3698
3699 if (start2 < end1)
3700 error ("Transposed regions overlap");
3701 else if (start1 == end1 || start2 == end2)
3702 error ("Transposed region has length 0");
3703
3704 /* The possibilities are:
3705 1. Adjacent (contiguous) regions, or separate but equal regions
3706 (no, really equal, in this case!), or
3707 2. Separate regions of unequal size.
3708
3709 The worst case is usually No. 2. It means that (aside from
3710 potential need for getting the gap out of the way), there also
3711 needs to be a shifting of the text between the two regions. So
3712 if they are spread far apart, we are that much slower... sigh. */
3713
3714 /* It must be pointed out that the really studly thing to do would
3715 be not to move the gap at all, but to leave it in place and work
3716 around it if necessary. This would be extremely efficient,
3717 especially considering that people are likely to do
3718 transpositions near where they are working interactively, which
3719 is exactly where the gap would be found. However, such code
3720 would be much harder to write and to read. So, if you are
3721 reading this comment and are feeling squirrely, by all means have
3722 a go! I just didn't feel like doing it, so I will simply move
3723 the gap the minimum distance to get it out of the way, and then
3724 deal with an unbroken array. */
3725
3726 /* Make sure the gap won't interfere, by moving it out of the text
3727 we will operate on. */
3728 if (start1 < gap && gap < end2)
3729 {
3730 if (gap - start1 < end2 - gap)
3731 move_gap (start1);
3732 else
3733 move_gap (end2);
3734 }
3735
3736 start1_byte = CHAR_TO_BYTE (start1);
3737 start2_byte = CHAR_TO_BYTE (start2);
3738 len1_byte = CHAR_TO_BYTE (end1) - start1_byte;
3739 len2_byte = CHAR_TO_BYTE (end2) - start2_byte;
3740
3741#ifdef BYTE_COMBINING_DEBUG
3742 if (end1 == start2)
3743 {
3744 if (count_combining_before (BYTE_POS_ADDR (start2_byte),
3745 len2_byte, start1, start1_byte)
3746 || count_combining_before (BYTE_POS_ADDR (start1_byte),
3747 len1_byte, end2, start2_byte + len2_byte)
3748 || count_combining_after (BYTE_POS_ADDR (start1_byte),
3749 len1_byte, end2, start2_byte + len2_byte))
3750 abort ();
3751 }
3752 else
3753 {
3754 if (count_combining_before (BYTE_POS_ADDR (start2_byte),
3755 len2_byte, start1, start1_byte)
3756 || count_combining_before (BYTE_POS_ADDR (start1_byte),
3757 len1_byte, start2, start2_byte)
3758 || count_combining_after (BYTE_POS_ADDR (start2_byte),
3759 len2_byte, end1, start1_byte + len1_byte)
3760 || count_combining_after (BYTE_POS_ADDR (start1_byte),
3761 len1_byte, end2, start2_byte + len2_byte))
3762 abort ();
3763 }
3764#endif
3765
3766 /* Hmmm... how about checking to see if the gap is large
3767 enough to use as the temporary storage? That would avoid an
3768 allocation... interesting. Later, don't fool with it now. */
3769
3770 /* Working without memmove, for portability (sigh), so must be
3771 careful of overlapping subsections of the array... */
3772
3773 if (end1 == start2) /* adjacent regions */
3774 {
3775 modify_region (current_buffer, start1, end2);
3776 record_change (start1, len1 + len2);
3777
3778 tmp_interval1 = copy_intervals (cur_intv, start1, len1);
3779 tmp_interval2 = copy_intervals (cur_intv, start2, len2);
3780 Fset_text_properties (make_number (start1), make_number (end2),
3781 Qnil, Qnil);
3782
3783 /* First region smaller than second. */
3784 if (len1_byte < len2_byte)
3785 {
3786 /* We use alloca only if it is small,
3787 because we want to avoid stack overflow. */
3788 if (len2_byte > 20000)
3789 temp = (unsigned char *) xmalloc (len2_byte);
3790 else
3791 temp = (unsigned char *) alloca (len2_byte);
3792
3793 /* Don't precompute these addresses. We have to compute them
3794 at the last minute, because the relocating allocator might
3795 have moved the buffer around during the xmalloc. */
3796 start1_addr = BYTE_POS_ADDR (start1_byte);
3797 start2_addr = BYTE_POS_ADDR (start2_byte);
3798
3799 bcopy (start2_addr, temp, len2_byte);
3800 bcopy (start1_addr, start1_addr + len2_byte, len1_byte);
3801 bcopy (temp, start1_addr, len2_byte);
3802 if (len2_byte > 20000)
3803 xfree (temp);
3804 }
3805 else
3806 /* First region not smaller than second. */
3807 {
3808 if (len1_byte > 20000)
3809 temp = (unsigned char *) xmalloc (len1_byte);
3810 else
3811 temp = (unsigned char *) alloca (len1_byte);
3812 start1_addr = BYTE_POS_ADDR (start1_byte);
3813 start2_addr = BYTE_POS_ADDR (start2_byte);
3814 bcopy (start1_addr, temp, len1_byte);
3815 bcopy (start2_addr, start1_addr, len2_byte);
3816 bcopy (temp, start1_addr + len2_byte, len1_byte);
3817 if (len1_byte > 20000)
3818 xfree (temp);
3819 }
3820 graft_intervals_into_buffer (tmp_interval1, start1 + len2,
3821 len1, current_buffer, 0);
3822 graft_intervals_into_buffer (tmp_interval2, start1,
3823 len2, current_buffer, 0);
3824 update_compositions (start1, start1 + len2, CHECK_BORDER);
3825 update_compositions (start1 + len2, end2, CHECK_TAIL);
3826 }
3827 /* Non-adjacent regions, because end1 != start2, bleagh... */
3828 else
3829 {
3830 len_mid = start2_byte - (start1_byte + len1_byte);
3831
3832 if (len1_byte == len2_byte)
3833 /* Regions are same size, though, how nice. */
3834 {
3835 modify_region (current_buffer, start1, end1);
3836 modify_region (current_buffer, start2, end2);
3837 record_change (start1, len1);
3838 record_change (start2, len2);
3839 tmp_interval1 = copy_intervals (cur_intv, start1, len1);
3840 tmp_interval2 = copy_intervals (cur_intv, start2, len2);
3841 Fset_text_properties (make_number (start1), make_number (end1),
3842 Qnil, Qnil);
3843 Fset_text_properties (make_number (start2), make_number (end2),
3844 Qnil, Qnil);
3845
3846 if (len1_byte > 20000)
3847 temp = (unsigned char *) xmalloc (len1_byte);
3848 else
3849 temp = (unsigned char *) alloca (len1_byte);
3850 start1_addr = BYTE_POS_ADDR (start1_byte);
3851 start2_addr = BYTE_POS_ADDR (start2_byte);
3852 bcopy (start1_addr, temp, len1_byte);
3853 bcopy (start2_addr, start1_addr, len2_byte);
3854 bcopy (temp, start2_addr, len1_byte);
3855 if (len1_byte > 20000)
3856 xfree (temp);
3857 graft_intervals_into_buffer (tmp_interval1, start2,
3858 len1, current_buffer, 0);
3859 graft_intervals_into_buffer (tmp_interval2, start1,
3860 len2, current_buffer, 0);
3861 }
3862
3863 else if (len1_byte < len2_byte) /* Second region larger than first */
3864 /* Non-adjacent & unequal size, area between must also be shifted. */
3865 {
3866 modify_region (current_buffer, start1, end2);
3867 record_change (start1, (end2 - start1));
3868 tmp_interval1 = copy_intervals (cur_intv, start1, len1);
3869 tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid);
3870 tmp_interval2 = copy_intervals (cur_intv, start2, len2);
3871 Fset_text_properties (make_number (start1), make_number (end2),
3872 Qnil, Qnil);
3873
3874 /* holds region 2 */
3875 if (len2_byte > 20000)
3876 temp = (unsigned char *) xmalloc (len2_byte);
3877 else
3878 temp = (unsigned char *) alloca (len2_byte);
3879 start1_addr = BYTE_POS_ADDR (start1_byte);
3880 start2_addr = BYTE_POS_ADDR (start2_byte);
3881 bcopy (start2_addr, temp, len2_byte);
3882 bcopy (start1_addr, start1_addr + len_mid + len2_byte, len1_byte);
3883 safe_bcopy (start1_addr + len1_byte, start1_addr + len2_byte, len_mid);
3884 bcopy (temp, start1_addr, len2_byte);
3885 if (len2_byte > 20000)
3886 xfree (temp);
3887 graft_intervals_into_buffer (tmp_interval1, end2 - len1,
3888 len1, current_buffer, 0);
3889 graft_intervals_into_buffer (tmp_interval_mid, start1 + len2,
3890 len_mid, current_buffer, 0);
3891 graft_intervals_into_buffer (tmp_interval2, start1,
3892 len2, current_buffer, 0);
3893 }
3894 else
3895 /* Second region smaller than first. */
3896 {
3897 record_change (start1, (end2 - start1));
3898 modify_region (current_buffer, start1, end2);
3899
3900 tmp_interval1 = copy_intervals (cur_intv, start1, len1);
3901 tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid);
3902 tmp_interval2 = copy_intervals (cur_intv, start2, len2);
3903 Fset_text_properties (make_number (start1), make_number (end2),
3904 Qnil, Qnil);
3905
3906 /* holds region 1 */
3907 if (len1_byte > 20000)
3908 temp = (unsigned char *) xmalloc (len1_byte);
3909 else
3910 temp = (unsigned char *) alloca (len1_byte);
3911 start1_addr = BYTE_POS_ADDR (start1_byte);
3912 start2_addr = BYTE_POS_ADDR (start2_byte);
3913 bcopy (start1_addr, temp, len1_byte);
3914 bcopy (start2_addr, start1_addr, len2_byte);
3915 bcopy (start1_addr + len1_byte, start1_addr + len2_byte, len_mid);
3916 bcopy (temp, start1_addr + len2_byte + len_mid, len1_byte);
3917 if (len1_byte > 20000)
3918 xfree (temp);
3919 graft_intervals_into_buffer (tmp_interval1, end2 - len1,
3920 len1, current_buffer, 0);
3921 graft_intervals_into_buffer (tmp_interval_mid, start1 + len2,
3922 len_mid, current_buffer, 0);
3923 graft_intervals_into_buffer (tmp_interval2, start1,
3924 len2, current_buffer, 0);
3925 }
3926
3927 update_compositions (start1, start1 + len2, CHECK_BORDER);
3928 update_compositions (end2 - len1, end2, CHECK_BORDER);
3929 }
3930
3931 /* When doing multiple transpositions, it might be nice
3932 to optimize this. Perhaps the markers in any one buffer
3933 should be organized in some sorted data tree. */
3934 if (NILP (leave_markers))
3935 {
3936 transpose_markers (start1, end1, start2, end2,
3937 start1_byte, start1_byte + len1_byte,
3938 start2_byte, start2_byte + len2_byte);
3939 fix_overlays_in_range (start1, end2);
3940 }
3941
3942 return Qnil;
3943}
3944
3945\f
3946void
3947syms_of_editfns ()
3948{
3949 environbuf = 0;
3950
3951 Qbuffer_access_fontify_functions
3952 = intern ("buffer-access-fontify-functions");
3953 staticpro (&Qbuffer_access_fontify_functions);
3954
3955 DEFVAR_LISP ("inhibit-field-text-motion", &Vinhibit_field_text_motion,
3956 doc: /* Non-nil means.text motion commands don't notice fields. */);
3957 Vinhibit_field_text_motion = Qnil;
3958
3959 DEFVAR_LISP ("buffer-access-fontify-functions",
3960 &Vbuffer_access_fontify_functions,
3961 doc: /* List of functions called by `buffer-substring' to fontify if necessary.
3962Each function is called with two arguments which specify the range
3963of the buffer being accessed. */);
3964 Vbuffer_access_fontify_functions = Qnil;
3965
3966 {
3967 Lisp_Object obuf;
3968 extern Lisp_Object Vprin1_to_string_buffer;
3969 obuf = Fcurrent_buffer ();
3970 /* Do this here, because init_buffer_once is too early--it won't work. */
3971 Fset_buffer (Vprin1_to_string_buffer);
3972 /* Make sure buffer-access-fontify-functions is nil in this buffer. */
3973 Fset (Fmake_local_variable (intern ("buffer-access-fontify-functions")),
3974 Qnil);
3975 Fset_buffer (obuf);
3976 }
3977
3978 DEFVAR_LISP ("buffer-access-fontified-property",
3979 &Vbuffer_access_fontified_property,
3980 doc: /* Property which (if non-nil) indicates text has been fontified.
3981`buffer-substring' need not call the `buffer-access-fontify-functions'
3982functions if all the text being accessed has this property. */);
3983 Vbuffer_access_fontified_property = Qnil;
3984
3985 DEFVAR_LISP ("system-name", &Vsystem_name,
3986 doc: /* The name of the machine Emacs is running on. */);
3987
3988 DEFVAR_LISP ("user-full-name", &Vuser_full_name,
3989 doc: /* The full name of the user logged in. */);
3990
3991 DEFVAR_LISP ("user-login-name", &Vuser_login_name,
3992 doc: /* The user's name, taken from environment variables if possible. */);
3993
3994 DEFVAR_LISP ("user-real-login-name", &Vuser_real_login_name,
3995 doc: /* The user's name, based upon the real uid only. */);
3996
3997 defsubr (&Spropertize);
3998 defsubr (&Schar_equal);
3999 defsubr (&Sgoto_char);
4000 defsubr (&Sstring_to_char);
4001 defsubr (&Schar_to_string);
4002 defsubr (&Sbuffer_substring);
4003 defsubr (&Sbuffer_substring_no_properties);
4004 defsubr (&Sbuffer_string);
4005
4006 defsubr (&Spoint_marker);
4007 defsubr (&Smark_marker);
4008 defsubr (&Spoint);
4009 defsubr (&Sregion_beginning);
4010 defsubr (&Sregion_end);
4011
4012 staticpro (&Qfield);
4013 Qfield = intern ("field");
4014 staticpro (&Qboundary);
4015 Qboundary = intern ("boundary");
4016 defsubr (&Sfield_beginning);
4017 defsubr (&Sfield_end);
4018 defsubr (&Sfield_string);
4019 defsubr (&Sfield_string_no_properties);
4020 defsubr (&Sdelete_field);
4021 defsubr (&Sconstrain_to_field);
4022
4023 defsubr (&Sline_beginning_position);
4024 defsubr (&Sline_end_position);
4025
4026/* defsubr (&Smark); */
4027/* defsubr (&Sset_mark); */
4028 defsubr (&Ssave_excursion);
4029 defsubr (&Ssave_current_buffer);
4030
4031 defsubr (&Sbufsize);
4032 defsubr (&Spoint_max);
4033 defsubr (&Spoint_min);
4034 defsubr (&Spoint_min_marker);
4035 defsubr (&Spoint_max_marker);
4036 defsubr (&Sgap_position);
4037 defsubr (&Sgap_size);
4038 defsubr (&Sposition_bytes);
4039 defsubr (&Sbyte_to_position);
4040
4041 defsubr (&Sbobp);
4042 defsubr (&Seobp);
4043 defsubr (&Sbolp);
4044 defsubr (&Seolp);
4045 defsubr (&Sfollowing_char);
4046 defsubr (&Sprevious_char);
4047 defsubr (&Schar_after);
4048 defsubr (&Schar_before);
4049 defsubr (&Sinsert);
4050 defsubr (&Sinsert_before_markers);
4051 defsubr (&Sinsert_and_inherit);
4052 defsubr (&Sinsert_and_inherit_before_markers);
4053 defsubr (&Sinsert_char);
4054
4055 defsubr (&Suser_login_name);
4056 defsubr (&Suser_real_login_name);
4057 defsubr (&Suser_uid);
4058 defsubr (&Suser_real_uid);
4059 defsubr (&Suser_full_name);
4060 defsubr (&Semacs_pid);
4061 defsubr (&Scurrent_time);
4062 defsubr (&Sformat_time_string);
4063 defsubr (&Sfloat_time);
4064 defsubr (&Sdecode_time);
4065 defsubr (&Sencode_time);
4066 defsubr (&Scurrent_time_string);
4067 defsubr (&Scurrent_time_zone);
4068 defsubr (&Sset_time_zone_rule);
4069 defsubr (&Ssystem_name);
4070 defsubr (&Smessage);
4071 defsubr (&Smessage_box);
4072 defsubr (&Smessage_or_box);
4073 defsubr (&Scurrent_message);
4074 defsubr (&Sformat);
4075
4076 defsubr (&Sinsert_buffer_substring);
4077 defsubr (&Scompare_buffer_substrings);
4078 defsubr (&Ssubst_char_in_region);
4079 defsubr (&Stranslate_region);
4080 defsubr (&Sdelete_region);
4081 defsubr (&Sdelete_and_extract_region);
4082 defsubr (&Swiden);
4083 defsubr (&Snarrow_to_region);
4084 defsubr (&Ssave_restriction);
4085 defsubr (&Stranspose_regions);
4086}