From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.ciao.gmane.io!not-for-mail From: Andrea Corallo Newsgroups: gmane.emacs.bugs Subject: bug#41242: Port feature/native-comp to Windows - Reduce the number of files probed when finding a lisp file. Date: Sat, 30 May 2020 14:15:30 +0000 Message-ID: References: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="ciao.gmane.io:159.69.161.202"; logging-data="88323"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux) Cc: 41242@debbugs.gnu.org To: Nicolas =?UTF-8?Q?B=C3=A9rtolo?= Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sat May 30 16:16:20 2020 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jf2Hc-000Mwl-2a for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 30 May 2020 16:16:20 +0200 Original-Received: from localhost ([::1]:33816 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jf2Hb-00062O-0I for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 30 May 2020 10:16:19 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:57430) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jf2HK-000622-3G for bug-gnu-emacs@gnu.org; Sat, 30 May 2020 10:16:02 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:47286) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jf2HJ-0004zm-Qb for bug-gnu-emacs@gnu.org; Sat, 30 May 2020 10:16:01 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1jf2HJ-0002vk-LL for bug-gnu-emacs@gnu.org; Sat, 30 May 2020 10:16:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Andrea Corallo Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 30 May 2020 14:16:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 41242 X-GNU-PR-Package: emacs Original-Received: via spool by 41242-submit@debbugs.gnu.org id=B41242.159084813711232 (code B ref 41242); Sat, 30 May 2020 14:16:01 +0000 Original-Received: (at 41242) by debbugs.gnu.org; 30 May 2020 14:15:37 +0000 Original-Received: from localhost ([127.0.0.1]:58832 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jf2Gt-0002v4-VW for submit@debbugs.gnu.org; Sat, 30 May 2020 10:15:37 -0400 Original-Received: from mx.sdf.org ([205.166.94.20]:55807) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jf2Gq-0002uu-RL for 41242@debbugs.gnu.org; Sat, 30 May 2020 10:15:34 -0400 Original-Received: from sdf.org (ma.sdf.org [205.166.94.33]) by mx.sdf.org (8.15.2/8.14.5) with ESMTPS id 04UEFU2w004365 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits) verified NO); Sat, 30 May 2020 14:15:30 GMT Original-Received: (from akrl@localhost) by sdf.org (8.15.2/8.12.8/Submit) id 04UEFUPG001690; Sat, 30 May 2020 14:15:30 GMT In-Reply-To: ("Nicolas =?UTF-8?Q?B=C3=A9rtolo?="'s message of "Wed, 13 May 2020 16:26:57 -0300") X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:181227 Archived-At: --=-=-= Content-Type: text/plain Hi Nico, my comments on "Reduce the number of files probed when finding a lisp file.", the full patch attached in case somebody likes to engage. > diff --git a/src/lread.c b/src/lread.c > index 46725d9b0f..aaf4ad1a37 100644 > --- a/src/lread.c > +++ b/src/lread.c > @@ -1056,33 +1056,25 @@ This uses the variables `load-suffixes' and `load-file-rep-suffixes'. */) > { > Lisp_Object exts = Vload_file_rep_suffixes; > Lisp_Object suffix = XCAR (suffixes); > - FOR_EACH_TAIL (exts) > - lst = Fcons (concat2 (suffix, XCAR (exts)), lst); > + if (false > +#ifdef HAVE_MODULES > + || strcmp (MODULES_SUFFIX, SSDATA (suffix)) == 0 > +#ifdef MODULES_SECONDARY_SUFFIX > + || strcmp (MODULES_SECONDARY_SUFFIX, SSDATA (suffix)) == 0 > +#endif > +#endif > +#ifdef HAVE_NATIVE_COMP > + || strcmp (NATIVE_ELISP_SUFFIX, SSDATA (suffix)) == 0 > +#endif > + ) We can also use NATIVE_COMP_FLAG instead of HAVE_NATIVE_COMP to limit the macrology when we are not forced to ifdef out code that involves data structures only defined with native-comp. > + lst = Fcons (suffix, lst); > + else > + FOR_EACH_TAIL (exts) > + lst = Fcons (concat2 (suffix, XCAR (exts)), lst); > } > return Fnreverse (lst); > } > > -static Lisp_Object > -effective_load_path (void) > -{ > -#ifndef HAVE_NATIVE_COMP > - return Vload_path; > -#else > - Lisp_Object lp = Vload_path; > - Lisp_Object new_lp = Qnil; > - FOR_EACH_TAIL (lp) > - { > - Lisp_Object el = XCAR (lp); > - new_lp = > - Fcons (concat2 (Ffile_name_as_directory (el), > - Vcomp_native_path_postfix), > - new_lp); > - new_lp = Fcons (el, new_lp); > - } > - return Fnreverse (new_lp); > -#endif > -} > - > /* Return true if STRING ends with SUFFIX. */ > bool > suffix_p (Lisp_Object string, const char *suffix) > @@ -1217,6 +1209,9 @@ Return t if the file exists and loads successfully. */) > #ifdef MODULES_SECONDARY_SUFFIX > || suffix_p (file, MODULES_SECONDARY_SUFFIX) > #endif > +#endif > +#ifdef HAVE_NATIVE_COMP > + || suffix_p (file, NATIVE_ELISP_SUFFIX) > #endif > ) Same as previous comment. > must_suffix = Qnil; > @@ -1236,8 +1231,8 @@ Return t if the file exists and loads successfully. */) > } > > fd = > - openp (effective_load_path (), file, suffixes, &found, Qnil, > - load_prefer_newer); > + openp (Vload_path, file, true, suffixes, &found, Qnil, > + load_prefer_newer); > } > > if (fd == -1) > @@ -1600,7 +1595,7 @@ directories, make sure the PREDICATE function returns `dir-ok' for them. */) > (Lisp_Object filename, Lisp_Object path, Lisp_Object suffixes, Lisp_Object predicate) > { > Lisp_Object file; > - int fd = openp (path, filename, suffixes, &file, predicate, false); > + int fd = openp (path, filename, Qnil, suffixes, &file, predicate, false); ^^^ false? > if (NILP (predicate) && fd >= 0) > emacs_close (fd); > return file; > @@ -1611,6 +1606,9 @@ directories, make sure the PREDICATE function returns `dir-ok' for them. */) > On success, return a file descriptor (or 1 or -2 as described below). > On failure, return -1 and set errno. > > + If ADD_ELN_DIR is nonzero, use the `comp-native-path-postfix' > + variable to change the searched path if the suffix is .eln. > + Is there a specific reason to add a parameter to exclude/includes elns? I'd say we want to have an homogeneous behavior across all call sites no? > SUFFIXES is a list of strings containing possible suffixes. > The empty suffix is automatically added if the list is empty. > > @@ -1633,8 +1631,9 @@ directories, make sure the PREDICATE function returns `dir-ok' for them. */) > or if a non-nil and non-t PREDICATE is specified. */ > > int > -openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, > - Lisp_Object *storeptr, Lisp_Object predicate, bool newer) > +openp (Lisp_Object path, Lisp_Object str, bool add_eln_dir, > + Lisp_Object suffixes, Lisp_Object *storeptr, Lisp_Object predicate, > + bool newer) > { > ptrdiff_t fn_size = 100; > char buf[100]; > @@ -1643,7 +1642,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, > ptrdiff_t want_length; > Lisp_Object filename; > Lisp_Object string, tail, encoded_fn, save_string; > - ptrdiff_t max_suffix_len = 0; > + ptrdiff_t max_extra_len = 0; > int last_errno = ENOENT; > int save_fd = -1; > USE_SAFE_ALLOCA; > @@ -1658,8 +1657,15 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, > FOR_EACH_TAIL_SAFE (tail) > { > CHECK_STRING_CAR (tail); > - max_suffix_len = max (max_suffix_len, > - SBYTES (XCAR (tail))); > + char * suf = SSDATA (XCAR (tail)); ^^ no space > + ptrdiff_t len = SBYTES (XCAR (tail)); > + if (add_eln_dir && strcmp (NATIVE_ELISP_SUFFIX, suf) == 0) > + { > + CHECK_STRING (Vcomp_native_path_postfix); > + len += 2; > + len += SBYTES (Vcomp_native_path_postfix); > + } > + max_extra_len = max (max_extra_len, len); > } > > string = filename = encoded_fn = save_string = Qnil; > @@ -1677,7 +1683,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, > executable. */ > FOR_EACH_TAIL_SAFE (path) > { > - ptrdiff_t baselen, prefixlen; > + ptrdiff_t dirnamelen, prefixlen, basenamewext_len; > > if (EQ (path, just_use_str)) > filename = str; > @@ -1694,22 +1700,27 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, > 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); > + want_length = max_extra_len + SBYTES (filename); > if (fn_size <= want_length) > { > fn_size = 100 + want_length; > fn = SAFE_ALLOCA (fn_size); > } > > + Lisp_Object dirnamewslash = Ffile_name_directory (filename); > + Lisp_Object basenamewext = Ffile_name_nondirectory (filename); > + > /* Copy FILENAME's data to FN but remove starting /: if any. */ > - prefixlen = ((SCHARS (filename) > 2 > - && SREF (filename, 0) == '/' > - && SREF (filename, 1) == ':') > + prefixlen = ((SCHARS (dirnamewslash) > 2 > + && SREF (dirnamewslash, 0) == '/' > + && SREF (dirnamewslash, 1) == ':') > ? 2 : 0); > - baselen = SBYTES (filename) - prefixlen; > - memcpy (fn, SDATA (filename) + prefixlen, baselen); > + dirnamelen = SBYTES (dirnamewslash) - prefixlen; > + basenamewext_len = SBYTES (basenamewext); > + memcpy (fn, SDATA (dirnamewslash) + prefixlen, dirnamelen); > > /* Loop over suffixes. */ > AUTO_LIST1 (empty_string_only, empty_unibyte_string); > @@ -1719,10 +1730,24 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, > Lisp_Object suffix = XCAR (tail); > ptrdiff_t fnlen, lsuffix = SBYTES (suffix); > Lisp_Object handler; > + bool add_native_comp_dir = add_eln_dir > + && (strcmp (SSDATA (suffix), NATIVE_ELISP_SUFFIX) == 0); I think this should be optimized for non native comp builds with a NATIVE_COMP_FLAG && in front. > + ptrdiff_t lmiddledir = add_native_comp_dir > + ? SBYTES (Vcomp_native_path_postfix) + 1 : 0; > + > + if (add_native_comp_dir) > + { > + memcpy (fn + dirnamelen, SDATA (Vcomp_native_path_postfix), > + lmiddledir - 1); Vcomp_native_path_postfix is only defined with HAVE_NATIVE_COMP so I guess this breaks the stock build and my previous suggestion is not applicable. > + fn[dirnamelen+(lmiddledir-1)] = '/'; Spaces around operators + -. I could not compile this patch because non all the calls to openp has been updated for the new parameter (my question on adding this stands). In general please recall to check the stock build when working on infrastructure integration, it's quite easy to break. Generally speaking I think the behavior we want to have is that when a .eln file is specified this is loaded without re-adding Vcomp_native_path_postfix. I could not test it but I suspect this is not handled. Thanks this is good to have in when tuned. Andrea -- akrl@sdf.org --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0001-Reduce-the-number-of-files-probed-when-finding-a-lis.patch >From d6b6ac651c62e6a5cd9701d94419cfd53e95976e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20B=C3=A9rtolo?= Date: Mon, 25 May 2020 18:05:23 -0300 Subject: [PATCH] Reduce the number of files probed when finding a lisp file. * src/lread.c (get-load-suffixes): Do not add any suffix to files that need to be loaded by the dynamic linker. (effective_load_path): Remove function. (load): Don't add any suffix if file ends in a suffix already. (openp): Add a parameter `add_eln_dir` that should be used when we desire the dir elt/eln-hash/ to be searched for each path in `path`. * src/lisp.h: Add new parameter to openp. * src/callproc.c: Add the new parameter to calls to openp(). * src/charset.c: Add the new parameter to calls to openp(). * src/emacs.c: Add the new parameter to calls to openp(). * src/image.c: Add the new parameter to calls to openp(). * src/process.c: Add the new parameter to calls to openp(). * src/w32.c: Add the new parameter to calls to openp(). * src/w32proc.c: Add the new parameter to calls to openp(). --- src/callproc.c | 2 +- src/charset.c | 2 +- src/emacs.c | 3 +- src/image.c | 4 +- src/lisp.h | 2 +- src/lread.c | 107 ++++++++++++++++++++++++++++++------------------- src/process.c | 2 +- src/w32.c | 3 +- src/w32proc.c | 3 +- 9 files changed, 78 insertions(+), 50 deletions(-) diff --git a/src/callproc.c b/src/callproc.c index 65c858393a..421e42de11 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -436,7 +436,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd, { int ok; - ok = openp (Vexec_path, args[0], Vexec_suffixes, &path, + ok = openp (Vexec_path, args[0], false, Vexec_suffixes, &path, make_fixnum (X_OK), false); if (ok < 0) report_file_error ("Searching for program", args[0]); diff --git a/src/charset.c b/src/charset.c index 8635aad3ed..da3ace743f 100644 --- a/src/charset.c +++ b/src/charset.c @@ -486,7 +486,7 @@ load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile, ptrdiff_t count = SPECPDL_INDEX (); record_unwind_protect_nothing (); specbind (Qfile_name_handler_alist, Qnil); - fd = openp (Vcharset_map_path, mapfile, suffixes, NULL, Qnil, false); + fd = openp (Vcharset_map_path, mapfile, false, suffixes, NULL, Qnil, false); fp = fd < 0 ? 0 : fdopen (fd, "r"); if (!fp) { diff --git a/src/emacs.c b/src/emacs.c index cd4f7a0b28..35ae9d0e66 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -454,7 +454,8 @@ set_invocation_vars (char *argv0, char const *original_pwd) { Lisp_Object found; int yes = openp (Vexec_path, Vinvocation_name, - Vexec_suffixes, &found, make_fixnum (X_OK), false); + false, Vexec_suffixes, &found, make_fixnum (X_OK), + false); if (yes == 1) { /* Add /: to the front of the name diff --git a/src/image.c b/src/image.c index c8a192aaaf..80ef801913 100644 --- a/src/image.c +++ b/src/image.c @@ -508,7 +508,7 @@ image_create_bitmap_from_file (struct frame *f, Lisp_Object file) } /* Search bitmap-file-path for the file, if appropriate. */ - if (openp (Vx_bitmap_file_path, file, Qnil, &found, + if (openp (Vx_bitmap_file_path, file, false, Qnil, &found, make_fixnum (R_OK), false) < 0) return -1; @@ -2983,7 +2983,7 @@ image_find_image_fd (Lisp_Object file, int *pfd) Vx_bitmap_file_path); /* Try to find FILE in data-directory/images, then x-bitmap-file-path. */ - fd = openp (search_path, file, Qnil, &file_found, + fd = openp (search_path, file, false, Qnil, &file_found, pfd ? Qt : make_fixnum (R_OK), false); if (fd >= 0 || fd == -2) { diff --git a/src/lisp.h b/src/lisp.h index 52242791aa..5f921d58dc 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -4094,7 +4094,7 @@ LOADHIST_ATTACH (Lisp_Object x) extern bool suffix_p (Lisp_Object, const char *); extern Lisp_Object save_match_data_load (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object); -extern int openp (Lisp_Object, Lisp_Object, Lisp_Object, +extern int openp (Lisp_Object, Lisp_Object, bool, Lisp_Object, Lisp_Object *, Lisp_Object, bool); enum { S2N_IGNORE_TRAILING = 1 }; extern Lisp_Object string_to_number (char const *, int, ptrdiff_t *); diff --git a/src/lread.c b/src/lread.c index 46725d9b0f..aaf4ad1a37 100644 --- a/src/lread.c +++ b/src/lread.c @@ -1056,33 +1056,25 @@ This uses the variables `load-suffixes' and `load-file-rep-suffixes'. */) { Lisp_Object exts = Vload_file_rep_suffixes; Lisp_Object suffix = XCAR (suffixes); - FOR_EACH_TAIL (exts) - lst = Fcons (concat2 (suffix, XCAR (exts)), lst); + if (false +#ifdef HAVE_MODULES + || strcmp (MODULES_SUFFIX, SSDATA (suffix)) == 0 +#ifdef MODULES_SECONDARY_SUFFIX + || strcmp (MODULES_SECONDARY_SUFFIX, SSDATA (suffix)) == 0 +#endif +#endif +#ifdef HAVE_NATIVE_COMP + || strcmp (NATIVE_ELISP_SUFFIX, SSDATA (suffix)) == 0 +#endif + ) + lst = Fcons (suffix, lst); + else + FOR_EACH_TAIL (exts) + lst = Fcons (concat2 (suffix, XCAR (exts)), lst); } return Fnreverse (lst); } -static Lisp_Object -effective_load_path (void) -{ -#ifndef HAVE_NATIVE_COMP - return Vload_path; -#else - Lisp_Object lp = Vload_path; - Lisp_Object new_lp = Qnil; - FOR_EACH_TAIL (lp) - { - Lisp_Object el = XCAR (lp); - new_lp = - Fcons (concat2 (Ffile_name_as_directory (el), - Vcomp_native_path_postfix), - new_lp); - new_lp = Fcons (el, new_lp); - } - return Fnreverse (new_lp); -#endif -} - /* Return true if STRING ends with SUFFIX. */ bool suffix_p (Lisp_Object string, const char *suffix) @@ -1217,6 +1209,9 @@ Return t if the file exists and loads successfully. */) #ifdef MODULES_SECONDARY_SUFFIX || suffix_p (file, MODULES_SECONDARY_SUFFIX) #endif +#endif +#ifdef HAVE_NATIVE_COMP + || suffix_p (file, NATIVE_ELISP_SUFFIX) #endif ) must_suffix = Qnil; @@ -1236,8 +1231,8 @@ Return t if the file exists and loads successfully. */) } fd = - openp (effective_load_path (), file, suffixes, &found, Qnil, - load_prefer_newer); + openp (Vload_path, file, true, suffixes, &found, Qnil, + load_prefer_newer); } if (fd == -1) @@ -1600,7 +1595,7 @@ directories, make sure the PREDICATE function returns `dir-ok' for them. */) (Lisp_Object filename, Lisp_Object path, Lisp_Object suffixes, Lisp_Object predicate) { Lisp_Object file; - int fd = openp (path, filename, suffixes, &file, predicate, false); + int fd = openp (path, filename, Qnil, suffixes, &file, predicate, false); if (NILP (predicate) && fd >= 0) emacs_close (fd); return file; @@ -1611,6 +1606,9 @@ directories, make sure the PREDICATE function returns `dir-ok' for them. */) On success, return a file descriptor (or 1 or -2 as described below). On failure, return -1 and set errno. + If ADD_ELN_DIR is nonzero, use the `comp-native-path-postfix' + variable to change the searched path if the suffix is .eln. + SUFFIXES is a list of strings containing possible suffixes. The empty suffix is automatically added if the list is empty. @@ -1633,8 +1631,9 @@ directories, make sure the PREDICATE function returns `dir-ok' for them. */) or if a non-nil and non-t PREDICATE is specified. */ int -openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, - Lisp_Object *storeptr, Lisp_Object predicate, bool newer) +openp (Lisp_Object path, Lisp_Object str, bool add_eln_dir, + Lisp_Object suffixes, Lisp_Object *storeptr, Lisp_Object predicate, + bool newer) { ptrdiff_t fn_size = 100; char buf[100]; @@ -1643,7 +1642,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, ptrdiff_t want_length; Lisp_Object filename; Lisp_Object string, tail, encoded_fn, save_string; - ptrdiff_t max_suffix_len = 0; + ptrdiff_t max_extra_len = 0; int last_errno = ENOENT; int save_fd = -1; USE_SAFE_ALLOCA; @@ -1658,8 +1657,15 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, FOR_EACH_TAIL_SAFE (tail) { CHECK_STRING_CAR (tail); - max_suffix_len = max (max_suffix_len, - SBYTES (XCAR (tail))); + char * suf = SSDATA (XCAR (tail)); + ptrdiff_t len = SBYTES (XCAR (tail)); + if (add_eln_dir && strcmp (NATIVE_ELISP_SUFFIX, suf) == 0) + { + CHECK_STRING (Vcomp_native_path_postfix); + len += 2; + len += SBYTES (Vcomp_native_path_postfix); + } + max_extra_len = max (max_extra_len, len); } string = filename = encoded_fn = save_string = Qnil; @@ -1677,7 +1683,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, executable. */ FOR_EACH_TAIL_SAFE (path) { - ptrdiff_t baselen, prefixlen; + ptrdiff_t dirnamelen, prefixlen, basenamewext_len; if (EQ (path, just_use_str)) filename = str; @@ -1694,22 +1700,27 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, 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); + want_length = max_extra_len + SBYTES (filename); if (fn_size <= want_length) { fn_size = 100 + want_length; fn = SAFE_ALLOCA (fn_size); } + Lisp_Object dirnamewslash = Ffile_name_directory (filename); + Lisp_Object basenamewext = Ffile_name_nondirectory (filename); + /* Copy FILENAME's data to FN but remove starting /: if any. */ - prefixlen = ((SCHARS (filename) > 2 - && SREF (filename, 0) == '/' - && SREF (filename, 1) == ':') + prefixlen = ((SCHARS (dirnamewslash) > 2 + && SREF (dirnamewslash, 0) == '/' + && SREF (dirnamewslash, 1) == ':') ? 2 : 0); - baselen = SBYTES (filename) - prefixlen; - memcpy (fn, SDATA (filename) + prefixlen, baselen); + dirnamelen = SBYTES (dirnamewslash) - prefixlen; + basenamewext_len = SBYTES (basenamewext); + memcpy (fn, SDATA (dirnamewslash) + prefixlen, dirnamelen); /* Loop over suffixes. */ AUTO_LIST1 (empty_string_only, empty_unibyte_string); @@ -1719,10 +1730,24 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object suffix = XCAR (tail); ptrdiff_t fnlen, lsuffix = SBYTES (suffix); Lisp_Object handler; + bool add_native_comp_dir = add_eln_dir + && (strcmp (SSDATA (suffix), NATIVE_ELISP_SUFFIX) == 0); + ptrdiff_t lmiddledir = add_native_comp_dir + ? SBYTES (Vcomp_native_path_postfix) + 1 : 0; + + if (add_native_comp_dir) + { + memcpy (fn + dirnamelen, SDATA (Vcomp_native_path_postfix), + lmiddledir - 1); + fn[dirnamelen+(lmiddledir-1)] = '/'; + } - /* Make complete filename by appending SUFFIX. */ - memcpy (fn + baselen, SDATA (suffix), lsuffix + 1); - fnlen = baselen + lsuffix; + memcpy (fn + dirnamelen + lmiddledir, SDATA (basenamewext), + basenamewext_len); + /* Make complete filename by appending SUFFIX. */ + memcpy (fn + dirnamelen + lmiddledir + basenamewext_len, + SDATA (suffix), lsuffix + 1); + fnlen = dirnamelen + lmiddledir + basenamewext_len + lsuffix; /* Check that the file exists and is not a directory. */ /* We used to only check for handlers on non-absolute file names: diff --git a/src/process.c b/src/process.c index 6e5bcf307a..e092fa0a0c 100644 --- a/src/process.c +++ b/src/process.c @@ -1903,7 +1903,7 @@ usage: (make-process &rest ARGS) */) && IS_DEVICE_SEP (SREF (program, 1)))) { tem = Qnil; - openp (Vexec_path, program, Vexec_suffixes, &tem, + openp (Vexec_path, program, false, Vexec_suffixes, &tem, make_fixnum (X_OK), false); if (NILP (tem)) report_file_error ("Searching for program", program); diff --git a/src/w32.c b/src/w32.c index 38bbc49656..3e71d0d383 100644 --- a/src/w32.c +++ b/src/w32.c @@ -10187,7 +10187,8 @@ check_windows_init_file (void) need to ENCODE_FILE here, but we do need to convert the file names from UTF-8 to ANSI. */ init_file = build_string ("term/w32-win"); - fd = openp (Vload_path, init_file, Fget_load_suffixes (), NULL, Qnil, 0); + fd = openp (Vload_path, init_file, true, Fget_load_suffixes (), NULL, + Qnil, 0); if (fd < 0) { Lisp_Object load_path_print = Fprin1_to_string (Vload_path, Qnil); diff --git a/src/w32proc.c b/src/w32proc.c index 16e32e4c58..4aa4c9fa0a 100644 --- a/src/w32proc.c +++ b/src/w32proc.c @@ -1918,7 +1918,8 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp) { program = build_string (cmdname); full = Qnil; - openp (Vexec_path, program, Vexec_suffixes, &full, make_fixnum (X_OK), 0); + openp (Vexec_path, program, false, Vexec_suffixes, &full, + make_fixnum (X_OK), 0); if (NILP (full)) { errno = EINVAL; -- 2.20.1 --=-=-=--