summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3sys.dtx')
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3sys.dtx454
1 files changed, 453 insertions, 1 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx b/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx
index 2d791425776..73d4e787f74 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2019-09-19}
+% \date{Released 2019-09-28}
%
% \maketitle
%
@@ -126,6 +126,156 @@
% |dvi| or |pdf|.
% \end{variable}
%
+% \section{Platform}
+%
+% \begin{function}[added = 2018-07-27, EXP, pTF]
+% {
+% \sys_if_platform_unix:,
+% \sys_if_platform_windows:
+% }
+% \begin{syntax}
+% \cs{sys_if_platform_unix:TF} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Conditionals which allow platform-specific code to be used. The names
+% follow the \Lua{} |os.type()| function, \emph{i.e.}~all Unix-like systems
+% are |unix| (including Linux and MacOS).
+% \end{function}
+%
+% \begin{variable}[added = 2018-07-27]{\c_sys_platform_str}
+% The current platform given as a lower case string: one of
+% |unix|, |windows| or |unknown|.
+% \end{variable}
+%
+% \section{Random numbers}
+%
+% \begin{function}[added = 2017-05-27, EXP]{\sys_rand_seed:}
+% \begin{syntax}
+% \cs{sys_rand_seed:}
+% \end{syntax}
+% Expands to the current value of the engine's random seed, a
+% non-negative integer. In engines without random number support this
+% expands to $0$.
+% \end{function}
+%
+% \begin{function}[added = 2017-05-27]{\sys_gset_rand_seed:n}
+% \begin{syntax}
+% \cs{sys_gset_rand_seed:n} \Arg{intexpr}
+% \end{syntax}
+% Globally sets the seed for the engine's pseudo-random number
+% generator to the \meta{integer expression}. This random seed
+% affects all \cs[no-index]{\ldots{}_rand} functions (such as
+% \cs{int_rand:nn} or \cs{clist_rand_item:n}) as well as other
+% packages relying on the engine's random number generator. In
+% engines without random number support this produces an error.
+% \begin{texnote}
+% While a $32$-bit (signed) integer can be given as a seed, only the
+% absolute value is used and any number beyond $2^{28}$ is divided
+% by an appropriate power of~$2$. We recommend using an integer in
+% $[0,2^{28}-1]$.
+% \end{texnote}
+% \end{function}
+%
+% \section{Access to the shell}
+%
+% \begin{function}[noTF, added = 2019-09-20]
+% {\sys_get_shell:nnN}
+% \begin{syntax}
+% \cs{sys_get_shell:nnN} \Arg{shell~command} \Arg{setup} \meta{tl~var}
+% \cs{sys_get_shell:nnNTF} \Arg{shell~command} \Arg{setup} \meta{tl~var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Defines \meta{tl} to the text returned by the \meta{shell command}.
+% The \meta{shell command} is converted to a string using
+% \cs{tl_to_str:n}. Category codes may need to be set appropriately
+% via the \meta{setup} argument, which is run just before running the
+% \meta{shell command} (in a group).
+% If shell escape is disabled, the \meta{tl~var} will be set to
+% \cs{q_no_value} in the non-branching version.
+% Note that quote characters (|"|) \emph{cannot} be used inside the
+% \meta{shell command}. The \cs{sys_get_shell:nnNTF} conditional
+% returns \texttt{true} if the shell is available and no quote is
+% detected, and \texttt{false} otherwise.
+% \end{function}
+%
+% \begin{variable}[added = 2017-05-27]{\c_sys_shell_escape_int}
+% This variable exposes the internal triple of the shell escape
+% status. The possible values are
+% \begin{description}
+% \item[0] Shell escape is disabled
+% \item[1] Unrestricted shell escape is enabled
+% \item[2] Restricted shell escape is enabled
+% \end{description}
+% \end{variable}
+%
+% \begin{function}[added = 2017-05-27, EXP, pTF]{\sys_if_shell:}
+% \begin{syntax}
+% \cs{sys_if_shell_p:}
+% \cs{sys_if_shell:TF} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Performs a check for whether shell escape is enabled. This
+% returns true if either of restricted or unrestricted shell escape
+% is enabled.
+% \end{function}
+%
+% \begin{function}[added = 2017-05-27, EXP, pTF]{\sys_if_shell_unrestricted:}
+% \begin{syntax}
+% \cs{sys_if_shell_unrestricted_p:}
+% \cs{sys_if_shell_unrestricted:TF} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Performs a check for whether \emph{unrestricted} shell escape is
+% enabled.
+% \end{function}
+%
+% \begin{function}[added = 2017-05-27, EXP, pTF]{\sys_if_shell_restricted:}
+% \begin{syntax}
+% \cs{sys_if_shell_restricted_p:}
+% \cs{sys_if_shell_restricted:TF} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Performs a check for whether \emph{restricted} shell escape is
+% enabled. This returns false if unrestricted shell escape is
+% enabled. Unrestricted shell escape is not considered a superset
+% of restricted shell escape in this case. To find whether any
+% shell escape is enabled use \cs{sys_if_shell:}.
+% \end{function}
+%
+% \begin{function}[added = 2017-05-27]{\sys_shell_now:n, \sys_shell_now:x}
+% \begin{syntax}
+% \cs{sys_shell_now:n} \Arg{tokens}
+% \end{syntax}
+% Execute \meta{tokens} through shell escape immediately.
+% \end{function}
+%
+% \begin{function}[added = 2017-05-27]{\sys_shell_shipout:n, \sys_shell_shipout:x}
+% \begin{syntax}
+% \cs{sys_shell_shipout:n} \Arg{tokens}
+% \end{syntax}
+% Execute \meta{tokens} through shell escape at shipout.
+% \end{function}
+%
+% \subsection{Loading configuration data}
+%
+% \begin{function}[added = 2019-09-12]{\sys_load_backend:n}
+% \begin{syntax}
+% \cs{sys_load_backend:n} \Arg{backend}
+% \end{syntax}
+% Loads the additional configuration file needed for backend support.
+% If the \meta{backend} is empty, the standard backend for the engine in
+% use will be loaded. This command may only be used once.
+% \end{function}
+%
+% \begin{variable}{\c_sys_backend_str}
+% Set to the name of the backend in use by \cs{sys_load_backend:n} when
+% issued.
+% \end{variable}
+%
+% \begin{function}[added = 2019-09-12]{\sys_load_debug:, \sys_load_deprecation:}
+% \begin{syntax}
+% \cs{sys_load_debug:}
+% \cs{sys_load_deprecation:}
+% \end{syntax}
+% Load the additional configuration files for debugging support and rolling
+% back deprecations, respectively.
+% \end{function}
+%
% \end{documentation}
%
% \begin{implementation}
@@ -318,6 +468,308 @@
% \end{macrocode}
% \end{macro}
%
+% \subsection{Platform}
+%
+% \begin{macro}[pTF]{\sys_if_platform_unix:, \sys_if_platform_windows:}
+% \begin{variable}{\c_sys_platform_str}
+% Setting these up requires the file module (file lookup), so is actually
+% implemented there.
+% \end{variable}
+% \end{macro}
+%
+% \subsection{Random numbers}
+%
+% \begin{macro}[EXP]{\sys_rand_seed:}
+% Unpack the primitive. When random numbers are not available, we
+% return zero after an error (and incidentally make sure the number of
+% expansions needed is the same as with random numbers available).
+% \begin{macrocode}
+\sys_if_rand_exist:TF
+ { \cs_new:Npn \sys_rand_seed: { \tex_the:D \tex_randomseed:D } }
+ {
+ \cs_new:Npn \sys_rand_seed:
+ {
+ \int_value:w
+ \__kernel_msg_expandable_error:nnn { kernel } { fp-no-random }
+ { \sys_rand_seed: }
+ \c_zero_int
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\sys_gset_rand_seed:n}
+% The primitive always assigns the seed globally.
+% \begin{macrocode}
+\sys_if_rand_exist:TF
+ {
+ \cs_new_protected:Npn \sys_gset_rand_seed:n #1
+ { \tex_setrandomseed:D \int_eval:n {#1} \exp_stop_f: }
+ }
+ {
+ \cs_new_protected:Npn \sys_gset_rand_seed:n #1
+ {
+ \__kernel_msg_error:nnn { kernel } { fp-no-random }
+ { \sys_gset_rand_seed:n {#1} }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Access to the shell}
+%
+% \begin{variable}{\c_sys_shell_escape_int}
+% Expose the engine's shell escape status to the user.
+% \begin{macrocode}
+\int_const:Nn \c_sys_shell_escape_int
+ {
+ \sys_if_engine_luatex:TF
+ {
+ \tex_directlua:D
+ { tex.sprint(status.shell_escape~or~os.execute()) }
+ }
+ {
+ \tex_shellescape:D
+ }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_internal_tl}
+% \begin{macrocode}
+\tl_new:N \l_@@_internal_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_@@_marker_tl}
+% The same idea as the marker for rescanning token lists.
+% \begin{macrocode}
+\tl_const:Nx \c_@@_marker_tl { : \token_to_str:N : }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[TF]{\sys_get_shell:nnN}
+% \begin{macro}{\sys_get_shell:nnN,\@@_get:nnN,\@@_get_do:Nw}
+% Setting using a shell is at this level just a slightly specialised file
+% operation, with an additional check for quotes, as these are not supported.
+% \begin{macrocode}
+\cs_new_protected:Npn \sys_get_shell:nnN #1#2#3
+ {
+ \sys_get_shell:nnNF {#1} {#2} #3
+ { \tl_set:Nn #3 { \q_no_value } }
+ }
+\prg_new_protected_conditional:Npnn \sys_get_shell:nnN #1#2#3 { T , F , TF }
+ {
+ \sys_if_shell:TF
+ { \exp_args:No \@@_get:nnN { \tl_to_str:n {#1} } {#2} #3 }
+ { \prg_return_false: }
+ }
+\cs_new_protected:Npn \@@_get:nnN #1#2#3
+ {
+ \tl_if_in:nnTF {#1} { " }
+ {
+ \__kernel_msg_error:nnx
+ { kernel } { quote-in-shell } {#1}
+ \prg_return_false:
+ }
+ {
+ \group_begin:
+ \if_false: { \fi:
+ \int_set_eq:NN \tex_tracingnesting:D \c_zero_int
+ \exp_args:No \tex_everyeof:D { \c_@@_marker_tl }
+ #2 \scan_stop:
+ \exp_after:wN \@@_get_do:Nw
+ \exp_after:wN #3
+ \exp_after:wN \prg_do_nothing:
+ \tex_input:D | "#1" \scan_stop:
+ \if_false: } \fi:
+ \prg_return_true:
+ }
+ }
+\exp_args:Nno \use:nn
+ { \cs_new_protected:Npn \@@_get_do:Nw #1#2 }
+ { \c_@@_marker_tl }
+ {
+ \group_end:
+ \tl_set:No #1 {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP, pTF]{\sys_if_shell:, \sys_if_shell_unrestricted:, \sys_if_shell_restricted:}
+% Performs a check for whether shell escape is enabled. The first set
+% of functions returns true if either of restricted or unrestricted
+% shell escape is enabled, while the other two sets of functions
+% return true in only one of these two cases.
+% \begin{macrocode}
+\@@_const:nn { sys_if_shell }
+ { \int_compare_p:nNn \c_sys_shell_escape_int > 0 }
+\@@_const:nn { sys_if_shell_unrestricted }
+ { \int_compare_p:nNn \c_sys_shell_escape_int = 1 }
+\@@_const:nn { sys_if_shell_restricted }
+ { \int_compare_p:nNn \c_sys_shell_escape_int = 2 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\c_@@_shell_stream_int}
+% This is not needed for \LuaTeX{}: shell escape there isn't done using
+% a \TeX{} interface.
+% \begin{macrocode}
+\sys_if_engine_luatex:F
+ { \int_const:Nn \c_@@_shell_stream_int { 18 } }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\sys_shell_now:n}
+% Execute commands through shell escape immediately.
+% \begin{macrocode}
+\sys_if_engine_luatex:TF
+ {
+ \cs_new_protected:Npn \sys_shell_now:n #1
+ {
+ \lua_now:e
+ { os.execute(" \lua_escape:e { \tl_to_str:n {#1} } ") }
+ }
+ }
+ {
+ \cs_new_protected:Npn \sys_shell_now:n #1
+ { \iow_now:Nn \c_@@_shell_stream_int {#1} }
+ }
+\cs_generate_variant:Nn \sys_shell_now:n { x }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\sys_shell_shipout:n}
+% Execute commands through shell escape at shipout.
+% \begin{macrocode}
+\sys_if_engine_luatex:TF
+ {
+ \cs_new_protected:Npn \sys_shell_shipout:n #1
+ {
+ \lua_shipout_e:n
+ { os.execute(" \lua_escape:e { \tl_to_str:n {#1} } ") }
+ }
+ }
+ {
+ \cs_new_protected:Npn \sys_shell_shipout:n #1
+ { \iow_shipout:Nn \c_@@_shell_stream_int {#1} }
+ }
+\cs_generate_variant:Nn \sys_shell_shipout:n { x }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Configurations}
+%
+% \begin{variable}{\g_@@_backend_tl}
+% As the backend has to be checked and possibly adjusted, the approach here
+% is to create a variable and use that in a one-shot to set a constant.
+% \begin{macrocode}
+\tl_new:N \g_@@_backend_tl
+\tl_gset:Nx \g_@@_backend_tl
+ {
+ \sys_if_engine_xetex:TF
+ { xdvipdfmx }
+ {
+ \sys_if_output_pdf:TF
+ { pdfmode }
+ {
+ \bool_lazy_or:nnTF
+ { \sys_if_engine_ptex_p: }
+ { \sys_if_engine_uptex_p: }
+ { dvipdfmx }
+ { dvips }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\sys_load_backend:n}
+% \begin{macro}{\@@_load_backend_check:N}
+% \begin{variable}{\c_sys_backend_str}
+% Loading the backend code is pretty simply: check that the backend is valid,
+% then load it up.
+% \begin{macrocode}
+\cs_new_protected:Npn \sys_load_backend:n #1
+ {
+ \str_if_exist:NTF \c_sys_backend_str
+ { \__kernel_msg_error:nnxx { sys } { backend-set } }
+ {
+ \tl_if_blank:nF {#1}
+ { \tl_set:Nn \g_@@_backend_tl {#1} }
+ \@@_load_backend_check:N \g_@@_backend_tl
+ \str_const:Nx \c_sys_backend_str { \g_@@_backend_tl }
+ \__kernel_sys_configuration_load:n
+ { l3backend- \c_sys_backend_str }
+ }
+ }
+\cs_new_protected:Npn \@@_load_backend_check:N #1
+ {
+ \sys_if_engine_xetex:TF
+ {
+ \str_if_eq:VnF #1 { xdvipdfmx }
+ {
+ \__kernel_msg_error:nnxx { sys } { wrong-backend }
+ #1 { xdvipdfmx }
+ \tl_gset:Nn #1 { xdvipdfmx }
+ }
+ }
+ {
+ \sys_if_output_pdf:TF
+ {
+ \str_if_eq:VnF #1 { pdfmode }
+ {
+ \__kernel_msg_error:nnxx { sys } { wrong-backend }
+ #1 { pdfmode }
+ \tl_gset:Nn #1 { pdfmode }
+ }
+ }
+ {
+ \str_case:VnF #1
+ {
+ { dvipdfmx } { }
+ { dvips } { }
+ { dvisvgm } { }
+ }
+ {
+ \__kernel_msg_error:nnxx { sys } { wrong-backend }
+ #1 { dvips }
+ \tl_gset:Nn #1 { dvips }
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\g_@@_debug_bool, \g_@@_deprecation_bool}
+% \begin{macrocode}
+\bool_new:N \g_@@_debug_bool
+\bool_new:N \g_@@_deprecation_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\sys_load_debug:, \sys_load_deprecation:}
+% Simple.
+% \begin{macrocode}
+\cs_new_protected:Npn \sys_load_debug:
+ {
+ \bool_if:NF \g_@@_debug_bool
+ { \__kernel_sys_configuration_load:n { l3debug } }
+ \bool_gset_true:N \g_@@_debug_bool
+ }
+\cs_new_protected:Npn \sys_load_deprecation:
+ {
+ \bool_if:NF \g_@@_deprecation_bool
+ { \__kernel_sys_configuration_load:n { l3deprecation } }
+ \bool_gset_true:N \g_@@_deprecation_bool
+ }
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macrocode}
%</initex|package>
% \end{macrocode}