comparison src/editfns.c @ 442:abe6d1db359e r21-2-36

Import from CVS: tag r21-2-36
author cvs
date Mon, 13 Aug 2007 11:35:02 +0200
parents 8de8e3f6228a
children 576fb035e263
comparison
equal deleted inserted replaced
441:72a7cfa4a488 442:abe6d1db359e
26 26
27 /* Hacked on for Mule by Ben Wing, December 1994. */ 27 /* Hacked on for Mule by Ben Wing, December 1994. */
28 28
29 #include <config.h> 29 #include <config.h>
30 #include "lisp.h" 30 #include "lisp.h"
31 #ifdef HAVE_UNISTD_H
32 #include <unistd.h>
33 #endif
34 31
35 #include "buffer.h" 32 #include "buffer.h"
36 #include "commands.h" 33 #include "commands.h"
37 #include "events.h" /* for EVENTP */ 34 #include "events.h" /* for EVENTP */
38 #include "extents.h" 35 #include "extents.h"
601 if (n < BUF_BEGV (b)) 598 if (n < BUF_BEGV (b))
602 return Qnil; 599 return Qnil;
603 return make_char (BUF_FETCH_CHAR (b, n)); 600 return make_char (BUF_FETCH_CHAR (b, n));
604 } 601 }
605 602
603 #if !defined(WINDOWSNT) && !defined(MSDOS)
604 #include <sys/stat.h>
605 #include <fcntl.h>
606 #include <errno.h>
607 #include <limits.h>
608 #endif
606 609
607 DEFUN ("temp-directory", Ftemp_directory, 0, 0, 0, /* 610 DEFUN ("temp-directory", Ftemp_directory, 0, 0, 0, /*
608 Return the pathname to the directory to use for temporary files. 611 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, 612 On MS Windows, this is obtained from the TEMP or TMP environment variables,
610 defaulting to / if they are both undefined. 613 defaulting to / if they are both undefined.
611 On Unix it is obtained from TMPDIR, with /tmp as the default 614 On Unix it is obtained from TMPDIR, with /tmp as the default
612 */ 615 */
613 ()) 616 ())
614 { 617 {
615 char *tmpdir; 618 char *tmpdir;
616 #if defined(WINDOWSNT) || defined(MSDOS) 619 #if defined(WIN32_NATIVE)
617 tmpdir = getenv ("TEMP"); 620 tmpdir = getenv ("TEMP");
618 if (!tmpdir) 621 if (!tmpdir)
619 tmpdir = getenv ("TMP"); 622 tmpdir = getenv ("TMP");
620 if (!tmpdir) 623 if (!tmpdir)
621 tmpdir = "/"; 624 tmpdir = "/";
622 #else /* WINDOWSNT || MSDOS */ 625 #else /* WIN32_NATIVE */
623 tmpdir = getenv ("TMPDIR"); 626 tmpdir = getenv ("TMPDIR");
624 if (!tmpdir) 627 if (!tmpdir)
628 {
629 struct stat st;
630 int myuid = getuid();
631 static char path[5 /* strlen ("/tmp/") */ + 1 + _POSIX_PATH_MAX];
632
633 strcpy (path, "/tmp/");
634 strncat (path, user_login_name (NULL), _POSIX_PATH_MAX);
635 if (lstat(path, &st) < 0 && errno == ENOENT)
636 {
637 mkdir(path, 0700); /* ignore retval -- checked next anyway. */
638 }
639 if (lstat(path, &st) == 0 && st.st_uid == myuid && S_ISDIR(st.st_mode))
640 {
641 tmpdir = path;
642 }
643 else
644 {
645 strcpy(path, getenv("HOME")); strncat(path, "/tmp/", _POSIX_PATH_MAX);
646 if (stat(path, &st) < 0 && errno == ENOENT)
647 {
648 int fd;
649 char warnpath[1+_POSIX_PATH_MAX];
650 mkdir(path, 0700); /* ignore retvals */
651 strcpy(warnpath, path);
652 strncat(warnpath, ".created_by_xemacs", _POSIX_PATH_MAX);
653 if ((fd = open(warnpath, O_WRONLY|O_CREAT, 0644)) > 0)
654 {
655 write(fd, "XEmacs created this directory because /tmp/<yourname> was unavailable -- \nPlease check !\n", 89);
656 close(fd);
657 }
658 }
659 if (stat(path, &st) == 0 && S_ISDIR(st.st_mode))
660 {
661 tmpdir = path;
662 }
663 else
664 {
625 tmpdir = "/tmp"; 665 tmpdir = "/tmp";
666 }
667 }
668 }
626 #endif 669 #endif
627 670
628 return build_ext_string (tmpdir, Qfile_name); 671 return build_ext_string (tmpdir, Qfile_name);
629 } 672 }
630 673
679 old environment (I site observed behavior on sunos and linux), so the 722 old environment (I site observed behavior on sunos and linux), so the
680 environment variables should be disregarded in that case. --Stig */ 723 environment variables should be disregarded in that case. --Stig */
681 char *user_name = getenv ("LOGNAME"); 724 char *user_name = getenv ("LOGNAME");
682 if (!user_name) 725 if (!user_name)
683 user_name = getenv ( 726 user_name = getenv (
684 #ifdef WINDOWSNT 727 #ifdef WIN32_NATIVE
685 "USERNAME" /* it's USERNAME on NT */ 728 "USERNAME" /* it's USERNAME on NT */
686 #else 729 #else
687 "USER" 730 "USER"
688 #endif 731 #endif
689 ); 732 );
690 if (user_name) 733 if (user_name)
691 return (user_name); 734 return (user_name);
692 else 735 else
693 { 736 {
694 struct passwd *pw = getpwuid (geteuid ()); 737 struct passwd *pw = getpwuid (geteuid ());
695 #ifdef __CYGWIN32__ 738 #ifdef CYGWIN
696 /* Since the Cygwin environment may not have an /etc/passwd, 739 /* Since the Cygwin environment may not have an /etc/passwd,
697 return "unknown" instead of the null if the username 740 return "unknown" instead of the null if the username
698 cannot be determined. 741 cannot be determined.
699 */ 742 */
700 return pw ? pw->pw_name : "unknown"; 743 return pw ? pw->pw_name : "unknown";
714 ()) 757 ())
715 { 758 {
716 struct passwd *pw = getpwuid (getuid ()); 759 struct passwd *pw = getpwuid (getuid ());
717 /* #### - I believe this should return nil instead of "unknown" when pw==0 */ 760 /* #### - I believe this should return nil instead of "unknown" when pw==0 */
718 761
719 #ifdef MSDOS
720 /* We let the real user name default to "root" because that's quite
721 accurate on MSDOG and because it lets Emacs find the init file.
722 (The DVX libraries override the Djgpp libraries here.) */
723 Lisp_Object tem = build_string (pw ? pw->pw_name : "root");/* no gettext */
724 #else
725 Lisp_Object tem = build_string (pw ? pw->pw_name : "unknown");/* no gettext */ 762 Lisp_Object tem = build_string (pw ? pw->pw_name : "unknown");/* no gettext */
726 #endif
727 return tem; 763 return tem;
728 } 764 }
729 765
730 DEFUN ("user-uid", Fuser_uid, 0, 0, 0, /* 766 DEFUN ("user-uid", Fuser_uid, 0, 0, 0, /*
731 Return the effective uid of Emacs, as an integer. 767 Return the effective uid of Emacs, as an integer.
762 return Vuser_full_name; 798 return Vuser_full_name;
763 799
764 user_name = (STRINGP (user) ? user : Fuser_login_name (user)); 800 user_name = (STRINGP (user) ? user : Fuser_login_name (user));
765 if (!NILP (user_name)) /* nil when nonexistent UID passed as arg */ 801 if (!NILP (user_name)) /* nil when nonexistent UID passed as arg */
766 { 802 {
767 CONST char *user_name_ext; 803 const char *user_name_ext;
768 804
769 /* Fuck me. getpwnam() can call select() and (under IRIX at least) 805 /* Fuck me. getpwnam() can call select() and (under IRIX at least)
770 things get wedged if a SIGIO arrives during this time. */ 806 things get wedged if a SIGIO arrives during this time. */
771 TO_EXTERNAL_FORMAT (LISP_STRING, user_name, 807 TO_EXTERNAL_FORMAT (LISP_STRING, user_name,
772 C_STRING_ALLOCA, user_name_ext, 808 C_STRING_ALLOCA, user_name_ext,
777 } 813 }
778 814
779 /* #### - Stig sez: this should return nil instead of "unknown" when pw==0 */ 815 /* #### - Stig sez: this should return nil instead of "unknown" when pw==0 */
780 /* Ben sez: bad idea because it's likely to break something */ 816 /* Ben sez: bad idea because it's likely to break something */
781 #ifndef AMPERSAND_FULL_NAME 817 #ifndef AMPERSAND_FULL_NAME
782 p = ((pw) ? USER_FULL_NAME : "unknown"); /* don't gettext */ 818 p = pw ? USER_FULL_NAME : "unknown"; /* don't gettext */
783 q = strchr (p, ','); 819 q = strchr (p, ',');
784 #else 820 #else
785 p = ((pw) ? USER_FULL_NAME : "unknown"); /* don't gettext */ 821 p = pw ? USER_FULL_NAME : "unknown"; /* don't gettext */
786 q = strchr (p, ','); 822 q = strchr (p, ',');
787 #endif 823 #endif
788 tem = ((!NILP (user) && !pw) 824 tem = ((!NILP (user) && !pw)
789 ? Qnil 825 ? Qnil
790 : make_ext_string ((Extbyte *) p, (q ? q - p : strlen (p)), 826 : make_ext_string ((Extbyte *) p, (q ? q - p : strlen (p)),
820 { 856 {
821 cached_home_directory = NULL; /* in some cases, this may cause the leaking 857 cached_home_directory = NULL; /* in some cases, this may cause the leaking
822 of a few bytes */ 858 of a few bytes */
823 } 859 }
824 860
861 /* !!#### not Mule correct. */
862
825 /* Returns the home directory, in external format */ 863 /* Returns the home directory, in external format */
826 Extbyte * 864 Extbyte *
827 get_home_directory (void) 865 get_home_directory (void)
828 { 866 {
867 /* !!#### this is hopelessly bogus. Rule #1: Do not make any assumptions
868 about what format an external string is in. Could be Unicode, for all
869 we know, and then all the operations below are totally bogus.
870 Instead, convert all data to internal format *right* at the juncture
871 between XEmacs and the outside world, the very moment we first get
872 the data. --ben */
829 int output_home_warning = 0; 873 int output_home_warning = 0;
830 874
831 if (cached_home_directory == NULL) 875 if (cached_home_directory == NULL)
832 { 876 {
833 if ((cached_home_directory = (Extbyte *) getenv("HOME")) == NULL) 877 if ((cached_home_directory = (Extbyte *) getenv("HOME")) == NULL)
834 { 878 {
835 #if defined(WINDOWSNT) && !defined(__CYGWIN32__) 879 #if defined(WIN32_NATIVE)
836 char *homedrive, *homepath; 880 char *homedrive, *homepath;
837 881
838 if ((homedrive = getenv("HOMEDRIVE")) != NULL && 882 if ((homedrive = getenv("HOMEDRIVE")) != NULL &&
839 (homepath = getenv("HOMEPATH")) != NULL) 883 (homepath = getenv("HOMEPATH")) != NULL)
840 { 884 {
845 homedrive, 889 homedrive,
846 homepath); 890 homepath);
847 } 891 }
848 else 892 else
849 { 893 {
850 # if 1 894 # if 0 /* changed by ben. This behavior absolutely stinks, and the
895 possibility being addressed here occurs quite commonly.
896 Using the current directory makes absolutely no sense. */
851 /* 897 /*
852 * Use the current directory. 898 * Use the current directory.
853 * This preserves the existing XEmacs behavior, but is different 899 * This preserves the existing XEmacs behavior, but is different
854 * from NT Emacs. 900 * from NT Emacs.
855 */ 901 */
856 if (initial_directory[0] != '\0') 902 if (initial_directory[0] != '\0')
857 { 903 {
858 cached_home_directory = initial_directory; 904 cached_home_directory = (Extbyte*) initial_directory;
859 } 905 }
860 else 906 else
861 { 907 {
862 /* This will probably give the wrong value */ 908 /* This will probably give the wrong value */
863 cached_home_directory = getcwd (NULL, 0); 909 cached_home_directory = (Extbyte*) getcwd (NULL, 0);
864 } 910 }
865 # else 911 # else
866 /* 912 /*
867 * This is NT Emacs behavior 913 * This is NT Emacs behavior
868 */ 914 */
869 cached_home_directory = (Extbyte *) "C:\\"; 915 cached_home_directory = (Extbyte *) "C:\\";
870 output_home_warning = 1; 916 output_home_warning = 1;
871 # endif 917 # endif
872 } 918 }
873 #else /* !WINDOWSNT */ 919 #else /* !WIN32_NATIVE */
874 /* 920 /*
875 * Unix, typically. 921 * Unix, typically.
876 * Using "/" isn't quite right, but what should we do? 922 * Using "/" isn't quite right, but what should we do?
877 * We probably should try to extract pw_dir from /etc/passwd, 923 * We probably should try to extract pw_dir from /etc/passwd,
878 * before falling back to this. 924 * before falling back to this.
879 */ 925 */
880 cached_home_directory = (Extbyte *) "/"; 926 cached_home_directory = (Extbyte *) "/";
881 output_home_warning = 1; 927 output_home_warning = 1;
882 #endif /* !WINDOWSNT */ 928 #endif /* !WIN32_NATIVE */
883 } 929 }
884 if (initialized && output_home_warning) 930 if (initialized && output_home_warning)
885 { 931 {
886 warn_when_safe (Quser_files_and_directories, Qwarning, "\n" 932 warn_when_safe (Quser_files_and_directories, Qwarning, "\n"
887 " XEmacs was unable to determine a good value for the user's $HOME\n" 933 " XEmacs was unable to determine a good value for the user's $HOME\n"
1002 { 1048 {
1003 unsigned int item = (unsigned int) the_time; 1049 unsigned int item = (unsigned int) the_time;
1004 return Fcons (make_int (item >> 16), make_int (item & 0xffff)); 1050 return Fcons (make_int (item >> 16), make_int (item & 0xffff));
1005 } 1051 }
1006 1052
1007 size_t emacs_strftime (char *string, size_t max, CONST char *format, 1053 size_t emacs_strftime (char *string, size_t max, const char *format,
1008 CONST struct tm *tm); 1054 const struct tm *tm);
1009 static long difftm (CONST struct tm *a, CONST struct tm *b); 1055 static long difftm (const struct tm *a, const struct tm *b);
1010 1056
1011 1057
1012 DEFUN ("format-time-string", Fformat_time_string, 1, 2, 0, /* 1058 DEFUN ("format-time-string", Fformat_time_string, 1, 2, 0, /*
1013 Use FORMAT-STRING to format the time TIME. 1059 Use FORMAT-STRING to format the time TIME.
1014 TIME is specified as (HIGH LOW . IGNORED) or (HIGH . LOW), as from 1060 TIME is specified as (HIGH LOW . IGNORED) or (HIGH . LOW), as from
1071 while (1) 1117 while (1)
1072 { 1118 {
1073 char *buf = (char *) alloca (size); 1119 char *buf = (char *) alloca (size);
1074 *buf = 1; 1120 *buf = 1;
1075 if (emacs_strftime (buf, size, 1121 if (emacs_strftime (buf, size,
1076 (CONST char *) XSTRING_DATA (format_string), 1122 (const char *) XSTRING_DATA (format_string),
1077 localtime (&value)) 1123 localtime (&value))
1078 || !*buf) 1124 || !*buf)
1079 return build_ext_string (buf, Qbinary); 1125 return build_ext_string (buf, Qbinary);
1080 /* If buffer was too small, make it bigger. */ 1126 /* If buffer was too small, make it bigger. */
1081 size *= 2; 1127 size *= 2;
1218 and from `file-attributes'. 1264 and from `file-attributes'.
1219 */ 1265 */
1220 (specified_time)) 1266 (specified_time))
1221 { 1267 {
1222 time_t value; 1268 time_t value;
1223 char buf[30]; 1269 char *the_ctime;
1224 char *tem; 1270 size_t len;
1225 1271
1226 if (! lisp_to_time (specified_time, &value)) 1272 if (! lisp_to_time (specified_time, &value))
1227 value = -1; 1273 value = -1;
1228 tem = (char *) ctime (&value); 1274 the_ctime = ctime (&value);
1229 1275
1230 strncpy (buf, tem, 24); 1276 /* ctime is documented as always returning a "\n\0"-terminated
1231 buf[24] = 0; 1277 26-byte American time string, but let's be careful anyways. */
1232 1278 for (len = 0; the_ctime[len] != '\n' && the_ctime[len] != '\0'; len++)
1233 return build_ext_string (buf, Qbinary); 1279 ;
1280
1281 return make_ext_string ((Extbyte *) the_ctime, len, Qbinary);
1234 } 1282 }
1235 1283
1236 #define TM_YEAR_ORIGIN 1900 1284 #define TM_YEAR_ORIGIN 1900
1237 1285
1238 /* Yield A - B, measured in seconds. */ 1286 /* Yield A - B, measured in seconds. */
1239 static long 1287 static long
1240 difftm (CONST struct tm *a, CONST struct tm *b) 1288 difftm (const struct tm *a, const struct tm *b)
1241 { 1289 {
1242 int ay = a->tm_year + (TM_YEAR_ORIGIN - 1); 1290 int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
1243 int by = b->tm_year + (TM_YEAR_ORIGIN - 1); 1291 int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
1244 /* Some compilers can't handle this as a single return statement. */ 1292 /* Some compilers can't handle this as a single return statement. */
1245 long days = ( 1293 long days = (
2511 executing each command that did not explicitly turn it on with the function 2559 executing each command that did not explicitly turn it on with the function
2512 zmacs-activate-region. Setting this to true lets a command be non-intrusive. 2560 zmacs-activate-region. Setting this to true lets a command be non-intrusive.
2513 See the variable `zmacs-regions'. 2561 See the variable `zmacs-regions'.
2514 2562
2515 The same effect can be achieved using the `_' interactive specification. 2563 The same effect can be achieved using the `_' interactive specification.
2564
2565 `zmacs-region-stays' is reset to nil before each command is executed.
2516 */ ); 2566 */ );
2517 zmacs_region_stays = 0; 2567 zmacs_region_stays = 0;
2518 2568
2519 DEFVAR_BOOL ("atomic-extent-goto-char-p", &atomic_extent_goto_char_p /* 2569 DEFVAR_BOOL ("atomic-extent-goto-char-p", &atomic_extent_goto_char_p /*
2520 Do not use this -- it will be going away soon. 2570 Do not use this -- it will be going away soon.