#define min(a, b) ((a) < (b) ? (a) : (b))
+/* Encode the file name NAME using the specified coding system
+ for file names, if any. */
+#define ENCODE_FILE(name) \
+ (! NILP (Vfile_name_coding_system) \
+ && XFASTINT (Vfile_name_coding_system) != 0 \
+ ? Fencode_coding_string (name, Vfile_name_coding_system, Qt) \
+ : name)
+
/* if system does not have symbolic links, it does not have lstat.
In that case, use ordinary stat instead. */
extern int completion_ignore_case;
extern Lisp_Object Vcompletion_regexp_list;
+extern Lisp_Object Vfile_name_coding_system;
Lisp_Object Vcompletion_ignored_extensions;
Lisp_Object Qcompletion_ignore_case;
DIR *d;
int dirnamelen;
Lisp_Object list, name, dirfilename;
+ Lisp_Object encoded_directory;
Lisp_Object handler;
struct re_pattern_buffer *bufp;
#endif
}
+ dirfilename = ENCODE_FILE (dirfilename);
+
+ encoded_directory = ENCODE_FILE (directory);
+
/* Now *bufp is the compiled form of MATCH; don't call anything
which might compile a new regexp until we're done with the loop! */
report_file_error ("Opening directory", Fcons (directory, Qnil));
list = Qnil;
- dirnamelen = XSTRING (directory)->size;
+ dirnamelen = XSTRING (encoded_directory)->size;
re_match_object = Qt;
/* Loop reading blocks */
/* Decide whether we need to add a directory separator. */
#ifndef VMS
if (dirnamelen == 0
- || !IS_ANY_SEP (XSTRING (directory)->data[dirnamelen - 1]))
+ || !IS_ANY_SEP (XSTRING (encoded_directory)->data[dirnamelen - 1]))
needsep = 1;
#endif /* VMS */
name = make_uninit_string (total + needsep);
- bcopy (XSTRING (directory)->data, XSTRING (name)->data,
+ bcopy (XSTRING (encoded_directory)->data, XSTRING (name)->data,
dirnamelen);
if (needsep)
XSTRING (name)->data[afterdirindex++] = DIRECTORY_SEP;
}
else
name = make_string (dp->d_name, len);
+ if (! NILP (Vfile_name_coding_system))
+ name = Fdecode_coding_string (name, Vfile_name_coding_system,
+ Qt);
list = Fcons (name, list);
}
}
unsigned char *p1, *p2;
int matchcount = 0;
Lisp_Object bestmatch, tem, elt, name;
+ Lisp_Object encoded_file;
+ Lisp_Object encoded_dir;
struct stat st;
int directoryp;
int passcount;
int count = specpdl_ptr - specpdl;
- struct gcpro gcpro1, gcpro2, gcpro3;
+ struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
#ifdef VMS
extern DIRENTRY * readdirver ();
file = FILE_SYSTEM_CASE (file);
#endif
bestmatch = Qnil;
- GCPRO3 (file, dirname, bestmatch);
+ encoded_file = encoded_dir = Qnil;
+ GCPRO5 (file, dirname, bestmatch, encoded_file, encoded_dir);
dirname = Fexpand_file_name (dirname, Qnil);
+ /* Do completion on the encoded file name
+ because the other names in the directory are (we presume)
+ encoded likewise. We decode the completed string at the end. */
+ encoded_file = ENCODE_FILE (file);
+
+ encoded_dir = ENCODE_FILE (dirname);
+
/* With passcount = 0, ignore files that end in an ignored extension.
If nothing found then try again with passcount = 1, don't ignore them.
If looking for all completions, start with passcount = 1,
for (passcount = !!all_flag; NILP (bestmatch) && passcount < 2; passcount++)
{
- if (!(d = opendir (XSTRING (Fdirectory_file_name (dirname))->data)))
+ d = opendir (XSTRING (Fdirectory_file_name (encoded_dir))->data);
+ if (!d)
report_file_error ("Opening directory", Fcons (dirname, Qnil));
/* Loop reading blocks */
if (!NILP (Vquit_flag) && NILP (Vinhibit_quit))
goto quit;
if (! DIRENTRY_NONEMPTY (dp)
- || len < XSTRING (file)->size
- || 0 <= scmp (dp->d_name, XSTRING (file)->data,
- XSTRING (file)->size))
+ || len < XSTRING (encoded_file)->size
+ || 0 <= scmp (dp->d_name, XSTRING (encoded_file)->data,
+ XSTRING (encoded_file)->size))
continue;
- if (file_name_completion_stat (dirname, dp, &st) < 0)
+ if (file_name_completion_stat (encoded_dir, dp, &st) < 0)
continue;
directoryp = ((st.st_mode & S_IFMT) == S_IFDIR);
{
/* Compare extensions-to-be-ignored against end of this file name */
/* if name is not an exact match against specified string */
- if (!passcount && len > XSTRING (file)->size)
+ if (!passcount && len > XSTRING (encoded_file)->size)
/* and exit this for loop if a match is found */
for (tem = Vcompletion_ignored_extensions;
CONSP (tem); tem = XCONS (tem)->cdr)
name = make_string (dp->d_name, len);
if (all_flag)
{
+ if (! NILP (Vfile_name_coding_system))
+ name = Fdecode_coding_string (name,
+ Vfile_name_coding_system, Qt);
bestmatch = Fcons (name, bestmatch);
}
else
==
(matchsize + !!directoryp
== XSTRING (bestmatch)->size))
- && !bcmp (p2, XSTRING (file)->data, XSTRING (file)->size)
- && bcmp (p1, XSTRING (file)->data, XSTRING (file)->size)))
+ && !bcmp (p2, XSTRING (encoded_file)->data, XSTRING (encoded_file)->size)
+ && bcmp (p1, XSTRING (encoded_file)->data, XSTRING (encoded_file)->size)))
{
bestmatch = make_string (dp->d_name, len);
if (directoryp)
bestmatch = unbind_to (count, bestmatch);
if (all_flag || NILP (bestmatch))
- return bestmatch;
+ {
+ if (! NILP (Vfile_name_coding_system)
+ && STRINGP (bestmatch))
+ bestmatch = Fdecode_coding_string (bestmatch,
+ Vfile_name_coding_system, Qt);
+ return bestmatch;
+ }
if (matchcount == 1 && bestmatchsize == XSTRING (file)->size)
return Qt;
- return Fsubstring (bestmatch, make_number (0), make_number (bestmatchsize));
+ bestmatch = Fsubstring (bestmatch, make_number (0),
+ make_number (bestmatchsize));
+ /* Now that we got the right initial segment of BESTMATCH,
+ decode it from the coding system in use. */
+ if (! NILP (Vfile_name_coding_system))
+ bestmatch = Fdecode_coding_string (bestmatch,
+ Vfile_name_coding_system, Qt);
+ return bestmatch;
+
quit:
if (d) closedir (d);
Vquit_flag = Qnil;
{
Lisp_Object values[12];
Lisp_Object dirname;
+ Lisp_Object encoded;
struct stat s;
struct stat sdir;
char modes[10];
if (!NILP (handler))
return call2 (handler, Qfile_attributes, filename);
- if (lstat (XSTRING (filename)->data, &s) < 0)
+ encoded = ENCODE_FILE (filename);
+
+ if (lstat (XSTRING (encoded)->data, &s) < 0)
return Qnil;
switch (s.st_mode & S_IFMT)
#endif
#ifdef BSD4_2 /* file gid will be dir gid */
dirname = Ffile_name_directory (filename);
- if (! NILP (dirname) && stat (XSTRING (dirname)->data, &sdir) == 0)
+ if (! NILP (dirname))
+ encoded = ENCODE_FILE (dirname);
+ if (! NILP (dirname) && stat (XSTRING (encoded)->data, &sdir) == 0)
values[9] = (sdir.st_gid != s.st_gid) ? Qt : Qnil;
else /* if we can't tell, assume worst */
values[9] = Qt;