comparison src/syswindows.h @ 4834:b3ea9c582280

Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
author Ben Wing <ben@xemacs.org>
date Tue, 12 Jan 2010 01:38:04 -0600
parents 11daf37dae4d
children 95c4ced5c07c
comparison
equal deleted inserted replaced
4833:4dd2389173fc 4834:b3ea9c582280
1 /* Copyright (C) 2000 Free Software Foundation, Inc. 1 /* Copyright (C) 2000 Free Software Foundation, Inc.
2 Copyright (C) 2000, 2001, 2002, 2004 Ben Wing. 2 Copyright (C) 2000, 2001, 2002, 2004, 2010 Ben Wing.
3 3
4 This file is part of XEmacs. 4 This file is part of XEmacs.
5 5
6 XEmacs is free software; you can redistribute it and/or modify it 6 XEmacs is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the 7 under the terms of the GNU General Public License as published by the
135 135
136 #ifdef CYGWIN_HEADERS 136 #ifdef CYGWIN_HEADERS
137 137
138 #include <cygwin/stat.h> /* for struct stat */ 138 #include <cygwin/stat.h> /* for struct stat */
139 #include <w32api.h> /* for version info */ 139 #include <w32api.h> /* for version info */
140 #include <sys/cygwin.h> /* path conversion functions */
140 141
141 /* Test for a specific version of w32api */ 142 /* Test for a specific version of w32api */
142 #define W32API_VER(major,minor) (((major) << 16) + (minor)) 143 #define W32API_VER(major,minor) (((major) << 16) + (minor))
143 #define W32API_INSTALLED_VER \ 144 #define W32API_INSTALLED_VER \
144 W32API_VER (__W32API_MAJOR_VERSION, __W32API_MINOR_VERSION) 145 W32API_VER (__W32API_MAJOR_VERSION, __W32API_MINOR_VERSION)
929 930
930 /* ------------------------- Filename conversion ------------------------- */ 931 /* ------------------------- Filename conversion ------------------------- */
931 932
932 #ifdef CYGWIN 933 #ifdef CYGWIN
933 934
934 BEGIN_C_DECLS 935 /* We should just remove the Windows 9x support */
935 936
936 void cygwin_win32_to_posix_path_list (const char *, char *); 937 #define CCP_POSIX_TO_WIN_T \
937 int cygwin_win32_to_posix_path_list_buf_size (const char *); 938 (XEUNICODE_P ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A)
938 void cygwin_posix_to_win32_path_list (const char *, char *); 939 #define CCP_WIN_T_TO_POSIX \
939 int cygwin_posix_to_win32_path_list_buf_size (const char *); 940 (XEUNICODE_P ? CCP_WIN_W_TO_POSIX : CCP_WIN_A_TO_POSIX)
940 extern int cygwin_conv_to_full_win32_path (const char *, char *); 941
941 942 #endif
942 END_C_DECLS 943
943 944 #ifdef HAVE_CYGWIN_CONV_PATH
944 #endif 945 #define LOCAL_FILE_FORMAT_TO_TSTR(path, out) \
945 946 do { \
946 #define LOCAL_FILE_FORMAT_TO_TSTR(path, out) \ 947 const Ibyte *lfftt = (path); \
947 do { \ 948 if (isalpha (lfftt[0]) && (IS_DEVICE_SEP (lfftt[1]))) \
948 Ibyte *lttff; \ 949 PATHNAME_CONVERT_OUT_TSTR (lfftt, out); \
949 \ 950 else \
950 LOCAL_TO_WIN32_FILE_FORMAT (XSTRING_DATA (path), lttff); \ 951 { \
951 PATHNAME_CONVERT_OUT (lttff, out); \ 952 int lfftt_size; \
953 Extbyte *lfftt_utf8_path; \
954 Extbyte *lfftt_tstr_path; \
955 \
956 PATHNAME_CONVERT_OUT_UTF_8 (lfftt, lfftt_utf8_path); \
957 lfftt_size = cygwin_conv_path (CCP_POSIX_TO_WIN_T | CCP_RELATIVE, \
958 lfftt_utf8_path, NULL, 0); \
959 lfftt_tstr_path = alloca_extbytes (lfftt_size); \
960 cygwin_conv_path (CCP_POSIX_TO_WIN_T | CCP_RELATIVE, \
961 lfftt_utf8_path, lfftt_tstr_path, lfftt_size); \
962 * (Extbyte **) &(out) = lfftt_tstr_path; \
963 } \
952 } while (0) 964 } while (0)
953 965 #define TSTR_TO_LOCAL_FILE_FORMAT(path, out) \
954 Lisp_Object tstr_to_local_file_format (Extbyte *pathout); 966 do { \
955 967 const Extbyte *ttlff = (path); \
968 int ttlff_size; \
969 Extbyte *ttlff_utf8_path; \
970 \
971 ttlff_size = cygwin_conv_path (CCP_WIN_T_TO_POSIX | CCP_RELATIVE, \
972 ttlff, NULL, 0); \
973 ttlff_utf8_path = alloca_extbytes (ttlff_size); \
974 cygwin_conv_path (CCP_WIN_T_TO_POSIX | CCP_RELATIVE, \
975 ttlff, ttlff_utf8_path, ttlff_size); \
976 EXTERNAL_TO_C_STRING (ttlff_utf8_path, out, Qutf_8); \
977 } while (0)
978 #else /* not HAVE_CYGWIN_CONV_PATH */
979 #define LOCAL_FILE_FORMAT_TO_TSTR(path, out) \
980 do { \
981 Ibyte *lfftt; \
982 \
983 LOCAL_FILE_FORMAT_TO_INTERNAL_MSWIN (path, lfftt); \
984 PATHNAME_CONVERT_OUT_TSTR (lfftt, out); \
985 } while (0)
986 #define TSTR_TO_LOCAL_FILE_FORMAT(path, out) \
987 do { \
988 Ibyte *ttlff; \
989 \
990 TSTR_TO_C_STRING (path, ttlff); \
991 INTERNAL_MSWIN_TO_LOCAL_FILE_FORMAT (ttlff, out); \
992 } while (0)
993 #endif /* (not) HAVE_CYGWIN_CONV_PATH */
994
995 #define LISP_LOCAL_FILE_FORMAT_TO_TSTR(path, out) \
996 LOCAL_FILE_FORMAT_TO_TSTR (XSTRING_DATA (path), out)
956 /* Convert from local file format, as used in XEmacs, to valid win32 997 /* Convert from local file format, as used in XEmacs, to valid win32
957 filenames as can be given to Windows API routines. Under native XEmacs, 998 filenames as can be given to Windows API routines. Under native XEmacs,
958 this is a no-op, but under Cygwin, the local names look different -- 999 this is a no-op, but under Cygwin, the local names look different --
959 Cygwin mount points, forward slashes, etc. Currently, under Cygwin, we 1000 Cygwin mount points, forward slashes, etc. Currently, under Cygwin, we
960 actually allow local names to be of both formats, i.e. Cygwin or Win32 1001 actually allow local names to be of both formats, i.e. Cygwin or Win32
961 native. So we check to see if we have Win32 native already (a cheesy 1002 native. So we check to see if we have Win32 native already (a cheesy
962 check, look for letter plus colon at beginning of name) and do nothing 1003 check, look for letter plus colon at beginning of name) and do nothing
963 in that case. */ 1004 in that case. */
964 1005
965 #ifdef CYGWIN 1006 #ifdef HAVE_CYGWIN_CONV_PATH
966 #define LOCAL_TO_WIN32_FILE_FORMAT(path, pathout) \ 1007 /* When Cygwin uses UTF-8, we can't just manipulate internal-format data
967 do { \ 1008 with its routines because it will mangle the high bytes, so we need to
968 /* NOTE: It is a bit evil that here and below we are passing \ 1009 convert to UTF-8 first, then to Win32 TSTR format (i.e. UTF-16, on
969 internal-format data to a function that (nominally) should work \ 1010 Windows NT), then back to internal format. Routines that want external
970 with external-format data. But in point of fact, the Cygwin \ 1011 format should avoid this by using LISP_LOCAL_FILE_FORMAT_TO_TSTR().
971 conversion functions are *NOT* localized, and will fail if they \ 1012 Same thing applies going the other direction. */
972 get 7-bit ISO2022-encoded data. We know that our internal format \ 1013 #define LOCAL_FILE_FORMAT_TO_INTERNAL_MSWIN(path, pathout) \
973 is ASCII-compatible, and so these functions will work fine with \ 1014 do \
974 this data. */ \ 1015 { \
975 Ibyte *ltwffp = (path); \ 1016 Extbyte *lfftiwp; \
976 if (isalpha (ltwffp[0]) && (IS_DEVICE_SEP (ltwffp[1]))) \ 1017 \
977 pathout = ltwffp; \ 1018 LOCAL_FILE_FORMAT_TO_TSTR (path, lfftiwp); \
978 else \ 1019 TSTR_TO_C_STRING (lfftiwp, pathout); \
979 { \ 1020 } \
980 int ltwff2 = \ 1021 while (0)
981 cygwin_posix_to_win32_path_list_buf_size ((char *) ltwffp); \ 1022 #define INTERNAL_MSWIN_TO_LOCAL_FILE_FORMAT(path, pathout) \
982 pathout = alloca_ibytes (ltwff2); \ 1023 do { \
983 cygwin_posix_to_win32_path_list ((char *) ltwffp, (char *) pathout); \ 1024 Extbyte *iwtlffp; \
984 } \ 1025 C_STRING_TO_TSTR (path, iwtlffp); \
1026 TSTR_TO_LOCAL_FILE_FORMAT (iwtlffp, pathout); \
985 } while (0) 1027 } while (0)
986 #else 1028 #elif defined (CYGWIN)
987 #define LOCAL_TO_WIN32_FILE_FORMAT(path, pathout) \ 1029 #define LOCAL_FILE_FORMAT_TO_INTERNAL_MSWIN(path, pathout) \
988 do { \ 1030 do { \
989 (pathout) = (path); \ 1031 /* NOTE: It is a bit evil that here and below we are passing \
1032 internal-format data to a function that (nominally) should work \
1033 with external-format data. But in point of fact, the Cygwin \
1034 conversion functions are *NOT* localized, and will fail if they \
1035 get 7-bit ISO2022-encoded data. We know that our internal format \
1036 is ASCII-compatible, and so these functions will work fine with \
1037 this data. */ \
1038 Ibyte *lfftiwp = (path); \
1039 if (isalpha (lfftiwp[0]) && (IS_DEVICE_SEP (lfftiwp[1]))) \
1040 pathout = lfftiwp; \
1041 else \
1042 { \
1043 int lfftiw2 = \
1044 cygwin_posix_to_win32_path_list_buf_size ((char *) lfftiwp); \
1045 pathout = alloca_ibytes (lfftiw2); \
1046 cygwin_posix_to_win32_path_list ((char *) lfftiwp, (char *) pathout); \
1047 } \
990 } while (0) 1048 } while (0)
991 #endif 1049 #define INTERNAL_MSWIN_TO_LOCAL_FILE_FORMAT(path, pathout) \
992
993 #ifdef CYGWIN
994 #define WIN32_TO_LOCAL_FILE_FORMAT(path, pathout) \
995 do { \ 1050 do { \
996 Ibyte *wtlff1 = (path); \ 1051 Ibyte *wtlff1 = (path); \
997 int wtlff2 = \ 1052 int wtlff2 = \
998 cygwin_win32_to_posix_path_list_buf_size ((char *) wtlff1); \ 1053 cygwin_win32_to_posix_path_list_buf_size ((char *) wtlff1); \
999 Ibyte *wtlff3 = alloca_ibytes (wtlff2); \ 1054 Ibyte *wtlff3 = alloca_ibytes (wtlff2); \
1000 cygwin_win32_to_posix_path_list ((char *) wtlff1, (char *) wtlff3); \ 1055 cygwin_win32_to_posix_path_list ((char *) wtlff1, (char *) wtlff3); \
1001 (pathout) = wtlff3; \ 1056 (pathout) = wtlff3; \
1002 } while (0) 1057 } while (0)
1003 #else 1058 #else /* not defined (CYGWIN) */
1004 #define WIN32_TO_LOCAL_FILE_FORMAT(path, pathout) \ 1059 #define LOCAL_FILE_FORMAT_TO_INTERNAL_MSWIN(path, pathout) \
1005 do { \ 1060 do { \
1006 (pathout) = (path); \ 1061 (pathout) = (path); \
1007 } while (0) 1062 } while (0)
1008 #endif 1063 #define INTERNAL_MSWIN_TO_LOCAL_FILE_FORMAT(path, pathout) \
1064 do { \
1065 (pathout) = (path); \
1066 } while (0)
1067 #endif /* (not) defined (CYGWIN) */
1068
1069 Lisp_Object tstr_to_local_file_format (Extbyte *pathout);
1009 1070
1010 /* Convert a local-format file name or URL in internal format into a Win32 1071 /* Convert a local-format file name or URL in internal format into a Win32
1011 file name or URL in tstr format. */ 1072 file name or URL in tstr format. */
1012 1073
1013 #ifdef CYGWIN 1074 #ifdef CYGWIN
1014 1075
1015 #define LOCAL_FILE_FORMAT_MAYBE_URL_TO_TSTR(lispstr, pathout) \ 1076 #define LISP_LOCAL_FILE_FORMAT_MAYBE_URL_TO_TSTR(lispstr, pathout) \
1016 do \ 1077 do \
1017 { \ 1078 { \
1018 Ibyte *lffmutt_fname1; \ 1079 Ibyte *lffmutt_fname1; \
1019 Ibyte *lffmutt_pathint = XSTRING_DATA (lispstr); \ 1080 Ibyte *lffmutt_pathint = XSTRING_DATA (lispstr); \
1020 \ 1081 \
1025 the like. so separate out the innards, process them, and put back \ 1086 the like. so separate out the innards, process them, and put back \
1026 together. */ \ 1087 together. */ \
1027 if (qxestrncasecmp_ascii (lffmutt_pathint, "file://", 7) == 0) \ 1088 if (qxestrncasecmp_ascii (lffmutt_pathint, "file://", 7) == 0) \
1028 { \ 1089 { \
1029 Ibyte *lffmutt_path1, *lffmutt_path2; \ 1090 Ibyte *lffmutt_path1, *lffmutt_path2; \
1030 LOCAL_TO_WIN32_FILE_FORMAT (lffmutt_pathint + 7, lffmutt_path1); \ 1091 LOCAL_FILE_FORMAT_TO_INTERNAL_MSWIN (lffmutt_pathint + 7, \
1092 lffmutt_path1); \
1031 if (lffmutt_path1 == lffmutt_pathint + 7) /* Optimization */ \ 1093 if (lffmutt_path1 == lffmutt_pathint + 7) /* Optimization */ \
1032 lffmutt_path2 = lffmutt_pathint; \ 1094 lffmutt_path2 = lffmutt_pathint; \
1033 else \ 1095 else \
1034 { \ 1096 { \
1035 lffmutt_path2 = alloca_ibytes (7 + qxestrlen (lffmutt_path1) \ 1097 lffmutt_path2 = alloca_ibytes (7 + qxestrlen (lffmutt_path1) \
1043 /* A straight URL, just convert */ \ 1105 /* A straight URL, just convert */ \
1044 LISP_STRING_TO_TSTR (lispstr, pathout); \ 1106 LISP_STRING_TO_TSTR (lispstr, pathout); \
1045 } \ 1107 } \
1046 else \ 1108 else \
1047 /* Not URL-style, must be a straight filename. */ \ 1109 /* Not URL-style, must be a straight filename. */ \
1048 LOCAL_FILE_FORMAT_TO_TSTR (lispstr, pathout); \ 1110 LISP_LOCAL_FILE_FORMAT_TO_TSTR (lispstr, pathout); \
1049 } while (0) 1111 } while (0)
1050 1112
1051 #else /* not CYGWIN */ 1113 #else /* not CYGWIN */
1052 1114
1053 /* URL's (and everything else) are already in the right format */ 1115 /* URL's (and everything else) are already in the right format */
1054 #define LOCAL_FILE_FORMAT_MAYBE_URL_TO_TSTR(lispstr, pathout) \ 1116 #define LISP_LOCAL_FILE_FORMAT_MAYBE_URL_TO_TSTR(lispstr, pathout) \
1055 LOCAL_FILE_FORMAT_TO_TSTR (lispstr, pathout) 1117 LISP_LOCAL_FILE_FORMAT_TO_TSTR (lispstr, pathout)
1056 1118
1057 #endif /* not CYGWIN */ 1119 #endif /* not CYGWIN */
1058 1120
1059 1121
1060 Ibyte *urlify_filename (Ibyte *filename); 1122 Ibyte *urlify_filename (Ibyte *filename);