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