XEmacs 21.2.29 "Hestia".
[chise/xemacs-chise.git.1] / src / editfns.c
1 /* Lisp functions pertaining to editing.
2    Copyright (C) 1985-1987, 1989, 1992-1995 Free Software Foundation, Inc.
3    Copyright (C) 1995 Tinker Systems and INS Engineering Corp.
4    Copyright (C) 1996 Ben Wing.
5
6 This file is part of XEmacs.
7
8 XEmacs is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
11 later version.
12
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with XEmacs; see the file COPYING.  If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.  */
22
23 /* Synched up with: Mule 2.0, FSF 19.30. */
24
25 /* This file has been Mule-ized. */
26
27 /* Hacked on for Mule by Ben Wing, December 1994. */
28
29 #include <config.h>
30 #include "lisp.h"
31 #ifdef HAVE_UNISTD_H
32 #include <unistd.h>
33 #endif
34
35 #include "buffer.h"
36 #include "commands.h"
37 #include "events.h"             /* for EVENTP */
38 #include "extents.h"
39 #include "frame.h"
40 #include "insdel.h"
41 #include "window.h"
42 #include "chartab.h"
43 #include "line-number.h"
44
45 #include "systime.h"
46 #include "sysdep.h"
47 #include "syspwd.h"
48 #include "sysfile.h"                    /* for getcwd */
49
50 /* Some static data, and a function to initialize it for each run */
51
52 Lisp_Object Vsystem_name;       /* #### - I don't see why this should be */
53                                 /* static, either...  --Stig */
54 #if 0                           /* XEmacs - this is now dynamic */
55                                 /* if at some point it's deemed desirable to
56                                    use lisp variables here, then they can be
57                                    initialized to nil and then set to their
58                                    real values upon the first call to the
59                                    functions that generate them. --stig */
60 Lisp_Object Vuser_real_login_name; /* login name of current user ID */
61 Lisp_Object Vuser_login_name;   /* user name from LOGNAME or USER.  */
62 #endif
63
64 /* It's useful to be able to set this as user customization, so we'll
65    keep it. */
66 Lisp_Object Vuser_full_name;
67 EXFUN (Fuser_full_name, 1);
68
69 Lisp_Object Qformat;
70
71 Lisp_Object Qpoint, Qmark, Qregion_beginning, Qregion_end;
72
73 Lisp_Object Quser_files_and_directories;
74
75 /* This holds the value of `environ' produced by the previous
76    call to Fset_time_zone_rule, or 0 if Fset_time_zone_rule
77    has never been called.  */
78 static char **environbuf;
79
80 void
81 init_editfns (void)
82 {
83 /* Only used in removed code below. */
84   char *p;
85
86   environbuf = 0;
87
88   /* Set up system_name even when dumping.  */
89   init_system_name ();
90
91 #ifndef CANNOT_DUMP
92   if (!initialized)
93     return;
94 #endif
95
96   if ((p = getenv ("NAME")))
97     /* I don't think it's the right thing to do the ampersand
98        modification on NAME.  Not that it matters anymore...  -hniksic */
99     Vuser_full_name = build_ext_string (p, Qnative);
100   else
101     Vuser_full_name = Fuser_full_name (Qnil);
102 }
103 \f
104 DEFUN ("char-to-string", Fchar_to_string, 1, 1, 0, /*
105 Convert arg CH to a one-character string containing that character.
106 */
107        (ch))
108 {
109   Bytecount len;
110   Bufbyte str[MAX_EMCHAR_LEN];
111
112   if (EVENTP (ch))
113     {
114       Lisp_Object ch2 = Fevent_to_character (ch, Qt, Qnil, Qnil);
115       if (NILP (ch2))
116         return
117           signal_simple_continuable_error
118             ("character has no ASCII equivalent:", Fcopy_event (ch, Qnil));
119       ch = ch2;
120     }
121
122   CHECK_CHAR_COERCE_INT (ch);
123
124   len = set_charptr_emchar (str, XCHAR (ch));
125   return make_string (str, len);
126 }
127
128 DEFUN ("string-to-char", Fstring_to_char, 1, 1, 0, /*
129 Convert arg STRING to a character, the first character of that string.
130 An empty string will return the constant `nil'.
131 */
132        (str))
133 {
134   Lisp_String *p;
135   CHECK_STRING (str);
136
137   p = XSTRING (str);
138   if (string_length (p) != 0)
139     return make_char (string_char (p, 0));
140   else
141     /* This used to return Qzero.  That is broken, broken, broken. */
142     /* It might be kinder to signal an error directly. -slb */
143     return Qnil;
144 }
145
146 \f
147 static Lisp_Object
148 buildmark (Bufpos val, Lisp_Object buffer)
149 {
150   Lisp_Object mark = Fmake_marker ();
151   Fset_marker (mark, make_int (val), buffer);
152   return mark;
153 }
154
155 DEFUN ("point", Fpoint, 0, 1, 0, /*
156 Return value of point, as an integer.
157 Beginning of buffer is position (point-min).
158 If BUFFER is nil, the current buffer is assumed.
159 */
160        (buffer))
161 {
162   struct buffer *b = decode_buffer (buffer, 1);
163   return make_int (BUF_PT (b));
164 }
165
166 DEFUN ("point-marker", Fpoint_marker, 0, 2, 0, /*
167 Return value of point, as a marker object.
168 This marker is a copy; you may modify it with reckless abandon.
169 If optional argument DONT-COPY-P is non-nil, then it returns the real
170 point-marker; modifying the position of this marker will move point.
171 It is illegal to change the buffer of it, or make it point nowhere.
172 If BUFFER is nil, the current buffer is assumed.
173 */
174        (dont_copy_p, buffer))
175 {
176   struct buffer *b = decode_buffer (buffer, 1);
177   if (NILP (dont_copy_p))
178     return Fcopy_marker (b->point_marker, Qnil);
179   else
180     return b->point_marker;
181 }
182
183 /* The following two functions end up being identical but it's
184    cleaner to declare them separately. */
185
186 Bufpos
187 bufpos_clip_to_bounds (Bufpos lower, Bufpos num, Bufpos upper)
188 {
189   return (num < lower ? lower :
190           num > upper ? upper :
191           num);
192 }
193
194 Bytind
195 bytind_clip_to_bounds (Bytind lower, Bytind num, Bytind upper)
196 {
197   return (num < lower ? lower :
198           num > upper ? upper :
199           num);
200 }
201
202 /*
203  * Chuck says:
204  * There is no absolute way to determine if goto-char is the function
205  * being run.  this-command doesn't work because it is often eval'd
206  * and this-command ends up set to eval-expression.  So this flag gets
207  * added for now.
208  *
209  * Jamie thinks he's wrong, but we'll leave this in for now.
210  */
211 int atomic_extent_goto_char_p;
212
213 DEFUN ("goto-char", Fgoto_char, 1, 2, "NGoto char: ", /*
214 Set point to POSITION, a number or marker.
215 Beginning of buffer is position (point-min), end is (point-max).
216 If BUFFER is nil, the current buffer is assumed.
217 Return value of POSITION, as an integer.
218 */
219        (position, buffer))
220 {
221   struct buffer *b = decode_buffer (buffer, 1);
222   Bufpos n = get_buffer_pos_char (b, position, GB_COERCE_RANGE);
223   BUF_SET_PT (b, n);
224   atomic_extent_goto_char_p = 1;
225   return make_int (n);
226 }
227
228 static Lisp_Object
229 region_limit (int beginningp, struct buffer *b)
230 {
231   Lisp_Object m;
232
233 #if 0 /* FSFmacs */
234   if (!NILP (Vtransient_mark_mode) && NILP (Vmark_even_if_inactive)
235       && NILP (b->mark_active))
236     Fsignal (Qmark_inactive, Qnil);
237 #endif
238   m = Fmarker_position (b->mark);
239   if (NILP (m)) error ("There is no region now");
240   if (!!(BUF_PT (b) < XINT (m)) == !!beginningp)
241     return make_int (BUF_PT (b));
242   else
243     return m;
244 }
245
246 DEFUN ("region-beginning", Fregion_beginning, 0, 1, 0, /*
247 Return position of beginning of region in BUFFER, as an integer.
248 If BUFFER is nil, the current buffer is assumed.
249 */
250        (buffer))
251 {
252   return region_limit (1, decode_buffer (buffer, 1));
253 }
254
255 DEFUN ("region-end", Fregion_end, 0, 1, 0, /*
256 Return position of end of region in BUFFER, as an integer.
257 If BUFFER is nil, the current buffer is assumed.
258 */
259        (buffer))
260 {
261   return region_limit (0, decode_buffer (buffer, 1));
262 }
263
264 /* Whether to use lispm-style active-regions */
265 int zmacs_regions;
266
267 /* Whether the zmacs region is active.  This is not per-buffer because
268    there can be only one active region at a time.  #### Now that the
269    zmacs region are not directly tied to the X selections this may not
270    necessarily have to be true.  */
271 int zmacs_region_active_p;
272
273 int zmacs_region_stays;
274
275 Lisp_Object Qzmacs_update_region, Qzmacs_deactivate_region;
276 Lisp_Object Qzmacs_region_buffer;
277
278 void
279 zmacs_update_region (void)
280 {
281   /* This function can GC */
282   if (zmacs_region_active_p)
283     call0 (Qzmacs_update_region);
284 }
285
286 void
287 zmacs_deactivate_region (void)
288 {
289   /* This function can GC */
290   if (zmacs_region_active_p)
291     call0 (Qzmacs_deactivate_region);
292 }
293
294 Lisp_Object
295 zmacs_region_buffer (void)
296 {
297   if (zmacs_region_active_p)
298     return call0 (Qzmacs_region_buffer);
299   else
300     return Qnil;
301 }
302
303 DEFUN ("mark-marker", Fmark_marker, 0, 2, 0, /*
304 Return this buffer's mark, as a marker object.
305 If `zmacs-regions' is true, then this returns nil unless the region is
306 currently in the active (highlighted) state.  If optional argument FORCE
307 is t, this returns the mark (if there is one) regardless of the zmacs-region
308 state.  You should *generally* not use the mark unless the region is active,
309 if the user has expressed a preference for the zmacs-region model.
310 Watch out!  Moving this marker changes the mark position.
311 If you set the marker not to point anywhere, the buffer will have no mark.
312 If BUFFER is nil, the current buffer is assumed.
313 */
314        (force, buffer))
315 {
316   struct buffer *b = decode_buffer (buffer, 1);
317   if (! zmacs_regions || zmacs_region_active_p || !NILP (force))
318     return b->mark;
319   return Qnil;
320 }
321
322 \f
323 /* The saved object is a cons:
324
325    (COPY-OF-POINT-MARKER . COPY-OF-MARK)
326
327    We used to have another cons for a VISIBLE-P element, which was t
328    if `(eq (current-buffer) (window-buffer (selected-window)))' but it
329    was unused for a long time, so I removed it.  --hniksic */
330 Lisp_Object
331 save_excursion_save (void)
332 {
333   struct buffer *b;
334
335   /* #### Huh?  --hniksic */
336   /*if (preparing_for_armageddon) return Qnil;*/
337
338 #ifdef ERROR_CHECK_BUFPOS
339   assert (XINT (Fpoint (Qnil)) ==
340           XINT (Fmarker_position (Fpoint_marker (Qt, Qnil))));
341 #endif
342
343   b = current_buffer;
344
345   return noseeum_cons (noseeum_copy_marker (b->point_marker, Qnil),
346                        noseeum_copy_marker (b->mark, Qnil));
347 }
348
349 Lisp_Object
350 save_excursion_restore (Lisp_Object info)
351 {
352   Lisp_Object buffer = Fmarker_buffer (XCAR (info));
353
354   /* If buffer being returned to is now deleted, avoid error --
355      otherwise could get error here while unwinding to top level and
356      crash.  In that case, Fmarker_buffer returns nil now.  */
357   if (!NILP (buffer))
358     {
359       struct buffer *buf = XBUFFER (buffer);
360       struct gcpro gcpro1;
361       GCPRO1 (info);
362       set_buffer_internal (buf);
363       Fgoto_char (XCAR (info), buffer);
364       Fset_marker (buf->mark, XCDR (info), buffer);
365
366 #if 0 /* We used to make the current buffer visible in the selected window
367          if that was true previously.  That avoids some anomalies.
368          But it creates others, and it wasn't documented, and it is simpler
369          and cleaner never to alter the window/buffer connections.  */
370       /* I'm certain some code somewhere depends on this behavior. --jwz */
371       /* Even if it did, it certainly doesn't matter anymore, because
372          this has been the behavior for countless XEmacs releases
373          now.  --hniksic */
374       if (visible
375           && (current_buffer != XBUFFER (XWINDOW (selected_window)->buffer)))
376         switch_to_buffer (Fcurrent_buffer (), Qnil);
377 #endif
378
379       UNGCPRO;
380     }
381
382   /* Free all the junk we allocated, so that a `save-excursion' comes
383      for free in terms of GC junk. */
384   free_marker (XMARKER (XCAR (info)));
385   free_marker (XMARKER (XCDR (info)));
386   free_cons (XCONS (info));
387   return Qnil;
388 }
389
390 DEFUN ("save-excursion", Fsave_excursion, 0, UNEVALLED, 0, /*
391 Save point, mark, and current buffer; execute BODY; restore those things.
392 Executes BODY just like `progn'.
393 The values of point, mark and the current buffer are restored
394 even in case of abnormal exit (throw or error).
395 */
396        (args))
397 {
398   /* This function can GC */
399   int speccount = specpdl_depth ();
400
401   record_unwind_protect (save_excursion_restore, save_excursion_save ());
402
403   return unbind_to (speccount, Fprogn (args));
404 }
405
406 Lisp_Object
407 save_current_buffer_restore (Lisp_Object buffer)
408 {
409   struct buffer *buf = XBUFFER (buffer);
410   /* Avoid signaling an error if the buffer is no longer alive.  This
411      is for consistency with save-excursion.  */
412   if (BUFFER_LIVE_P (buf))
413     set_buffer_internal (buf);
414   return Qnil;
415 }
416
417 DEFUN ("save-current-buffer", Fsave_current_buffer, 0, UNEVALLED, 0, /*
418 Save the current buffer; execute BODY; restore the current buffer.
419 Executes BODY just like `progn'.
420 */
421        (args))
422 {
423   /* This function can GC */
424   int speccount = specpdl_depth ();
425
426   record_unwind_protect (save_current_buffer_restore, Fcurrent_buffer ());
427
428   return unbind_to (speccount, Fprogn (args));
429 }
430 \f
431 DEFUN ("buffer-size", Fbuffer_size, 0, 1, 0, /*
432 Return the number of characters in BUFFER.
433 If BUFFER is nil, the current buffer is assumed.
434 */
435        (buffer))
436 {
437   struct buffer *b = decode_buffer (buffer, 1);
438   return make_int (BUF_SIZE (b));
439 }
440
441 DEFUN ("point-min", Fpoint_min, 0, 1, 0, /*
442 Return the minimum permissible value of point in BUFFER.
443 This is 1, unless narrowing (a buffer restriction)
444 is in effect, in which case it may be greater.
445 If BUFFER is nil, the current buffer is assumed.
446 */
447        (buffer))
448 {
449   struct buffer *b = decode_buffer (buffer, 1);
450   return make_int (BUF_BEGV (b));
451 }
452
453 DEFUN ("point-min-marker", Fpoint_min_marker, 0, 1, 0, /*
454 Return a marker to the minimum permissible value of point in BUFFER.
455 This is the beginning, unless narrowing (a buffer restriction)
456 is in effect, in which case it may be greater.
457 If BUFFER is nil, the current buffer is assumed.
458 */
459        (buffer))
460 {
461   struct buffer *b = decode_buffer (buffer, 1);
462   return buildmark (BUF_BEGV (b), make_buffer (b));
463 }
464
465 DEFUN ("point-max", Fpoint_max, 0, 1, 0, /*
466 Return the maximum permissible value of point in BUFFER.
467 This is (1+ (buffer-size)), unless narrowing (a buffer restriction)
468 is in effect, in which case it may be less.
469 If BUFFER is nil, the current buffer is assumed.
470 */
471        (buffer))
472 {
473   struct buffer *b = decode_buffer (buffer, 1);
474   return make_int (BUF_ZV (b));
475 }
476
477 DEFUN ("point-max-marker", Fpoint_max_marker, 0, 1, 0, /*
478 Return a marker to the maximum permissible value of point in BUFFER.
479 This is (1+ (buffer-size)), unless narrowing (a buffer restriction)
480 is in effect, in which case it may be less.
481 If BUFFER is nil, the current buffer is assumed.
482 */
483        (buffer))
484 {
485   struct buffer *b = decode_buffer (buffer, 1);
486   return buildmark (BUF_ZV (b), make_buffer (b));
487 }
488
489 DEFUN ("following-char", Ffollowing_char, 0, 1, 0, /*
490 Return the character following point.
491 At the end of the buffer or accessible region, return 0.
492 If BUFFER is nil, the current buffer is assumed.
493 */
494        (buffer))
495 {
496   struct buffer *b = decode_buffer (buffer, 1);
497   if (BUF_PT (b) >= BUF_ZV (b))
498     return Qzero;             /* #### Gag me! */
499   else
500     return make_char (BUF_FETCH_CHAR (b, BUF_PT (b)));
501 }
502
503 DEFUN ("preceding-char", Fpreceding_char, 0, 1, 0, /*
504 Return the character preceding point.
505 At the beginning of the buffer or accessible region, return 0.
506 If BUFFER is nil, the current buffer is assumed.
507 */
508        (buffer))
509 {
510   struct buffer *b = decode_buffer (buffer, 1);
511   if (BUF_PT (b) <= BUF_BEGV (b))
512     return Qzero;             /* #### Gag me! */
513   else
514     return make_char (BUF_FETCH_CHAR (b, BUF_PT (b) - 1));
515 }
516
517 DEFUN ("bobp", Fbobp, 0, 1, 0, /*
518 Return t if point is at the beginning of the buffer.
519 If the buffer is narrowed, this means the beginning of the narrowed part.
520 If BUFFER is nil, the current buffer is assumed.
521 */
522        (buffer))
523 {
524   struct buffer *b = decode_buffer (buffer, 1);
525   return BUF_PT (b) == BUF_BEGV (b) ? Qt : Qnil;
526 }
527
528 DEFUN ("eobp", Feobp, 0, 1, 0, /*
529 Return t if point is at the end of the buffer.
530 If the buffer is narrowed, this means the end of the narrowed part.
531 If BUFFER is nil, the current buffer is assumed.
532 */
533        (buffer))
534 {
535   struct buffer *b = decode_buffer (buffer, 1);
536   return BUF_PT (b) == BUF_ZV (b) ? Qt : Qnil;
537 }
538
539 int
540 beginning_of_line_p (struct buffer *b, Bufpos pt)
541 {
542   return pt <= BUF_BEGV (b) || BUF_FETCH_CHAR (b, pt - 1) == '\n';
543 }
544
545
546 DEFUN ("bolp", Fbolp, 0, 1, 0, /*
547 Return t if point is at the beginning of a line.
548 If BUFFER is nil, the current buffer is assumed.
549 */
550        (buffer))
551 {
552   struct buffer *b = decode_buffer (buffer, 1);
553   return beginning_of_line_p (b, BUF_PT (b)) ? Qt : Qnil;
554 }
555
556 DEFUN ("eolp", Feolp, 0, 1, 0, /*
557 Return t if point is at the end of a line.
558 `End of a line' includes point being at the end of the buffer.
559 If BUFFER is nil, the current buffer is assumed.
560 */
561        (buffer))
562 {
563   struct buffer *b = decode_buffer (buffer, 1);
564   return (BUF_PT (b) == BUF_ZV (b) || BUF_FETCH_CHAR (b, BUF_PT (b)) == '\n')
565     ? Qt : Qnil;
566 }
567
568 DEFUN ("char-after", Fchar_after, 0, 2, 0, /*
569 Return the character at position POS in BUFFER.
570 POS is an integer or a marker.
571 If POS is out of range, the value is nil.
572 if POS is nil, the value of point is assumed.
573 If BUFFER is nil, the current buffer is assumed.
574 */
575        (pos, buffer))
576 {
577   struct buffer *b = decode_buffer (buffer, 1);
578   Bufpos n = (NILP (pos) ? BUF_PT (b) :
579               get_buffer_pos_char (b, pos, GB_NO_ERROR_IF_BAD));
580
581   if (n < 0 || n == BUF_ZV (b))
582     return Qnil;
583   return make_char (BUF_FETCH_CHAR (b, n));
584 }
585
586 DEFUN ("char-before", Fchar_before, 0, 2, 0, /*
587 Return the character preceding position POS in BUFFER.
588 POS is an integer or a marker.
589 If POS is out of range, the value is nil.
590 if POS is nil, the value of point is assumed.
591 If BUFFER is nil, the current buffer is assumed.
592 */
593        (pos, buffer))
594 {
595   struct buffer *b = decode_buffer (buffer, 1);
596   Bufpos n = (NILP (pos) ? BUF_PT (b) :
597               get_buffer_pos_char (b, pos, GB_NO_ERROR_IF_BAD));
598
599   n--;
600
601   if (n < BUF_BEGV (b))
602     return Qnil;
603   return make_char (BUF_FETCH_CHAR (b, n));
604 }
605
606 \f
607 DEFUN ("temp-directory", Ftemp_directory, 0, 0, 0, /*
608 Return the pathname to the directory to use for temporary files.
609 On NT/MSDOS, this is obtained from the TEMP or TMP environment variables,
610 defaulting to / if they are both undefined.
611 On Unix it is obtained from TMPDIR, with /tmp as the default
612 */
613        ())
614 {
615   char *tmpdir;
616 #if defined(WINDOWSNT) || defined(MSDOS)
617   tmpdir = getenv ("TEMP");
618   if (!tmpdir)
619     tmpdir = getenv ("TMP");
620   if (!tmpdir)
621     tmpdir = "/";
622 #else /* WINDOWSNT || MSDOS */
623  tmpdir = getenv ("TMPDIR");
624  if (!tmpdir)
625    tmpdir = "/tmp";
626 #endif
627
628   return build_ext_string (tmpdir, Qfile_name);
629 }
630
631 DEFUN ("user-login-name", Fuser_login_name, 0, 1, 0, /*
632 Return the name under which the user logged in, as a string.
633 This is based on the effective uid, not the real uid.
634 Also, if the environment variable LOGNAME or USER is set,
635 that determines the value of this function.
636 If the optional argument UID is present, then environment variables are
637 ignored and this function returns the login name for that UID, or nil.
638 */
639        (uid))
640 {
641   char *returned_name;
642   uid_t local_uid;
643
644   if (!NILP (uid))
645     {
646       CHECK_INT (uid);
647       local_uid = XINT (uid);
648       returned_name = user_login_name (&local_uid);
649     }
650   else
651     {
652       returned_name = user_login_name (NULL);
653     }
654   /* #### - I believe this should return nil instead of "unknown" when pw==0
655      pw=0 is indicated by a null return from user_login_name
656   */
657   return returned_name ? build_string (returned_name) : Qnil;
658 }
659
660 /* This function may be called from other C routines when a
661    character string representation of the user_login_name is
662    needed but a Lisp Object is not.  The UID is passed by
663    reference.  If UID == NULL, then the USER name
664    for the user running XEmacs will be returned.  This
665    corresponds to a nil argument to Fuser_login_name.
666 */
667 char*
668 user_login_name (uid_t *uid)
669 {
670   /* uid == NULL to return name of this user */
671   if (uid != NULL)
672     {
673       struct passwd *pw = getpwuid (*uid);
674       return pw ? pw->pw_name : NULL;
675     }
676   else
677     {
678       /* #### - when euid != uid, then LOGNAME and USER are leftovers from the
679          old environment (I site observed behavior on sunos and linux), so the
680          environment variables should be disregarded in that case.  --Stig */
681       char *user_name = getenv ("LOGNAME");
682       if (!user_name)
683         user_name = getenv (
684 #ifdef WINDOWSNT
685                             "USERNAME" /* it's USERNAME on NT */
686 #else
687                             "USER"
688 #endif
689                             );
690       if (user_name)
691         return (user_name);
692       else
693         {
694           struct passwd *pw = getpwuid (geteuid ());
695 #ifdef __CYGWIN32__
696           /* Since the Cygwin environment may not have an /etc/passwd,
697              return "unknown" instead of the null if the username
698              cannot be determined.
699           */
700           return pw ? pw->pw_name : "unknown";
701 #else
702           /* For all but Cygwin return NULL (nil) */
703           return pw ? pw->pw_name : NULL;
704 #endif
705         }
706     }
707 }
708
709 DEFUN ("user-real-login-name", Fuser_real_login_name, 0, 0, 0, /*
710 Return the name of the user's real uid, as a string.
711 This ignores the environment variables LOGNAME and USER, so it differs from
712 `user-login-name' when running under `su'.
713 */
714        ())
715 {
716   struct passwd *pw = getpwuid (getuid ());
717   /* #### - I believe this should return nil instead of "unknown" when pw==0 */
718
719 #ifdef MSDOS
720   /* We let the real user name default to "root" because that's quite
721      accurate on MSDOG and because it lets Emacs find the init file.
722      (The DVX libraries override the Djgpp libraries here.)  */
723   Lisp_Object tem = build_string (pw ? pw->pw_name : "root");/* no gettext */
724 #else
725   Lisp_Object tem = build_string (pw ? pw->pw_name : "unknown");/* no gettext */
726 #endif
727   return tem;
728 }
729
730 DEFUN ("user-uid", Fuser_uid, 0, 0, 0, /*
731 Return the effective uid of Emacs, as an integer.
732 */
733        ())
734 {
735   return make_int (geteuid ());
736 }
737
738 DEFUN ("user-real-uid", Fuser_real_uid, 0, 0, 0, /*
739 Return the real uid of Emacs, as an integer.
740 */
741        ())
742 {
743   return make_int (getuid ());
744 }
745
746 DEFUN ("user-full-name", Fuser_full_name, 0, 1, 0, /*
747 Return the full name of the user logged in, as a string.
748 If the optional argument USER is given, then the full name for that
749 user is returned, or nil.  USER may be either a login name or a uid.
750
751 If USER is nil, and `user-full-name' contains a string, the
752 value of `user-full-name' is returned.
753 */
754        (user))
755 {
756   Lisp_Object user_name;
757   struct passwd *pw = NULL;
758   Lisp_Object tem;
759   const char *p, *q;
760
761   if (NILP (user) && STRINGP (Vuser_full_name))
762     return Vuser_full_name;
763
764   user_name = (STRINGP (user) ? user : Fuser_login_name (user));
765   if (!NILP (user_name))        /* nil when nonexistent UID passed as arg */
766     {
767       const char *user_name_ext;
768
769       /* Fuck me.  getpwnam() can call select() and (under IRIX at least)
770          things get wedged if a SIGIO arrives during this time. */
771       TO_EXTERNAL_FORMAT (LISP_STRING, user_name,
772                           C_STRING_ALLOCA, user_name_ext,
773                           Qnative);
774       slow_down_interrupts ();
775       pw = (struct passwd *) getpwnam (user_name_ext);
776       speed_up_interrupts ();
777     }
778
779   /* #### - Stig sez: this should return nil instead of "unknown" when pw==0 */
780   /* Ben sez: bad idea because it's likely to break something */
781 #ifndef AMPERSAND_FULL_NAME
782   p = ((pw) ? USER_FULL_NAME : "unknown"); /* don't gettext */
783   q = strchr (p, ',');
784 #else
785   p = ((pw) ? USER_FULL_NAME : "unknown"); /* don't gettext */
786   q = strchr (p, ',');
787 #endif
788   tem = ((!NILP (user) && !pw)
789          ? Qnil
790          : make_ext_string ((Extbyte *) p, (q ? q - p : strlen (p)),
791                             Qnative));
792
793 #ifdef AMPERSAND_FULL_NAME
794   if (!NILP (tem))
795     {
796       p = (char *) XSTRING_DATA (tem);
797       q = strchr (p, '&');
798       /* Substitute the login name for the &, upcasing the first character.  */
799       if (q)
800         {
801           char *r = (char *) alloca (strlen (p) + XSTRING_LENGTH (user_name) + 1);
802           memcpy (r, p, q - p);
803           r[q - p] = 0;
804           strcat (r, (char *) XSTRING_DATA (user_name));
805           /* #### current_buffer dependency! */
806           r[q - p] = UPCASE (current_buffer, r[q - p]);
807           strcat (r, q + 1);
808           tem = build_string (r);
809         }
810     }
811 #endif /* AMPERSAND_FULL_NAME */
812
813   return tem;
814 }
815
816 static Extbyte *cached_home_directory;
817
818 void
819 uncache_home_directory (void)
820 {
821   cached_home_directory = NULL; /* in some cases, this may cause the leaking
822                                    of a few bytes */
823 }
824
825 /* Returns the home directory, in external format */
826 Extbyte *
827 get_home_directory (void)
828 {
829   int output_home_warning = 0;
830
831   if (cached_home_directory == NULL)
832     {
833       if ((cached_home_directory = (Extbyte *) getenv("HOME")) == NULL)
834         {
835 #if defined(WINDOWSNT) && !defined(__CYGWIN32__)
836           char *homedrive, *homepath;
837
838           if ((homedrive = getenv("HOMEDRIVE")) != NULL &&
839               (homepath = getenv("HOMEPATH")) != NULL)
840             {
841               cached_home_directory =
842                 (Extbyte *) xmalloc (strlen (homedrive) +
843                                      strlen (homepath) + 1);
844               sprintf((char *) cached_home_directory, "%s%s",
845                       homedrive,
846                       homepath);
847             }
848           else
849             {
850 # if 1
851               /*
852                * Use the current directory.
853                * This preserves the existing XEmacs behavior, but is different
854                * from NT Emacs.
855                */
856               if (initial_directory[0] != '\0')
857                 {
858                   cached_home_directory = initial_directory;
859                 }
860               else
861                 {
862                   /* This will probably give the wrong value */
863                   cached_home_directory = getcwd (NULL, 0);
864                 }
865 # else
866               /*
867                * This is NT Emacs behavior
868                */
869               cached_home_directory = (Extbyte *) "C:\\";
870               output_home_warning = 1;
871 # endif
872             }
873 #else   /* !WINDOWSNT */
874           /*
875            * Unix, typically.
876            * Using "/" isn't quite right, but what should we do?
877            * We probably should try to extract pw_dir from /etc/passwd,
878            * before falling back to this.
879            */
880           cached_home_directory = (Extbyte *) "/";
881           output_home_warning = 1;
882 #endif  /* !WINDOWSNT */
883         }
884       if (initialized && output_home_warning)
885         {
886           warn_when_safe (Quser_files_and_directories, Qwarning, "\n"
887 "       XEmacs was unable to determine a good value for the user's $HOME\n"
888 "       directory, and will be using the value:\n"
889 "               %s\n"
890 "       This is probably incorrect.",
891                           cached_home_directory
892                           );
893         }
894     }
895   return cached_home_directory;
896 }
897
898 DEFUN ("user-home-directory", Fuser_home_directory, 0, 0, 0, /*
899 Return the user's home directory, as a string.
900 */
901        ())
902 {
903   Extbyte *path = get_home_directory ();
904
905   return path == NULL ? Qnil :
906     Fexpand_file_name (Fsubstitute_in_file_name
907                        (build_ext_string ((char *) path, Qfile_name)),
908                        Qnil);
909 }
910
911 DEFUN ("system-name", Fsystem_name, 0, 0, 0, /*
912 Return the name of the machine you are running on, as a string.
913 */
914        ())
915 {
916     return Fcopy_sequence (Vsystem_name);
917 }
918
919 DEFUN ("emacs-pid", Femacs_pid, 0, 0, 0, /*
920 Return the process ID of Emacs, as an integer.
921 */
922        ())
923 {
924   return make_int (getpid ());
925 }
926
927 DEFUN ("current-time", Fcurrent_time, 0, 0, 0, /*
928 Return the current time, as the number of seconds since 1970-01-01 00:00:00.
929 The time is returned as a list of three integers.  The first has the
930 most significant 16 bits of the seconds, while the second has the
931 least significant 16 bits.  The third integer gives the microsecond
932 count.
933
934 The microsecond count is zero on systems that do not provide
935 resolution finer than a second.
936 */
937        ())
938 {
939   EMACS_TIME t;
940
941   EMACS_GET_TIME (t);
942   return list3 (make_int ((EMACS_SECS (t) >> 16) & 0xffff),
943                 make_int ((EMACS_SECS (t) >> 0)  & 0xffff),
944                 make_int (EMACS_USECS (t)));
945 }
946
947 DEFUN ("current-process-time", Fcurrent_process_time, 0, 0, 0, /*
948 Return the amount of time used by this XEmacs process so far.
949 The return value is a list of three floating-point numbers, expressing
950 the user, system, and real times used by the process.  The user time
951 measures the time actually spent by the CPU executing the code in this
952 process.  The system time measures time spent by the CPU executing kernel
953 code on behalf of this process (e.g. I/O requests made by the process).
954
955 Note that the user and system times measure processor time, as opposed
956 to real time, and only accrue when the processor is actually doing
957 something: Time spent in an idle wait (waiting for user events to come
958 in or for I/O on a disk drive or other device to complete) does not
959 count.  Thus, the user and system times will often be considerably
960 less than the real time.
961
962 Some systems do not allow the user and system times to be distinguished.
963 In this case, the user time will be the total processor time used by
964 the process, and the system time will be 0.
965
966 Some systems do not allow the real and processor times to be distinguished.
967 In this case, the user and real times will be the same and the system
968 time will be 0.
969 */
970        ())
971 {
972   double user, sys, real;
973
974   get_process_times (&user, &sys, &real);
975   return list3 (make_float (user), make_float (sys), make_float (real));
976 }
977
978 \f
979 int lisp_to_time (Lisp_Object specified_time, time_t *result);
980 int
981 lisp_to_time (Lisp_Object specified_time, time_t *result)
982 {
983   Lisp_Object high, low;
984
985   if (NILP (specified_time))
986     return time (result) != -1;
987
988   CHECK_CONS (specified_time);
989   high = XCAR (specified_time);
990   low  = XCDR (specified_time);
991   if (CONSP (low))
992     low = XCAR (low);
993   CHECK_INT (high);
994   CHECK_INT (low);
995   *result = (XINT (high) << 16) + (XINT (low) & 0xffff);
996   return *result >> 16 == XINT (high);
997 }
998
999 Lisp_Object time_to_lisp (time_t the_time);
1000 Lisp_Object
1001 time_to_lisp (time_t the_time)
1002 {
1003   unsigned int item = (unsigned int) the_time;
1004   return Fcons (make_int (item >> 16), make_int (item & 0xffff));
1005 }
1006
1007 size_t emacs_strftime (char *string, size_t max, const char *format,
1008                        const struct tm *tm);
1009 static long difftm (const struct tm *a, const struct tm *b);
1010
1011
1012 DEFUN ("format-time-string", Fformat_time_string, 1, 2, 0, /*
1013 Use FORMAT-STRING to format the time TIME.
1014 TIME is specified as (HIGH LOW . IGNORED) or (HIGH . LOW), as from
1015 `current-time' and `file-attributes'.  If TIME is not specified it
1016 defaults to the current time.
1017 FORMAT-STRING may contain %-sequences to substitute parts of the time.
1018 %a is replaced by the abbreviated name of the day of week.
1019 %A is replaced by the full name of the day of week.
1020 %b is replaced by the abbreviated name of the month.
1021 %B is replaced by the full name of the month.
1022 %c is a synonym for "%x %X".
1023 %C is a locale-specific synonym, which defaults to "%A, %B %e, %Y" in the C locale.
1024 %d is replaced by the day of month, zero-padded.
1025 %D is a synonym for "%m/%d/%y".
1026 %e is replaced by the day of month, blank-padded.
1027 %h is a synonym for "%b".
1028 %H is replaced by the hour (00-23).
1029 %I is replaced by the hour (00-12).
1030 %j is replaced by the day of the year (001-366).
1031 %k is replaced by the hour (0-23), blank padded.
1032 %l is replaced by the hour (1-12), blank padded.
1033 %m is replaced by the month (01-12).
1034 %M is replaced by the minute (00-59).
1035 %n is a synonym for "\\n".
1036 %p is replaced by AM or PM, as appropriate.
1037 %r is a synonym for "%I:%M:%S %p".
1038 %R is a synonym for "%H:%M".
1039 %s is replaced by the time in seconds since 00:00:00, Jan 1, 1970 (a
1040       nonstandard extension)
1041 %S is replaced by the second (00-60).
1042 %t is a synonym for "\\t".
1043 %T is a synonym for "%H:%M:%S".
1044 %U is replaced by the week of the year (00-53), first day of week is Sunday.
1045 %w is replaced by the day of week (0-6), Sunday is day 0.
1046 %W is replaced by the week of the year (00-53), first day of week is Monday.
1047 %x is a locale-specific synonym, which defaults to "%D" in the C locale.
1048 %X is a locale-specific synonym, which defaults to "%T" in the C locale.
1049 %y is replaced by the year without century (00-99).
1050 %Y is replaced by the year with century.
1051 %Z is replaced by the time zone abbreviation.
1052
1053 The number of options reflects the `strftime' function.
1054
1055 BUG: If the charset used by the current locale is not ISO 8859-1, the
1056 characters appearing in the day and month names may be incorrect.
1057 */
1058        (format_string, time_))
1059 {
1060   time_t value;
1061   size_t size;
1062
1063   CHECK_STRING (format_string);
1064
1065   if (! lisp_to_time (time_, &value))
1066     error ("Invalid time specification");
1067
1068   /* This is probably enough.  */
1069   size = XSTRING_LENGTH (format_string) * 6 + 50;
1070
1071   while (1)
1072     {
1073       char *buf = (char *) alloca (size);
1074       *buf = 1;
1075       if (emacs_strftime (buf, size,
1076                           (const char *) XSTRING_DATA (format_string),
1077                           localtime (&value))
1078           || !*buf)
1079         return build_ext_string (buf, Qbinary);
1080       /* If buffer was too small, make it bigger.  */
1081       size *= 2;
1082     }
1083 }
1084
1085 DEFUN ("decode-time", Fdecode_time, 0, 1, 0, /*
1086 Decode a time value as (SEC MINUTE HOUR DAY MONTH YEAR DOW DST ZONE).
1087 The optional SPECIFIED-TIME should be a list of (HIGH LOW . IGNORED)
1088 or (HIGH . LOW), as from `current-time' and `file-attributes', or `nil'
1089 to use the current time.  The list has the following nine members:
1090 SEC is an integer between 0 and 60; SEC is 60 for a leap second, which
1091 only some operating systems support.  MINUTE is an integer between 0 and 59.
1092 HOUR is an integer between 0 and 23.  DAY is an integer between 1 and 31.
1093 MONTH is an integer between 1 and 12.  YEAR is an integer indicating the
1094 four-digit year.  DOW is the day of week, an integer between 0 and 6, where
1095 0 is Sunday.  DST is t if daylight savings time is effect, otherwise nil.
1096 ZONE is an integer indicating the number of seconds east of Greenwich.
1097 \(Note that Common Lisp has different meanings for DOW and ZONE.)
1098 */
1099        (specified_time))
1100 {
1101   time_t time_spec;
1102   struct tm save_tm;
1103   struct tm *decoded_time;
1104   Lisp_Object list_args[9];
1105
1106   if (! lisp_to_time (specified_time, &time_spec))
1107     error ("Invalid time specification");
1108
1109   decoded_time = localtime (&time_spec);
1110   list_args[0] = make_int (decoded_time->tm_sec);
1111   list_args[1] = make_int (decoded_time->tm_min);
1112   list_args[2] = make_int (decoded_time->tm_hour);
1113   list_args[3] = make_int (decoded_time->tm_mday);
1114   list_args[4] = make_int (decoded_time->tm_mon + 1);
1115   list_args[5] = make_int (decoded_time->tm_year + 1900);
1116   list_args[6] = make_int (decoded_time->tm_wday);
1117   list_args[7] = (decoded_time->tm_isdst)? Qt : Qnil;
1118
1119   /* Make a copy, in case gmtime modifies the struct.  */
1120   save_tm = *decoded_time;
1121   decoded_time = gmtime (&time_spec);
1122   if (decoded_time == 0)
1123     list_args[8] = Qnil;
1124   else
1125     list_args[8] = make_int (difftm (&save_tm, decoded_time));
1126   return Flist (9, list_args);
1127 }
1128
1129 static void set_time_zone_rule (char *tzstring);
1130
1131 DEFUN ("encode-time", Fencode_time, 6, MANY, 0, /*
1132   Convert SECOND, MINUTE, HOUR, DAY, MONTH, YEAR and ZONE to internal time.
1133 This is the reverse operation of `decode-time', which see.
1134 ZONE defaults to the current time zone rule.  This can
1135 be a string (as from `set-time-zone-rule'), or it can be a list
1136 \(as from `current-time-zone') or an integer (as from `decode-time')
1137 applied without consideration for daylight savings time.
1138
1139 You can pass more than 7 arguments; then the first six arguments
1140 are used as SECOND through YEAR, and the *last* argument is used as ZONE.
1141 The intervening arguments are ignored.
1142 This feature lets (apply 'encode-time (decode-time ...)) work.
1143
1144 Out-of-range values for SEC, MINUTE, HOUR, DAY, or MONTH are allowed;
1145 for example, a DAY of 0 means the day preceding the given month.
1146 Year numbers less than 100 are treated just like other year numbers.
1147 If you want them to stand for years in this century, you must do that yourself.
1148 */
1149        (int nargs, Lisp_Object *args))
1150 {
1151   time_t the_time;
1152   struct tm tm;
1153   Lisp_Object zone = (nargs > 6) ? args[nargs - 1] : Qnil;
1154
1155   CHECK_INT (*args); tm.tm_sec  = XINT (*args++);       /* second */
1156   CHECK_INT (*args); tm.tm_min  = XINT (*args++);       /* minute */
1157   CHECK_INT (*args); tm.tm_hour = XINT (*args++);       /* hour */
1158   CHECK_INT (*args); tm.tm_mday = XINT (*args++);       /* day */
1159   CHECK_INT (*args); tm.tm_mon  = XINT (*args++) - 1;   /* month */
1160   CHECK_INT (*args); tm.tm_year = XINT (*args++) - 1900;/* year */
1161
1162   tm.tm_isdst = -1;
1163
1164   if (CONSP (zone))
1165     zone = XCAR (zone);
1166   if (NILP (zone))
1167     the_time = mktime (&tm);
1168   else
1169     {
1170       char tzbuf[100];
1171       char *tzstring;
1172       char **oldenv = environ, **newenv;
1173
1174       if (STRINGP (zone))
1175         tzstring = (char *) XSTRING_DATA (zone);
1176       else if (INTP (zone))
1177         {
1178           int abszone = abs (XINT (zone));
1179           sprintf (tzbuf, "XXX%s%d:%02d:%02d", "-" + (XINT (zone) < 0),
1180                    abszone / (60*60), (abszone/60) % 60, abszone % 60);
1181           tzstring = tzbuf;
1182         }
1183       else
1184         error ("Invalid time zone specification");
1185
1186       /* Set TZ before calling mktime; merely adjusting mktime's returned
1187          value doesn't suffice, since that would mishandle leap seconds.  */
1188       set_time_zone_rule (tzstring);
1189
1190       the_time = mktime (&tm);
1191
1192       /* Restore TZ to previous value.  */
1193       newenv = environ;
1194       environ = oldenv;
1195       free (newenv);
1196 #ifdef LOCALTIME_CACHE
1197       tzset ();
1198 #endif
1199     }
1200
1201   if (the_time == (time_t) -1)
1202     error ("Specified time is not representable");
1203
1204   return wasteful_word_to_lisp (the_time);
1205 }
1206
1207 DEFUN ("current-time-string", Fcurrent_time_string, 0, 1, 0, /*
1208 Return the current time, as a human-readable string.
1209 Programs can use this function to decode a time,
1210 since the number of columns in each field is fixed.
1211 The format is `Sun Sep 16 01:03:52 1973'.
1212 If an argument is given, it specifies a time to format
1213 instead of the current time.  The argument should have the form:
1214   (HIGH . LOW)
1215 or the form:
1216   (HIGH LOW . IGNORED).
1217 Thus, you can use times obtained from `current-time'
1218 and from `file-attributes'.
1219 */
1220        (specified_time))
1221 {
1222   time_t value;
1223   char buf[30];
1224   char *tem;
1225
1226   if (! lisp_to_time (specified_time, &value))
1227     value = -1;
1228   tem = (char *) ctime (&value);
1229
1230   strncpy (buf, tem, 24);
1231   buf[24] = 0;
1232
1233   return build_ext_string (buf, Qbinary);
1234 }
1235
1236 #define TM_YEAR_ORIGIN 1900
1237
1238 /* Yield A - B, measured in seconds.  */
1239 static long
1240 difftm (const struct tm *a, const struct tm *b)
1241 {
1242   int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
1243   int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
1244   /* Some compilers can't handle this as a single return statement.  */
1245   long days = (
1246               /* difference in day of year */
1247               a->tm_yday - b->tm_yday
1248               /* + intervening leap days */
1249               +  ((ay >> 2) - (by >> 2))
1250               -  (ay/100 - by/100)
1251               +  ((ay/100 >> 2) - (by/100 >> 2))
1252               /* + difference in years * 365 */
1253               +  (long)(ay-by) * 365
1254               );
1255   return (60*(60*(24*days + (a->tm_hour - b->tm_hour))
1256               + (a->tm_min - b->tm_min))
1257           + (a->tm_sec - b->tm_sec));
1258 }
1259
1260 DEFUN ("current-time-zone", Fcurrent_time_zone, 0, 1, 0, /*
1261 Return the offset and name for the local time zone.
1262 This returns a list of the form (OFFSET NAME).
1263 OFFSET is an integer number of seconds ahead of UTC (east of Greenwich).
1264     A negative value means west of Greenwich.
1265 NAME is a string giving the name of the time zone.
1266 If an argument is given, it specifies when the time zone offset is determined
1267 instead of using the current time.  The argument should have the form:
1268   (HIGH . LOW)
1269 or the form:
1270   (HIGH LOW . IGNORED).
1271 Thus, you can use times obtained from `current-time'
1272 and from `file-attributes'.
1273
1274 Some operating systems cannot provide all this information to Emacs;
1275 in this case, `current-time-zone' returns a list containing nil for
1276 the data it can't find.
1277 */
1278        (specified_time))
1279 {
1280   time_t value;
1281   struct tm *t = NULL;
1282
1283   if (lisp_to_time (specified_time, &value)
1284       && (t = gmtime (&value)) != 0)
1285     {
1286       struct tm gmt = *t;       /* Make a copy, in case localtime modifies *t.  */
1287       long offset;
1288       char *s, buf[6];
1289
1290       t = localtime (&value);
1291       offset = difftm (t, &gmt);
1292       s = 0;
1293 #ifdef HAVE_TM_ZONE
1294       if (t->tm_zone)
1295         s = (char *)t->tm_zone;
1296 #else /* not HAVE_TM_ZONE */
1297 #ifdef HAVE_TZNAME
1298       if (t->tm_isdst == 0 || t->tm_isdst == 1)
1299         s = tzname[t->tm_isdst];
1300 #endif
1301 #endif /* not HAVE_TM_ZONE */
1302       if (!s)
1303         {
1304           /* No local time zone name is available; use "+-NNNN" instead.  */
1305           int am = (offset < 0 ? -offset : offset) / 60;
1306           sprintf (buf, "%c%02d%02d", (offset < 0 ? '-' : '+'), am/60, am%60);
1307           s = buf;
1308         }
1309       return list2 (make_int (offset), build_string (s));
1310     }
1311   else
1312     return list2 (Qnil, Qnil);
1313 }
1314
1315 #ifdef LOCALTIME_CACHE
1316
1317 /* These two values are known to load tz files in buggy implementations,
1318    i.e. Solaris 1 executables running under either Solaris 1 or Solaris 2.
1319    Their values shouldn't matter in non-buggy implementations.
1320    We don't use string literals for these strings,
1321    since if a string in the environment is in readonly
1322    storage, it runs afoul of bugs in SVR4 and Solaris 2.3.
1323    See Sun bugs 1113095 and 1114114, ``Timezone routines
1324    improperly modify environment''.  */
1325
1326 static char set_time_zone_rule_tz1[] = "TZ=GMT+0";
1327 static char set_time_zone_rule_tz2[] = "TZ=GMT+1";
1328
1329 #endif
1330
1331 /* Set the local time zone rule to TZSTRING.
1332    This allocates memory into `environ', which it is the caller's
1333    responsibility to free.  */
1334 static void
1335 set_time_zone_rule (char *tzstring)
1336 {
1337   int envptrs;
1338   char **from, **to, **newenv;
1339
1340   for (from = environ; *from; from++)
1341     continue;
1342   envptrs = from - environ + 2;
1343   newenv = to = (char **) xmalloc (envptrs * sizeof (char *)
1344                                    + (tzstring ? strlen (tzstring) + 4 : 0));
1345   if (tzstring)
1346     {
1347       char *t = (char *) (to + envptrs);
1348       strcpy (t, "TZ=");
1349       strcat (t, tzstring);
1350       *to++ = t;
1351     }
1352
1353   for (from = environ; *from; from++)
1354     if (strncmp (*from, "TZ=", 3) != 0)
1355       *to++ = *from;
1356   *to = 0;
1357
1358   environ = newenv;
1359
1360 #ifdef LOCALTIME_CACHE
1361   {
1362     /* In SunOS 4.1.3_U1 and 4.1.4, if TZ has a value like
1363        "US/Pacific" that loads a tz file, then changes to a value like
1364        "XXX0" that does not load a tz file, and then changes back to
1365        its original value, the last change is (incorrectly) ignored.
1366        Also, if TZ changes twice in succession to values that do
1367        not load a tz file, tzset can dump core (see Sun bug#1225179).
1368        The following code works around these bugs.  */
1369
1370     if (tzstring)
1371       {
1372         /* Temporarily set TZ to a value that loads a tz file
1373            and that differs from tzstring.  */
1374         char *tz = *newenv;
1375         *newenv = (strcmp (tzstring, set_time_zone_rule_tz1 + 3) == 0
1376                    ? set_time_zone_rule_tz2 : set_time_zone_rule_tz1);
1377         tzset ();
1378         *newenv = tz;
1379       }
1380     else
1381       {
1382         /* The implied tzstring is unknown, so temporarily set TZ to
1383            two different values that each load a tz file.  */
1384         *to = set_time_zone_rule_tz1;
1385         to[1] = 0;
1386         tzset ();
1387         *to = set_time_zone_rule_tz2;
1388         tzset ();
1389         *to = 0;
1390       }
1391
1392     /* Now TZ has the desired value, and tzset can be invoked safely.  */
1393   }
1394
1395   tzset ();
1396 #endif
1397 }
1398
1399 DEFUN ("set-time-zone-rule", Fset_time_zone_rule, 1, 1, 0, /*
1400 Set the local time zone using TZ, a string specifying a time zone rule.
1401 If TZ is nil, use implementation-defined default time zone information.
1402 */
1403        (tz))
1404 {
1405   char *tzstring;
1406
1407   if (NILP (tz))
1408     tzstring = 0;
1409   else
1410     {
1411       CHECK_STRING (tz);
1412       tzstring = (char *) XSTRING_DATA (tz);
1413     }
1414
1415   set_time_zone_rule (tzstring);
1416   if (environbuf)
1417     xfree (environbuf);
1418   environbuf = environ;
1419
1420   return Qnil;
1421 }
1422
1423 \f
1424 void
1425 buffer_insert1 (struct buffer *buf, Lisp_Object arg)
1426 {
1427   /* This function can GC */
1428   struct gcpro gcpro1;
1429   GCPRO1 (arg);
1430  retry:
1431   if (CHAR_OR_CHAR_INTP (arg))
1432     {
1433       buffer_insert_emacs_char (buf, XCHAR_OR_CHAR_INT (arg));
1434     }
1435   else if (STRINGP (arg))
1436     {
1437       buffer_insert_lisp_string (buf, arg);
1438     }
1439   else
1440     {
1441       arg = wrong_type_argument (Qchar_or_string_p, arg);
1442       goto retry;
1443     }
1444   zmacs_region_stays = 0;
1445   UNGCPRO;
1446 }
1447
1448
1449 /* Callers passing one argument to Finsert need not gcpro the
1450    argument "array", since the only element of the array will
1451    not be used after calling insert_emacs_char or insert_lisp_string,
1452    so we don't care if it gets trashed.  */
1453
1454 DEFUN ("insert", Finsert, 0, MANY, 0, /*
1455 Insert the arguments, either strings or characters, at point.
1456 Point moves forward so that it ends up after the inserted text.
1457 Any other markers at the point of insertion remain before the text.
1458 If a string has non-null string-extent-data, new extents will be created.
1459 */
1460        (int nargs, Lisp_Object *args))
1461 {
1462   /* This function can GC */
1463   REGISTER int argnum;
1464
1465   for (argnum = 0; argnum < nargs; argnum++)
1466     {
1467       buffer_insert1 (current_buffer, args[argnum]);
1468     }
1469
1470   return Qnil;
1471 }
1472
1473 DEFUN ("insert-before-markers", Finsert_before_markers, 0, MANY, 0, /*
1474 Insert strings or characters at point, relocating markers after the text.
1475 Point moves forward so that it ends up after the inserted text.
1476 Any other markers at the point of insertion also end up after the text.
1477 */
1478        (int nargs, Lisp_Object *args))
1479 {
1480   /* This function can GC */
1481   REGISTER int argnum;
1482   REGISTER Lisp_Object tem;
1483
1484   for (argnum = 0; argnum < nargs; argnum++)
1485     {
1486       tem = args[argnum];
1487     retry:
1488       if (CHAR_OR_CHAR_INTP (tem))
1489         {
1490           buffer_insert_emacs_char_1 (current_buffer, -1,
1491                                       XCHAR_OR_CHAR_INT (tem),
1492                                       INSDEL_BEFORE_MARKERS);
1493         }
1494       else if (STRINGP (tem))
1495         {
1496           buffer_insert_lisp_string_1 (current_buffer, -1, tem,
1497                                        INSDEL_BEFORE_MARKERS);
1498         }
1499       else
1500         {
1501           tem = wrong_type_argument (Qchar_or_string_p, tem);
1502           goto retry;
1503         }
1504     }
1505   zmacs_region_stays = 0;
1506   return Qnil;
1507 }
1508
1509 DEFUN ("insert-string", Finsert_string, 1, 2, 0, /*
1510 Insert STRING into BUFFER at BUFFER's point.
1511 Point moves forward so that it ends up after the inserted text.
1512 Any other markers at the point of insertion remain before the text.
1513 If a string has non-null string-extent-data, new extents will be created.
1514 BUFFER defaults to the current buffer.
1515 */
1516        (string, buffer))
1517 {
1518   struct buffer *b = decode_buffer (buffer, 1);
1519   CHECK_STRING (string);
1520   buffer_insert_lisp_string (b, string);
1521   zmacs_region_stays = 0;
1522   return Qnil;
1523 }
1524
1525 /* Third argument in FSF is INHERIT:
1526
1527 "The optional third arg INHERIT, if non-nil, says to inherit text properties
1528 from adjoining text, if those properties are sticky."
1529
1530 Jamie thinks this is bogus. */
1531
1532 \f
1533 DEFUN ("insert-char", Finsert_char, 1, 4, 0, /*
1534 Insert COUNT (second arg) copies of CHR (first arg).
1535 Point and all markers are affected as in the function `insert'.
1536 COUNT defaults to 1 if omitted.
1537 The optional third arg IGNORED is INHERIT under FSF Emacs.
1538 This is highly bogus, however, and XEmacs always behaves as if
1539 `t' were passed to INHERIT.
1540 The optional fourth arg BUFFER specifies the buffer to insert the
1541 text into.  If BUFFER is nil, the current buffer is assumed.
1542 */
1543        (chr, count, ignored, buffer))
1544 {
1545   /* This function can GC */
1546   REGISTER Bufbyte *string;
1547   REGISTER int slen;
1548   REGISTER int i, j;
1549   REGISTER Bytecount n;
1550   REGISTER Bytecount charlen;
1551   Bufbyte str[MAX_EMCHAR_LEN];
1552   struct buffer *b = decode_buffer (buffer, 1);
1553   int cou;
1554
1555   CHECK_CHAR_COERCE_INT (chr);
1556   if (NILP (count))
1557     cou = 1;
1558   else
1559     {
1560       CHECK_INT (count);
1561       cou = XINT (count);
1562     }
1563
1564   charlen = set_charptr_emchar (str, XCHAR (chr));
1565   n = cou * charlen;
1566   if (n <= 0)
1567     return Qnil;
1568   slen = min (n, 768);
1569   string = alloca_array (Bufbyte, slen);
1570   /* Write as many copies of the character into the temp string as will fit. */
1571   for (i = 0; i + charlen <= slen; i += charlen)
1572     for (j = 0; j < charlen; j++)
1573       string[i + j] = str[j];
1574   slen = i;
1575   while (n >= slen)
1576     {
1577       buffer_insert_raw_string (b, string, slen);
1578       n -= slen;
1579     }
1580   if (n > 0)
1581 #if 0 /* FSFmacs bogosity */
1582     {
1583       if (!NILP (inherit))
1584         insert_and_inherit (string, n);
1585       else
1586         insert (string, n);
1587     }
1588 #else
1589     buffer_insert_raw_string (b, string, n);
1590 #endif
1591
1592   zmacs_region_stays = 0;
1593   return Qnil;
1594 }
1595
1596 \f
1597 /* Making strings from buffer contents.  */
1598
1599 DEFUN ("buffer-substring", Fbuffer_substring, 0, 3, 0, /*
1600 Return the contents of part of BUFFER as a string.
1601 The two arguments START and END are character positions;
1602 they can be in either order.  If omitted, they default to the beginning
1603 and end of BUFFER, respectively.
1604 If there are duplicable extents in the region, the string remembers
1605 them in its extent data.
1606 If BUFFER is nil, the current buffer is assumed.
1607 */
1608        (start, end, buffer))
1609 {
1610   /* This function can GC */
1611   Bufpos begv, zv;
1612   struct buffer *b = decode_buffer (buffer, 1);
1613
1614   get_buffer_range_char (b, start, end, &begv, &zv, GB_ALLOW_NIL);
1615   return make_string_from_buffer (b, begv, zv - begv);
1616 }
1617
1618 /* It might make more sense to name this
1619    `buffer-substring-no-extents', but this name is FSFmacs-compatible,
1620    and what the function does is probably good enough for what the
1621    user-code will typically want to use it for. */
1622 DEFUN ("buffer-substring-no-properties", Fbuffer_substring_no_properties, 0, 3, 0, /*
1623 Return the text from BEG to END, as a string, without copying the extents.
1624 */
1625        (start, end, buffer))
1626 {
1627   /* This function can GC */
1628   Bufpos begv, zv;
1629   struct buffer *b = decode_buffer (buffer, 1);
1630
1631   get_buffer_range_char (b, start, end, &begv, &zv, GB_ALLOW_NIL);
1632   return make_string_from_buffer_no_extents (b, begv, zv - begv);
1633 }
1634
1635 DEFUN ("insert-buffer-substring", Finsert_buffer_substring, 1, 3, 0, /*
1636 Insert before point a substring of the contents of buffer BUFFER.
1637 BUFFER may be a buffer or a buffer name.
1638 Arguments START and END are character numbers specifying the substring.
1639 They default to the beginning and the end of BUFFER.
1640 */
1641        (buffer, start, end))
1642 {
1643   /* This function can GC */
1644   Bufpos b, e;
1645   struct buffer *bp;
1646
1647   bp = XBUFFER (get_buffer (buffer, 1));
1648   get_buffer_range_char (bp, start, end, &b, &e, GB_ALLOW_NIL);
1649
1650   if (b < e)
1651     buffer_insert_from_buffer (current_buffer, bp, b, e - b);
1652
1653   return Qnil;
1654 }
1655 \f
1656 DEFUN ("compare-buffer-substrings", Fcompare_buffer_substrings, 6, 6, 0, /*
1657 Compare two substrings of two buffers; return result as number.
1658 the value is -N if first string is less after N-1 chars,
1659 +N if first string is greater after N-1 chars, or 0 if strings match.
1660 Each substring is represented as three arguments: BUFFER, START and END.
1661 That makes six args in all, three for each substring.
1662
1663 The value of `case-fold-search' in the current buffer
1664 determines whether case is significant or ignored.
1665 */
1666        (buffer1, start1, end1, buffer2, start2, end2))
1667 {
1668   Bufpos begp1, endp1, begp2, endp2;
1669   REGISTER Charcount len1, len2, length, i;
1670   struct buffer *bp1, *bp2;
1671   Lisp_Object trt = ((!NILP (current_buffer->case_fold_search)) ?
1672                      current_buffer->case_canon_table : Qnil);
1673
1674   /* Find the first buffer and its substring.  */
1675
1676   bp1 = decode_buffer (buffer1, 1);
1677   get_buffer_range_char (bp1, start1, end1, &begp1, &endp1, GB_ALLOW_NIL);
1678
1679   /* Likewise for second substring.  */
1680
1681   bp2 = decode_buffer (buffer2, 1);
1682   get_buffer_range_char (bp2, start2, end2, &begp2, &endp2, GB_ALLOW_NIL);
1683
1684   len1 = endp1 - begp1;
1685   len2 = endp2 - begp2;
1686   length = len1;
1687   if (len2 < length)
1688     length = len2;
1689
1690   for (i = 0; i < length; i++)
1691     {
1692       Emchar c1 = BUF_FETCH_CHAR (bp1, begp1 + i);
1693       Emchar c2 = BUF_FETCH_CHAR (bp2, begp2 + i);
1694       if (!NILP (trt))
1695         {
1696           c1 = TRT_TABLE_OF (trt, c1);
1697           c2 = TRT_TABLE_OF (trt, c2);
1698         }
1699       if (c1 < c2)
1700         return make_int (- 1 - i);
1701       if (c1 > c2)
1702         return make_int (i + 1);
1703     }
1704
1705   /* The strings match as far as they go.
1706      If one is shorter, that one is less.  */
1707   if (length < len1)
1708     return make_int (length + 1);
1709   else if (length < len2)
1710     return make_int (- length - 1);
1711
1712   /* Same length too => they are equal.  */
1713   return Qzero;
1714 }
1715
1716 \f
1717 static Lisp_Object
1718 subst_char_in_region_unwind (Lisp_Object arg)
1719 {
1720   XBUFFER (XCAR (arg))->undo_list = XCDR (arg);
1721   return Qnil;
1722 }
1723
1724 static Lisp_Object
1725 subst_char_in_region_unwind_1 (Lisp_Object arg)
1726 {
1727   XBUFFER (XCAR (arg))->filename = XCDR (arg);
1728   return Qnil;
1729 }
1730
1731 DEFUN ("subst-char-in-region", Fsubst_char_in_region, 4, 5, 0, /*
1732 From START to END, replace FROMCHAR with TOCHAR each time it occurs.
1733 If optional arg NOUNDO is non-nil, don't record this change for undo
1734 and don't mark the buffer as really changed.
1735 */
1736   (start, end, fromchar, tochar, noundo))
1737 {
1738   /* This function can GC */
1739   Bufpos pos, stop;
1740   Emchar fromc, toc;
1741   int mc_count;
1742   struct buffer *buf = current_buffer;
1743   int count = specpdl_depth ();
1744
1745   get_buffer_range_char (buf, start, end, &pos, &stop, 0);
1746   CHECK_CHAR_COERCE_INT (fromchar);
1747   CHECK_CHAR_COERCE_INT (tochar);
1748
1749   fromc = XCHAR (fromchar);
1750   toc = XCHAR (tochar);
1751
1752   /* If we don't want undo, turn off putting stuff on the list.
1753      That's faster than getting rid of things,
1754      and it prevents even the entry for a first change.
1755      Also inhibit locking the file.  */
1756   if (!NILP (noundo))
1757     {
1758       record_unwind_protect (subst_char_in_region_unwind,
1759                              Fcons (Fcurrent_buffer (), buf->undo_list));
1760       buf->undo_list = Qt;
1761       /* Don't do file-locking.  */
1762       record_unwind_protect (subst_char_in_region_unwind_1,
1763                              Fcons (Fcurrent_buffer (), buf->filename));
1764       buf->filename = Qnil;
1765     }
1766
1767   mc_count = begin_multiple_change (buf, pos, stop);
1768   while (pos < stop)
1769     {
1770       if (BUF_FETCH_CHAR (buf, pos) == fromc)
1771         {
1772           /* There used to be some code here that set the buffer to
1773              unmodified if NOUNDO was specified and there was only
1774              one change to the buffer since it was last saved.
1775              This is a crock of shit, so I'm not duplicating this
1776              behavior.  I think this was left over from when
1777              prepare_to_modify_buffer() actually bumped MODIFF,
1778              so that code was supposed to undo this change. --ben */
1779           buffer_replace_char (buf, pos, toc, !NILP (noundo), 0);
1780
1781           /* If noundo is not nil then we don't mark the buffer as
1782              modified.  In reality that needs to happen externally
1783              only.  Internally redisplay needs to know that the actual
1784              contents it should be displaying have changed. */
1785           if (!NILP (noundo))
1786             Fset_buffer_modified_p (Fbuffer_modified_p (Qnil), Qnil);
1787         }
1788       pos++;
1789     }
1790   end_multiple_change (buf, mc_count);
1791
1792   unbind_to (count, Qnil);
1793   return Qnil;
1794 }
1795
1796 /* #### Shouldn't this also accept a BUFFER argument, in the good old
1797    XEmacs tradition?  */
1798 DEFUN ("translate-region", Ftranslate_region, 3, 3, 0, /*
1799 Translate characters from START to END according to TABLE.
1800
1801 If TABLE is a string, the Nth character in it is the mapping for the
1802 character with code N.
1803
1804 If TABLE is a vector, its Nth element is the mapping for character
1805 with code N.  The values of elements may be characters, strings, or
1806 nil (nil meaning don't replace.)
1807
1808 If TABLE is a char-table, its elements describe the mapping between
1809 characters and their replacements.  The char-table should be of type
1810 `char' or `generic'.
1811
1812 Returns the number of substitutions performed.
1813 */
1814        (start, end, table))
1815 {
1816   /* This function can GC */
1817   Bufpos pos, stop;     /* Limits of the region. */
1818   int cnt = 0;          /* Number of changes made. */
1819   int mc_count;
1820   struct buffer *buf = current_buffer;
1821   Emchar oc;
1822
1823   get_buffer_range_char (buf, start, end, &pos, &stop, 0);
1824   mc_count = begin_multiple_change (buf, pos, stop);
1825   if (STRINGP (table))
1826     {
1827       Lisp_String *stable = XSTRING (table);
1828       Charcount size = string_char_length (stable);
1829 #ifdef MULE
1830       /* Under Mule, string_char(n) is O(n), so for large tables or
1831          large regions it makes sense to create an array of Emchars.  */
1832       if (size * (stop - pos) > 65536)
1833         {
1834           Emchar *etable = alloca_array (Emchar, size);
1835           convert_bufbyte_string_into_emchar_string
1836             (string_data (stable), string_length (stable), etable);
1837           for (; pos < stop && (oc = BUF_FETCH_CHAR (buf, pos), 1); pos++)
1838             {
1839               if (oc < size)
1840                 {
1841                   Emchar nc = etable[oc];
1842                   if (nc != oc)
1843                     {
1844                       buffer_replace_char (buf, pos, nc, 0, 0);
1845                       ++cnt;
1846                     }
1847                 }
1848             }
1849         }
1850       else
1851 #endif /* MULE */
1852         {
1853           for (; pos < stop && (oc = BUF_FETCH_CHAR (buf, pos), 1); pos++)
1854             {
1855               if (oc < size)
1856                 {
1857                   Emchar nc = string_char (stable, oc);
1858                   if (nc != oc)
1859                     {
1860                       buffer_replace_char (buf, pos, nc, 0, 0);
1861                       ++cnt;
1862                     }
1863                 }
1864             }
1865         }
1866     }
1867   else if (VECTORP (table))
1868     {
1869       Charcount size = XVECTOR_LENGTH (table);
1870       Lisp_Object *vtable = XVECTOR_DATA (table);
1871
1872       for (; pos < stop && (oc = BUF_FETCH_CHAR (buf, pos), 1); pos++)
1873         {
1874           if (oc < size)
1875             {
1876               Lisp_Object replacement = vtable[oc];
1877             retry:
1878               if (CHAR_OR_CHAR_INTP (replacement))
1879                 {
1880                   Emchar nc = XCHAR_OR_CHAR_INT (replacement);
1881                   if (nc != oc)
1882                     {
1883                       buffer_replace_char (buf, pos, nc, 0, 0);
1884                       ++cnt;
1885                     }
1886                 }
1887               else if (STRINGP (replacement))
1888                 {
1889                   Charcount incr = XSTRING_CHAR_LENGTH (replacement) - 1;
1890                   buffer_delete_range (buf, pos, pos + 1, 0);
1891                   buffer_insert_lisp_string_1 (buf, pos, replacement, 0);
1892                   pos += incr, stop += incr;
1893                   ++cnt;
1894                 }
1895               else if (!NILP (replacement))
1896                 {
1897                   replacement = wrong_type_argument (Qchar_or_string_p, replacement);
1898                   goto retry;
1899                 }
1900             }
1901         }
1902     }
1903   else if (CHAR_TABLEP (table)
1904            && (XCHAR_TABLE_TYPE (table) == CHAR_TABLE_TYPE_GENERIC
1905                || XCHAR_TABLE_TYPE (table) == CHAR_TABLE_TYPE_CHAR))
1906     {
1907       Lisp_Char_Table *ctable = XCHAR_TABLE (table);
1908
1909       for (; pos < stop && (oc = BUF_FETCH_CHAR (buf, pos), 1); pos++)
1910         {
1911           Lisp_Object replacement = get_char_table (oc, ctable);
1912         retry2:
1913           if (CHAR_OR_CHAR_INTP (replacement))
1914             {
1915               Emchar nc = XCHAR_OR_CHAR_INT (replacement);
1916               if (nc != oc)
1917                 {
1918                   buffer_replace_char (buf, pos, nc, 0, 0);
1919                   ++cnt;
1920                 }
1921             }
1922           else if (STRINGP (replacement))
1923             {
1924               Charcount incr = XSTRING_CHAR_LENGTH (replacement) - 1;
1925               buffer_delete_range (buf, pos, pos + 1, 0);
1926               buffer_insert_lisp_string_1 (buf, pos, replacement, 0);
1927               pos += incr, stop += incr;
1928               ++cnt;
1929             }
1930           else if (!NILP (replacement))
1931             {
1932               replacement = wrong_type_argument (Qchar_or_string_p, replacement);
1933               goto retry2;
1934             }
1935         }
1936     }
1937   else
1938     dead_wrong_type_argument (Qstringp, table);
1939   end_multiple_change (buf, mc_count);
1940
1941   return make_int (cnt);
1942 }
1943
1944 DEFUN ("delete-region", Fdelete_region, 2, 3, "r", /*
1945 Delete the text between point and mark.
1946 When called from a program, expects two arguments,
1947 positions (integers or markers) specifying the stretch to be deleted.
1948 If BUFFER is nil, the current buffer is assumed.
1949 */
1950        (b, e, buffer))
1951 {
1952   /* This function can GC */
1953   Bufpos start, end;
1954   struct buffer *buf = decode_buffer (buffer, 1);
1955
1956   get_buffer_range_char (buf, b, e, &start, &end, 0);
1957   buffer_delete_range (buf, start, end, 0);
1958   zmacs_region_stays = 0;
1959   return Qnil;
1960 }
1961 \f
1962 void
1963 widen_buffer (struct buffer *b, int no_clip)
1964 {
1965   if (BUF_BEGV (b) != BUF_BEG (b))
1966     {
1967       clip_changed = 1;
1968       SET_BOTH_BUF_BEGV (b, BUF_BEG (b), BI_BUF_BEG (b));
1969     }
1970   if (BUF_ZV (b) != BUF_Z (b))
1971     {
1972       clip_changed = 1;
1973       SET_BOTH_BUF_ZV (b, BUF_Z (b), BI_BUF_Z (b));
1974     }
1975   if (clip_changed)
1976     {
1977       if (!no_clip)
1978         MARK_CLIP_CHANGED;
1979       /* Changing the buffer bounds invalidates any recorded current
1980          column.  */
1981       invalidate_current_column ();
1982       narrow_line_number_cache (b);
1983     }
1984 }
1985
1986 DEFUN ("widen", Fwiden, 0, 1, "", /*
1987 Remove restrictions (narrowing) from BUFFER.
1988 This allows the buffer's full text to be seen and edited.
1989 If BUFFER is nil, the current buffer is assumed.
1990 */
1991        (buffer))
1992 {
1993   struct buffer *b = decode_buffer (buffer, 1);
1994   widen_buffer (b, 0);
1995   zmacs_region_stays = 0;
1996   return Qnil;
1997 }
1998
1999 DEFUN ("narrow-to-region", Fnarrow_to_region, 2, 3, "r", /*
2000 Restrict editing in BUFFER to the current region.
2001 The rest of the text becomes temporarily invisible and untouchable
2002 but is not deleted; if you save the buffer in a file, the invisible
2003 text is included in the file.  \\[widen] makes all visible again.
2004 If BUFFER is nil, the current buffer is assumed.
2005 See also `save-restriction'.
2006
2007 When calling from a program, pass two arguments; positions (integers
2008 or markers) bounding the text that should remain visible.
2009 */
2010        (b, e, buffer))
2011 {
2012   Bufpos start, end;
2013   struct buffer *buf = decode_buffer (buffer, 1);
2014   Bytind bi_start, bi_end;
2015
2016   get_buffer_range_char (buf, b, e, &start, &end, GB_ALLOW_PAST_ACCESSIBLE);
2017   bi_start = bufpos_to_bytind (buf, start);
2018   bi_end = bufpos_to_bytind (buf, end);
2019
2020   SET_BOTH_BUF_BEGV (buf, start, bi_start);
2021   SET_BOTH_BUF_ZV (buf, end, bi_end);
2022   if (BUF_PT (buf) < start)
2023     BUF_SET_PT (buf, start);
2024   if (BUF_PT (buf) > end)
2025     BUF_SET_PT (buf, end);
2026   MARK_CLIP_CHANGED;
2027   /* Changing the buffer bounds invalidates any recorded current column.  */
2028   invalidate_current_column ();
2029   narrow_line_number_cache (buf);
2030   zmacs_region_stays = 0;
2031   return Qnil;
2032 }
2033
2034 Lisp_Object
2035 save_restriction_save (void)
2036 {
2037   Lisp_Object bottom, top;
2038   /* Note: I tried using markers here, but it does not win
2039      because insertion at the end of the saved region
2040      does not advance mh and is considered "outside" the saved region. */
2041   bottom = make_int (BUF_BEGV (current_buffer) - BUF_BEG (current_buffer));
2042   top = make_int (BUF_Z (current_buffer) - BUF_ZV (current_buffer));
2043
2044   return noseeum_cons (Fcurrent_buffer (), noseeum_cons (bottom, top));
2045 }
2046
2047 Lisp_Object
2048 save_restriction_restore (Lisp_Object data)
2049 {
2050   struct buffer *buf;
2051   Charcount newhead, newtail;
2052   Lisp_Object tem;
2053   int local_clip_changed = 0;
2054
2055   buf = XBUFFER (XCAR (data));
2056   if (!BUFFER_LIVE_P (buf))
2057     {
2058       /* someone could have killed the buffer in the meantime ... */
2059       free_cons (XCONS (XCDR (data)));
2060       free_cons (XCONS (data));
2061       return Qnil;
2062     }
2063   tem = XCDR (data);
2064   newhead = XINT (XCAR (tem));
2065   newtail = XINT (XCDR (tem));
2066
2067   free_cons (XCONS (XCDR (data)));
2068   free_cons (XCONS (data));
2069
2070   if (newhead + newtail > BUF_Z (buf) - BUF_BEG (buf))
2071     {
2072       newhead = 0;
2073       newtail = 0;
2074     }
2075
2076   {
2077     Bufpos start, end;
2078     Bytind bi_start, bi_end;
2079
2080     start = BUF_BEG (buf) + newhead;
2081     end = BUF_Z (buf) - newtail;
2082
2083     bi_start = bufpos_to_bytind (buf, start);
2084     bi_end = bufpos_to_bytind (buf, end);
2085
2086     if (BUF_BEGV (buf) != start)
2087       {
2088         local_clip_changed = 1;
2089         SET_BOTH_BUF_BEGV (buf, start, bi_start);
2090         narrow_line_number_cache (buf);
2091       }
2092     if (BUF_ZV (buf) != end)
2093       {
2094         local_clip_changed = 1;
2095         SET_BOTH_BUF_ZV (buf, end, bi_end);
2096       }
2097   }
2098   if (local_clip_changed)
2099     MARK_CLIP_CHANGED;
2100
2101   /* If point is outside the new visible range, move it inside. */
2102   BUF_SET_PT (buf,
2103               bufpos_clip_to_bounds (BUF_BEGV (buf),
2104                                      BUF_PT (buf),
2105                                      BUF_ZV (buf)));
2106
2107   return Qnil;
2108 }
2109
2110 DEFUN ("save-restriction", Fsave_restriction, 0, UNEVALLED, 0, /*
2111 Execute BODY, saving and restoring current buffer's restrictions.
2112 The buffer's restrictions make parts of the beginning and end invisible.
2113 \(They are set up with `narrow-to-region' and eliminated with `widen'.)
2114 This special form, `save-restriction', saves the current buffer's restrictions
2115 when it is entered, and restores them when it is exited.
2116 So any `narrow-to-region' within BODY lasts only until the end of the form.
2117 The old restrictions settings are restored
2118 even in case of abnormal exit (throw or error).
2119
2120 The value returned is the value of the last form in BODY.
2121
2122 `save-restriction' can get confused if, within the BODY, you widen
2123 and then make changes outside the area within the saved restrictions.
2124
2125 Note: if you are using both `save-excursion' and `save-restriction',
2126 use `save-excursion' outermost:
2127     (save-excursion (save-restriction ...))
2128 */
2129        (body))
2130 {
2131   /* This function can GC */
2132   int speccount = specpdl_depth ();
2133
2134   record_unwind_protect (save_restriction_restore, save_restriction_save ());
2135
2136   return unbind_to (speccount, Fprogn (body));
2137 }
2138
2139 \f
2140 DEFUN ("format", Fformat, 1, MANY, 0, /*
2141 Format a string out of a control-string and arguments.
2142 The first argument is a control string.
2143 The other arguments are substituted into it to make the result, a string.
2144 It may contain %-sequences meaning to substitute the next argument.
2145 %s means print all objects as-is, using `princ'.
2146 %S means print all objects as s-expressions, using `prin1'.
2147 %d or %i means print as an integer in decimal (%o octal, %x lowercase hex,
2148   %X uppercase hex).
2149 %c means print as a single character.
2150 %f means print as a floating-point number in fixed notation (e.g. 785.200).
2151 %e or %E means print as a floating-point number in scientific notation
2152   (e.g. 7.85200e+03).
2153 %g or %G means print as a floating-point number in "pretty format";
2154   depending on the number, either %f or %e/%E format will be used, and
2155   trailing zeroes are removed from the fractional part.
2156 The argument used for all but %s and %S must be a number.  It will be
2157   converted to an integer or a floating-point number as necessary.
2158
2159 %$ means reposition to read a specific numbered argument; for example,
2160   %3$s would apply the `%s' to the third argument after the control string,
2161   and the next format directive would use the fourth argument, the
2162   following one the fifth argument, etc. (There must be a positive integer
2163   between the % and the $).
2164 Zero or more of the flag characters `-', `+', ` ', `0', and `#' may be
2165   specified between the optional repositioning spec and the conversion
2166   character; see below.
2167 An optional minimum field width may be specified after any flag characters
2168   and before the conversion character; it specifies the minimum number of
2169   characters that the converted argument will take up.  Padding will be
2170   added on the left (or on the right, if the `-' flag is specified), as
2171   necessary.  Padding is done with spaces, or with zeroes if the `0' flag
2172   is specified.
2173 If the field width is specified as `*', the field width is assumed to have
2174   been specified as an argument.  Any repositioning specification that
2175   would normally specify the argument to be converted will now specify
2176   where to find this field width argument, not where to find the argument
2177   to be converted.  If there is no repositioning specification, the normal
2178   next argument is used.  The argument to be converted will be the next
2179   argument after the field width argument unless the precision is also
2180   specified as `*' (see below).
2181
2182 An optional period character and precision may be specified after any
2183   minimum field width.  It specifies the minimum number of digits to
2184   appear in %d, %i, %o, %x, and %X conversions (the number is padded
2185   on the left with zeroes as necessary); the number of digits printed
2186   after the decimal point for %f, %e, and %E conversions; the number
2187   of significant digits printed in %g and %G conversions; and the
2188   maximum number of non-padding characters printed in %s and %S
2189   conversions.  The default precision for floating-point conversions
2190   is six.
2191 If the precision is specified as `*', the precision is assumed to have been
2192   specified as an argument.  The argument used will be the next argument
2193   after the field width argument, if any.  If the field width was not
2194   specified as an argument, any repositioning specification that would
2195   normally specify the argument to be converted will now specify where to
2196   find the precision argument.  If there is no repositioning specification,
2197   the normal next argument is used.
2198
2199 The ` ' and `+' flags mean prefix non-negative numbers with a space or
2200   plus sign, respectively.
2201 The `#' flag means print numbers in an alternate, more verbose format:
2202   octal numbers begin with zero; hex numbers begin with a 0x or 0X;
2203   a decimal point is printed in %f, %e, and %E conversions even if no
2204   numbers are printed after it; and trailing zeroes are not omitted in
2205    %g and %G conversions.
2206
2207 Use %% to put a single % into the output.
2208 */
2209        (int nargs, Lisp_Object *args))
2210 {
2211   /* It should not be necessary to GCPRO ARGS, because
2212      the caller in the interpreter should take care of that.  */
2213
2214   CHECK_STRING (args[0]);
2215   return emacs_doprnt_string_lisp (0, args[0], 0, nargs - 1, args + 1);
2216 }
2217
2218 \f
2219 DEFUN ("char-equal", Fchar_equal, 2, 3, 0, /*
2220 Return t if two characters match, optionally ignoring case.
2221 Both arguments must be characters (i.e. NOT integers).
2222 Case is ignored if `case-fold-search' is non-nil in BUFFER.
2223 If BUFFER is nil, the current buffer is assumed.
2224 */
2225        (c1, c2, buffer))
2226 {
2227   Emchar x1, x2;
2228   struct buffer *b = decode_buffer (buffer, 1);
2229
2230   CHECK_CHAR_COERCE_INT (c1);
2231   CHECK_CHAR_COERCE_INT (c2);
2232   x1 = XCHAR (c1);
2233   x2 = XCHAR (c2);
2234
2235   return (!NILP (b->case_fold_search)
2236           ? DOWNCASE (b, x1) == DOWNCASE (b, x2)
2237           : x1 == x2)
2238     ? Qt : Qnil;
2239 }
2240
2241 DEFUN ("char=", Fchar_Equal, 2, 2, 0, /*
2242 Return t if two characters match, case is significant.
2243 Both arguments must be characters (i.e. NOT integers).
2244 */
2245        (c1, c2))
2246 {
2247   CHECK_CHAR_COERCE_INT (c1);
2248   CHECK_CHAR_COERCE_INT (c2);
2249
2250   return EQ (c1, c2) ? Qt : Qnil;
2251 }
2252 \f
2253 #if 0 /* Undebugged FSFmacs code */
2254 /* Transpose the markers in two regions of the current buffer, and
2255    adjust the ones between them if necessary (i.e.: if the regions
2256    differ in size).
2257
2258    Traverses the entire marker list of the buffer to do so, adding an
2259    appropriate amount to some, subtracting from some, and leaving the
2260    rest untouched.  Most of this is copied from adjust_markers in insdel.c.
2261
2262    It's the caller's job to see that (start1 <= end1 <= start2 <= end2).  */
2263
2264 void
2265 transpose_markers (Bufpos start1, Bufpos end1, Bufpos start2, Bufpos end2)
2266 {
2267   Charcount amt1, amt2, diff;
2268   Lisp_Object marker;
2269   struct buffer *buf = current_buffer;
2270
2271   /* Update point as if it were a marker.  */
2272   if (BUF_PT (buf) < start1)
2273     ;
2274   else if (BUF_PT (buf) < end1)
2275     BUF_SET_PT (buf, BUF_PT (buf) + (end2 - end1));
2276   else if (BUF_PT (buf) < start2)
2277     BUF_SET_PT (buf, BUF_PT (buf) + (end2 - start2) - (end1 - start1));
2278   else if (BUF_PT (buf) < end2)
2279     BUF_SET_PT (buf, BUF_PT (buf) - (start2 - start1));
2280
2281   /* We used to adjust the endpoints here to account for the gap, but that
2282      isn't good enough.  Even if we assume the caller has tried to move the
2283      gap out of our way, it might still be at start1 exactly, for example;
2284      and that places it `inside' the interval, for our purposes.  The amount
2285      of adjustment is nontrivial if there's a `denormalized' marker whose
2286      position is between GPT and GPT + GAP_SIZE, so it's simpler to leave
2287      the dirty work to Fmarker_position, below.  */
2288
2289   /* The difference between the region's lengths */
2290   diff = (end2 - start2) - (end1 - start1);
2291
2292   /* For shifting each marker in a region by the length of the other
2293    * region plus the distance between the regions.
2294    */
2295   amt1 = (end2 - start2) + (start2 - end1);
2296   amt2 = (end1 - start1) + (start2 - end1);
2297
2298   for (marker = BUF_MARKERS (buf); !NILP (marker);
2299        marker = XMARKER (marker)->chain)
2300     {
2301       Bufpos mpos = marker_position (marker);
2302       if (mpos >= start1 && mpos < end2)
2303         {
2304           if (mpos < end1)
2305             mpos += amt1;
2306           else if (mpos < start2)
2307             mpos += diff;
2308           else
2309             mpos -= amt2;
2310           set_marker_position (marker, mpos);
2311         }
2312     }
2313 }
2314
2315 #endif /* 0 */
2316
2317 DEFUN ("transpose-regions", Ftranspose_regions, 4, 5, 0, /*
2318 Transpose region START1 to END1 with START2 to END2.
2319 The regions may not be overlapping, because the size of the buffer is
2320 never changed in a transposition.
2321
2322 Optional fifth arg LEAVE_MARKERS, if non-nil, means don't transpose
2323 any markers that happen to be located in the regions. (#### BUG: currently
2324 this function always acts as if LEAVE_MARKERS is non-nil.)
2325
2326 Transposing beyond buffer boundaries is an error.
2327 */
2328   (startr1, endr1, startr2, endr2, leave_markers))
2329 {
2330   Bufpos start1, end1, start2, end2;
2331   Charcount len1, len2;
2332   Lisp_Object string1, string2;
2333   struct buffer *buf = current_buffer;
2334
2335   get_buffer_range_char (buf, startr1, endr1, &start1, &end1, 0);
2336   get_buffer_range_char (buf, startr2, endr2, &start2, &end2, 0);
2337
2338   len1 = end1 - start1;
2339   len2 = end2 - start2;
2340
2341   if (start2 < end1)
2342     error ("transposed regions not properly ordered");
2343   else if (start1 == end1 || start2 == end2)
2344     error ("transposed region may not be of length 0");
2345
2346   string1 = make_string_from_buffer (buf, start1, len1);
2347   string2 = make_string_from_buffer (buf, start2, len2);
2348   buffer_delete_range (buf, start2, end2, 0);
2349   buffer_insert_lisp_string_1 (buf, start2, string1, 0);
2350   buffer_delete_range (buf, start1, end1, 0);
2351   buffer_insert_lisp_string_1 (buf, start1, string2, 0);
2352
2353   /* In FSFmacs there is a whole bunch of really ugly code here
2354      to attempt to transpose the regions without using up any
2355      extra memory.  Although the intent may be good, the result
2356      was highly bogus. */
2357
2358   return Qnil;
2359 }
2360
2361 \f
2362 /************************************************************************/
2363 /*                            initialization                            */
2364 /************************************************************************/
2365
2366 void
2367 syms_of_editfns (void)
2368 {
2369   defsymbol (&Qpoint, "point");
2370   defsymbol (&Qmark, "mark");
2371   defsymbol (&Qregion_beginning, "region-beginning");
2372   defsymbol (&Qregion_end, "region-end");
2373   defsymbol (&Qformat, "format");
2374   defsymbol (&Quser_files_and_directories, "user-files-and-directories");
2375
2376   DEFSUBR (Fchar_equal);
2377   DEFSUBR (Fchar_Equal);
2378   DEFSUBR (Fgoto_char);
2379   DEFSUBR (Fstring_to_char);
2380   DEFSUBR (Fchar_to_string);
2381   DEFSUBR (Fbuffer_substring);
2382   DEFSUBR (Fbuffer_substring_no_properties);
2383
2384   DEFSUBR (Fpoint_marker);
2385   DEFSUBR (Fmark_marker);
2386   DEFSUBR (Fpoint);
2387   DEFSUBR (Fregion_beginning);
2388   DEFSUBR (Fregion_end);
2389   DEFSUBR (Fsave_excursion);
2390   DEFSUBR (Fsave_current_buffer);
2391
2392   DEFSUBR (Fbuffer_size);
2393   DEFSUBR (Fpoint_max);
2394   DEFSUBR (Fpoint_min);
2395   DEFSUBR (Fpoint_min_marker);
2396   DEFSUBR (Fpoint_max_marker);
2397
2398   DEFSUBR (Fbobp);
2399   DEFSUBR (Feobp);
2400   DEFSUBR (Fbolp);
2401   DEFSUBR (Feolp);
2402   DEFSUBR (Ffollowing_char);
2403   DEFSUBR (Fpreceding_char);
2404   DEFSUBR (Fchar_after);
2405   DEFSUBR (Fchar_before);
2406   DEFSUBR (Finsert);
2407   DEFSUBR (Finsert_string);
2408   DEFSUBR (Finsert_before_markers);
2409   DEFSUBR (Finsert_char);
2410
2411   DEFSUBR (Ftemp_directory);
2412   DEFSUBR (Fuser_login_name);
2413   DEFSUBR (Fuser_real_login_name);
2414   DEFSUBR (Fuser_uid);
2415   DEFSUBR (Fuser_real_uid);
2416   DEFSUBR (Fuser_full_name);
2417   DEFSUBR (Fuser_home_directory);
2418   DEFSUBR (Femacs_pid);
2419   DEFSUBR (Fcurrent_time);
2420   DEFSUBR (Fcurrent_process_time);
2421   DEFSUBR (Fformat_time_string);
2422   DEFSUBR (Fdecode_time);
2423   DEFSUBR (Fencode_time);
2424   DEFSUBR (Fcurrent_time_string);
2425   DEFSUBR (Fcurrent_time_zone);
2426   DEFSUBR (Fset_time_zone_rule);
2427   DEFSUBR (Fsystem_name);
2428   DEFSUBR (Fformat);
2429
2430   DEFSUBR (Finsert_buffer_substring);
2431   DEFSUBR (Fcompare_buffer_substrings);
2432   DEFSUBR (Fsubst_char_in_region);
2433   DEFSUBR (Ftranslate_region);
2434   DEFSUBR (Fdelete_region);
2435   DEFSUBR (Fwiden);
2436   DEFSUBR (Fnarrow_to_region);
2437   DEFSUBR (Fsave_restriction);
2438   DEFSUBR (Ftranspose_regions);
2439
2440   defsymbol (&Qzmacs_update_region, "zmacs-update-region");
2441   defsymbol (&Qzmacs_deactivate_region, "zmacs-deactivate-region");
2442   defsymbol (&Qzmacs_region_buffer, "zmacs-region-buffer");
2443 }
2444
2445 void
2446 vars_of_editfns (void)
2447 {
2448   staticpro (&Vsystem_name);
2449 #if 0
2450   staticpro (&Vuser_name);
2451   staticpro (&Vuser_real_name);
2452 #endif
2453   DEFVAR_BOOL ("zmacs-regions", &zmacs_regions /*
2454 *Whether LISPM-style active regions should be used.
2455 This means that commands which operate on the region (the area between the
2456 point and the mark) will only work while the region is in the ``active''
2457 state, which is indicated by highlighting.  Executing most commands causes
2458 the region to not be in the active state, so (for example) \\[kill-region] will only
2459 work immediately after activating the region.
2460
2461 More specifically:
2462
2463  - Commands which operate on the region only work if the region is active.
2464  - Only a very small set of commands cause the region to become active:
2465    Those commands whose semantics are to mark an area, like mark-defun.
2466  - The region is deactivated after each command that is executed, except that:
2467  - "Motion" commands do not change whether the region is active or not.
2468
2469 set-mark-command (C-SPC) pushes a mark and activates the region.  Moving the
2470 cursor with normal motion commands (C-n, C-p, etc) will cause the region
2471 between point and the recently-pushed mark to be highlighted.  It will
2472 remain highlighted until some non-motion command is executed.
2473
2474 exchange-point-and-mark (\\[exchange-point-and-mark]) activates the region.  So if you mark a
2475 region and execute a command that operates on it, you can reactivate the
2476 same region with \\[exchange-point-and-mark] (or perhaps \\[exchange-point-and-mark] \\[exchange-point-and-mark]) to operate on it
2477 again.
2478
2479 Generally, commands which push marks as a means of navigation (like
2480 beginning-of-buffer and end-of-buffer (M-< and M->)) do not activate the
2481 region.  But commands which push marks as a means of marking an area of
2482 text (like mark-defun (\\[mark-defun]), mark-word (\\[mark-word]) or mark-whole-buffer (\\[mark-whole-buffer]))
2483 do activate the region.
2484
2485 The way the command loop actually works with regard to deactivating the
2486 region is as follows:
2487
2488 - If the variable `zmacs-region-stays' has been set to t during the command
2489   just executed, the region is left alone (this is how the motion commands
2490   make the region stay around; see the `_' flag in the `interactive'
2491   specification).  `zmacs-region-stays' is reset to nil before each command
2492   is executed.
2493 - If the function `zmacs-activate-region' has been called during the command
2494   just executed, the region is left alone.  Very few functions should
2495   actually call this function.
2496 - Otherwise, if the region is active, the region is deactivated and
2497   the `zmacs-deactivate-region-hook' is called.
2498 */ );
2499   /* Zmacs style active regions are now ON by default */
2500   zmacs_regions = 1;
2501
2502   DEFVAR_BOOL ("zmacs-region-active-p", &zmacs_region_active_p /*
2503 Do not alter this.  It is for internal use only.
2504 */ );
2505   zmacs_region_active_p = 0;
2506
2507   DEFVAR_BOOL ("zmacs-region-stays", &zmacs_region_stays /*
2508 Whether the current command will deactivate the region.
2509 Commands which do not wish to affect whether the region is currently
2510 highlighted should set this to t.  Normally, the region is turned off after
2511 executing each command that did not explicitly turn it on with the function
2512 zmacs-activate-region. Setting this to true lets a command be non-intrusive.
2513 See the variable `zmacs-regions'.
2514
2515 The same effect can be achieved using the `_' interactive specification.
2516 */ );
2517   zmacs_region_stays = 0;
2518
2519   DEFVAR_BOOL ("atomic-extent-goto-char-p", &atomic_extent_goto_char_p /*
2520 Do not use this -- it will be going away soon.
2521 Indicates if `goto-char' has just been run.  This information is allegedly
2522 needed to get the desired behavior for atomic extents and unfortunately
2523 is not available by any other means.
2524 */ );
2525   atomic_extent_goto_char_p = 0;
2526 #ifdef AMPERSAND_FULL_NAME
2527   Fprovide(intern("ampersand-full-name"));
2528 #endif
2529
2530   DEFVAR_LISP ("user-full-name", &Vuser_full_name /*
2531 *The name of the user.
2532 The function `user-full-name', which will return the value of this
2533  variable, when called without arguments.
2534 This is initialized to the value of the NAME environment variable.
2535 */ );
2536   /* Initialized at run-time. */
2537   Vuser_full_name = Qnil;
2538 }