Mercurial > hg > xemacs-beta
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. |