absolute = complete_filename_p (str);
- do
- {
- ptrdiff_t baselen, prefixlen;
-
- if (NILP (path))
- filename = str;
- else
- filename = Fexpand_file_name (str, XCAR (path));
- if (!complete_filename_p (filename))
- /* If there are non-absolute elts in PATH (eg "."). */
- /* Of course, this could conceivably lose if luser sets
- default-directory to be something non-absolute... */
- {
- filename = Fexpand_file_name (filename, BVAR (current_buffer, directory));
- if (!complete_filename_p (filename))
- /* Give up on this path element! */
- continue;
- }
+ do {
+ ptrdiff_t baselen, prefixlen;
+
+ if (NILP (path))
+ filename = str;
+ else
+ filename = Fexpand_file_name (str, XCAR (path));
+ if (!complete_filename_p (filename))
+ /* If there are non-absolute elts in PATH (eg "."). */
+ /* Of course, this could conceivably lose if luser sets
+ default-directory to be something non-absolute... */
+ {
+ filename = Fexpand_file_name (filename, BVAR (current_buffer, directory));
+ if (!complete_filename_p (filename))
+ /* Give up on this path element! */
+ continue;
+ }
- /* Calculate maximum length of any filename made from
- this path element/specified file name and any possible suffix. */
- want_length = max_suffix_len + SBYTES (filename);
- if (fn_size <= want_length)
- {
- fn_size = 100 + want_length;
- fn = SAFE_ALLOCA (fn_size);
- }
+ /* Calculate maximum length of any filename made from
+ this path element/specified file name and any possible suffix. */
+ want_length = max_suffix_len + SBYTES (filename);
+ if (fn_size <= want_length)
+ {
+ fn_size = 100 + want_length;
+ fn = SAFE_ALLOCA (fn_size);
+ }
- /* Copy FILENAME's data to FN but remove starting /: if any. */
- prefixlen = ((SCHARS (filename) > 2
- && SREF (filename, 0) == '/'
- && SREF (filename, 1) == ':')
- ? 2 : 0);
- baselen = SBYTES (filename) - prefixlen;
- memcpy (fn, SDATA (filename) + prefixlen, baselen);
-
- /* Loop over suffixes. */
- for (tail = NILP (suffixes) ? list1 (empty_unibyte_string) : suffixes;
- CONSP (tail); tail = XCDR (tail))
- {
- Lisp_Object suffix = XCAR (tail);
- ptrdiff_t fnlen, lsuffix = SBYTES (suffix);
- Lisp_Object handler;
-
- /* Make complete filename by appending SUFFIX. */
- memcpy (fn + baselen, SDATA (suffix), lsuffix + 1);
- fnlen = baselen + lsuffix;
-
- /* Check that the file exists and is not a directory. */
- /* We used to only check for handlers on non-absolute file names:
- if (absolute)
- handler = Qnil;
- else
- handler = Ffind_file_name_handler (filename, Qfile_exists_p);
- It's not clear why that was the case and it breaks things like
- (load "/bar.el") where the file is actually "/bar.el.gz". */
- /* make_string has its own ideas on when to return a unibyte
- string and when a multibyte string, but we know better.
- We must have a unibyte string when dumping, since
- file-name encoding is shaky at best at that time, and in
- particular default-file-name-coding-system is reset
- several times during loadup. We therefore don't want to
- encode the file before passing it to file I/O library
- functions. */
- if (!STRING_MULTIBYTE (filename) && !STRING_MULTIBYTE (suffix))
- string = make_unibyte_string (fn, fnlen);
- else
- string = make_string (fn, fnlen);
- handler = Ffind_file_name_handler (string, Qfile_exists_p);
- if ((!NILP (handler) || (!NILP (predicate) && !EQ (predicate, Qt)))
- && !NATNUMP (predicate))
- {
- bool exists;
- if (NILP (predicate) || EQ (predicate, Qt))
- exists = !NILP (Ffile_readable_p (string));
- else
- {
- Lisp_Object tmp = call1 (predicate, string);
- if (NILP (tmp))
+ /* Copy FILENAME's data to FN but remove starting /: if any. */
+ prefixlen = ((SCHARS (filename) > 2
+ && SREF (filename, 0) == '/'
+ && SREF (filename, 1) == ':')
+ ? 2 : 0);
+ baselen = SBYTES (filename) - prefixlen;
+ memcpy (fn, SDATA (filename) + prefixlen, baselen);
+
+ /* Loop over suffixes. */
+ for (tail = NILP (suffixes) ? list1 (empty_unibyte_string) : suffixes;
+ CONSP (tail); tail = XCDR (tail))
+ {
+ Lisp_Object suffix = XCAR (tail);
+ ptrdiff_t fnlen, lsuffix = SBYTES (suffix);
+ Lisp_Object handler;
+
+ /* Make complete filename by appending SUFFIX. */
+ memcpy (fn + baselen, SDATA (suffix), lsuffix + 1);
+ fnlen = baselen + lsuffix;
+
+ /* Check that the file exists and is not a directory. */
+ /* We used to only check for handlers on non-absolute file names:
+ if (absolute)
+ handler = Qnil;
+ else
+ handler = Ffind_file_name_handler (filename, Qfile_exists_p);
+ It's not clear why that was the case and it breaks things like
+ (load "/bar.el") where the file is actually "/bar.el.gz". */
+ /* make_string has its own ideas on when to return a unibyte
+ string and when a multibyte string, but we know better.
+ We must have a unibyte string when dumping, since
+ file-name encoding is shaky at best at that time, and in
+ particular default-file-name-coding-system is reset
+ several times during loadup. We therefore don't want to
+ encode the file before passing it to file I/O library
+ functions. */
+ if (!STRING_MULTIBYTE (filename) && !STRING_MULTIBYTE (suffix))
+ string = make_unibyte_string (fn, fnlen);
+ else
+ string = make_string (fn, fnlen);
+ handler = Ffind_file_name_handler (string, Qfile_exists_p);
+ if ((!NILP (handler) || (!NILP (predicate) && !EQ (predicate, Qt)))
+ && !NATNUMP (predicate))
+ {
+ bool exists;
+ if (NILP (predicate) || EQ (predicate, Qt))
+ exists = !NILP (Ffile_readable_p (string));
+ else
+ {
+ Lisp_Object tmp = call1 (predicate, string);
+ if (NILP (tmp))
+ exists = false;
+ else if (EQ (tmp, Qdir_ok)
+ || NILP (Ffile_directory_p (string)))
+ exists = true;
+ else
+ {
exists = false;
- else if (EQ (tmp, Qdir_ok)
- || NILP (Ffile_directory_p (string)))
- exists = true;
- else
- {
- exists = false;
- last_errno = EISDIR;
- }
- }
+ last_errno = EISDIR;
+ }
+ }
- if (exists)
- {
- /* We succeeded; return this descriptor and filename. */
- if (storeptr)
- *storeptr = string;
- SAFE_FREE ();
- return -2;
- }
- }
- else
- {
- int fd;
- const char *pfn;
- struct stat st;
+ if (exists)
+ {
+ /* We succeeded; return this descriptor and filename. */
+ if (storeptr)
+ *storeptr = string;
+ SAFE_FREE ();
+ return -2;
+ }
+ }
+ else
+ {
+ int fd;
+ const char *pfn;
+ struct stat st;
- encoded_fn = ENCODE_FILE (string);
- pfn = SSDATA (encoded_fn);
+ encoded_fn = ENCODE_FILE (string);
+ pfn = SSDATA (encoded_fn);
- /* Check that we can access or open it. */
- if (NATNUMP (predicate))
- {
- fd = -1;
- if (INT_MAX < XFASTINT (predicate))
- last_errno = EINVAL;
- else if (faccessat (AT_FDCWD, pfn, XFASTINT (predicate),
- AT_EACCESS)
- == 0)
- {
- if (file_directory_p (encoded_fn))
- last_errno = EISDIR;
- else
- fd = 1;
- }
- }
- else
- {
- fd = emacs_open (pfn, O_RDONLY, 0);
- if (fd < 0)
- {
- if (errno != ENOENT)
- last_errno = errno;
- }
- else
- {
- int err = (fstat (fd, &st) != 0 ? errno
- : S_ISDIR (st.st_mode) ? EISDIR : 0);
- if (err)
- {
- last_errno = err;
- emacs_close (fd);
- fd = -1;
- }
- }
- }
+ /* Check that we can access or open it. */
+ if (NATNUMP (predicate))
+ {
+ fd = -1;
+ if (INT_MAX < XFASTINT (predicate))
+ last_errno = EINVAL;
+ else if (faccessat (AT_FDCWD, pfn, XFASTINT (predicate),
+ AT_EACCESS)
+ == 0)
+ {
+ if (file_directory_p (encoded_fn))
+ last_errno = EISDIR;
+ else
+ fd = 1;
+ }
+ }
+ else
+ {
+ fd = emacs_open (pfn, O_RDONLY, 0);
+ if (fd < 0)
+ {
+ if (errno != ENOENT)
+ last_errno = errno;
+ }
+ else
+ {
+ int err = (fstat (fd, &st) != 0 ? errno
+ : S_ISDIR (st.st_mode) ? EISDIR : 0);
+ if (err)
+ {
+ last_errno = err;
+ emacs_close (fd);
+ fd = -1;
+ }
+ }
+ }
- if (fd >= 0)
- {
- if (newer && !NATNUMP (predicate))
- {
- struct timespec mtime = get_stat_mtime (&st);
+ if (fd >= 0)
+ {
+ if (newer && !NATNUMP (predicate))
+ {
+ struct timespec mtime = get_stat_mtime (&st);
- if (timespec_cmp (mtime, save_mtime) <= 0)
- emacs_close (fd);
- else
- {
- if (0 <= save_fd)
- emacs_close (save_fd);
- save_fd = fd;
- save_mtime = mtime;
- save_string = string;
- }
- }
- else
- {
- /* We succeeded; return this descriptor and filename. */
- if (storeptr)
- *storeptr = string;
- SAFE_FREE ();
- return fd;
- }
- }
+ if (timespec_cmp (mtime, save_mtime) <= 0)
+ emacs_close (fd);
+ else
+ {
+ if (0 <= save_fd)
+ emacs_close (save_fd);
+ save_fd = fd;
+ save_mtime = mtime;
+ save_string = string;
+ }
+ }
+ else
+ {
+ /* We succeeded; return this descriptor and filename. */
+ if (storeptr)
+ *storeptr = string;
+ SAFE_FREE ();
+ return fd;
+ }
+ }
- /* No more suffixes. Return the newest. */
- if (0 <= save_fd && ! CONSP (XCDR (tail)))
- {
- if (storeptr)
- *storeptr = save_string;
- SAFE_FREE ();
- return save_fd;
- }
- }
- }
- if (absolute)
- break;
- path = XCDR (path);
- } while (CONSP (path));
+ /* No more suffixes. Return the newest. */
+ if (0 <= save_fd && ! CONSP (XCDR (tail)))
+ {
+ if (storeptr)
+ *storeptr = save_string;
+ SAFE_FREE ();
+ return save_fd;
+ }
+ }
+ }
+ if (absolute)
+ break;
+ path = XCDR (path);
+ } while (CONSP (path));
SAFE_FREE ();
errno = last_errno;