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