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