# Double \ProvidesFile in LaTeX kernel. Why?

The LaTeX kernel defines \ProvidesFile twice:

 121: \def\ProvidesFile#1{%
122:   \begingroup
123:     \catcode\ 10 %
124:     \ifnum \endlinechar<256 %
125:       \ifnum \endlinechar>\m@ne
126:         \catcode\endlinechar 10 %
127:       \fi
128:     \fi
129:     \@makeother\/%
130:     \@ifnextchar[{\@providesfile{#1}}{\@providesfile{#1}[]}}
.....
7580: \def\ProvidesFile#1{%
7581:   \begingroup
7582:     \catcode\ 10 %
7583:     \ifnum \endlinechar<256 %
7584:       \ifnum \endlinechar>\m@ne
7585:         \catcode\endlinechar 10 %
7586:       \fi
7587:     \fi
7588:     \@makeother\/%
7589:     \@makeother\&%
7590:     \kernel@ifnextchar[{\@providesfile{#1}}{\@providesfile{#1}[]}}


The only meaningful difference here is the addition of \@makeother\& (since \let\kernel@ifnextchar\@ifnextchar on line 1055). Is this necessary?

source2e.pdf mentions this regarding the first definition (p 4):

This is a special version of \ProvidesFile for initex use.

...and this regarding the second (re)definition (p 459):

Like \ProvidesPackage, but for arbitrary files.

What does the catcode difference of & make here?

• The files that are input before the redefinition are fonttext.ltx, fontmath.cfg and fontmath.ltx. Also \@providesfile is modified at the end of latex.ltx. – egreg Jan 8 '17 at 22:41

You linked to latex.ltx which is fine but of course that is the version stripped of all documentation.

In the documented sources you see for the first one

% \subsection{Some bits of 2e}
%    \begin{macrocode}
%<*2ekernel>
\def\two@digits#1{\ifnum#1<10 0\fi\number#1}
\long\def\@firstoftwo#1#2{#1}
\long\def\@secondoftwo#1#2{#2}
%    \end{macrocode}
% \changes{v1.0e}{1994/05/11}
%         {Add \cs{ProvidesFile} as used in fd files.}
% \changes{v1.0l}{1995/10/17}
%         {Modify initex version of \cs{ProvidesFile}}
% \changes{v1.0n}{1995/11/01}
% This is a special version of |\ProvidesFile| for initex use.
% \changes{v1.0x}{2001/05/25}{Explicitly set catcode of
%                              \cs{endlinechar} to 10 (pr/3334)}
% \changes{v1.0y}{2001/06/04}{But only if it is a char (pr/3334)}
%    \begin{macrocode}


So it is part of a suite of commands given initial basic definitions to allow latex to bootstrap itself up from a core initex with no preloaded format.

In particular this is part of dircheck.dtx which is used in unpack.ins as

\let\documentclass\undefined
\input ltdirchk.dtx


so if you need to unpack latex.ltx from the documented sources just using initex with no plain or latex format available, the ltdircheck.dtx file needs to define every macro that it uses.

The definitions in this initial set are not always the final definitions. Sometimes because there are special requirements (eg in the case of \ProvidesFile files input during format building are not processed for \listfiles) but mostly any differences are because the ltdircheck versions are just defined with the bare minimum required to allow the latex source to unpack itself and bootstrap up to dumping the format.

The documentation for the second one (in ltclass.dtx) more or less hints at the & difference (which is of no consequence) & was added later

% \changes{v1.1a}{1998/03/21}
%         {Allow \&. Internal/2702}


As the number of files input during format building is known and & is known to be safe in those the ltdircheck.dtx version wasn't changed probably had it been there initially it would have ended up in both versions just because of ease of copying code.