% \iffalse
%% File: l3file.dtx Copyright (C) 2009-2010 LaTeX3 project
%%
%% It may be distributed and/or modified under the conditions of the
%% LaTeX Project Public License (LPPL), either version 1.3c of this
%% license or (at your option) any later version.  The latest version
%% of this license is in the file
%%
%%    http://www.latex-project.org/lppl.txt
%%
%% This file is part of the ``expl3 bundle'' (The Work in LPPL)
%% and all files in that bundle must be distributed together.
%%
%% The released version of this bundle is available from CTAN.
%%
%% -----------------------------------------------------------------------
%%
%% The development version of the bundle can be found at
%%
%%    http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
%%%%%%%%%%%
%% NOTE: %%
%%%%%%%%%%%
%%
%%   Snapshots taken from the repository represent work in progress and may
%%   not work or may contain conflicting material!  We therefore ask
%%   people _not_ to put them into distributions, archives, etc. without
%%   prior consultation with the LaTeX Project Team.
%%
%% -----------------------------------------------------------------------
%% 
%
%<*driver|package>
\RequirePackage{l3names}
%</driver|package>
%\fi
\GetIdInfo$Id: l3file.dtx 1853 2010-03-21 09:11:08Z joseph $
  {L3 Experimental file loading}
%\iffalse
%<*driver>
%\fi
\ProvidesFile{\filename.\filenameext}
  [\filedate\space v\fileversion\space\filedescription]
%\iffalse
\documentclass[full]{l3doc}
\begin{document}
  \DocInput{l3file.dtx}
\end{document}
%</driver>
% \fi
%
% \title{The \textsf{l3file} package\thanks{This file
%         has version number \fileversion, last
%         revised \filedate.}\\
% File Loading}
% \author{\Team}
% \date{\filedate}
% \maketitle
%
% \begin{documentation}
% 
% \section{Loading files}
%
% In contrast to the \pkg{l3io} module, which deals with the lowest
% level of file management, the \pkg{l3file} module provides a higher
% level interface for handling file contents. This involves providing
% convenient wrappers around many of the functions in \pkg{l3io}
% to make them more generally accessible.
% 
% It is important to remember that \TeX\ will attempt to locate
% files using both the operating system path and entries in the 
% \TeX\ file database (most \TeX\ systems use such a database). Thus
% the `current path' for \TeX\ is somewhat broader than that for other
% programs.
% 
%\begin{variable}{ \g_file_current_name_tl }
%  Contains the name of the current LaTeX file. This variable
%  should not be modified: it is intended for information only. It
%  will be equal to \cs{c_job_name_tl} at the start of a \LaTeX\
%  run and will be modified each time a file is read using
%  \cs{file_input:n}.
%\end{variable}
%
%\begin{function}{ 
%  \file_if_exist:n / (TF)  |
%  \file_if_exist:V / (TF) 
%}
%  \begin{syntax}
%    \cs{file_if_exist:nTF} \Arg{file name} \Arg{true code} \Arg{false code}
%  \end{syntax}
%  Searches for \meta{file name} using the current \TeX\ search 
%  path and the additional paths controlled by 
%  \cs{file_path_include:n}). The branching versions then leave 
%  either \meta{true code} or \meta{false code} in the input stream, 
%  as appropriate to the truth of the test and the variant of the 
%  function chosen.
%\end{function} 
%
%\begin{function}{ 
%  \file_input:n |
%  \file_input:V
%}
%  \begin{syntax}
%    \cs{file_input:n} \Arg{file name}
%  \end{syntax}
%  Searches for \meta{file name} in the path as detailed for 
%  \cs{file_if_exist:nTF}, and if found reads in the file as
%  additional \LaTeX\ source. All files read are recorded 
%  for information and the file name stack is updated by this
%  function.
%\end{function}
%
%\begin{function}{ \file_path_include:n }
%  \begin{syntax}
%    \cs{file_path_include:n} \Arg{path}
%  \end{syntax}
%  Adds \meta{path} to the list of those used to search for files
%  by the \cs{file_input:n} and \cs{file_if_exist:n} function. The
%  assignment is local.
%\end{function}
%
%\begin{function}{ \file_path_remove:n }
%  \begin{syntax}
%    \cs{file_path_remove:n} \Arg{path}
%  \end{syntax}
%  Removes \meta{path} from the list of those used to search for files
%  by the \cs{file_input:n} and \cs{file_if_exist:n} function. The
%  assignment is local.
%\end{function}
%
%\begin{function}{ \file_list: }
%  \begin{syntax}
%    \cs{file_list:}
%  \end{syntax}
%  This function will list all files loaded using \cs{file_input:n}
%  in the log file.
%\end{function}
% 
% \end{documentation}
% 
% \begin{implementation}
%
% \section{\pkg{l3file} implementation}
%
% The usual lead-off.
%    \begin{macrocode}
%<*package>
\ProvidesExplPackage
  {\filename}{\filedate}{\fileversion}{\filedescription}
\package_check_loaded_expl:
%</package>
%<*initex|package>
%    \end{macrocode}
%
%\begin{macro}{\g_file_current_name_tl}
%\begin{macro}{\g_file_stack_seq}
% The name of the current file should be available at all times.
%    \begin{macrocode}
\tl_new:N \g_file_current_name_tl
\seq_new:N \g_file_stack_seq
%    \end{macrocode}
%    
% For the format the file name needs to be picked up at the start of the
% file. In package mode the current file name is collected from LaTeX2e.
%    \begin{macrocode}
%</initex|package>
%<*initex>
\toks_put_right:Nn \tex_everyjob:D { 
  \tl_gset:Nx \g_file_current_name_tl { \tex_jobname:D }
}
%</initex>
%<*package>
\tl_gset_eq:NN \g_file_current_name_tl \@currname
%</package>
%<*initex|package>
%    \end{macrocode}
%\end{macro} 
%\end{macro}
%
%\begin{macro}{\g_file_record_seq}
% The total list of files used is recorded separately from the
% stack.
%    \begin{macrocode}
\seq_new:N \g_file_record_seq
%    \end{macrocode}
%    
% The current file name should be included in the file list!
%    \begin{macrocode}
%</initex|package>
%<*initex>
\toks_put_right:Nn \tex_everyjob:D {  
  \seq_gput_right:NV \g_file_record_seq \g_file_current_name_tl
}
%</initex>
%<*initex|package>
%    \end{macrocode}
%\end{macro}
%
%\begin{macro}{\l_file_search_path_seq}
% The current search path.
%    \begin{macrocode}
\seq_new:N \l_file_search_path_seq
%    \end{macrocode}
%\end{macro}
%
%\begin{macro}{\l_file_search_path_saved_seq}
% The current search path has to be saved for package use.
%    \begin{macrocode}
%</initex|package>
%<*package>
\seq_new:N \l_file_search_path_saved_seq
%</package>
%<*initex|package>
%    \end{macrocode}
%\end{macro}
%
%\begin{macro}{\l_file_name_tl}
%\begin{macro}{\g_file_test_stream} 
%\begin{macro}[TF]{\file_if_exist:n}
%\begin{macro}[TF]{\file_if_exist:V}
%\begin{macro}[aux]{\file_if_exist_aux:n}
% Checking if a file exists takes place in two parts. First, look on
% the TeX path, then look on the LaTeX path. The
% token list \cs{l_file_name_tl} is used as a marker for finding
% the file, and is also needed by \cs{file_input:n}.
%    \begin{macrocode}
\tl_new:N \l_file_name_tl
\prg_new_protected_conditional:Nnn \file_if_exist:n { T , F , TF } {
  \ior_open:Nn \g_file_test_stream {#1}
  \ior_if_eof:NTF \g_file_test_stream 
    { \file_if_exist_path_aux:n {#1} }
    {
      \ior_close:N \g_file_test_stream
      \tl_set:Nn \l_file_name_tl {#1}
      \prg_return_true:
    }
}
\cs_new_protected_nopar:Npn \file_if_exist_path_aux:n #1 {
  \tl_clear:N \l_file_name_tl
%</initex|package>
%<*package>
  \cs_if_exist:NT \input@path 
    {
      \seq_set_eq:NN \l_file_search_path_saved_seq 
        \l_file_search_path_seq
      \clist_map_inline:Nn \input@path
        { \seq_put_right:Nn \l_file_search_path_seq {##1} }
    }
%</package>
%<*initex|package>
  \seq_map_inline:Nn \l_file_search_path_seq
    {
      \ior_open:Nn \g_file_test_stream { ##1 #1 }
      \ior_if_eof:NF \g_file_test_stream 
        { 
          \tl_set:Nn \l_file_name_tl { ##1 #1 } 
          \seq_map_break:
        }
    } 
%</initex|package>
%<*package>
  \cs_if_exist:NT \input@path 
    {
      \seq_set_eq:NN \l_file_search_path_seq 
        \l_file_search_path_saved_seq
    }
%</package>
%<*initex|package>
  \ior_close:N \g_file_test_stream
  \tl_if_empty:NTF \l_file_name_tl 
    { \prg_return_false: }
    { \prg_return_true: }
}
\cs_generate_variant:Nn \file_if_exist:nT  { V }
\cs_generate_variant:Nn \file_if_exist:nF  { V }
\cs_generate_variant:Nn \file_if_exist:nTF { V }
%    \end{macrocode}
%\end{macro}    
%\end{macro} 
%\end{macro} 
%\end{macro} 
%\end{macro} 
%
%\begin{macro}{\file_input:n}
%\begin{macro}{\file_input:V}
% Most of the work is done by the file test above.
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \file_input:n #1 {
  \file_if_exist:nT {#1}
    {
%</initex|package>
%<*package>
      \@addtofilelist {#1}
%</package>
%<*initex|package>
      \seq_gpush:NV \g_file_stack_seq \g_file_current_name_tl
      \tl_gset:Nn \g_file_current_name_tl {#1}
      \tex_expandafter:D \tex_input:D \l_file_name_tl ~
      \seq_gpop:NN \g_file_stack_seq \g_file_current_name_tl
    }
}
\cs_generate_variant:Nn \file_input:n { V }
%    \end{macrocode}
%\end{macro}
%\end{macro}
%
%\begin{macro}{\file_path_include:n}
%\begin{macro}{\file_path_remove:n}
% Wrapper functions to manage the search path.
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \file_path_include:n #1 {
  \seq_put_right:Nn \l_file_search_path_seq {#1}
  \seq_remove_duplicates:N \l_file_search_path_seq
}
\cs_new_protected_nopar:Npn \file_path_remove:n #1 {
  \seq_remove_element:Nn \l_file_search_path_seq {#1}
}
%    \end{macrocode}
%\end{macro}
%\end{macro}
%
%\begin{macro}{\file_list:}
%\begin{macro}[aux]{\file_list_aux:n}
% A function to list all files used to the log.
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \file_list: {
  \seq_remove_duplicates:N \g_file_record_seq
  \iow_log:n { *~File~List~* }
  \seq_map_function:NN \g_file_record_seq \file_list_aux:n
  \iow_log:n { ************* }
}
\cs_new_protected_nopar:Npn \file_list_aux:n #1 { \iow_log:n {#1} }
%    \end{macrocode}
%\end{macro}
%\end{macro}
%
% When used as a package, there is a need to hold onto the standard
% file list as well as the new one here.
%    \begin{macrocode}
%</initex|package>
%<*package>
\AtBeginDocument{
  \clist_map_inline:Nn \@filelist
    { \seq_put_right:Nn \g_file_record_seq {#1} }
}
%</package>
%    \end{macrocode}
%
% \end{implementation}
% 
% \PrintIndex
