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