]> code.delx.au - gnu-emacs/blobdiff - src/dired.c
Merge from emacs--rel--22
[gnu-emacs] / src / dired.c
index 27f9f953eb648d513fc9b5a8849c0ac54841f37f..3efc87ac84423294317a3607c2c07bc9e1acb122 100644 (file)
@@ -1,12 +1,12 @@
 /* Lisp functions for making directory listings.
    Copyright (C) 1985, 1986, 1993, 1994, 1999, 2000, 2001, 2002, 2003,
-                 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+                 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
@@ -116,10 +116,10 @@ extern void filemodestring P_ ((struct stat *, char *));
 #endif
 
 extern int completion_ignore_case;
+extern Lisp_Object Qcompletion_ignore_case;
 extern Lisp_Object Vcompletion_regexp_list;
 
 Lisp_Object Vcompletion_ignored_extensions;
-Lisp_Object Qcompletion_ignore_case;
 Lisp_Object Qdirectory_files;
 Lisp_Object Qdirectory_files_and_attributes;
 Lisp_Object Qfile_name_completion;
@@ -671,8 +671,15 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
          if (!NILP (predicate))
            {
              Lisp_Object decoded;
+             Lisp_Object val;
+             struct gcpro gcpro1;
+
+             GCPRO1 (name);
              decoded = Fexpand_file_name (DECODE_FILE (name), dirname);
-             if (NILP (call1 (predicate, decoded)))
+             val = call1 (predicate, decoded);
+             UNGCPRO;
+
+             if (NILP (val))
                continue;
            }
 
@@ -695,7 +702,7 @@ file_name_completion (file, dirname, all_flag, ver_flag, predicate)
              compare = min (bestmatchsize, len);
              p1 = SDATA (bestmatch);
              p2 = (unsigned char *) dp->d_name;
-             matchsize = scmp(p1, p2, compare);
+             matchsize = scmp (p1, p2, compare);
              if (matchsize < 0)
                matchsize = compare;
              if (completion_ignore_case)
@@ -910,10 +917,12 @@ Elements of the attribute list are:
  7. Size in bytes.
   This is a floating point number if the size is too large for an integer.
  8. File modes, as a string of ten letters or dashes as in ls -l.
- 9. t iff file's gid would change if file were deleted and recreated.
+ 9. t if file's gid would change if file were deleted and recreated.
 10. inode number.  If inode number is larger than the Emacs integer,
-  this is a cons cell containing two integers: first the high part,
-  then the low 16 bits.
+  but still fits into a 32-bit number, this is a cons cell containing two
+  integers: first the high part, then the low 16 bits.  If the inode number
+  is wider than 32 bits, this is a cons cell containing three integers:
+  first the high 24 bits, then middle 24 bits, and finally the low 16 bits.
 11. Device number.  If it is larger than the Emacs integer, this is
   a cons cell, similar to the inode number.  */)
      (filename, id_format)
@@ -970,8 +979,16 @@ Elements of the attribute list are:
      shorter than an int (e.g., `short'), GCC whines about comparison
      being always false due to limited range of data type.  Fix by
      copying s.st_uid and s.st_gid into int variables.  */
+#ifdef WINDOWSNT
+  /* Windows uses signed short for the uid and gid in the stat structure,
+     but we use an int for getuid (limited to the range 0-60000).
+     So users with uid > 32767 need their uid patched back here.  */ 
+  uid = (unsigned short) s.st_uid;
+  gid = (unsigned short) s.st_gid;
+#else
   uid = s.st_uid;
   gid = s.st_gid;
+#endif
   if (NILP (id_format) || EQ (id_format, Qinteger))
     {
       values[2] = make_fixnum_or_float (uid);
@@ -1014,15 +1031,32 @@ Elements of the attribute list are:
   values[9] = (gid != getegid ()) ? Qt : Qnil;
 #endif /* BSD4_2 (or BSD4_3) */
   /* Shut up GCC warnings in FIXNUM_OVERFLOW_P below.  */
-  ino = s.st_ino;
-  if (FIXNUM_OVERFLOW_P (ino))
+  if (sizeof (s.st_ino) > sizeof (ino))
+    ino = (EMACS_INT)(s.st_ino & 0xffffffff);
+  else
+    ino = s.st_ino;
+  if (!FIXNUM_OVERFLOW_P (ino)
+      && (sizeof (s.st_ino) <= sizeof (ino) || (s.st_ino & ~INTMASK) == 0))
+    /* Keep the most common cases as integers.  */
+    values[10] = make_number (ino);
+  else if (sizeof (s.st_ino) <= sizeof (ino)
+          || ((s.st_ino >> 16) & ~INTMASK) == 0)
     /* To allow inode numbers larger than VALBITS, separate the bottom
        16 bits.  */
-    values[10] = Fcons (make_number (ino >> 16),
-                       make_number (ino & 0xffff));
+    values[10] = Fcons (make_number ((EMACS_INT)(s.st_ino >> 16)),
+                       make_number ((EMACS_INT)(s.st_ino & 0xffff)));
   else
-    /* But keep the most common cases as integers.  */
-    values[10] = make_number (ino);
+    {
+      /* To allow inode numbers beyond 32 bits, separate into 2 24-bit
+        high parts and a 16-bit bottom part.  */
+      EMACS_INT high_ino = s.st_ino >> 32;
+      EMACS_INT low_ino  = s.st_ino & 0xffffffff;
+
+      values[10] = Fcons (make_number (high_ino >> 8),
+                         Fcons (make_number (((high_ino & 0xff) << 16)
+                                             + (low_ino >> 16)),
+                                make_number (low_ino & 0xffff)));
+    }
 
   /* Likewise for device.  */
   if (FIXNUM_OVERFLOW_P (s.st_dev))
@@ -1071,11 +1105,6 @@ syms_of_dired ()
   defsubr (&Sfile_attributes);
   defsubr (&Sfile_attributes_lessp);
 
-#ifdef VMS
-  Qcompletion_ignore_case = intern ("completion-ignore-case");
-  staticpro (&Qcompletion_ignore_case);
-#endif /* VMS */
-
   DEFVAR_LISP ("completion-ignored-extensions", &Vcompletion_ignored_extensions,
               doc: /* Completion ignores file names ending in any string in this list.
 It does not ignore them if all possible completions end in one of