Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
emacs
emacs
Commits
1fd201bb
Commit
1fd201bb
authored
Nov 02, 2013
by
Eli Zaretskii
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adapted dostounix_filename. w32-short/long-filename work with wide APIs.
parent
5c4a19a9
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
131 additions
and
157 deletions
+131
-157
src/emacs.c
src/emacs.c
+16
-3
src/fileio.c
src/fileio.c
+12
-8
src/filelock.c
src/filelock.c
+1
-1
src/msdos.c
src/msdos.c
+3
-3
src/msdos.h
src/msdos.h
+1
-1
src/termcap.c
src/termcap.c
+1
-1
src/unexw32.c
src/unexw32.c
+8
-2
src/w32.c
src/w32.c
+73
-129
src/w32.h
src/w32.h
+6
-1
src/w32fns.c
src/w32fns.c
+2
-2
src/w32proc.c
src/w32proc.c
+8
-6
No files found.
src/emacs.c
View file @
1fd201bb
...
...
@@ -2153,9 +2153,15 @@ decode_env_path (const char *evarname, const char *defalt)
Lisp_Object
lpath
,
element
,
tem
;
#ifdef WINDOWSNT
bool
defaulted
=
0
;
const
char
*
emacs_dir
=
egetenv
(
"emacs_dir"
);
static
const
char
*
emacs_dir_env
=
"%emacs_dir%/"
;
const
size_t
emacs_dir_len
=
strlen
(
emacs_dir_env
);
const
char
*
edir
=
egetenv
(
"emacs_dir"
);
char
emacs_dir
[
MAX_UTF8_PATH
];
/* egetenv looks in process-environment, which holds the variables
in their original system-locale encoding. We need emacs_dir to
be in UTF-8. */
filename_from_ansi
(
edir
,
emacs_dir
);
#endif
/* It's okay to use getenv here, because this function is only used
...
...
@@ -2176,9 +2182,16 @@ decode_env_path (const char *evarname, const char *defalt)
/* Ensure values from the environment use the proper directory separator. */
if
(
path
)
{
char
*
path_copy
=
alloca
(
strlen
(
path
)
+
1
);
char
*
path_copy
;
#ifdef WINDOWSNT
path_copy
=
alloca
(
MAX_UTF8_PATH
);
filename_from_ansi
(
path
,
path_copy
);
#else
/* MSDOS */
path_copy
=
alloca
(
strlen
(
path
)
+
1
);
strcpy
(
path_copy
,
path
);
dostounix_filename
(
path_copy
,
0
);
#endif
dostounix_filename
(
path_copy
);
path
=
path_copy
;
}
#endif
...
...
src/fileio.c
View file @
1fd201bb
...
...
@@ -459,7 +459,8 @@ Given a Unix syntax file name, returns a string ending in slash. */)
strcat
(
res
,
"/"
);
beg
=
res
;
p
=
beg
+
strlen
(
beg
);
dostounix_filename
(
beg
,
0
);
dostounix_filename
(
beg
);
/* FIXME: Figure out the multibyte vs unibyte stuff here. */
tem_fn
=
make_specified_string
(
beg
,
-
1
,
p
-
beg
,
STRING_MULTIBYTE
(
filename
));
}
...
...
@@ -470,7 +471,7 @@ Given a Unix syntax file name, returns a string ending in slash. */)
else
if
(
STRING_MULTIBYTE
(
filename
))
{
tem_fn
=
make_specified_string
(
beg
,
-
1
,
p
-
beg
,
1
);
dostounix_filename
(
SSDATA
(
tem_fn
)
,
1
);
dostounix_filename
(
SSDATA
(
tem_fn
));
#ifdef WINDOWSNT
if
(
!
NILP
(
Vw32_downcase_file_names
))
tem_fn
=
Fdowncase
(
tem_fn
);
...
...
@@ -478,7 +479,7 @@ Given a Unix syntax file name, returns a string ending in slash. */)
}
else
{
dostounix_filename
(
beg
,
0
);
dostounix_filename
(
beg
);
tem_fn
=
make_specified_string
(
beg
,
-
1
,
p
-
beg
,
0
);
}
return
tem_fn
;
...
...
@@ -582,7 +583,7 @@ file_name_as_directory (char *dst, const char *src, ptrdiff_t srclen,
dst
[
srclen
++
]
=
DIRECTORY_SEP
;
dst
[
srclen
]
=
0
;
#ifdef DOS_NT
dostounix_filename
(
dst
,
multibyte
);
dostounix_filename
(
dst
);
#endif
return
srclen
;
}
...
...
@@ -651,7 +652,7 @@ directory_file_name (char *dst, char *src, ptrdiff_t srclen, bool multibyte)
memcpy
(
dst
,
src
,
srclen
);
dst
[
srclen
]
=
0
;
#ifdef DOS_NT
dostounix_filename
(
dst
,
multibyte
);
dostounix_filename
(
dst
);
#endif
return
srclen
;
}
...
...
@@ -1082,7 +1083,8 @@ filesystem tree, not (expand-file-name ".." dirname). */)
#ifdef DOS_NT
/* Make sure directories are all separated with /, but
avoid allocation of a new string when not required. */
dostounix_filename
(
nm
,
multibyte
);
/* FIXME: Figure out multibyte and downcase here. */
dostounix_filename
(
nm
);
#ifdef WINDOWSNT
if
(
IS_DIRECTORY_SEP
(
nm
[
1
]))
{
...
...
@@ -1465,7 +1467,8 @@ filesystem tree, not (expand-file-name ".." dirname). */)
target
[
1
]
=
':'
;
}
result
=
make_specified_string
(
target
,
-
1
,
o
-
target
,
multibyte
);
dostounix_filename
(
SSDATA
(
result
),
multibyte
);
/* FIXME: Figure out the multibyte and downcase here. */
dostounix_filename
(
SSDATA
(
result
));
#ifdef WINDOWSNT
if
(
!
NILP
(
Vw32_downcase_file_names
))
result
=
Fdowncase
(
result
);
...
...
@@ -1749,7 +1752,8 @@ those `/' is discarded. */)
nm
=
xlispstrdupa
(
filename
);
#ifdef DOS_NT
dostounix_filename
(
nm
,
multibyte
);
/* FIXME: Figure out multibyte and downcase. */
dostounix_filename
(
nm
);
substituted
=
(
memcmp
(
nm
,
SDATA
(
filename
),
SBYTES
(
filename
))
!=
0
);
#endif
endp
=
nm
+
SBYTES
(
filename
);
...
...
src/filelock.c
View file @
1fd201bb
...
...
@@ -689,7 +689,7 @@ lock_file (Lisp_Object fn)
/* Ensure we have only '/' separators, to avoid problems with
looking (inside fill_in_lock_file_name) for backslashes in file
names encoded by some DBCS codepage. */
dostounix_filename
(
SSDATA
(
fn
)
,
1
);
dostounix_filename
(
SSDATA
(
fn
));
#endif
encoded_fn
=
ENCODE_FILE
(
fn
);
...
...
src/msdos.c
View file @
1fd201bb
...
...
@@ -3295,7 +3295,7 @@ void msdos_downcase_filename (unsigned char *);
/* Destructively turn backslashes into slashes. */
void
dostounix_filename
(
char
*
p
,
int
ignore
)
dostounix_filename
(
char
*
p
)
{
msdos_downcase_filename
(
p
);
...
...
@@ -3559,7 +3559,7 @@ init_environment (int argc, char **argv, int skip_args)
if
(
!
s
)
s
=
"c:/command.com"
;
t
=
alloca
(
strlen
(
s
)
+
1
);
strcpy
(
t
,
s
);
dostounix_filename
(
t
,
0
);
dostounix_filename
(
t
);
setenv
(
"SHELL"
,
t
,
0
);
/* PATH is also downcased and backslashes mirrored. */
...
...
@@ -3569,7 +3569,7 @@ init_environment (int argc, char **argv, int skip_args)
/* Current directory is always considered part of MsDos's path but it is
not normally mentioned. Now it is. */
strcat
(
strcpy
(
t
,
".;"
),
s
);
dostounix_filename
(
t
,
0
);
/* Not a single file name, but this should work. */
dostounix_filename
(
t
);
/* Not a single file name, but this should work. */
setenv
(
"PATH"
,
t
,
1
);
/* In some sense all dos users have root privileges, so... */
...
...
src/msdos.h
View file @
1fd201bb
...
...
@@ -29,7 +29,7 @@ void dos_set_window_size (int *, int *);
int
getdefdir
(
int
,
char
*
);
void
unixtodos_filename
(
char
*
);
void
dostounix_filename
(
char
*
,
int
);
void
dostounix_filename
(
char
*
);
char
*
rootrelativepath
(
char
*
);
void
init_environment
(
int
,
char
**
,
int
);
void
internal_terminal_init
(
void
);
...
...
src/termcap.c
View file @
1fd201bb
...
...
@@ -393,7 +393,7 @@ tgetent (char *bp, const char *name)
if
(
termcap_name
&&
(
*
termcap_name
==
'\\'
||
*
termcap_name
==
'/'
||
termcap_name
[
1
]
==
':'
))
dostounix_filename
(
termcap_name
,
0
);
dostounix_filename
(
termcap_name
);
#endif
filep
=
termcap_name
&&
valid_filename_p
(
termcap_name
);
...
...
src/unexw32.c
View file @
1fd201bb
...
...
@@ -728,9 +728,15 @@ unexec (const char *new_name, const char *old_name)
char
*
q
;
/* Ignore old_name, and get our actual location from the OS. */
if
(
!
GetModuleFileName
(
NULL
,
in_filename
,
MAX_PATH
))
if
(
!
GetModuleFileName
A
(
NULL
,
in_filename
,
MAX_PATH
))
abort
();
dostounix_filename
(
in_filename
,
0
);
/* Can't use dostounix_filename here, since that needs its file name
argument encoded in UTF-8. */
for
(
p
=
in_filename
;
*
p
;
p
=
CharNextA
(
p
))
if
(
*
p
==
'\\'
)
*
p
=
'/'
;
strcpy
(
out_filename
,
in_filename
);
/* Change the base of the output filename to match the requested name. */
...
...
src/w32.c
View file @
1fd201bb
...
...
@@ -1336,7 +1336,7 @@ filename_to_ansi (const char *fn_in, char *fn_out)
return -1;
}
static
int
int
filename_from_ansi (const char *fn_in, char *fn_out)
{
wchar_t fn_utf16[MAXPATHLEN];
...
...
@@ -1799,31 +1799,20 @@ max_filename_mbslen (void)
return cp_info.MaxCharSize;
}
/* Normalize filename by converting all path separators to
the specified separator. Also conditionally convert upper
case path name components to lower case. */
/* Normalize filename by converting in-place all of its path
separators to the separator specified by PATH_SEP. */
static void
normalize_filename (register char *fp, char path_sep
, int multibyte
)
normalize_filename (register char *fp, char path_sep)
{
char sep;
char *elem, *p2;
int dbcs_p = max_filename_mbslen () > 1;
/* Multibyte file names are in the Emacs internal representation, so
we can traverse them by bytes with no problems. */
if (multibyte)
dbcs_p = 0;
char *p2;
/* Always lower-case drive letters a-z, even if the filesystem
preserves case in filenames.
This is so filenames can be compared by string comparison
functions that are case-sensitive. Even case-preserving filesystems
do not distinguish case in drive letters. */
if (dbcs_p)
p2 = CharNextExA (file_name_codepage, fp, 0);
else
p2 = fp + 1;
p2 = fp + 1;
if (*p2 == ':' && *fp >= 'A' && *fp <= 'Z')
{
...
...
@@ -1831,68 +1820,26 @@ normalize_filename (register char *fp, char path_sep, int multibyte)
fp += 2;
}
if (multibyte || NILP (Vw32_downcase_file_names)
)
while (*fp
)
{
while (*fp)
{
if (*fp == '/' || *fp == '\\')
*fp = path_sep;
if (!dbcs_p)
fp++;
else
fp = CharNextExA (file_name_codepage, fp, 0);
}
return;
if (*fp == '/' || *fp == '\\')
*fp = path_sep;
fp++;
}
sep = path_sep; /* convert to this path separator */
elem = fp; /* start of current path element */
do {
if (*fp >= 'a' && *fp <= 'z')
elem = 0; /* don't convert this element */
if (*fp == 0 || *fp == ':')
{
sep = *fp; /* restore current separator (or 0) */
*fp = '/'; /* after conversion of this element */
}
if (*fp == '/' || *fp == '\\')
{
if (elem && elem != fp)
{
*fp = 0; /* temporary end of string */
_mbslwr (elem); /* while we convert to lower case */
}
*fp = sep; /* convert (or restore) path separator */
elem = fp + 1; /* next element starts after separator */
sep = path_sep;
}
if (*fp)
{
if (!dbcs_p)
fp++;
else
fp = CharNextExA (file_name_codepage, fp, 0);
}
} while (*fp);
}
/* Destructively turn backslashes into slashes. MULTIBYTE non-zero
means the file name is a multibyte string in Emacs's internal
representation. */
/* Destructively turn backslashes into slashes. */
void
dostounix_filename (register char *p
, int multibyte
)
dostounix_filename (register char *p)
{
normalize_filename (p, '/'
, multibyte
);
normalize_filename (p, '/');
}
/* Destructively turn slashes into backslashes. */
void
unixtodos_filename (register char *p)
{
normalize_filename (p, '\\'
, 0
);
normalize_filename (p, '\\');
}
/* Remove all CR's that are followed by a LF.
...
...
@@ -1943,17 +1890,13 @@ parse_root (char * name, char ** pPath)
else if (IS_DIRECTORY_SEP (name[0]) && IS_DIRECTORY_SEP (name[1]))
{
int slashes = 2;
int dbcs_p = max_filename_mbslen () > 1;
name += 2;
do
{
if (IS_DIRECTORY_SEP (*name) && --slashes == 0)
break;
if (dbcs_p)
name = CharNextExA (file_name_codepage, name, 0);
else
name++;
name++;
}
while ( *name );
if (IS_DIRECTORY_SEP (name[0]))
...
...
@@ -1970,23 +1913,44 @@ parse_root (char * name, char ** pPath)
static int
get_long_basename (char * name, char * buf, int size)
{
WIN32_FIND_DATA find_data;
HANDLE dir_handle;
char fname_utf8[MAX_UTF8_PATH];
int len = 0;
int cstatus;
/*
m
ust be valid filename, no wild cards or other invalid characters */
if (
_mbs
pbrk (name, "*?|<>\""))
/*
M
ust be valid filename, no wild cards or other invalid characters
.
*/
if (
str
pbrk (name, "*?|<>\""))
return 0;
dir_handle = FindFirstFile (name, &find_data);
if (dir_handle != INVALID_HANDLE_VALUE)
if (w32_unicode_filenames)
{
if ((len = strlen (find_data.cFileName)) < size)
memcpy (buf, find_data.cFileName, len + 1);
else
len = 0;
FindClose (dir_handle);
wchar_t fname_utf16[MAX_PATH];
WIN32_FIND_DATAW find_data_wide;
filename_to_utf16 (name, fname_utf16);
dir_handle = FindFirstFileW (fname_utf16, &find_data_wide);
if (dir_handle != INVALID_HANDLE_VALUE)
cstatus = filename_from_utf16 (find_data_wide.cFileName, fname_utf8);
}
else
{
char fname_ansi[MAX_PATH];
WIN32_FIND_DATAA find_data_ansi;
filename_to_ansi (name, fname_ansi);
dir_handle = FindFirstFileA (fname_ansi, &find_data_ansi);
if (dir_handle != INVALID_HANDLE_VALUE)
cstatus = filename_from_ansi (find_data_ansi.cFileName, fname_utf8);
}
if (cstatus == 0 && (len = strlen (fname_utf8)) < size)
memcpy (buf, fname_utf8, len + 1);
else
len = 0;
if (dir_handle != INVALID_HANDLE_VALUE)
FindClose (dir_handle);
return len;
}
...
...
@@ -1997,11 +1961,11 @@ w32_get_long_filename (char * name, char * buf, int size)
char * o = buf;
char * p;
char * q;
char full[ MAX_PATH ];
char full[ MAX_
UTF8_
PATH ];
int len;
len = strlen (name);
if (len >= MAX_PATH)
if (len >= MAX_
UTF8_
PATH)
return FALSE;
/* Use local copy for destructive modification. */
...
...
@@ -2018,7 +1982,7 @@ w32_get_long_filename (char * name, char * buf, int size)
while (p != NULL && *p)
{
q = p;
p =
_mbs
chr (q, '\\');
p =
str
chr (q, '\\');
if (p) *p = '\0';
len = get_long_basename (full, o, size);
if (len > 0)
...
...
@@ -2042,6 +2006,29 @@ w32_get_long_filename (char * name, char * buf, int size)
return TRUE;
}
unsigned int
w32_get_short_filename (char * name, char * buf, int size)
{
if (w32_unicode_filenames)
{
wchar_t name_utf16[MAX_PATH], short_name[MAX_PATH];
unsigned int retval;
filename_to_utf16 (name, name_utf16);
retval = GetShortPathNameW (name_utf16, short_name, size);
if (retval && retval < size)
filename_from_utf16 (short_name, buf);
return retval;
}
else
{
char name_ansi[MAX_PATH];
filename_to_ansi (name, name_ansi);
return GetShortPathNameA (name_ansi, buf, size);
}
}
static int
is_unc_volume (const char *filename)
{
...
...
@@ -2506,7 +2493,7 @@ emacs_root_dir (void)
emacs_abort ();
strcpy (root_dir, p);
root_dir[parse_root (root_dir, NULL)] = '\0';
dostounix_filename (root_dir
, 0
);
dostounix_filename (root_dir);
return root_dir;
}
...
...
@@ -3937,49 +3924,6 @@ convert_from_time_t (time_t time, FILETIME * pft)
pft->dwLowDateTime = tmp.LowPart;
}
#if 0
/* No reason to keep this; faking inode values either by hashing or even
using the file index from GetInformationByHandle, is not perfect and
so by default Emacs doesn't use the inode values on Windows.
Instead, we now determine file-truename correctly (except for
possible drive aliasing etc). */
/* Modified version of "PJW" algorithm (see the "Dragon" compiler book). */
static unsigned
hashval (const unsigned char * str)
{
unsigned h = 0;
while (*str)
{
h = (h << 4) + *str++;
h ^= (h >> 28);
}
return h;
}
/* Return the hash value of the canonical pathname, excluding the
drive/UNC header, to get a hopefully unique inode number. */
static DWORD
generate_inode_val (const char * name)
{
char fullname[ MAX_PATH ];
char * p;
unsigned hash;
/* Get the truly canonical filename, if it exists. (Note: this
doesn't resolve aliasing due to subst commands, or recognize hard
links. */
if (!w32_get_long_filename ((char *)name, fullname, MAX_PATH))
emacs_abort ();
parse_root (fullname, &p);
/* Normal W32 filesystems are still case insensitive. */
_strlwr (p);
return hashval (p);
}
#endif
static PSECURITY_DESCRIPTOR
get_file_security_desc_by_handle (HANDLE h)
{
...
...
src/w32.h
View file @
1fd201bb
...
...
@@ -152,6 +152,9 @@ extern int w32_valid_pointer_p (void *, int);
/* Get long (aka "true") form of file name, if it exists. */
extern
BOOL
w32_get_long_filename
(
char
*
name
,
char
*
buf
,
int
size
);
/* Get the short (a.k.a. "8+3") form of a file name. */
extern
unsigned
int
w32_get_short_filename
(
char
*
,
char
*
,
int
);
/* Prepare our standard handles for proper inheritance by child processes. */
extern
void
prepare_standard_handles
(
int
in
,
int
out
,
int
err
,
HANDLE
handles
[
4
]);
...
...
@@ -181,8 +184,10 @@ extern void init_environment (char **);
extern
void
check_windows_init_file
(
void
);
extern
void
syms_of_ntproc
(
void
);
extern
void
syms_of_ntterm
(
void
);
extern
void
dostounix_filename
(
register
char
*
,
int
);
extern
void
dostounix_filename
(
register
char
*
);
extern
void
unixtodos_filename
(
register
char
*
);
extern
int
filename_from_ansi
(
const
char
*
,
char
*
);
extern
BOOL
init_winsock
(
int
load_now
);
extern
void
srandom
(
int
);
extern
int
random
(
void
);
...
...
src/w32fns.c
View file @
1fd201bb
...
...
@@ -6466,8 +6466,8 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */)
#ifdef NTGUI_UNICODE
filename
=
from_unicode_buffer
(
filename_buf
);
#else
/* !NTGUI_UNICODE */
dostounix_filename
(filename_buf
, 0
);
filename = DECODE_FILE (build_string
(filename
_buf
));
filename
=
DECODE_FILE
(
build_unibyte_string
(
filename_buf
)
);
dostounix_filename
(
SSDATA
(
filename
));
#endif
/* NTGUI_UNICODE */
#ifdef CYGWIN
...
...
src/w32proc.c
View file @
1fd201bb
...
...
@@ -2647,10 +2647,11 @@ All path elements in FILENAME are converted to their short names. */)
filename
=
Fexpand_file_name
(
filename
,
Qnil
);
/* luckily, this returns the short version of each element in the path. */
if
(
GetShortPathName
(
SDATA
(
ENCODE_FILE
(
filename
)),
shortname
,
MAX_PATH
)
==
0
)
if
(
w32_get_short_filename
(
SDATA
(
ENCODE_FILE
(
filename
)),
shortname
,
MAX_PATH
)
==
0
)
return
Qnil
;
dostounix_filename
(
shortname
,
0
);
dostounix_filename
(
shortname
);
/* No need to DECODE_FILE, because 8.3 names are pure ASCII. */
return
build_string
(
shortname
);
...
...
@@ -2664,7 +2665,7 @@ If FILENAME does not exist, return nil.
All path elements in FILENAME are converted to their long names. */
)
(
Lisp_Object
filename
)
{
char
longname
[
MAX_PATH
];
char
longname
[
MAX_
UTF8_
PATH
];
int
drive_only
=
0
;
CHECK_STRING
(
filename
);
...
...
@@ -2676,10 +2677,11 @@ All path elements in FILENAME are converted to their long names. */)
/* first expand it. */
filename
=
Fexpand_file_name
(
filename
,
Qnil
);
if
(
!
w32_get_long_filename
(
SDATA
(
ENCODE_FILE
(
filename
)),
longname
,
MAX_PATH
))
if
(
!
w32_get_long_filename
(
SDATA
(
ENCODE_FILE
(
filename
)),
longname
,
MAX_UTF8_PATH
))
return
Qnil
;
dostounix_filename
(
longname
,
0
);
dostounix_filename
(
longname
);
/* If we were passed only a drive, make sure that a slash is not appended
for consistency with directories. Allow for drive mapping via SUBST
...
...
@@ -2687,7 +2689,7 @@ All path elements in FILENAME are converted to their long names. */)
if
(
drive_only
&&
longname
[
1
]
==
':'
&&
longname
[
2
]
==
'/'
&&
!
longname
[
3
])
longname
[
2
]
=
'\0'
;
return
DECODE_FILE
(
build_string
(
longname
));
return
DECODE_FILE
(
build_
unibyte_
string
(
longname
));
}
DEFUN
(
"w32-set-process-priority"
,
Fw32_set_process_priority
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment