Mercurial > hg > xemacs-beta
comparison src/dired-msw.c @ 263:727739f917cb r20-5b30
Import from CVS: tag r20-5b30
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:24:41 +0200 |
parents | |
children | c5d627a313b1 |
comparison
equal
deleted
inserted
replaced
262:9d8607af9e13 | 263:727739f917cb |
---|---|
1 /* fast dired replacement routines for mswindows. | |
2 Copyright (C) 1998 Darryl Okahata | |
3 Portions Copyright (C) 1992, 1994 by Sebastian Kremer <sk@thp.uni-koeln.de> | |
4 | |
5 This file is part of XEmacs. | |
6 | |
7 XEmacs is free software; you can redistribute it and/or modify it | |
8 under the terms of the GNU General Public License as published by the | |
9 Free Software Foundation; either version 2, or (at your option) any | |
10 later version. | |
11 | |
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with XEmacs; see the file COPYING. If not, write to | |
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
20 Boston, MA 02111-1307, USA. */ | |
21 | |
22 /* Synched up with: Not in FSF. */ | |
23 | |
24 /* | |
25 * Parts of this code (& comments) were taken from ls-lisp.el | |
26 * Author: Sebastian Kremer <sk@thp.uni-koeln.de> | |
27 */ | |
28 | |
29 /* | |
30 * insert-directory | |
31 * - must insert _exactly_one_line_ describing FILE if WILDCARD and | |
32 * FULL-DIRECTORY-P is nil. | |
33 * The single line of output must display FILE's name as it was | |
34 * given, namely, an absolute path name. | |
35 * - must insert exactly one line for each file if WILDCARD or | |
36 * FULL-DIRECTORY-P is t, plus one optional "total" line | |
37 * before the file lines, plus optional text after the file lines. | |
38 * Lines are delimited by "\n", so filenames containing "\n" are not | |
39 * allowed. | |
40 * File lines should display the basename. | |
41 * - must be consistent with | |
42 * - functions dired-move-to-filename, (these two define what a file line is) | |
43 * dired-move-to-end-of-filename, | |
44 * dired-between-files, (shortcut for (not (dired-move-to-filename))) | |
45 * dired-insert-headerline | |
46 * dired-after-subdir-garbage (defines what a "total" line is) | |
47 * - variable dired-subdir-regexp | |
48 */ | |
49 | |
50 /* | |
51 * Insert directory listing for FILE, formatted according to SWITCHES. | |
52 * Leaves point after the inserted text. | |
53 * SWITCHES may be a string of options, or a list of strings. | |
54 * Optional third arg WILDCARD means treat FILE as shell wildcard. | |
55 * Optional fourth arg FULL-DIRECTORY-P means file is a directory and | |
56 * switches do not contain `d', so that a full listing is expected. | |
57 * | |
58 * This works by running a directory listing program | |
59 * whose name is in the variable `insert-directory-program'. | |
60 * If WILDCARD, it also runs the shell specified by `shell-file-name'." | |
61 */ | |
62 | |
63 /* | |
64 * Set INDENT_LISTING to non-zero if the inserted text should be shifted | |
65 * over by two spaces. | |
66 */ | |
67 #define INDENT_LISTING 0 | |
68 | |
69 #define ROUND_FILE_SIZES 4096 | |
70 | |
71 | |
72 #include <config.h> | |
73 #include "lisp.h" | |
74 | |
75 #include "buffer.h" | |
76 #include "regex.h" | |
77 | |
78 #include "sysfile.h" | |
79 #include "sysdir.h" | |
80 | |
81 #include <windows.h> | |
82 | |
83 #if ROUND_FILE_SIZES > 0 | |
84 #include <math.h> /* for floor() */ | |
85 #endif | |
86 | |
87 | |
88 Lisp_Object Vmswindows_ls_sort_case_insensitive; | |
89 Lisp_Object Vmswindows_ls_round_file_size; | |
90 Lisp_Object Qmswindows_insert_directory; | |
91 | |
92 extern Lisp_Object Vmswindows_downcase_file_names; /* in device-msw.c */ | |
93 | |
94 | |
95 enum mswindows_sortby { | |
96 MSWINDOWS_SORT_BY_NAME, | |
97 MSWINDOWS_SORT_BY_NAME_NOCASE, | |
98 MSWINDOWS_SORT_BY_MOD_DATE, | |
99 MSWINDOWS_SORT_BY_SIZE | |
100 }; | |
101 | |
102 | |
103 static enum mswindows_sortby mswindows_sort_method; | |
104 static int mswindows_reverse_sort; | |
105 | |
106 | |
107 #define CMPDWORDS(t1a, t1b, t2a, t2b) \ | |
108 (((t1a) == (t2a)) ? (((t1b) == (t2b)) ? 0 : (((t1b) < (t2b)) ? -1 : 1)) \ | |
109 : (((t1a) < (t2a)) ? -1 : 1)) | |
110 | |
111 | |
112 static int | |
113 mswindows_ls_sort_fcn (const void *elem1, const void *elem2) | |
114 { | |
115 WIN32_FIND_DATA *e1, *e2; | |
116 int status; | |
117 | |
118 e1 = *(WIN32_FIND_DATA **)elem1; | |
119 e2 = *(WIN32_FIND_DATA **)elem2; | |
120 switch (mswindows_sort_method) | |
121 { | |
122 case MSWINDOWS_SORT_BY_NAME: | |
123 status = strcmp(e1->cFileName, e2->cFileName); | |
124 break; | |
125 case MSWINDOWS_SORT_BY_NAME_NOCASE: | |
126 status = _stricmp(e1->cFileName, e2->cFileName); | |
127 break; | |
128 case MSWINDOWS_SORT_BY_MOD_DATE: | |
129 status = CMPDWORDS(e1->ftLastWriteTime.dwHighDateTime, | |
130 e1->ftLastWriteTime.dwLowDateTime, | |
131 e2->ftLastWriteTime.dwHighDateTime, | |
132 e2->ftLastWriteTime.dwLowDateTime); | |
133 break; | |
134 case MSWINDOWS_SORT_BY_SIZE: | |
135 status = CMPDWORDS(e1->nFileSizeHigh, e1->nFileSizeLow, | |
136 e2->nFileSizeHigh, e2->nFileSizeLow); | |
137 break; | |
138 default: | |
139 status = 0; | |
140 break; | |
141 } | |
142 if (mswindows_reverse_sort) | |
143 { | |
144 status = -status; | |
145 } | |
146 return (status); | |
147 } | |
148 | |
149 | |
150 static void | |
151 mswindows_sort_files (WIN32_FIND_DATA **files, int nfiles, | |
152 enum mswindows_sortby sort_by, int reverse) | |
153 { | |
154 mswindows_sort_method = sort_by; | |
155 mswindows_reverse_sort = reverse; | |
156 qsort(files, nfiles, sizeof(WIN32_FIND_DATA *), mswindows_ls_sort_fcn); | |
157 } | |
158 | |
159 | |
160 static WIN32_FIND_DATA * | |
161 mswindows_get_files (char *dirfile, int nowild, Lisp_Object pattern, | |
162 int hide_dot, int hide_system, int *nfiles) | |
163 { | |
164 WIN32_FIND_DATA *files; | |
165 int array_size; | |
166 struct re_pattern_buffer *bufp = NULL; | |
167 int findex, len; | |
168 char win32pattern[MAXNAMLEN+3]; | |
169 HANDLE fh; | |
170 | |
171 /* | |
172 * Much of the following code and comments were taken from dired.c. | |
173 * Yes, this is something of a waste, but we want speed, speed, SPEED. | |
174 */ | |
175 files = NULL; | |
176 array_size = *nfiles = 0; | |
177 while (1) | |
178 { | |
179 if (!NILP(pattern)) | |
180 { | |
181 /* PATTERN might be a flawed regular expression. Rather than | |
182 catching and signalling our own errors, we just call | |
183 compile_pattern to do the work for us. */ | |
184 bufp = compile_pattern (pattern, 0, 0, 0, ERROR_ME); | |
185 } | |
186 /* Now *bufp is the compiled form of PATTERN; don't call anything | |
187 which might compile a new regexp until we're done with the loop! */ | |
188 | |
189 /* Initialize file info array */ | |
190 array_size = 100; /* initial size */ | |
191 files = xmalloc(array_size * sizeof (WIN32_FIND_DATA)); | |
192 | |
193 /* for Win32, we need to insure that the pathname ends with "\*". */ | |
194 strcpy (win32pattern, dirfile); | |
195 if (!nowild) | |
196 { | |
197 len = strlen (win32pattern) - 1; | |
198 if (!IS_DIRECTORY_SEP (win32pattern[len])) | |
199 strcat (win32pattern, "\\"); | |
200 strcat (win32pattern, "*"); | |
201 } | |
202 | |
203 /* | |
204 * Here, we use FindFirstFile()/FindNextFile() instead of opendir(), | |
205 * stat(), & friends, because stat() is VERY expensive in terms of | |
206 * time. Hence, we take the time to write complicated Win32-specific | |
207 * code, instead of simple Unix-style stuff. | |
208 */ | |
209 findex = 0; | |
210 fh = INVALID_HANDLE_VALUE; | |
211 | |
212 while (1) | |
213 { | |
214 int len; | |
215 char *filename; | |
216 int result; | |
217 | |
218 if (fh == INVALID_HANDLE_VALUE) | |
219 { | |
220 fh = FindFirstFile(win32pattern, &files[findex]); | |
221 if (fh == INVALID_HANDLE_VALUE) | |
222 { | |
223 report_file_error ("Opening directory", | |
224 list1(build_string(dirfile))); | |
225 } | |
226 } | |
227 else | |
228 { | |
229 if (!FindNextFile(fh, &files[findex])) | |
230 { | |
231 if (GetLastError() == ERROR_NO_MORE_FILES) | |
232 { | |
233 break; | |
234 } | |
235 FindClose(fh); | |
236 report_file_error ("Reading directory", | |
237 list1(build_string(dirfile))); | |
238 } | |
239 } | |
240 | |
241 filename = files[findex].cFileName; | |
242 if (!NILP(Vmswindows_downcase_file_names)) | |
243 { | |
244 strlwr(filename); | |
245 } | |
246 len = strlen(filename); | |
247 result = (NILP(pattern) | |
248 || (0 <= re_search (bufp, filename, | |
249 len, 0, len, 0))); | |
250 if (result) | |
251 { | |
252 if ( ! (filename[0] == '.' && | |
253 ((hide_system && (filename[1] == '\0' || | |
254 (filename[1] == '.' && | |
255 filename[2] == '\0'))) || | |
256 hide_dot))) | |
257 { | |
258 if (++findex >= array_size) | |
259 { | |
260 array_size = findex * 2; | |
261 files = xrealloc(files, | |
262 array_size * sizeof(WIN32_FIND_DATA)); | |
263 } | |
264 } | |
265 } | |
266 } | |
267 if (fh != INVALID_HANDLE_VALUE) | |
268 { | |
269 FindClose (fh); | |
270 } | |
271 *nfiles = findex; | |
272 break; | |
273 } | |
274 return (files); | |
275 } | |
276 | |
277 | |
278 static void | |
279 mswindows_format_file (WIN32_FIND_DATA *file, char *buf, int display_size, | |
280 int add_newline) | |
281 { | |
282 char *cptr; | |
283 int len; | |
284 Lisp_Object luser; | |
285 double file_size; | |
286 | |
287 len = strlen(file->cFileName); | |
288 file_size = | |
289 file->nFileSizeHigh * (double)UINT_MAX + file->nFileSizeLow; | |
290 cptr = buf; | |
291 #if INDENT_LISTING | |
292 *cptr++ = ' '; | |
293 *cptr++ = ' '; | |
294 #endif | |
295 if (display_size) | |
296 { | |
297 sprintf(cptr, "%6d ", (int)((file_size + 1023.) / 1024.)); | |
298 cptr += 7; | |
299 } | |
300 if (file->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) | |
301 { | |
302 *cptr++ = 'd'; | |
303 } else { | |
304 *cptr++ = '-'; | |
305 } | |
306 cptr[0] = cptr[3] = cptr[6] = 'r'; | |
307 if (file->dwFileAttributes & FILE_ATTRIBUTE_READONLY) | |
308 { | |
309 cptr[1] = cptr[4] = cptr[7] = '-'; | |
310 } else { | |
311 cptr[1] = cptr[4] = cptr[7] = 'w'; | |
312 } | |
313 if ((file->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) || | |
314 len > 4 && | |
315 (_stricmp(&file->cFileName[len - 4], ".exe") == 0 | |
316 || _stricmp(&file->cFileName[len - 4], ".com") == 0 | |
317 || _stricmp(&file->cFileName[len - 4], ".bat") == 0 | |
318 #if 0 | |
319 || _stricmp(&file->cFileName[len - 4], ".pif") == 0 | |
320 #endif | |
321 )) | |
322 { | |
323 cptr[2] = cptr[5] = cptr[8] = 'x'; | |
324 } else { | |
325 cptr[2] = cptr[5] = cptr[8] = '-'; | |
326 } | |
327 cptr += 9; | |
328 if (file->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) | |
329 { | |
330 strcpy(cptr, " 2 "); | |
331 } else { | |
332 strcpy(cptr, " 1 "); | |
333 } | |
334 cptr += 5; | |
335 luser = Fuser_login_name(Qnil); | |
336 if (!STRINGP(luser)) | |
337 { | |
338 sprintf(cptr, "%-9d", 0); | |
339 } else { | |
340 char *str; | |
341 | |
342 str = XSTRING_DATA(luser); | |
343 sprintf(cptr, "%-8s ", str); | |
344 } | |
345 while (*cptr) | |
346 { | |
347 ++cptr; | |
348 } | |
349 sprintf(cptr, "%-8d ", getgid()); | |
350 cptr += 9; | |
351 if (file_size > 99999999.0) | |
352 { | |
353 file_size = (file_size + 1023.0) / 1024.; | |
354 if (file_size > 999999.0) | |
355 { | |
356 sprintf(cptr, "%6.0fMB ", (file_size + 1023.0) / 1024.); | |
357 } else { | |
358 sprintf(cptr, "%6.0fKB ", file_size); | |
359 } | |
360 } else { | |
361 sprintf(cptr, "%8.0f ", file_size); | |
362 } | |
363 while (*cptr) | |
364 { | |
365 ++cptr; | |
366 } | |
367 { | |
368 time_t t, now; | |
369 char *ctimebuf; | |
370 extern char *sys_ctime(const time_t *t); /* in nt.c */ | |
371 | |
372 if ( | |
373 #if 0 | |
374 /* | |
375 * This doesn't work. | |
376 * This code should be correct ... | |
377 */ | |
378 FileTimeToLocalFileTime(&file->ftLastWriteTime, &localtime) && | |
379 ((t = convert_time(localtime)) != 0) && | |
380 #else | |
381 /* | |
382 * But this code "works" ... | |
383 */ | |
384 ((t = convert_time(file->ftLastWriteTime)) != 0) && | |
385 #endif | |
386 ((ctimebuf = sys_ctime(&t)) != NULL)) | |
387 { | |
388 memcpy(cptr, &ctimebuf[4], 7); | |
389 now = time(NULL); | |
390 if (now - t > (365. / 2.0) * 86400.) | |
391 { | |
392 /* more than 6 months */ | |
393 cptr[7] = ' '; | |
394 memcpy(&cptr[8], &ctimebuf[20], 4); | |
395 } else { | |
396 /* less than 6 months */ | |
397 memcpy(&cptr[7], &ctimebuf[11], 5); | |
398 } | |
399 cptr += 12; | |
400 *cptr++ = ' '; | |
401 } | |
402 } | |
403 if (add_newline) | |
404 { | |
405 sprintf(cptr, "%s\n", file->cFileName); | |
406 } | |
407 else | |
408 { | |
409 strcpy(cptr, file->cFileName); | |
410 } | |
411 } | |
412 | |
413 | |
414 DEFUN ("mswindows-insert-directory", Fmswindows_insert_directory, 2, 4, 0, /* | |
415 Insert directory listing for FILE, formatted according to SWITCHES. | |
416 Leaves point after the inserted text. | |
417 SWITCHES may be a string of options, or a list of strings. | |
418 Optional third arg WILDCARD means treat FILE as shell wildcard. | |
419 Optional fourth arg FULL-DIRECTORY-P means file is a directory and | |
420 switches do not contain `d', so that a full listing is expected. | |
421 */ | |
422 (file, switches, wildcard, full_directory_p)) | |
423 { | |
424 Lisp_Object result, handler, wildpat, fns, basename; | |
425 char *filename; | |
426 char *switchstr; | |
427 int len, nfiles, i; | |
428 int hide_system, hide_dot, reverse, display_size; | |
429 WIN32_FIND_DATA *files, **sorted_files; | |
430 enum mswindows_sortby sort_by; | |
431 char fmtbuf[MAXNAMLEN+100]; /* larger than necessary */ | |
432 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; | |
433 | |
434 result = Qnil; | |
435 wildpat = Qnil; | |
436 fns = Qnil; | |
437 basename = Qnil; | |
438 GCPRO5(result, file, wildpat, fns, basename); | |
439 sorted_files = NULL; | |
440 switchstr = NULL; | |
441 hide_system = 1; | |
442 hide_dot = 1; | |
443 display_size = 0; | |
444 reverse = 0; | |
445 if (NILP(Vmswindows_ls_sort_case_insensitive)) | |
446 { | |
447 sort_by = MSWINDOWS_SORT_BY_NAME; | |
448 } else { | |
449 sort_by = MSWINDOWS_SORT_BY_NAME_NOCASE; | |
450 } | |
451 nfiles = 0; | |
452 while (1) | |
453 { | |
454 handler = Ffind_file_name_handler (file, Qmswindows_insert_directory); | |
455 if (!NILP(handler)) | |
456 { | |
457 result = call5(handler, Qmswindows_insert_directory, file, switches, | |
458 wildcard, full_directory_p); | |
459 break; | |
460 } | |
461 CHECK_STRING (file); | |
462 if (!NILP(switches)) | |
463 { | |
464 char *cptr; | |
465 | |
466 CHECK_STRING (switches); | |
467 switchstr = XSTRING_DATA(switches); | |
468 for (cptr = switchstr; *cptr; ++cptr) | |
469 { | |
470 switch (*cptr) | |
471 { | |
472 case 'A': | |
473 hide_dot = 0; | |
474 break; | |
475 case 'a': | |
476 hide_system = 0; | |
477 hide_dot = 0; | |
478 break; | |
479 case 'r': | |
480 reverse = 1; | |
481 break; | |
482 case 's': | |
483 display_size = 1; | |
484 break; | |
485 case 'S': | |
486 sort_by = MSWINDOWS_SORT_BY_SIZE; | |
487 break; | |
488 case 't': | |
489 sort_by = MSWINDOWS_SORT_BY_MOD_DATE; | |
490 break; | |
491 } | |
492 } | |
493 } | |
494 | |
495 /* | |
496 * Sometimes we get ".../foo* /" as FILE (without the space). | |
497 * While the shell and `ls' don't mind, we certainly do, | |
498 * because it makes us think there is no wildcard, only a | |
499 * directory name. | |
500 */ | |
501 if (!NILP(Fstring_match(build_string("[[?*]"), file, Qnil, Qnil))) | |
502 { | |
503 wildcard = Qt; | |
504 filename = XSTRING_DATA(file); | |
505 len = strlen(filename); | |
506 if (len > 0 && (filename[len - 1] == '\\' || | |
507 filename[len - 1] == '/')) | |
508 { | |
509 filename[len - 1] = '\0'; | |
510 } | |
511 file = build_string(filename); | |
512 } | |
513 if (!NILP(wildcard)) | |
514 { | |
515 Lisp_Object newfile; | |
516 | |
517 basename = Ffile_name_nondirectory(file); | |
518 fns = intern("wildcard-to-regexp"); | |
519 wildpat = call1(fns, basename); | |
520 newfile = Ffile_name_directory(file); | |
521 if (NILP(newfile)) | |
522 { | |
523 /* Ffile_name_directory() can GC */ | |
524 newfile = Ffile_name_directory(Fexpand_file_name(file, Qnil)); | |
525 } | |
526 file = newfile; | |
527 } | |
528 if (!NILP(wildcard) || !NILP(full_directory_p)) | |
529 { | |
530 CHECK_STRING(file); | |
531 if (!NILP(wildpat)) | |
532 { | |
533 CHECK_STRING(wildpat); | |
534 } | |
535 | |
536 files = mswindows_get_files(XSTRING_DATA(file), FALSE, wildpat, | |
537 hide_dot, hide_system, &nfiles); | |
538 if (files == NULL || nfiles == 0) | |
539 { | |
540 break; | |
541 } | |
542 } | |
543 else | |
544 { | |
545 files = mswindows_get_files(XSTRING_DATA(file), TRUE, wildpat, | |
546 hide_dot, hide_system, &nfiles); | |
547 } | |
548 if ((sorted_files = xmalloc(nfiles * sizeof(WIN32_FIND_DATA *))) | |
549 == NULL) | |
550 { | |
551 break; | |
552 } | |
553 for (i = 0; i < nfiles; ++i) | |
554 { | |
555 sorted_files[i] = &files[i]; | |
556 } | |
557 if (nfiles > 1) | |
558 { | |
559 mswindows_sort_files(sorted_files, nfiles, sort_by, reverse); | |
560 } | |
561 if (!NILP(wildcard) || !NILP(full_directory_p)) | |
562 { | |
563 /* | |
564 * By using doubles, we can handle files up to 2^53 bytes in | |
565 * size (IEEE doubles have 53 bits of resolution). However, | |
566 * as we divide by 1024 (or 2^10), the total size is | |
567 * accurate up to 2^(53+10) --> 2^63 bytes. | |
568 * | |
569 * Hopefully, we won't have to handle these file sizes anytime | |
570 * soon. | |
571 */ | |
572 double total_size, file_size, block_size; | |
573 | |
574 if ((block_size = XINT(Vmswindows_ls_round_file_size)) <= 0) | |
575 { | |
576 block_size = 0; | |
577 } | |
578 total_size = 0; | |
579 for (i = 0; i < nfiles; ++i) | |
580 { | |
581 file_size = | |
582 sorted_files[i]->nFileSizeHigh * (double)UINT_MAX + | |
583 sorted_files[i]->nFileSizeLow; | |
584 if (block_size > 0) | |
585 { | |
586 /* | |
587 * Round file_size up to the next nearest block size. | |
588 */ | |
589 file_size = | |
590 floor((file_size + block_size - 1) / block_size) | |
591 * block_size; | |
592 } | |
593 /* Here, we round to the nearest 1K */ | |
594 total_size += floor((file_size + 512.) / 1024.); | |
595 } | |
596 sprintf(fmtbuf, | |
597 #if INDENT_LISTING | |
598 /* ANSI C compilers auto-concatenate adjacent strings */ | |
599 " " | |
600 #endif | |
601 "total %.0f\n", total_size); | |
602 buffer_insert1(current_buffer, build_string(fmtbuf)); | |
603 } | |
604 for (i = 0; i < nfiles; ++i) | |
605 { | |
606 mswindows_format_file(sorted_files[i], fmtbuf, display_size, TRUE); | |
607 buffer_insert1(current_buffer, build_string(fmtbuf)); | |
608 } | |
609 break; | |
610 } | |
611 if (sorted_files) | |
612 { | |
613 xfree(sorted_files); | |
614 } | |
615 UNGCPRO; | |
616 return (result); | |
617 } | |
618 | |
619 | |
620 | |
621 /************************************************************************/ | |
622 /* initialization */ | |
623 /************************************************************************/ | |
624 | |
625 void | |
626 syms_of_dired_mswindows (void) | |
627 { | |
628 defsymbol (&Qmswindows_insert_directory, "mswindows-insert-directory"); | |
629 | |
630 DEFSUBR (Fmswindows_insert_directory); | |
631 } | |
632 | |
633 | |
634 void | |
635 vars_of_dired_mswindows (void) | |
636 { | |
637 DEFVAR_LISP ("mswindows-ls-sort-case-insensitive", &Vmswindows_ls_sort_case_insensitive, /* | |
638 *Non-nil means filenames are sorted in a case-insensitive fashion. | |
639 Nil means filenames are sorted in a case-sensitive fashion, just like Unix. | |
640 */ ); | |
641 Vmswindows_ls_sort_case_insensitive = Qt; | |
642 | |
643 DEFVAR_INT ("mswindows-ls-round-file-size", &Vmswindows_ls_round_file_size /* | |
644 *If non-zero, file sizes are rounded in terms of this block size when | |
645 the file totals are being calculated. This is useful for getting a more | |
646 accurate estimate of allocated disk space. Note that this only affects | |
647 the total size calculation; the individual displayed file sizes are not | |
648 changed. This block size should also be a power of 2 (but this is not | |
649 enforced), as filesystem block (cluster) sizes are typically powers-of-2. | |
650 */ ); | |
651 /* | |
652 * Here, we choose 4096 because it's the cluster size for both FAT32 | |
653 * and NTFS (?). This is probably much too small for people using | |
654 * plain FAT, but, hopefully, plain FAT will go away someday. | |
655 * | |
656 * We should allow something like a alist here, to make the size | |
657 * dependent on the drive letter, etc.. | |
658 */ | |
659 Vmswindows_ls_round_file_size = 4096; | |
660 } |