]> code.delx.au - gnu-emacs/blob - src/editfns.c
(change_frame_size): Keep cursor coords in range.
[gnu-emacs] / src / editfns.c
1 /* Lisp functions pertaining to editing.
2 Copyright (C) 1985,86,87,89,93,94 Free Software Foundation, Inc.
3
4 This file is part of GNU Emacs.
5
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 1, or (at your option)
9 any later version.
10
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21 #include <sys/types.h>
22
23 #include <config.h>
24
25 #ifdef VMS
26 #include "vms-pwd.h"
27 #else
28 #include <pwd.h>
29 #endif
30
31 #include "lisp.h"
32 #include "intervals.h"
33 #include "buffer.h"
34 #include "window.h"
35
36 #include "systime.h"
37
38 #define min(a, b) ((a) < (b) ? (a) : (b))
39 #define max(a, b) ((a) > (b) ? (a) : (b))
40
41 /* Some static data, and a function to initialize it for each run */
42
43 Lisp_Object Vsystem_name;
44 Lisp_Object Vuser_real_name; /* login name of current user ID */
45 Lisp_Object Vuser_full_name; /* full name of current user */
46 Lisp_Object Vuser_name; /* user name from LOGNAME or USER */
47
48 void
49 init_editfns ()
50 {
51 char *user_name;
52 register unsigned char *p, *q, *r;
53 struct passwd *pw; /* password entry for the current user */
54 extern char *index ();
55 Lisp_Object tem;
56
57 /* Set up system_name even when dumping. */
58
59 Vsystem_name = build_string (get_system_name ());
60 p = XSTRING (Vsystem_name)->data;
61 while (*p)
62 {
63 if (*p == ' ' || *p == '\t')
64 *p = '-';
65 p++;
66 }
67
68 #ifndef CANNOT_DUMP
69 /* Don't bother with this on initial start when just dumping out */
70 if (!initialized)
71 return;
72 #endif /* not CANNOT_DUMP */
73
74 pw = (struct passwd *) getpwuid (getuid ());
75 Vuser_real_name = build_string (pw ? pw->pw_name : "unknown");
76
77 /* Get the effective user name, by consulting environment variables,
78 or the effective uid if those are unset. */
79 user_name = (char *) getenv ("LOGNAME");
80 if (!user_name)
81 user_name = (char *) getenv ("USER");
82 if (!user_name)
83 {
84 pw = (struct passwd *) getpwuid (geteuid ());
85 user_name = (char *) (pw ? pw->pw_name : "unknown");
86 }
87 Vuser_name = build_string (user_name);
88
89 /* If the user name claimed in the environment vars differs from
90 the real uid, use the claimed name to find the full name. */
91 tem = Fstring_equal (Vuser_name, Vuser_real_name);
92 if (NILP (tem))
93 pw = (struct passwd *) getpwnam (XSTRING (Vuser_name)->data);
94
95 p = (unsigned char *) (pw ? USER_FULL_NAME : "unknown");
96 q = (unsigned char *) index (p, ',');
97 Vuser_full_name = make_string (p, q ? q - p : strlen (p));
98
99 #ifdef AMPERSAND_FULL_NAME
100 p = XSTRING (Vuser_full_name)->data;
101 q = (char *) index (p, '&');
102 /* Substitute the login name for the &, upcasing the first character. */
103 if (q)
104 {
105 r = (char *) alloca (strlen (p) + XSTRING (Vuser_name)->size + 1);
106 bcopy (p, r, q - p);
107 r[q - p] = 0;
108 strcat (r, XSTRING (Vuser_name)->data);
109 r[q - p] = UPCASE (r[q - p]);
110 strcat (r, q + 1);
111 Vuser_full_name = build_string (r);
112 }
113 #endif /* AMPERSAND_FULL_NAME */
114 }
115 \f
116 DEFUN ("char-to-string", Fchar_to_string, Schar_to_string, 1, 1, 0,
117 "Convert arg CHAR to a one-character string containing that character.")
118 (n)
119 Lisp_Object n;
120 {
121 char c;
122 CHECK_NUMBER (n, 0);
123
124 c = XINT (n);
125 return make_string (&c, 1);
126 }
127
128 DEFUN ("string-to-char", Fstring_to_char, Sstring_to_char, 1, 1, 0,
129 "Convert arg STRING to a character, the first character of that string.")
130 (str)
131 register Lisp_Object str;
132 {
133 register Lisp_Object val;
134 register struct Lisp_String *p;
135 CHECK_STRING (str, 0);
136
137 p = XSTRING (str);
138 if (p->size)
139 XFASTINT (val) = ((unsigned char *) p->data)[0];
140 else
141 XFASTINT (val) = 0;
142 return val;
143 }
144 \f
145 static Lisp_Object
146 buildmark (val)
147 int val;
148 {
149 register Lisp_Object mark;
150 mark = Fmake_marker ();
151 Fset_marker (mark, make_number (val), Qnil);
152 return mark;
153 }
154
155 DEFUN ("point", Fpoint, Spoint, 0, 0, 0,
156 "Return value of point, as an integer.\n\
157 Beginning of buffer is position (point-min)")
158 ()
159 {
160 Lisp_Object temp;
161 XFASTINT (temp) = point;
162 return temp;
163 }
164
165 DEFUN ("point-marker", Fpoint_marker, Spoint_marker, 0, 0, 0,
166 "Return value of point, as a marker object.")
167 ()
168 {
169 return buildmark (point);
170 }
171
172 int
173 clip_to_bounds (lower, num, upper)
174 int lower, num, upper;
175 {
176 if (num < lower)
177 return lower;
178 else if (num > upper)
179 return upper;
180 else
181 return num;
182 }
183
184 DEFUN ("goto-char", Fgoto_char, Sgoto_char, 1, 1, "NGoto char: ",
185 "Set point to POSITION, a number or marker.\n\
186 Beginning of buffer is position (point-min), end is (point-max).")
187 (n)
188 register Lisp_Object n;
189 {
190 CHECK_NUMBER_COERCE_MARKER (n, 0);
191
192 SET_PT (clip_to_bounds (BEGV, XINT (n), ZV));
193 return n;
194 }
195
196 static Lisp_Object
197 region_limit (beginningp)
198 int beginningp;
199 {
200 extern Lisp_Object Vmark_even_if_inactive; /* Defined in callint.c. */
201 register Lisp_Object m;
202 if (!NILP (Vtransient_mark_mode) && NILP (Vmark_even_if_inactive)
203 && NILP (current_buffer->mark_active))
204 Fsignal (Qmark_inactive, Qnil);
205 m = Fmarker_position (current_buffer->mark);
206 if (NILP (m)) error ("There is no region now");
207 if ((point < XFASTINT (m)) == beginningp)
208 return (make_number (point));
209 else
210 return (m);
211 }
212
213 DEFUN ("region-beginning", Fregion_beginning, Sregion_beginning, 0, 0, 0,
214 "Return position of beginning of region, as an integer.")
215 ()
216 {
217 return (region_limit (1));
218 }
219
220 DEFUN ("region-end", Fregion_end, Sregion_end, 0, 0, 0,
221 "Return position of end of region, as an integer.")
222 ()
223 {
224 return (region_limit (0));
225 }
226
227 #if 0 /* now in lisp code */
228 DEFUN ("mark", Fmark, Smark, 0, 0, 0,
229 "Return this buffer's mark value as integer, or nil if no mark.\n\
230 If you are using this in an editing command, you are most likely making\n\
231 a mistake; see the documentation of `set-mark'.")
232 ()
233 {
234 return Fmarker_position (current_buffer->mark);
235 }
236 #endif /* commented out code */
237
238 DEFUN ("mark-marker", Fmark_marker, Smark_marker, 0, 0, 0,
239 "Return this buffer's mark, as a marker object.\n\
240 Watch out! Moving this marker changes the mark position.\n\
241 If you set the marker not to point anywhere, the buffer will have no mark.")
242 ()
243 {
244 return current_buffer->mark;
245 }
246
247 #if 0 /* this is now in lisp code */
248 DEFUN ("set-mark", Fset_mark, Sset_mark, 1, 1, 0,
249 "Set this buffer's mark to POS. Don't use this function!\n\
250 That is to say, don't use this function unless you want\n\
251 the user to see that the mark has moved, and you want the previous\n\
252 mark position to be lost.\n\
253 \n\
254 Normally, when a new mark is set, the old one should go on the stack.\n\
255 This is why most applications should use push-mark, not set-mark.\n\
256 \n\
257 Novice programmers often try to use the mark for the wrong purposes.\n\
258 The mark saves a location for the user's convenience.\n\
259 Most editing commands should not alter the mark.\n\
260 To remember a location for internal use in the Lisp program,\n\
261 store it in a Lisp variable. Example:\n\
262 \n\
263 (let ((beg (point))) (forward-line 1) (delete-region beg (point))).")
264 (pos)
265 Lisp_Object pos;
266 {
267 if (NILP (pos))
268 {
269 current_buffer->mark = Qnil;
270 return Qnil;
271 }
272 CHECK_NUMBER_COERCE_MARKER (pos, 0);
273
274 if (NILP (current_buffer->mark))
275 current_buffer->mark = Fmake_marker ();
276
277 Fset_marker (current_buffer->mark, pos, Qnil);
278 return pos;
279 }
280 #endif /* commented-out code */
281
282 Lisp_Object
283 save_excursion_save ()
284 {
285 register int visible = (XBUFFER (XWINDOW (selected_window)->buffer)
286 == current_buffer);
287
288 return Fcons (Fpoint_marker (),
289 Fcons (Fcopy_marker (current_buffer->mark),
290 Fcons (visible ? Qt : Qnil,
291 current_buffer->mark_active)));
292 }
293
294 Lisp_Object
295 save_excursion_restore (info)
296 register Lisp_Object info;
297 {
298 register Lisp_Object tem, tem1, omark, nmark;
299
300 tem = Fmarker_buffer (Fcar (info));
301 /* If buffer being returned to is now deleted, avoid error */
302 /* Otherwise could get error here while unwinding to top level
303 and crash */
304 /* In that case, Fmarker_buffer returns nil now. */
305 if (NILP (tem))
306 return Qnil;
307 Fset_buffer (tem);
308 tem = Fcar (info);
309 Fgoto_char (tem);
310 unchain_marker (tem);
311 tem = Fcar (Fcdr (info));
312 omark = Fmarker_position (current_buffer->mark);
313 Fset_marker (current_buffer->mark, tem, Fcurrent_buffer ());
314 nmark = Fmarker_position (tem);
315 unchain_marker (tem);
316 tem = Fcdr (Fcdr (info));
317 #if 0 /* We used to make the current buffer visible in the selected window
318 if that was true previously. That avoids some anomalies.
319 But it creates others, and it wasn't documented, and it is simpler
320 and cleaner never to alter the window/buffer connections. */
321 tem1 = Fcar (tem);
322 if (!NILP (tem1)
323 && current_buffer != XBUFFER (XWINDOW (selected_window)->buffer))
324 Fswitch_to_buffer (Fcurrent_buffer (), Qnil);
325 #endif /* 0 */
326
327 tem1 = current_buffer->mark_active;
328 current_buffer->mark_active = Fcdr (tem);
329 if (!NILP (Vrun_hooks))
330 {
331 /* If mark is active now, and either was not active
332 or was at a different place, run the activate hook. */
333 if (! NILP (current_buffer->mark_active))
334 {
335 if (! EQ (omark, nmark))
336 call1 (Vrun_hooks, intern ("activate-mark-hook"));
337 }
338 /* If mark has ceased to be active, run deactivate hook. */
339 else if (! NILP (tem1))
340 call1 (Vrun_hooks, intern ("deactivate-mark-hook"));
341 }
342 return Qnil;
343 }
344
345 DEFUN ("save-excursion", Fsave_excursion, Ssave_excursion, 0, UNEVALLED, 0,
346 "Save point, mark, and current buffer; execute BODY; restore those things.\n\
347 Executes BODY just like `progn'.\n\
348 The values of point, mark and the current buffer are restored\n\
349 even in case of abnormal exit (throw or error).\n\
350 The state of activation of the mark is also restored.")
351 (args)
352 Lisp_Object args;
353 {
354 register Lisp_Object val;
355 int count = specpdl_ptr - specpdl;
356
357 record_unwind_protect (save_excursion_restore, save_excursion_save ());
358
359 val = Fprogn (args);
360 return unbind_to (count, val);
361 }
362 \f
363 DEFUN ("buffer-size", Fbufsize, Sbufsize, 0, 0, 0,
364 "Return the number of characters in the current buffer.")
365 ()
366 {
367 Lisp_Object temp;
368 XFASTINT (temp) = Z - BEG;
369 return temp;
370 }
371
372 DEFUN ("point-min", Fpoint_min, Spoint_min, 0, 0, 0,
373 "Return the minimum permissible value of point in the current buffer.\n\
374 This is 1, unless narrowing (a buffer restriction) is in effect.")
375 ()
376 {
377 Lisp_Object temp;
378 XFASTINT (temp) = BEGV;
379 return temp;
380 }
381
382 DEFUN ("point-min-marker", Fpoint_min_marker, Spoint_min_marker, 0, 0, 0,
383 "Return a marker to the minimum permissible value of point in this buffer.\n\
384 This is the beginning, unless narrowing (a buffer restriction) is in effect.")
385 ()
386 {
387 return buildmark (BEGV);
388 }
389
390 DEFUN ("point-max", Fpoint_max, Spoint_max, 0, 0, 0,
391 "Return the maximum permissible value of point in the current buffer.\n\
392 This is (1+ (buffer-size)), unless narrowing (a buffer restriction)\n\
393 is in effect, in which case it is less.")
394 ()
395 {
396 Lisp_Object temp;
397 XFASTINT (temp) = ZV;
398 return temp;
399 }
400
401 DEFUN ("point-max-marker", Fpoint_max_marker, Spoint_max_marker, 0, 0, 0,
402 "Return a marker to the maximum permissible value of point in this buffer.\n\
403 This is (1+ (buffer-size)), unless narrowing (a buffer restriction)\n\
404 is in effect, in which case it is less.")
405 ()
406 {
407 return buildmark (ZV);
408 }
409
410 DEFUN ("following-char", Ffollowing_char, Sfollowing_char, 0, 0, 0,
411 "Return the character following point, as a number.\n\
412 At the end of the buffer or accessible region, return 0.")
413 ()
414 {
415 Lisp_Object temp;
416 if (point >= ZV)
417 XFASTINT (temp) = 0;
418 else
419 XFASTINT (temp) = FETCH_CHAR (point);
420 return temp;
421 }
422
423 DEFUN ("preceding-char", Fprevious_char, Sprevious_char, 0, 0, 0,
424 "Return the character preceding point, as a number.\n\
425 At the beginning of the buffer or accessible region, return 0.")
426 ()
427 {
428 Lisp_Object temp;
429 if (point <= BEGV)
430 XFASTINT (temp) = 0;
431 else
432 XFASTINT (temp) = FETCH_CHAR (point - 1);
433 return temp;
434 }
435
436 DEFUN ("bobp", Fbobp, Sbobp, 0, 0, 0,
437 "Return T if point is at the beginning of the buffer.\n\
438 If the buffer is narrowed, this means the beginning of the narrowed part.")
439 ()
440 {
441 if (point == BEGV)
442 return Qt;
443 return Qnil;
444 }
445
446 DEFUN ("eobp", Feobp, Seobp, 0, 0, 0,
447 "Return T if point is at the end of the buffer.\n\
448 If the buffer is narrowed, this means the end of the narrowed part.")
449 ()
450 {
451 if (point == ZV)
452 return Qt;
453 return Qnil;
454 }
455
456 DEFUN ("bolp", Fbolp, Sbolp, 0, 0, 0,
457 "Return T if point is at the beginning of a line.")
458 ()
459 {
460 if (point == BEGV || FETCH_CHAR (point - 1) == '\n')
461 return Qt;
462 return Qnil;
463 }
464
465 DEFUN ("eolp", Feolp, Seolp, 0, 0, 0,
466 "Return T if point is at the end of a line.\n\
467 `End of a line' includes point being at the end of the buffer.")
468 ()
469 {
470 if (point == ZV || FETCH_CHAR (point) == '\n')
471 return Qt;
472 return Qnil;
473 }
474
475 DEFUN ("char-after", Fchar_after, Schar_after, 1, 1, 0,
476 "Return character in current buffer at position POS.\n\
477 POS is an integer or a buffer pointer.\n\
478 If POS is out of range, the value is nil.")
479 (pos)
480 Lisp_Object pos;
481 {
482 register Lisp_Object val;
483 register int n;
484
485 CHECK_NUMBER_COERCE_MARKER (pos, 0);
486
487 n = XINT (pos);
488 if (n < BEGV || n >= ZV) return Qnil;
489
490 XFASTINT (val) = FETCH_CHAR (n);
491 return val;
492 }
493 \f
494 DEFUN ("user-login-name", Fuser_login_name, Suser_login_name, 0, 0, 0,
495 "Return the name under which the user logged in, as a string.\n\
496 This is based on the effective uid, not the real uid.\n\
497 Also, if the environment variable LOGNAME or USER is set,\n\
498 that determines the value of this function.")
499 ()
500 {
501 return Vuser_name;
502 }
503
504 DEFUN ("user-real-login-name", Fuser_real_login_name, Suser_real_login_name,
505 0, 0, 0,
506 "Return the name of the user's real uid, as a string.\n\
507 This ignores the environment variables LOGNAME and USER, so it differs from\n\
508 `user-login-name' when running under `su'.")
509 ()
510 {
511 return Vuser_real_name;
512 }
513
514 DEFUN ("user-uid", Fuser_uid, Suser_uid, 0, 0, 0,
515 "Return the effective uid of Emacs, as an integer.")
516 ()
517 {
518 return make_number (geteuid ());
519 }
520
521 DEFUN ("user-real-uid", Fuser_real_uid, Suser_real_uid, 0, 0, 0,
522 "Return the real uid of Emacs, as an integer.")
523 ()
524 {
525 return make_number (getuid ());
526 }
527
528 DEFUN ("user-full-name", Fuser_full_name, Suser_full_name, 0, 0, 0,
529 "Return the full name of the user logged in, as a string.")
530 ()
531 {
532 return Vuser_full_name;
533 }
534
535 DEFUN ("system-name", Fsystem_name, Ssystem_name, 0, 0, 0,
536 "Return the name of the machine you are running on, as a string.")
537 ()
538 {
539 return Vsystem_name;
540 }
541
542 DEFUN ("emacs-pid", Femacs_pid, Semacs_pid, 0, 0, 0,
543 "Return the process ID of Emacs, as an integer.")
544 ()
545 {
546 return make_number (getpid ());
547 }
548
549 DEFUN ("current-time", Fcurrent_time, Scurrent_time, 0, 0, 0,
550 "Return the current time, as the number of seconds since 12:00 AM January 1970.\n\
551 The time is returned as a list of three integers. The first has the\n\
552 most significant 16 bits of the seconds, while the second has the\n\
553 least significant 16 bits. The third integer gives the microsecond\n\
554 count.\n\
555 \n\
556 The microsecond count is zero on systems that do not provide\n\
557 resolution finer than a second.")
558 ()
559 {
560 EMACS_TIME t;
561 Lisp_Object result[3];
562
563 EMACS_GET_TIME (t);
564 XSET (result[0], Lisp_Int, (EMACS_SECS (t) >> 16) & 0xffff);
565 XSET (result[1], Lisp_Int, (EMACS_SECS (t) >> 0) & 0xffff);
566 XSET (result[2], Lisp_Int, EMACS_USECS (t));
567
568 return Flist (3, result);
569 }
570 \f
571
572 static int
573 lisp_time_argument (specified_time, result)
574 Lisp_Object specified_time;
575 time_t *result;
576 {
577 if (NILP (specified_time))
578 return time (result) != -1;
579 else
580 {
581 Lisp_Object high, low;
582 high = Fcar (specified_time);
583 CHECK_NUMBER (high, 0);
584 low = Fcdr (specified_time);
585 if (XTYPE (low) == Lisp_Cons)
586 low = Fcar (low);
587 CHECK_NUMBER (low, 0);
588 *result = (XINT (high) << 16) + (XINT (low) & 0xffff);
589 return *result >> 16 == XINT (high);
590 }
591 }
592
593 DEFUN ("current-time-string", Fcurrent_time_string, Scurrent_time_string, 0, 1, 0,
594 "Return the current time, as a human-readable string.\n\
595 Programs can use this function to decode a time,\n\
596 since the number of columns in each field is fixed.\n\
597 The format is `Sun Sep 16 01:03:52 1973'.\n\
598 If an argument is given, it specifies a time to format\n\
599 instead of the current time. The argument should have the form:\n\
600 (HIGH . LOW)\n\
601 or the form:\n\
602 (HIGH LOW . IGNORED).\n\
603 Thus, you can use times obtained from `current-time'\n\
604 and from `file-attributes'.")
605 (specified_time)
606 Lisp_Object specified_time;
607 {
608 time_t value;
609 char buf[30];
610 register char *tem;
611
612 if (! lisp_time_argument (specified_time, &value))
613 value = -1;
614 tem = (char *) ctime (&value);
615
616 strncpy (buf, tem, 24);
617 buf[24] = 0;
618
619 return build_string (buf);
620 }
621
622 #define TM_YEAR_ORIGIN 1900
623
624 /* Yield A - B, measured in seconds. */
625 static long
626 difftm (a, b)
627 struct tm *a, *b;
628 {
629 int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
630 int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
631 /* Some compilers can't handle this as a single return statement. */
632 int days = (
633 /* difference in day of year */
634 a->tm_yday - b->tm_yday
635 /* + intervening leap days */
636 + ((ay >> 2) - (by >> 2))
637 - (ay/100 - by/100)
638 + ((ay/100 >> 2) - (by/100 >> 2))
639 /* + difference in years * 365 */
640 + (long)(ay-by) * 365
641 );
642 return (60*(60*(24*days + (a->tm_hour - b->tm_hour))
643 + (a->tm_min - b->tm_min))
644 + (a->tm_sec - b->tm_sec));
645 }
646
647 DEFUN ("current-time-zone", Fcurrent_time_zone, Scurrent_time_zone, 0, 1, 0,
648 "Return the offset and name for the local time zone.\n\
649 This returns a list of the form (OFFSET NAME).\n\
650 OFFSET is an integer number of seconds ahead of UTC (east of Greenwich).\n\
651 A negative value means west of Greenwich.\n\
652 NAME is a string giving the name of the time zone.\n\
653 If an argument is given, it specifies when the time zone offset is determined\n\
654 instead of using the current time. The argument should have the form:\n\
655 (HIGH . LOW)\n\
656 or the form:\n\
657 (HIGH LOW . IGNORED).\n\
658 Thus, you can use times obtained from `current-time'\n\
659 and from `file-attributes'.\n\
660 \n\
661 Some operating systems cannot provide all this information to Emacs;\n\
662 in this case, `current-time-zone' returns a list containing nil for\n\
663 the data it can't find.")
664 (specified_time)
665 Lisp_Object specified_time;
666 {
667 time_t value;
668 struct tm *t;
669
670 if (lisp_time_argument (specified_time, &value)
671 && (t = gmtime (&value)) != 0)
672 {
673 struct tm gmt;
674 long offset;
675 char *s, buf[6];
676
677 gmt = *t; /* Make a copy, in case localtime modifies *t. */
678 t = localtime (&value);
679 offset = difftm (t, &gmt);
680 s = 0;
681 #ifdef HAVE_TM_ZONE
682 if (t->tm_zone)
683 s = (char *)t->tm_zone;
684 #else /* not HAVE_TM_ZONE */
685 #ifdef HAVE_TZNAME
686 if (t->tm_isdst == 0 || t->tm_isdst == 1)
687 s = tzname[t->tm_isdst];
688 #endif
689 #endif /* not HAVE_TM_ZONE */
690 if (!s)
691 {
692 /* No local time zone name is available; use "+-NNNN" instead. */
693 int am = (offset < 0 ? -offset : offset) / 60;
694 sprintf (buf, "%c%02d%02d", (offset < 0 ? '-' : '+'), am/60, am%60);
695 s = buf;
696 }
697 return Fcons (make_number (offset), Fcons (build_string (s), Qnil));
698 }
699 else
700 return Fmake_list (2, Qnil);
701 }
702
703 \f
704 void
705 insert1 (arg)
706 Lisp_Object arg;
707 {
708 Finsert (1, &arg);
709 }
710
711
712 /* Callers passing one argument to Finsert need not gcpro the
713 argument "array", since the only element of the array will
714 not be used after calling insert or insert_from_string, so
715 we don't care if it gets trashed. */
716
717 DEFUN ("insert", Finsert, Sinsert, 0, MANY, 0,
718 "Insert the arguments, either strings or characters, at point.\n\
719 Point moves forward so that it ends up after the inserted text.\n\
720 Any other markers at the point of insertion remain before the text.")
721 (nargs, args)
722 int nargs;
723 register Lisp_Object *args;
724 {
725 register int argnum;
726 register Lisp_Object tem;
727 char str[1];
728
729 for (argnum = 0; argnum < nargs; argnum++)
730 {
731 tem = args[argnum];
732 retry:
733 if (XTYPE (tem) == Lisp_Int)
734 {
735 str[0] = XINT (tem);
736 insert (str, 1);
737 }
738 else if (XTYPE (tem) == Lisp_String)
739 {
740 insert_from_string (tem, 0, XSTRING (tem)->size, 0);
741 }
742 else
743 {
744 tem = wrong_type_argument (Qchar_or_string_p, tem);
745 goto retry;
746 }
747 }
748
749 return Qnil;
750 }
751
752 DEFUN ("insert-and-inherit", Finsert_and_inherit, Sinsert_and_inherit,
753 0, MANY, 0,
754 "Insert the arguments at point, inheriting properties from adjoining text.\n\
755 Point moves forward so that it ends up after the inserted text.\n\
756 Any other markers at the point of insertion remain before the text.")
757 (nargs, args)
758 int nargs;
759 register Lisp_Object *args;
760 {
761 register int argnum;
762 register Lisp_Object tem;
763 char str[1];
764
765 for (argnum = 0; argnum < nargs; argnum++)
766 {
767 tem = args[argnum];
768 retry:
769 if (XTYPE (tem) == Lisp_Int)
770 {
771 str[0] = XINT (tem);
772 insert (str, 1);
773 }
774 else if (XTYPE (tem) == Lisp_String)
775 {
776 insert_from_string (tem, 0, XSTRING (tem)->size, 1);
777 }
778 else
779 {
780 tem = wrong_type_argument (Qchar_or_string_p, tem);
781 goto retry;
782 }
783 }
784
785 return Qnil;
786 }
787
788 DEFUN ("insert-before-markers", Finsert_before_markers, Sinsert_before_markers, 0, MANY, 0,
789 "Insert strings or characters at point, relocating markers after the text.\n\
790 Point moves forward so that it ends up after the inserted text.\n\
791 Any other markers at the point of insertion also end up after the text.")
792 (nargs, args)
793 int nargs;
794 register Lisp_Object *args;
795 {
796 register int argnum;
797 register Lisp_Object tem;
798 char str[1];
799
800 for (argnum = 0; argnum < nargs; argnum++)
801 {
802 tem = args[argnum];
803 retry:
804 if (XTYPE (tem) == Lisp_Int)
805 {
806 str[0] = XINT (tem);
807 insert_before_markers (str, 1);
808 }
809 else if (XTYPE (tem) == Lisp_String)
810 {
811 insert_from_string_before_markers (tem, 0, XSTRING (tem)->size, 0);
812 }
813 else
814 {
815 tem = wrong_type_argument (Qchar_or_string_p, tem);
816 goto retry;
817 }
818 }
819
820 return Qnil;
821 }
822
823 DEFUN ("insert-before-markers-and-inherit",
824 Finsert_and_inherit_before_markers, Sinsert_and_inherit_before_markers,
825 0, MANY, 0,
826 "Insert text at point, relocating markers and inheriting properties.\n\
827 Point moves forward so that it ends up after the inserted text.\n\
828 Any other markers at the point of insertion also end up after the text.")
829 (nargs, args)
830 int nargs;
831 register Lisp_Object *args;
832 {
833 register int argnum;
834 register Lisp_Object tem;
835 char str[1];
836
837 for (argnum = 0; argnum < nargs; argnum++)
838 {
839 tem = args[argnum];
840 retry:
841 if (XTYPE (tem) == Lisp_Int)
842 {
843 str[0] = XINT (tem);
844 insert_before_markers (str, 1);
845 }
846 else if (XTYPE (tem) == Lisp_String)
847 {
848 insert_from_string_before_markers (tem, 0, XSTRING (tem)->size, 1);
849 }
850 else
851 {
852 tem = wrong_type_argument (Qchar_or_string_p, tem);
853 goto retry;
854 }
855 }
856
857 return Qnil;
858 }
859 \f
860 DEFUN ("insert-char", Finsert_char, Sinsert_char, 2, 2, 0,
861 "Insert COUNT (second arg) copies of CHAR (first arg).\n\
862 Point and all markers are affected as in the function `insert'.\n\
863 Both arguments are required.")
864 (chr, count)
865 Lisp_Object chr, count;
866 {
867 register unsigned char *string;
868 register int strlen;
869 register int i, n;
870
871 CHECK_NUMBER (chr, 0);
872 CHECK_NUMBER (count, 1);
873
874 n = XINT (count);
875 if (n <= 0)
876 return Qnil;
877 strlen = min (n, 256);
878 string = (unsigned char *) alloca (strlen);
879 for (i = 0; i < strlen; i++)
880 string[i] = XFASTINT (chr);
881 while (n >= strlen)
882 {
883 insert (string, strlen);
884 n -= strlen;
885 }
886 if (n > 0)
887 insert (string, n);
888 return Qnil;
889 }
890
891 \f
892 /* Making strings from buffer contents. */
893
894 /* Return a Lisp_String containing the text of the current buffer from
895 START to END. If text properties are in use and the current buffer
896 has properties in the range specified, the resulting string will also
897 have them.
898
899 We don't want to use plain old make_string here, because it calls
900 make_uninit_string, which can cause the buffer arena to be
901 compacted. make_string has no way of knowing that the data has
902 been moved, and thus copies the wrong data into the string. This
903 doesn't effect most of the other users of make_string, so it should
904 be left as is. But we should use this function when conjuring
905 buffer substrings. */
906
907 Lisp_Object
908 make_buffer_string (start, end)
909 int start, end;
910 {
911 Lisp_Object result, tem, tem1;
912
913 if (start < GPT && GPT < end)
914 move_gap (start);
915
916 result = make_uninit_string (end - start);
917 bcopy (&FETCH_CHAR (start), XSTRING (result)->data, end - start);
918
919 tem = Fnext_property_change (make_number (start), Qnil, make_number (end));
920 tem1 = Ftext_properties_at (make_number (start), Qnil);
921
922 #ifdef USE_TEXT_PROPERTIES
923 if (XINT (tem) != end || !NILP (tem1))
924 copy_intervals_to_string (result, current_buffer, start, end - start);
925 #endif
926
927 return result;
928 }
929
930 DEFUN ("buffer-substring", Fbuffer_substring, Sbuffer_substring, 2, 2, 0,
931 "Return the contents of part of the current buffer as a string.\n\
932 The two arguments START and END are character positions;\n\
933 they can be in either order.")
934 (b, e)
935 Lisp_Object b, e;
936 {
937 register int beg, end;
938
939 validate_region (&b, &e);
940 beg = XINT (b);
941 end = XINT (e);
942
943 return make_buffer_string (beg, end);
944 }
945
946 DEFUN ("buffer-string", Fbuffer_string, Sbuffer_string, 0, 0, 0,
947 "Return the contents of the current buffer as a string.")
948 ()
949 {
950 return make_buffer_string (BEGV, ZV);
951 }
952
953 DEFUN ("insert-buffer-substring", Finsert_buffer_substring, Sinsert_buffer_substring,
954 1, 3, 0,
955 "Insert before point a substring of the contents of buffer BUFFER.\n\
956 BUFFER may be a buffer or a buffer name.\n\
957 Arguments START and END are character numbers specifying the substring.\n\
958 They default to the beginning and the end of BUFFER.")
959 (buf, b, e)
960 Lisp_Object buf, b, e;
961 {
962 register int beg, end, temp, len, opoint, start;
963 register struct buffer *bp;
964 Lisp_Object buffer;
965
966 buffer = Fget_buffer (buf);
967 if (NILP (buffer))
968 nsberror (buf);
969 bp = XBUFFER (buffer);
970
971 if (NILP (b))
972 beg = BUF_BEGV (bp);
973 else
974 {
975 CHECK_NUMBER_COERCE_MARKER (b, 0);
976 beg = XINT (b);
977 }
978 if (NILP (e))
979 end = BUF_ZV (bp);
980 else
981 {
982 CHECK_NUMBER_COERCE_MARKER (e, 1);
983 end = XINT (e);
984 }
985
986 if (beg > end)
987 temp = beg, beg = end, end = temp;
988
989 /* Move the gap or create enough gap in the current buffer. */
990
991 if (point != GPT)
992 move_gap (point);
993 if (GAP_SIZE < end - beg)
994 make_gap (end - beg - GAP_SIZE);
995
996 len = end - beg;
997 start = beg;
998 opoint = point;
999
1000 if (!(BUF_BEGV (bp) <= beg
1001 && beg <= end
1002 && end <= BUF_ZV (bp)))
1003 args_out_of_range (b, e);
1004
1005 /* Now the actual insertion will not do any gap motion,
1006 so it matters not if BUF is the current buffer. */
1007 if (beg < BUF_GPT (bp))
1008 {
1009 insert (BUF_CHAR_ADDRESS (bp, beg), min (end, BUF_GPT (bp)) - beg);
1010 beg = min (end, BUF_GPT (bp));
1011 }
1012 if (beg < end)
1013 insert (BUF_CHAR_ADDRESS (bp, beg), end - beg);
1014
1015 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
1016 graft_intervals_into_buffer (copy_intervals (bp->intervals, start, len),
1017 opoint, len, current_buffer, 0);
1018
1019 return Qnil;
1020 }
1021
1022 DEFUN ("compare-buffer-substrings", Fcompare_buffer_substrings, Scompare_buffer_substrings,
1023 6, 6, 0,
1024 "Compare two substrings of two buffers; return result as number.\n\
1025 the value is -N if first string is less after N-1 chars,\n\
1026 +N if first string is greater after N-1 chars, or 0 if strings match.\n\
1027 Each substring is represented as three arguments: BUFFER, START and END.\n\
1028 That makes six args in all, three for each substring.\n\n\
1029 The value of `case-fold-search' in the current buffer\n\
1030 determines whether case is significant or ignored.")
1031 (buffer1, start1, end1, buffer2, start2, end2)
1032 Lisp_Object buffer1, start1, end1, buffer2, start2, end2;
1033 {
1034 register int begp1, endp1, begp2, endp2, temp, len1, len2, length, i;
1035 register struct buffer *bp1, *bp2;
1036 register unsigned char *trt
1037 = (!NILP (current_buffer->case_fold_search)
1038 ? XSTRING (current_buffer->case_canon_table)->data : 0);
1039
1040 /* Find the first buffer and its substring. */
1041
1042 if (NILP (buffer1))
1043 bp1 = current_buffer;
1044 else
1045 {
1046 Lisp_Object buf1;
1047 buf1 = Fget_buffer (buffer1);
1048 if (NILP (buf1))
1049 nsberror (buffer1);
1050 bp1 = XBUFFER (buf1);
1051 }
1052
1053 if (NILP (start1))
1054 begp1 = BUF_BEGV (bp1);
1055 else
1056 {
1057 CHECK_NUMBER_COERCE_MARKER (start1, 1);
1058 begp1 = XINT (start1);
1059 }
1060 if (NILP (end1))
1061 endp1 = BUF_ZV (bp1);
1062 else
1063 {
1064 CHECK_NUMBER_COERCE_MARKER (end1, 2);
1065 endp1 = XINT (end1);
1066 }
1067
1068 if (begp1 > endp1)
1069 temp = begp1, begp1 = endp1, endp1 = temp;
1070
1071 if (!(BUF_BEGV (bp1) <= begp1
1072 && begp1 <= endp1
1073 && endp1 <= BUF_ZV (bp1)))
1074 args_out_of_range (start1, end1);
1075
1076 /* Likewise for second substring. */
1077
1078 if (NILP (buffer2))
1079 bp2 = current_buffer;
1080 else
1081 {
1082 Lisp_Object buf2;
1083 buf2 = Fget_buffer (buffer2);
1084 if (NILP (buf2))
1085 nsberror (buffer2);
1086 bp2 = XBUFFER (buffer2);
1087 }
1088
1089 if (NILP (start2))
1090 begp2 = BUF_BEGV (bp2);
1091 else
1092 {
1093 CHECK_NUMBER_COERCE_MARKER (start2, 4);
1094 begp2 = XINT (start2);
1095 }
1096 if (NILP (end2))
1097 endp2 = BUF_ZV (bp2);
1098 else
1099 {
1100 CHECK_NUMBER_COERCE_MARKER (end2, 5);
1101 endp2 = XINT (end2);
1102 }
1103
1104 if (begp2 > endp2)
1105 temp = begp2, begp2 = endp2, endp2 = temp;
1106
1107 if (!(BUF_BEGV (bp2) <= begp2
1108 && begp2 <= endp2
1109 && endp2 <= BUF_ZV (bp2)))
1110 args_out_of_range (start2, end2);
1111
1112 len1 = endp1 - begp1;
1113 len2 = endp2 - begp2;
1114 length = len1;
1115 if (len2 < length)
1116 length = len2;
1117
1118 for (i = 0; i < length; i++)
1119 {
1120 int c1 = *BUF_CHAR_ADDRESS (bp1, begp1 + i);
1121 int c2 = *BUF_CHAR_ADDRESS (bp2, begp2 + i);
1122 if (trt)
1123 {
1124 c1 = trt[c1];
1125 c2 = trt[c2];
1126 }
1127 if (c1 < c2)
1128 return make_number (- 1 - i);
1129 if (c1 > c2)
1130 return make_number (i + 1);
1131 }
1132
1133 /* The strings match as far as they go.
1134 If one is shorter, that one is less. */
1135 if (length < len1)
1136 return make_number (length + 1);
1137 else if (length < len2)
1138 return make_number (- length - 1);
1139
1140 /* Same length too => they are equal. */
1141 return make_number (0);
1142 }
1143 \f
1144 DEFUN ("subst-char-in-region", Fsubst_char_in_region,
1145 Ssubst_char_in_region, 4, 5, 0,
1146 "From START to END, replace FROMCHAR with TOCHAR each time it occurs.\n\
1147 If optional arg NOUNDO is non-nil, don't record this change for undo\n\
1148 and don't mark the buffer as really changed.")
1149 (start, end, fromchar, tochar, noundo)
1150 Lisp_Object start, end, fromchar, tochar, noundo;
1151 {
1152 register int pos, stop, look;
1153 int changed = 0;
1154
1155 validate_region (&start, &end);
1156 CHECK_NUMBER (fromchar, 2);
1157 CHECK_NUMBER (tochar, 3);
1158
1159 pos = XINT (start);
1160 stop = XINT (end);
1161 look = XINT (fromchar);
1162
1163 while (pos < stop)
1164 {
1165 if (FETCH_CHAR (pos) == look)
1166 {
1167 if (! changed)
1168 {
1169 modify_region (current_buffer, XINT (start), stop);
1170
1171 if (! NILP (noundo))
1172 {
1173 if (MODIFF - 1 == current_buffer->save_modified)
1174 current_buffer->save_modified++;
1175 if (MODIFF - 1 == current_buffer->auto_save_modified)
1176 current_buffer->auto_save_modified++;
1177 }
1178
1179 changed = 1;
1180 }
1181
1182 if (NILP (noundo))
1183 record_change (pos, 1);
1184 FETCH_CHAR (pos) = XINT (tochar);
1185 }
1186 pos++;
1187 }
1188
1189 if (changed)
1190 signal_after_change (XINT (start),
1191 stop - XINT (start), stop - XINT (start));
1192
1193 return Qnil;
1194 }
1195
1196 DEFUN ("translate-region", Ftranslate_region, Stranslate_region, 3, 3, 0,
1197 "From START to END, translate characters according to TABLE.\n\
1198 TABLE is a string; the Nth character in it is the mapping\n\
1199 for the character with code N. Returns the number of characters changed.")
1200 (start, end, table)
1201 Lisp_Object start;
1202 Lisp_Object end;
1203 register Lisp_Object table;
1204 {
1205 register int pos, stop; /* Limits of the region. */
1206 register unsigned char *tt; /* Trans table. */
1207 register int oc; /* Old character. */
1208 register int nc; /* New character. */
1209 int cnt; /* Number of changes made. */
1210 Lisp_Object z; /* Return. */
1211 int size; /* Size of translate table. */
1212
1213 validate_region (&start, &end);
1214 CHECK_STRING (table, 2);
1215
1216 size = XSTRING (table)->size;
1217 tt = XSTRING (table)->data;
1218
1219 pos = XINT (start);
1220 stop = XINT (end);
1221 modify_region (current_buffer, pos, stop);
1222
1223 cnt = 0;
1224 for (; pos < stop; ++pos)
1225 {
1226 oc = FETCH_CHAR (pos);
1227 if (oc < size)
1228 {
1229 nc = tt[oc];
1230 if (nc != oc)
1231 {
1232 record_change (pos, 1);
1233 FETCH_CHAR (pos) = nc;
1234 signal_after_change (pos, 1, 1);
1235 ++cnt;
1236 }
1237 }
1238 }
1239
1240 XFASTINT (z) = cnt;
1241 return (z);
1242 }
1243
1244 DEFUN ("delete-region", Fdelete_region, Sdelete_region, 2, 2, "r",
1245 "Delete the text between point and mark.\n\
1246 When called from a program, expects two arguments,\n\
1247 positions (integers or markers) specifying the stretch to be deleted.")
1248 (b, e)
1249 Lisp_Object b, e;
1250 {
1251 validate_region (&b, &e);
1252 del_range (XINT (b), XINT (e));
1253 return Qnil;
1254 }
1255 \f
1256 DEFUN ("widen", Fwiden, Swiden, 0, 0, "",
1257 "Remove restrictions (narrowing) from current buffer.\n\
1258 This allows the buffer's full text to be seen and edited.")
1259 ()
1260 {
1261 BEGV = BEG;
1262 SET_BUF_ZV (current_buffer, Z);
1263 clip_changed = 1;
1264 /* Changing the buffer bounds invalidates any recorded current column. */
1265 invalidate_current_column ();
1266 return Qnil;
1267 }
1268
1269 DEFUN ("narrow-to-region", Fnarrow_to_region, Snarrow_to_region, 2, 2, "r",
1270 "Restrict editing in this buffer to the current region.\n\
1271 The rest of the text becomes temporarily invisible and untouchable\n\
1272 but is not deleted; if you save the buffer in a file, the invisible\n\
1273 text is included in the file. \\[widen] makes all visible again.\n\
1274 See also `save-restriction'.\n\
1275 \n\
1276 When calling from a program, pass two arguments; positions (integers\n\
1277 or markers) bounding the text that should remain visible.")
1278 (b, e)
1279 register Lisp_Object b, e;
1280 {
1281 register int i;
1282
1283 CHECK_NUMBER_COERCE_MARKER (b, 0);
1284 CHECK_NUMBER_COERCE_MARKER (e, 1);
1285
1286 if (XINT (b) > XINT (e))
1287 {
1288 i = XFASTINT (b);
1289 b = e;
1290 XFASTINT (e) = i;
1291 }
1292
1293 if (!(BEG <= XINT (b) && XINT (b) <= XINT (e) && XINT (e) <= Z))
1294 args_out_of_range (b, e);
1295
1296 BEGV = XFASTINT (b);
1297 SET_BUF_ZV (current_buffer, XFASTINT (e));
1298 if (point < XFASTINT (b))
1299 SET_PT (XFASTINT (b));
1300 if (point > XFASTINT (e))
1301 SET_PT (XFASTINT (e));
1302 clip_changed = 1;
1303 /* Changing the buffer bounds invalidates any recorded current column. */
1304 invalidate_current_column ();
1305 return Qnil;
1306 }
1307
1308 Lisp_Object
1309 save_restriction_save ()
1310 {
1311 register Lisp_Object bottom, top;
1312 /* Note: I tried using markers here, but it does not win
1313 because insertion at the end of the saved region
1314 does not advance mh and is considered "outside" the saved region. */
1315 XFASTINT (bottom) = BEGV - BEG;
1316 XFASTINT (top) = Z - ZV;
1317
1318 return Fcons (Fcurrent_buffer (), Fcons (bottom, top));
1319 }
1320
1321 Lisp_Object
1322 save_restriction_restore (data)
1323 Lisp_Object data;
1324 {
1325 register struct buffer *buf;
1326 register int newhead, newtail;
1327 register Lisp_Object tem;
1328
1329 buf = XBUFFER (XCONS (data)->car);
1330
1331 data = XCONS (data)->cdr;
1332
1333 tem = XCONS (data)->car;
1334 newhead = XINT (tem);
1335 tem = XCONS (data)->cdr;
1336 newtail = XINT (tem);
1337 if (newhead + newtail > BUF_Z (buf) - BUF_BEG (buf))
1338 {
1339 newhead = 0;
1340 newtail = 0;
1341 }
1342 BUF_BEGV (buf) = BUF_BEG (buf) + newhead;
1343 SET_BUF_ZV (buf, BUF_Z (buf) - newtail);
1344 clip_changed = 1;
1345
1346 /* If point is outside the new visible range, move it inside. */
1347 SET_BUF_PT (buf,
1348 clip_to_bounds (BUF_BEGV (buf), BUF_PT (buf), BUF_ZV (buf)));
1349
1350 return Qnil;
1351 }
1352
1353 DEFUN ("save-restriction", Fsave_restriction, Ssave_restriction, 0, UNEVALLED, 0,
1354 "Execute BODY, saving and restoring current buffer's restrictions.\n\
1355 The buffer's restrictions make parts of the beginning and end invisible.\n\
1356 \(They are set up with `narrow-to-region' and eliminated with `widen'.)\n\
1357 This special form, `save-restriction', saves the current buffer's restrictions\n\
1358 when it is entered, and restores them when it is exited.\n\
1359 So any `narrow-to-region' within BODY lasts only until the end of the form.\n\
1360 The old restrictions settings are restored\n\
1361 even in case of abnormal exit (throw or error).\n\
1362 \n\
1363 The value returned is the value of the last form in BODY.\n\
1364 \n\
1365 `save-restriction' can get confused if, within the BODY, you widen\n\
1366 and then make changes outside the area within the saved restrictions.\n\
1367 \n\
1368 Note: if you are using both `save-excursion' and `save-restriction',\n\
1369 use `save-excursion' outermost:\n\
1370 (save-excursion (save-restriction ...))")
1371 (body)
1372 Lisp_Object body;
1373 {
1374 register Lisp_Object val;
1375 int count = specpdl_ptr - specpdl;
1376
1377 record_unwind_protect (save_restriction_restore, save_restriction_save ());
1378 val = Fprogn (body);
1379 return unbind_to (count, val);
1380 }
1381 \f
1382 /* Buffer for the most recent text displayed by Fmessage. */
1383 static char *message_text;
1384
1385 /* Allocated length of that buffer. */
1386 static int message_length;
1387
1388 DEFUN ("message", Fmessage, Smessage, 1, MANY, 0,
1389 "Print a one-line message at the bottom of the screen.\n\
1390 The first argument is a control string.\n\
1391 It may contain %s or %d or %c to print successive following arguments.\n\
1392 %s means print an argument as a string, %d means print as number in decimal,\n\
1393 %c means print a number as a single character.\n\
1394 The argument used by %s must be a string or a symbol;\n\
1395 the argument used by %d or %c must be a number.\n\
1396 If the first argument is nil, clear any existing message; let the\n\
1397 minibuffer contents show.")
1398 (nargs, args)
1399 int nargs;
1400 Lisp_Object *args;
1401 {
1402 if (NILP (args[0]))
1403 {
1404 message (0);
1405 return Qnil;
1406 }
1407 else
1408 {
1409 register Lisp_Object val;
1410 val = Fformat (nargs, args);
1411 /* Copy the data so that it won't move when we GC. */
1412 if (! message_text)
1413 {
1414 message_text = (char *)xmalloc (80);
1415 message_length = 80;
1416 }
1417 if (XSTRING (val)->size > message_length)
1418 {
1419 message_length = XSTRING (val)->size;
1420 message_text = (char *)xrealloc (message_text, message_length);
1421 }
1422 bcopy (XSTRING (val)->data, message_text, XSTRING (val)->size);
1423 message2 (message_text, XSTRING (val)->size);
1424 return val;
1425 }
1426 }
1427
1428 DEFUN ("format", Fformat, Sformat, 1, MANY, 0,
1429 "Format a string out of a control-string and arguments.\n\
1430 The first argument is a control string.\n\
1431 The other arguments are substituted into it to make the result, a string.\n\
1432 It may contain %-sequences meaning to substitute the next argument.\n\
1433 %s means print a string argument. Actually, prints any object, with `princ'.\n\
1434 %d means print as number in decimal (%o octal, %x hex).\n\
1435 %c means print a number as a single character.\n\
1436 %S means print any object as an s-expression (using prin1).\n\
1437 The argument used for %d, %o, %x or %c must be a number.\n\
1438 Use %% to put a single % into the output.")
1439 (nargs, args)
1440 int nargs;
1441 register Lisp_Object *args;
1442 {
1443 register int n; /* The number of the next arg to substitute */
1444 register int total = 5; /* An estimate of the final length */
1445 char *buf;
1446 register unsigned char *format, *end;
1447 int length;
1448 extern char *index ();
1449 /* It should not be necessary to GCPRO ARGS, because
1450 the caller in the interpreter should take care of that. */
1451
1452 CHECK_STRING (args[0], 0);
1453 format = XSTRING (args[0])->data;
1454 end = format + XSTRING (args[0])->size;
1455
1456 n = 0;
1457 while (format != end)
1458 if (*format++ == '%')
1459 {
1460 int minlen;
1461
1462 /* Process a numeric arg and skip it. */
1463 minlen = atoi (format);
1464 if (minlen > 0)
1465 total += minlen;
1466 else
1467 total -= minlen;
1468 while ((*format >= '0' && *format <= '9')
1469 || *format == '-' || *format == ' ' || *format == '.')
1470 format++;
1471
1472 if (*format == '%')
1473 format++;
1474 else if (++n >= nargs)
1475 error ("not enough arguments for format string");
1476 else if (*format == 'S')
1477 {
1478 /* For `S', prin1 the argument and then treat like a string. */
1479 register Lisp_Object tem;
1480 tem = Fprin1_to_string (args[n], Qnil);
1481 args[n] = tem;
1482 goto string;
1483 }
1484 else if (XTYPE (args[n]) == Lisp_Symbol)
1485 {
1486 XSET (args[n], Lisp_String, XSYMBOL (args[n])->name);
1487 goto string;
1488 }
1489 else if (XTYPE (args[n]) == Lisp_String)
1490 {
1491 string:
1492 if (*format != 's' && *format != 'S')
1493 error ("format specifier doesn't match argument type");
1494 total += XSTRING (args[n])->size;
1495 }
1496 /* Would get MPV otherwise, since Lisp_Int's `point' to low memory. */
1497 else if (XTYPE (args[n]) == Lisp_Int && *format != 's')
1498 {
1499 #ifdef LISP_FLOAT_TYPE
1500 /* The following loop assumes the Lisp type indicates
1501 the proper way to pass the argument.
1502 So make sure we have a flonum if the argument should
1503 be a double. */
1504 if (*format == 'e' || *format == 'f' || *format == 'g')
1505 args[n] = Ffloat (args[n]);
1506 #endif
1507 total += 10;
1508 }
1509 #ifdef LISP_FLOAT_TYPE
1510 else if (XTYPE (args[n]) == Lisp_Float && *format != 's')
1511 {
1512 if (! (*format == 'e' || *format == 'f' || *format == 'g'))
1513 args[n] = Ftruncate (args[n]);
1514 total += 20;
1515 }
1516 #endif
1517 else
1518 {
1519 /* Anything but a string, convert to a string using princ. */
1520 register Lisp_Object tem;
1521 tem = Fprin1_to_string (args[n], Qt);
1522 args[n] = tem;
1523 goto string;
1524 }
1525 }
1526
1527 {
1528 register int nstrings = n + 1;
1529
1530 /* Allocate twice as many strings as we have %-escapes; floats occupy
1531 two slots, and we're not sure how many of those we have. */
1532 register unsigned char **strings
1533 = (unsigned char **) alloca (2 * nstrings * sizeof (unsigned char *));
1534 int i;
1535
1536 i = 0;
1537 for (n = 0; n < nstrings; n++)
1538 {
1539 if (n >= nargs)
1540 strings[i++] = (unsigned char *) "";
1541 else if (XTYPE (args[n]) == Lisp_Int)
1542 /* We checked above that the corresponding format effector
1543 isn't %s, which would cause MPV. */
1544 strings[i++] = (unsigned char *) XINT (args[n]);
1545 #ifdef LISP_FLOAT_TYPE
1546 else if (XTYPE (args[n]) == Lisp_Float)
1547 {
1548 union { double d; int half[2]; } u;
1549
1550 u.d = XFLOAT (args[n])->data;
1551 strings[i++] = (unsigned char *) u.half[0];
1552 strings[i++] = (unsigned char *) u.half[1];
1553 }
1554 #endif
1555 else
1556 strings[i++] = XSTRING (args[n])->data;
1557 }
1558
1559 /* Format it in bigger and bigger buf's until it all fits. */
1560 while (1)
1561 {
1562 buf = (char *) alloca (total + 1);
1563 buf[total - 1] = 0;
1564
1565 length = doprnt (buf, total + 1, strings[0], end, i-1, strings + 1);
1566 if (buf[total - 1] == 0)
1567 break;
1568
1569 total *= 2;
1570 }
1571 }
1572
1573 /* UNGCPRO; */
1574 return make_string (buf, length);
1575 }
1576
1577 /* VARARGS 1 */
1578 Lisp_Object
1579 #ifdef NO_ARG_ARRAY
1580 format1 (string1, arg0, arg1, arg2, arg3, arg4)
1581 int arg0, arg1, arg2, arg3, arg4;
1582 #else
1583 format1 (string1)
1584 #endif
1585 char *string1;
1586 {
1587 char buf[100];
1588 #ifdef NO_ARG_ARRAY
1589 int args[5];
1590 args[0] = arg0;
1591 args[1] = arg1;
1592 args[2] = arg2;
1593 args[3] = arg3;
1594 args[4] = arg4;
1595 doprnt (buf, sizeof buf, string1, 0, 5, args);
1596 #else
1597 doprnt (buf, sizeof buf, string1, 0, 5, &string1 + 1);
1598 #endif
1599 return build_string (buf);
1600 }
1601 \f
1602 DEFUN ("char-equal", Fchar_equal, Schar_equal, 2, 2, 0,
1603 "Return t if two characters match, optionally ignoring case.\n\
1604 Both arguments must be characters (i.e. integers).\n\
1605 Case is ignored if `case-fold-search' is non-nil in the current buffer.")
1606 (c1, c2)
1607 register Lisp_Object c1, c2;
1608 {
1609 unsigned char *downcase = DOWNCASE_TABLE;
1610 CHECK_NUMBER (c1, 0);
1611 CHECK_NUMBER (c2, 1);
1612
1613 if (!NILP (current_buffer->case_fold_search)
1614 ? (downcase[0xff & XFASTINT (c1)] == downcase[0xff & XFASTINT (c2)]
1615 && (XFASTINT (c1) & ~0xff) == (XFASTINT (c2) & ~0xff))
1616 : XINT (c1) == XINT (c2))
1617 return Qt;
1618 return Qnil;
1619 }
1620 \f
1621 /* Transpose the markers in two regions of the current buffer, and
1622 adjust the ones between them if necessary (i.e.: if the regions
1623 differ in size).
1624
1625 Traverses the entire marker list of the buffer to do so, adding an
1626 appropriate amount to some, subtracting from some, and leaving the
1627 rest untouched. Most of this is copied from adjust_markers in insdel.c.
1628
1629 It's caller's job to see that (start1 <= end1 <= start2 <= end2),
1630 and that the buffer gap will not conflict with the markers. This
1631 last requirement is odd and maybe should be taken out, but it works
1632 for now because Ftranspose_regions does in fact guarantee that, in
1633 addition to providing universal health-care coverage. */
1634
1635 void
1636 transpose_markers (start1, end1, start2, end2)
1637 register int start1, end1, start2, end2;
1638 {
1639 register int amt1, amt2, diff, mpos;
1640 register Lisp_Object marker;
1641 register struct Lisp_Marker *m;
1642
1643 /* Update point as if it were a marker.
1644 Do this before adjusting the start/end values for the gap. */
1645 if (PT < start1)
1646 ;
1647 else if (PT < end1)
1648 TEMP_SET_PT (PT + (end2 - end1));
1649 else if (PT < start2)
1650 TEMP_SET_PT (PT + (end2 - start2) - (end1 - start1));
1651 else if (PT < end2)
1652 TEMP_SET_PT (PT - (start2 - start1));
1653
1654 /* Internally, marker positions take the gap into account, so if the
1655 * gap is before one or both of the regions, the region's limits
1656 * must be adjusted to compensate. The caller guaranteed that the
1657 * gap is not inside any of the regions, however, so this is fairly
1658 * simple.
1659 */
1660 if (GPT < start1)
1661 {
1662 register int gs = GAP_SIZE;
1663 start1 += gs; end1 += gs;
1664 start2 += gs; end2 += gs;
1665 }
1666 else if (GPT < start2)
1667 {
1668 /* If the regions are of equal size, the gap could, in theory,
1669 * be somewhere between them. */
1670 register int gs = GAP_SIZE;
1671 start2 += gs; end2 += gs;
1672 }
1673
1674 /* The difference between the region's lengths */
1675 diff = (end2 - start2) - (end1 - start1);
1676
1677 /* For shifting each marker in a region by the length of the other
1678 * region plus the distance between the regions.
1679 */
1680 amt1 = (end2 - start2) + (start2 - end1);
1681 amt2 = (end1 - start1) + (start2 - end1);
1682
1683 marker = current_buffer->markers;
1684
1685 while (!NILP (marker))
1686 {
1687 m = XMARKER (marker);
1688 mpos = m->bufpos;
1689 if (mpos >= start1 && mpos < end1) /* in region 1 */
1690 {
1691 m->bufpos += amt1;
1692 }
1693 else if (mpos >= start2 && mpos < end2) /* in region 2 */
1694 {
1695 m->bufpos -= amt2;
1696 }
1697 else if (mpos >= end1 && mpos < start2) /* between the regions */
1698 {
1699 m->bufpos += diff;
1700 }
1701 marker = m->chain;
1702 }
1703 }
1704
1705 DEFUN ("transpose-regions", Ftranspose_regions, Stranspose_regions, 4, 5, 0,
1706 "Transpose region START1 to END1 with START2 to END2.\n\
1707 The regions may not be overlapping, because the size of the buffer is\n\
1708 never changed in a transposition.\n\
1709 \n\
1710 Optional fifth arg LEAVE_MARKERS, if non-nil, means don't transpose\n\
1711 any markers that happen to be located in the regions.\n\
1712 \n\
1713 Transposing beyond buffer boundaries is an error.")
1714 (startr1, endr1, startr2, endr2, leave_markers)
1715 Lisp_Object startr1, endr1, startr2, endr2, leave_markers;
1716 {
1717 register int start1, end1, start2, end2,
1718 gap, len1, len_mid, len2;
1719 unsigned char *start1_addr, *start2_addr, *temp;
1720
1721 #ifdef USE_TEXT_PROPERTIES
1722 INTERVAL cur_intv, tmp_interval1, tmp_interval_mid, tmp_interval2;
1723 cur_intv = current_buffer->intervals;
1724 #endif /* USE_TEXT_PROPERTIES */
1725
1726 validate_region (&startr1, &endr1);
1727 validate_region (&startr2, &endr2);
1728
1729 start1 = XFASTINT (startr1);
1730 end1 = XFASTINT (endr1);
1731 start2 = XFASTINT (startr2);
1732 end2 = XFASTINT (endr2);
1733 gap = GPT;
1734
1735 /* Swap the regions if they're reversed. */
1736 if (start2 < end1)
1737 {
1738 register int glumph = start1;
1739 start1 = start2;
1740 start2 = glumph;
1741 glumph = end1;
1742 end1 = end2;
1743 end2 = glumph;
1744 }
1745
1746 len1 = end1 - start1;
1747 len2 = end2 - start2;
1748
1749 if (start2 < end1)
1750 error ("transposed regions not properly ordered");
1751 else if (start1 == end1 || start2 == end2)
1752 error ("transposed region may not be of length 0");
1753
1754 /* The possibilities are:
1755 1. Adjacent (contiguous) regions, or separate but equal regions
1756 (no, really equal, in this case!), or
1757 2. Separate regions of unequal size.
1758
1759 The worst case is usually No. 2. It means that (aside from
1760 potential need for getting the gap out of the way), there also
1761 needs to be a shifting of the text between the two regions. So
1762 if they are spread far apart, we are that much slower... sigh. */
1763
1764 /* It must be pointed out that the really studly thing to do would
1765 be not to move the gap at all, but to leave it in place and work
1766 around it if necessary. This would be extremely efficient,
1767 especially considering that people are likely to do
1768 transpositions near where they are working interactively, which
1769 is exactly where the gap would be found. However, such code
1770 would be much harder to write and to read. So, if you are
1771 reading this comment and are feeling squirrely, by all means have
1772 a go! I just didn't feel like doing it, so I will simply move
1773 the gap the minimum distance to get it out of the way, and then
1774 deal with an unbroken array. */
1775
1776 /* Make sure the gap won't interfere, by moving it out of the text
1777 we will operate on. */
1778 if (start1 < gap && gap < end2)
1779 {
1780 if (gap - start1 < end2 - gap)
1781 move_gap (start1);
1782 else
1783 move_gap (end2);
1784 }
1785
1786 start1_addr = BUF_CHAR_ADDRESS (current_buffer, start1);
1787 start2_addr = BUF_CHAR_ADDRESS (current_buffer, start2);
1788
1789 /* Hmmm... how about checking to see if the gap is large
1790 enough to use as the temporary storage? That would avoid an
1791 allocation... interesting. Later, don't fool with it now. */
1792
1793 /* Working without memmove, for portability (sigh), so must be
1794 careful of overlapping subsections of the array... */
1795
1796 if (end1 == start2) /* adjacent regions */
1797 {
1798 modify_region (current_buffer, start1, end2);
1799 record_change (start1, len1 + len2);
1800
1801 #ifdef USE_TEXT_PROPERTIES
1802 tmp_interval1 = copy_intervals (cur_intv, start1, len1);
1803 tmp_interval2 = copy_intervals (cur_intv, start2, len2);
1804 Fset_text_properties (start1, end2, Qnil, Qnil);
1805 #endif /* USE_TEXT_PROPERTIES */
1806
1807 /* First region smaller than second. */
1808 if (len1 < len2)
1809 {
1810 /* We use alloca only if it is small,
1811 because we want to avoid stack overflow. */
1812 if (len2 > 20000)
1813 temp = (unsigned char *) xmalloc (len2);
1814 else
1815 temp = (unsigned char *) alloca (len2);
1816 bcopy (start2_addr, temp, len2);
1817 bcopy (start1_addr, start1_addr + len2, len1);
1818 bcopy (temp, start1_addr, len2);
1819 if (len2 > 20000)
1820 free (temp);
1821 }
1822 else
1823 /* First region not smaller than second. */
1824 {
1825 if (len1 > 20000)
1826 temp = (unsigned char *) xmalloc (len1);
1827 else
1828 temp = (unsigned char *) alloca (len1);
1829 bcopy (start1_addr, temp, len1);
1830 bcopy (start2_addr, start1_addr, len2);
1831 bcopy (temp, start1_addr + len2, len1);
1832 if (len1 > 20000)
1833 free (temp);
1834 }
1835 #ifdef USE_TEXT_PROPERTIES
1836 graft_intervals_into_buffer (tmp_interval1, start1 + len2,
1837 len1, current_buffer, 0);
1838 graft_intervals_into_buffer (tmp_interval2, start1,
1839 len2, current_buffer, 0);
1840 #endif /* USE_TEXT_PROPERTIES */
1841 }
1842 /* Non-adjacent regions, because end1 != start2, bleagh... */
1843 else
1844 {
1845 if (len1 == len2)
1846 /* Regions are same size, though, how nice. */
1847 {
1848 modify_region (current_buffer, start1, end1);
1849 modify_region (current_buffer, start2, end2);
1850 record_change (start1, len1);
1851 record_change (start2, len2);
1852 #ifdef USE_TEXT_PROPERTIES
1853 tmp_interval1 = copy_intervals (cur_intv, start1, len1);
1854 tmp_interval2 = copy_intervals (cur_intv, start2, len2);
1855 Fset_text_properties (start1, end1, Qnil, Qnil);
1856 Fset_text_properties (start2, end2, Qnil, Qnil);
1857 #endif /* USE_TEXT_PROPERTIES */
1858
1859 if (len1 > 20000)
1860 temp = (unsigned char *) xmalloc (len1);
1861 else
1862 temp = (unsigned char *) alloca (len1);
1863 bcopy (start1_addr, temp, len1);
1864 bcopy (start2_addr, start1_addr, len2);
1865 bcopy (temp, start2_addr, len1);
1866 if (len1 > 20000)
1867 free (temp);
1868 #ifdef USE_TEXT_PROPERTIES
1869 graft_intervals_into_buffer (tmp_interval1, start2,
1870 len1, current_buffer, 0);
1871 graft_intervals_into_buffer (tmp_interval2, start1,
1872 len2, current_buffer, 0);
1873 #endif /* USE_TEXT_PROPERTIES */
1874 }
1875
1876 else if (len1 < len2) /* Second region larger than first */
1877 /* Non-adjacent & unequal size, area between must also be shifted. */
1878 {
1879 len_mid = start2 - end1;
1880 modify_region (current_buffer, start1, end2);
1881 record_change (start1, (end2 - start1));
1882 #ifdef USE_TEXT_PROPERTIES
1883 tmp_interval1 = copy_intervals (cur_intv, start1, len1);
1884 tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid);
1885 tmp_interval2 = copy_intervals (cur_intv, start2, len2);
1886 Fset_text_properties (start1, end2, Qnil, Qnil);
1887 #endif /* USE_TEXT_PROPERTIES */
1888
1889 /* holds region 2 */
1890 if (len2 > 20000)
1891 temp = (unsigned char *) xmalloc (len2);
1892 else
1893 temp = (unsigned char *) alloca (len2);
1894 bcopy (start2_addr, temp, len2);
1895 bcopy (start1_addr, start1_addr + len_mid + len2, len1);
1896 safe_bcopy (start1_addr + len1, start1_addr + len2, len_mid);
1897 bcopy (temp, start1_addr, len2);
1898 if (len2 > 20000)
1899 free (temp);
1900 #ifdef USE_TEXT_PROPERTIES
1901 graft_intervals_into_buffer (tmp_interval1, end2 - len1,
1902 len1, current_buffer, 0);
1903 graft_intervals_into_buffer (tmp_interval_mid, start1 + len2,
1904 len_mid, current_buffer, 0);
1905 graft_intervals_into_buffer (tmp_interval2, start1,
1906 len2, current_buffer, 0);
1907 #endif /* USE_TEXT_PROPERTIES */
1908 }
1909 else
1910 /* Second region smaller than first. */
1911 {
1912 len_mid = start2 - end1;
1913 record_change (start1, (end2 - start1));
1914 modify_region (current_buffer, start1, end2);
1915
1916 #ifdef USE_TEXT_PROPERTIES
1917 tmp_interval1 = copy_intervals (cur_intv, start1, len1);
1918 tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid);
1919 tmp_interval2 = copy_intervals (cur_intv, start2, len2);
1920 Fset_text_properties (start1, end2, Qnil, Qnil);
1921 #endif /* USE_TEXT_PROPERTIES */
1922
1923 /* holds region 1 */
1924 if (len1 > 20000)
1925 temp = (unsigned char *) xmalloc (len1);
1926 else
1927 temp = (unsigned char *) alloca (len1);
1928 bcopy (start1_addr, temp, len1);
1929 bcopy (start2_addr, start1_addr, len2);
1930 bcopy (start1_addr + len1, start1_addr + len2, len_mid);
1931 bcopy (temp, start1_addr + len2 + len_mid, len1);
1932 if (len1 > 20000)
1933 free (temp);
1934 #ifdef USE_TEXT_PROPERTIES
1935 graft_intervals_into_buffer (tmp_interval1, end2 - len1,
1936 len1, current_buffer, 0);
1937 graft_intervals_into_buffer (tmp_interval_mid, start1 + len2,
1938 len_mid, current_buffer, 0);
1939 graft_intervals_into_buffer (tmp_interval2, start1,
1940 len2, current_buffer, 0);
1941 #endif /* USE_TEXT_PROPERTIES */
1942 }
1943 }
1944
1945 /* todo: this will be slow, because for every transposition, we
1946 traverse the whole friggin marker list. Possible solutions:
1947 somehow get a list of *all* the markers across multiple
1948 transpositions and do it all in one swell phoop. Or maybe modify
1949 Emacs' marker code to keep an ordered list or tree. This might
1950 be nicer, and more beneficial in the long run, but would be a
1951 bunch of work. Plus the way they're arranged now is nice. */
1952 if (NILP (leave_markers))
1953 {
1954 transpose_markers (start1, end1, start2, end2);
1955 fix_overlays_in_range (start1, end2);
1956 }
1957
1958 return Qnil;
1959 }
1960
1961 \f
1962 void
1963 syms_of_editfns ()
1964 {
1965 staticpro (&Vuser_name);
1966 staticpro (&Vuser_full_name);
1967 staticpro (&Vuser_real_name);
1968 staticpro (&Vsystem_name);
1969
1970 defsubr (&Schar_equal);
1971 defsubr (&Sgoto_char);
1972 defsubr (&Sstring_to_char);
1973 defsubr (&Schar_to_string);
1974 defsubr (&Sbuffer_substring);
1975 defsubr (&Sbuffer_string);
1976
1977 defsubr (&Spoint_marker);
1978 defsubr (&Smark_marker);
1979 defsubr (&Spoint);
1980 defsubr (&Sregion_beginning);
1981 defsubr (&Sregion_end);
1982 /* defsubr (&Smark); */
1983 /* defsubr (&Sset_mark); */
1984 defsubr (&Ssave_excursion);
1985
1986 defsubr (&Sbufsize);
1987 defsubr (&Spoint_max);
1988 defsubr (&Spoint_min);
1989 defsubr (&Spoint_min_marker);
1990 defsubr (&Spoint_max_marker);
1991
1992 defsubr (&Sbobp);
1993 defsubr (&Seobp);
1994 defsubr (&Sbolp);
1995 defsubr (&Seolp);
1996 defsubr (&Sfollowing_char);
1997 defsubr (&Sprevious_char);
1998 defsubr (&Schar_after);
1999 defsubr (&Sinsert);
2000 defsubr (&Sinsert_before_markers);
2001 defsubr (&Sinsert_and_inherit);
2002 defsubr (&Sinsert_and_inherit_before_markers);
2003 defsubr (&Sinsert_char);
2004
2005 defsubr (&Suser_login_name);
2006 defsubr (&Suser_real_login_name);
2007 defsubr (&Suser_uid);
2008 defsubr (&Suser_real_uid);
2009 defsubr (&Suser_full_name);
2010 defsubr (&Semacs_pid);
2011 defsubr (&Scurrent_time);
2012 defsubr (&Scurrent_time_string);
2013 defsubr (&Scurrent_time_zone);
2014 defsubr (&Ssystem_name);
2015 defsubr (&Smessage);
2016 defsubr (&Sformat);
2017
2018 defsubr (&Sinsert_buffer_substring);
2019 defsubr (&Scompare_buffer_substrings);
2020 defsubr (&Ssubst_char_in_region);
2021 defsubr (&Stranslate_region);
2022 defsubr (&Sdelete_region);
2023 defsubr (&Swiden);
2024 defsubr (&Snarrow_to_region);
2025 defsubr (&Ssave_restriction);
2026 defsubr (&Stranspose_regions);
2027 }