From f5ca63db413aadaf543b71d4c2a5d86faedd43d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20Fabian=20Kr=C3=BCger?= Date: Mon, 26 Apr 2021 18:18:49 +0200 Subject: [PATCH] Dont't duplicate \pdffilesize in \file_full_name:n --- l3kernel/CHANGELOG.md | 1 + l3kernel/l3file.dtx | 82 +++++++++++++++++++++++++------------------ 2 files changed, 49 insertions(+), 34 deletions(-) diff --git a/l3kernel/CHANGELOG.md b/l3kernel/CHANGELOG.md index d762fc294d..570ebd586c 100644 --- a/l3kernel/CHANGELOG.md +++ b/l3kernel/CHANGELOG.md @@ -18,6 +18,7 @@ this project uses date-based 'snapshot' version identifiers. approach to expand the file name. - `\pdf_version_gset:n` for `dvips`. - Improve handling of `\exp_not:n` in `\text_expand:n` (issue #875) +- `\file_full_name:n` now avoids calling `\pdffilesize` multiple times on the same file. ### Fixed - Evalutate integer constants only once (issue#861) diff --git a/l3kernel/l3file.dtx b/l3kernel/l3file.dtx index 0576d78169..f9b67fd9f8 100644 --- a/l3kernel/l3file.dtx +++ b/l3kernel/l3file.dtx @@ -2659,14 +2659,17 @@ % \end{macro} % % \begin{macro}[EXP]{\file_full_name:n, \@@_full_name:n} +% \begin{macro}[EXP]{\@@_full_name_aux:nn} % \begin{macro}[EXP]{\@@_full_name_aux:Nnn} % \begin{macro}[EXP]{\@@_full_name_aux:nN} +% \begin{macro}[EXP]{\@@_full_name_aux:nnN} % \begin{macro}[EXP]{\@@_name_cleanup:w} % \begin{macro}[EXP]{\@@_name_end:} -% \begin{macro}[EXP]{\@@_name_ext_check:n} -% \begin{macro}[EXP]{\@@_name_ext_check:nw} -% \begin{macro}[EXP]{\@@_name_ext_check:nnw} % \begin{macro}[EXP]{\@@_name_ext_check:nn} +% \begin{macro}[EXP]{\@@_name_ext_check:nnw} +% \begin{macro}[EXP]{\@@_name_ext_check:nnnw} +% \begin{macro}[EXP]{\@@_name_ext_check:nnn} +% \begin{macro}[EXP]{\@@_name_ext_check:nnnn} % File searching can be carried out if the \tn{pdffilesize} primitive % or an equivalent is available. That of course means we need to % arrange for everything else to here to be done by expansion too. @@ -2682,25 +2685,29 @@ % First, we check of the file is just here: no mapping so we do not % need the break part of the broader auxiliary. We are using the fact % that the primitive here returns nothing if the file is entirely absent. +% To avoid unnecessary filesystem lookups, the result of \tn{pdffilesize} +% is kept available as an argument. % For package mode, \tn{input@path} is a token list not a sequence. % \begin{macrocode} \cs_new:Npn \@@_full_name:n #1 { \tl_if_blank:nF {#1} + { \exp_args:Nne \@@_full_name_aux:nn {#1} { \@@_size:n {#1} } } + } +\cs_new:Npn \@@_full_name_aux:nn #1 #2 + { + \tl_if_blank:nTF {#2} { - \tl_if_blank:eTF { \@@_size:n {#1} } + \seq_map_tokens:Nn \l_file_search_path_seq + { \@@_full_name_aux:Nnn \seq_map_break:n {#1} } + \cs_if_exist:NT \input@path { - \seq_map_tokens:Nn \l_file_search_path_seq - { \@@_full_name_aux:Nnn \seq_map_break:n {#1} } - \cs_if_exist:NT \input@path - { - \tl_map_tokens:Nn \input@path - { \@@_full_name_aux:Nnn \tl_map_break:n {#1} } - } - \@@_name_end: + \tl_map_tokens:Nn \input@path + { \@@_full_name_aux:Nnn \tl_map_break:n {#1} } } - { \@@_ext_check:n {#1} } + \@@_name_end: } + { \@@_ext_check:nn {#1} {#2} } } % \end{macrocode} % Two pars to the auxiliary here so we can avoid doing quoting @@ -2708,13 +2715,15 @@ % \begin{macrocode} \cs_new:Npn \@@_full_name_aux:Nnn #1#2#3 { \exp_args:Ne \@@_full_name_aux:nN { \tl_to_str:n {#3} / #2 } #1 } -\cs_new:Npn \@@_full_name_aux:nN #1 #2 +\cs_new:Npn \@@_full_name_aux:nN #1 + { \exp_args:Nne \@@_full_name_aux:nnN {#1} { \@@_size:n {#1} } } +\cs_new:Npn \@@_full_name_aux:nnN #1 #2 #3 { - \tl_if_blank:eF { \@@_size:n {#1} } + \tl_if_blank:nF {#2} { - #2 + #3 { - \@@_ext_check:n {#1} + \@@_ext_check:nn {#1} {#2} \@@_name_cleanup:w } } @@ -2726,35 +2735,37 @@ % there is a little clean up to do here. First, make sure we are not in the % directory part, saving that. Then check for an extension. % \begin{macrocode} -\cs_new:Npn \@@_ext_check:n #1 - { \@@_ext_check:nw { / } #1 / \q_@@_nil / \s_@@_stop } -\cs_new:Npn \@@_ext_check:nw #1 #2 / #3 / #4 \s_@@_stop +\cs_new:Npn \@@_ext_check:nn #1 #2 +{ \@@_ext_check:nnw {#2} { / } #1 / \q_@@_nil / \s_@@_stop } +\cs_new:Npn \@@_ext_check:nnw #1 #2 #3 / #4 / #5 \s_@@_stop { - \@@_quark_if_nil:nTF {#3} + \@@_quark_if_nil:nTF {#4} { - \exp_args:No \@@_ext_check:nnw - { \use_none:n #1 } {#2} #2 . \q_@@_nil . \s_@@_stop + \exp_args:No \@@_ext_check:nnnw + { \use_none:n #2 } {#1} {#3} #3 . \q_@@_nil . \s_@@_stop } - { \@@_ext_check:nw { #1 #2 / } #3 / #4 \s_@@_stop } + { \@@_ext_check:nnw {#1} { #2 #3 / } #4 / #5 \s_@@_stop } } -\cs_new:Npx \@@_ext_check:nnw #1#2#3 . #4 . #5 \s_@@_stop +\cs_new:Npx \@@_ext_check:nnnw #1#2#3#4 . #5 . #6 \s_@@_stop { - \exp_not:N \@@_quark_if_nil:nTF {#4} + \exp_not:N \@@_quark_if_nil:nTF {#5} { - \exp_not:N \@@_ext_check:nn - { #1 #2 } { #1 #2 \tl_to_str:n { .tex } } + \exp_not:N \@@_ext_check:nnn + { #1 #3 \tl_to_str:n { .tex } } { #1 #3 } {#2} } - { #1 #2 } + { #1 #3 } } -\cs_new:Npn \@@_ext_check:nn #1#2 +\cs_new:Npn \@@_ext_check:nnn #1 + { \exp_args:Nne \@@_ext_check:nnnn {#1} { \@@_size:n {#1} } } +\cs_new:Npn \@@_ext_check:nnnn #1#2#3#4 { - \tl_if_blank:eTF { \@@_size:n {#2} } - {#1} + \tl_if_blank:nTF {#2} + {#3} { \int_compare:nNnTF - { \@@_size:n {#1} } = { \@@_size:n {#2} } - {#2} + {#4} = {#2} {#1} + {#3} } } % \end{macrocode} @@ -2785,6 +2796,9 @@ % \end{macro} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % % \begin{macro}{\file_get_full_name:nN, \file_get_full_name:VN} % \begin{macro}[TF]{\file_get_full_name:nN, \file_get_full_name:VN}