aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman1997-09-08 10:09:15 +0000
committerRichard M. Stallman1997-09-08 10:09:15 +0000
commit24c2a54f4ca12a428d0402ab76f926bfb1723261 (patch)
tree1cc54096ab8bba0d7c817f62867cd77d724be70a /src
parentfe487a71280026a7ca47b6bf425aae4c67889a76 (diff)
downloademacs-24c2a54f4ca12a428d0402ab76f926bfb1723261.tar.gz
emacs-24c2a54f4ca12a428d0402ab76f926bfb1723261.zip
(ENCODE_FILE): New macro.
(Ffile_attributes): Encode the file names to operate on. (file_name_completion): Do completion on encoded name, then decode. (Fdirectory_files): Encode the argument. Decode all result file names using Vfile_name_coding_system.
Diffstat (limited to 'src')
-rw-r--r--src/dired.c84
1 files changed, 67 insertions, 17 deletions
diff --git a/src/dired.c b/src/dired.c
index 7fc39dcd722..60fba4f6839 100644
--- a/src/dired.c
+++ b/src/dired.c
@@ -86,6 +86,14 @@ extern struct re_pattern_buffer *compile_pattern ();
86 86
87#define min(a, b) ((a) < (b) ? (a) : (b)) 87#define min(a, b) ((a) < (b) ? (a) : (b))
88 88
89/* Encode the file name NAME using the specified coding system
90 for file names, if any. */
91#define ENCODE_FILE(name) \
92 (! NILP (Vfile_name_coding_system) \
93 && XFASTINT (Vfile_name_coding_system) != 0 \
94 ? Fencode_coding_string (name, Vfile_name_coding_system, Qt) \
95 : name)
96
89/* if system does not have symbolic links, it does not have lstat. 97/* if system does not have symbolic links, it does not have lstat.
90 In that case, use ordinary stat instead. */ 98 In that case, use ordinary stat instead. */
91 99
@@ -95,6 +103,7 @@ extern struct re_pattern_buffer *compile_pattern ();
95 103
96extern int completion_ignore_case; 104extern int completion_ignore_case;
97extern Lisp_Object Vcompletion_regexp_list; 105extern Lisp_Object Vcompletion_regexp_list;
106extern Lisp_Object Vfile_name_coding_system;
98 107
99Lisp_Object Vcompletion_ignored_extensions; 108Lisp_Object Vcompletion_ignored_extensions;
100Lisp_Object Qcompletion_ignore_case; 109Lisp_Object Qcompletion_ignore_case;
@@ -117,6 +126,7 @@ If NOSORT is non-nil, the list is not sorted--its order is unpredictable.\n\
117 DIR *d; 126 DIR *d;
118 int dirnamelen; 127 int dirnamelen;
119 Lisp_Object list, name, dirfilename; 128 Lisp_Object list, name, dirfilename;
129 Lisp_Object encoded_directory;
120 Lisp_Object handler; 130 Lisp_Object handler;
121 struct re_pattern_buffer *bufp; 131 struct re_pattern_buffer *bufp;
122 132
@@ -164,6 +174,10 @@ If NOSORT is non-nil, the list is not sorted--its order is unpredictable.\n\
164#endif 174#endif
165 } 175 }
166 176
177 dirfilename = ENCODE_FILE (dirfilename);
178
179 encoded_directory = ENCODE_FILE (directory);
180
167 /* Now *bufp is the compiled form of MATCH; don't call anything 181 /* Now *bufp is the compiled form of MATCH; don't call anything
168 which might compile a new regexp until we're done with the loop! */ 182 which might compile a new regexp until we're done with the loop! */
169 183
@@ -176,7 +190,7 @@ If NOSORT is non-nil, the list is not sorted--its order is unpredictable.\n\
176 report_file_error ("Opening directory", Fcons (directory, Qnil)); 190 report_file_error ("Opening directory", Fcons (directory, Qnil));
177 191
178 list = Qnil; 192 list = Qnil;
179 dirnamelen = XSTRING (directory)->size; 193 dirnamelen = XSTRING (encoded_directory)->size;
180 re_match_object = Qt; 194 re_match_object = Qt;
181 195
182 /* Loop reading blocks */ 196 /* Loop reading blocks */
@@ -201,12 +215,12 @@ If NOSORT is non-nil, the list is not sorted--its order is unpredictable.\n\
201 /* Decide whether we need to add a directory separator. */ 215 /* Decide whether we need to add a directory separator. */
202#ifndef VMS 216#ifndef VMS
203 if (dirnamelen == 0 217 if (dirnamelen == 0
204 || !IS_ANY_SEP (XSTRING (directory)->data[dirnamelen - 1])) 218 || !IS_ANY_SEP (XSTRING (encoded_directory)->data[dirnamelen - 1]))
205 needsep = 1; 219 needsep = 1;
206#endif /* VMS */ 220#endif /* VMS */
207 221
208 name = make_uninit_string (total + needsep); 222 name = make_uninit_string (total + needsep);
209 bcopy (XSTRING (directory)->data, XSTRING (name)->data, 223 bcopy (XSTRING (encoded_directory)->data, XSTRING (name)->data,
210 dirnamelen); 224 dirnamelen);
211 if (needsep) 225 if (needsep)
212 XSTRING (name)->data[afterdirindex++] = DIRECTORY_SEP; 226 XSTRING (name)->data[afterdirindex++] = DIRECTORY_SEP;
@@ -215,6 +229,9 @@ If NOSORT is non-nil, the list is not sorted--its order is unpredictable.\n\
215 } 229 }
216 else 230 else
217 name = make_string (dp->d_name, len); 231 name = make_string (dp->d_name, len);
232 if (! NILP (Vfile_name_coding_system))
233 name = Fdecode_coding_string (name, Vfile_name_coding_system,
234 Qt);
218 list = Fcons (name, list); 235 list = Fcons (name, list);
219 } 236 }
220 } 237 }
@@ -290,11 +307,13 @@ file_name_completion (file, dirname, all_flag, ver_flag)
290 unsigned char *p1, *p2; 307 unsigned char *p1, *p2;
291 int matchcount = 0; 308 int matchcount = 0;
292 Lisp_Object bestmatch, tem, elt, name; 309 Lisp_Object bestmatch, tem, elt, name;
310 Lisp_Object encoded_file;
311 Lisp_Object encoded_dir;
293 struct stat st; 312 struct stat st;
294 int directoryp; 313 int directoryp;
295 int passcount; 314 int passcount;
296 int count = specpdl_ptr - specpdl; 315 int count = specpdl_ptr - specpdl;
297 struct gcpro gcpro1, gcpro2, gcpro3; 316 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
298 317
299#ifdef VMS 318#ifdef VMS
300 extern DIRENTRY * readdirver (); 319 extern DIRENTRY * readdirver ();
@@ -316,9 +335,17 @@ file_name_completion (file, dirname, all_flag, ver_flag)
316 file = FILE_SYSTEM_CASE (file); 335 file = FILE_SYSTEM_CASE (file);
317#endif 336#endif
318 bestmatch = Qnil; 337 bestmatch = Qnil;
319 GCPRO3 (file, dirname, bestmatch); 338 encoded_file = encoded_dir = Qnil;
339 GCPRO5 (file, dirname, bestmatch, encoded_file, encoded_dir);
320 dirname = Fexpand_file_name (dirname, Qnil); 340 dirname = Fexpand_file_name (dirname, Qnil);
321 341
342 /* Do completion on the encoded file name
343 because the other names in the directory are (we presume)
344 encoded likewise. We decode the completed string at the end. */
345 encoded_file = ENCODE_FILE (file);
346
347 encoded_dir = ENCODE_FILE (dirname);
348
322 /* With passcount = 0, ignore files that end in an ignored extension. 349 /* With passcount = 0, ignore files that end in an ignored extension.
323 If nothing found then try again with passcount = 1, don't ignore them. 350 If nothing found then try again with passcount = 1, don't ignore them.
324 If looking for all completions, start with passcount = 1, 351 If looking for all completions, start with passcount = 1,
@@ -329,7 +356,8 @@ file_name_completion (file, dirname, all_flag, ver_flag)
329 356
330 for (passcount = !!all_flag; NILP (bestmatch) && passcount < 2; passcount++) 357 for (passcount = !!all_flag; NILP (bestmatch) && passcount < 2; passcount++)
331 { 358 {
332 if (!(d = opendir (XSTRING (Fdirectory_file_name (dirname))->data))) 359 d = opendir (XSTRING (Fdirectory_file_name (encoded_dir))->data);
360 if (!d)
333 report_file_error ("Opening directory", Fcons (dirname, Qnil)); 361 report_file_error ("Opening directory", Fcons (dirname, Qnil));
334 362
335 /* Loop reading blocks */ 363 /* Loop reading blocks */
@@ -351,12 +379,12 @@ file_name_completion (file, dirname, all_flag, ver_flag)
351 if (!NILP (Vquit_flag) && NILP (Vinhibit_quit)) 379 if (!NILP (Vquit_flag) && NILP (Vinhibit_quit))
352 goto quit; 380 goto quit;
353 if (! DIRENTRY_NONEMPTY (dp) 381 if (! DIRENTRY_NONEMPTY (dp)
354 || len < XSTRING (file)->size 382 || len < XSTRING (encoded_file)->size
355 || 0 <= scmp (dp->d_name, XSTRING (file)->data, 383 || 0 <= scmp (dp->d_name, XSTRING (encoded_file)->data,
356 XSTRING (file)->size)) 384 XSTRING (encoded_file)->size))
357 continue; 385 continue;
358 386
359 if (file_name_completion_stat (dirname, dp, &st) < 0) 387 if (file_name_completion_stat (encoded_dir, dp, &st) < 0)
360 continue; 388 continue;
361 389
362 directoryp = ((st.st_mode & S_IFMT) == S_IFDIR); 390 directoryp = ((st.st_mode & S_IFMT) == S_IFDIR);
@@ -375,7 +403,7 @@ file_name_completion (file, dirname, all_flag, ver_flag)
375 { 403 {
376 /* Compare extensions-to-be-ignored against end of this file name */ 404 /* Compare extensions-to-be-ignored against end of this file name */
377 /* if name is not an exact match against specified string */ 405 /* if name is not an exact match against specified string */
378 if (!passcount && len > XSTRING (file)->size) 406 if (!passcount && len > XSTRING (encoded_file)->size)
379 /* and exit this for loop if a match is found */ 407 /* and exit this for loop if a match is found */
380 for (tem = Vcompletion_ignored_extensions; 408 for (tem = Vcompletion_ignored_extensions;
381 CONSP (tem); tem = XCONS (tem)->cdr) 409 CONSP (tem); tem = XCONS (tem)->cdr)
@@ -432,6 +460,9 @@ file_name_completion (file, dirname, all_flag, ver_flag)
432 name = make_string (dp->d_name, len); 460 name = make_string (dp->d_name, len);
433 if (all_flag) 461 if (all_flag)
434 { 462 {
463 if (! NILP (Vfile_name_coding_system))
464 name = Fdecode_coding_string (name,
465 Vfile_name_coding_system, Qt);
435 bestmatch = Fcons (name, bestmatch); 466 bestmatch = Fcons (name, bestmatch);
436 } 467 }
437 else 468 else
@@ -472,8 +503,8 @@ file_name_completion (file, dirname, all_flag, ver_flag)
472 == 503 ==
473 (matchsize + !!directoryp 504 (matchsize + !!directoryp
474 == XSTRING (bestmatch)->size)) 505 == XSTRING (bestmatch)->size))
475 && !bcmp (p2, XSTRING (file)->data, XSTRING (file)->size) 506 && !bcmp (p2, XSTRING (encoded_file)->data, XSTRING (encoded_file)->size)
476 && bcmp (p1, XSTRING (file)->data, XSTRING (file)->size))) 507 && bcmp (p1, XSTRING (encoded_file)->data, XSTRING (encoded_file)->size)))
477 { 508 {
478 bestmatch = make_string (dp->d_name, len); 509 bestmatch = make_string (dp->d_name, len);
479 if (directoryp) 510 if (directoryp)
@@ -498,10 +529,24 @@ file_name_completion (file, dirname, all_flag, ver_flag)
498 bestmatch = unbind_to (count, bestmatch); 529 bestmatch = unbind_to (count, bestmatch);
499 530
500 if (all_flag || NILP (bestmatch)) 531 if (all_flag || NILP (bestmatch))
501 return bestmatch; 532 {
533 if (! NILP (Vfile_name_coding_system)
534 && STRINGP (bestmatch))
535 bestmatch = Fdecode_coding_string (bestmatch,
536 Vfile_name_coding_system, Qt);
537 return bestmatch;
538 }
502 if (matchcount == 1 && bestmatchsize == XSTRING (file)->size) 539 if (matchcount == 1 && bestmatchsize == XSTRING (file)->size)
503 return Qt; 540 return Qt;
504 return Fsubstring (bestmatch, make_number (0), make_number (bestmatchsize)); 541 bestmatch = Fsubstring (bestmatch, make_number (0),
542 make_number (bestmatchsize));
543 /* Now that we got the right initial segment of BESTMATCH,
544 decode it from the coding system in use. */
545 if (! NILP (Vfile_name_coding_system))
546 bestmatch = Fdecode_coding_string (bestmatch,
547 Vfile_name_coding_system, Qt);
548 return bestmatch;
549
505 quit: 550 quit:
506 if (d) closedir (d); 551 if (d) closedir (d);
507 Vquit_flag = Qnil; 552 Vquit_flag = Qnil;
@@ -631,6 +676,7 @@ If file does not exist, returns nil.")
631{ 676{
632 Lisp_Object values[12]; 677 Lisp_Object values[12];
633 Lisp_Object dirname; 678 Lisp_Object dirname;
679 Lisp_Object encoded;
634 struct stat s; 680 struct stat s;
635 struct stat sdir; 681 struct stat sdir;
636 char modes[10]; 682 char modes[10];
@@ -644,7 +690,9 @@ If file does not exist, returns nil.")
644 if (!NILP (handler)) 690 if (!NILP (handler))
645 return call2 (handler, Qfile_attributes, filename); 691 return call2 (handler, Qfile_attributes, filename);
646 692
647 if (lstat (XSTRING (filename)->data, &s) < 0) 693 encoded = ENCODE_FILE (filename);
694
695 if (lstat (XSTRING (encoded)->data, &s) < 0)
648 return Qnil; 696 return Qnil;
649 697
650 switch (s.st_mode & S_IFMT) 698 switch (s.st_mode & S_IFMT)
@@ -675,7 +723,9 @@ If file does not exist, returns nil.")
675#endif 723#endif
676#ifdef BSD4_2 /* file gid will be dir gid */ 724#ifdef BSD4_2 /* file gid will be dir gid */
677 dirname = Ffile_name_directory (filename); 725 dirname = Ffile_name_directory (filename);
678 if (! NILP (dirname) && stat (XSTRING (dirname)->data, &sdir) == 0) 726 if (! NILP (dirname))
727 encoded = ENCODE_FILE (dirname);
728 if (! NILP (dirname) && stat (XSTRING (encoded)->data, &sdir) == 0)
679 values[9] = (sdir.st_gid != s.st_gid) ? Qt : Qnil; 729 values[9] = (sdir.st_gid != s.st_gid) ? Qt : Qnil;
680 else /* if we can't tell, assume worst */ 730 else /* if we can't tell, assume worst */
681 values[9] = Qt; 731 values[9] = Qt;