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