# How can I perform a simple file search in LaTeX?

I'm looking to improve my gitinfo package by reducing the amount of setup needed.

For this, I want to be able to search for a file in the current directory, then the parent, then the grandparent ... until either (a) I find the file [OK] or (b) find a directory called .git [Error message a] or (c) fall off the top of the file system tree [Error message b].

I've tried nesting \InputIfFileExists, but that only gives me a fixed maximum number of levels.

Sorry, I really don't have a clue as to the simplest approach; so pointers to useful packages to use or copy would be a good option, rather than predigested answers (though these, obviously, would be very welcome).

Having done a little more reading, finding a directory might be a bit more difficult, so finding a file .git/description would do.

-
TeX is unable to find files without extension, I'm afraid: if no extension is supplied, TeX adds .tex. I believe this is doable with pdftex and luatex, but not with xetex unless shell escape is enabled. Checking whether we are at the top might be tougher, because Unix system allow cd .. when at the top. – egreg Feb 13 '13 at 14:27
@egreg Yes, I thought that no extension might prove problematic. I guess that the solution will have to be LuaTeX, but that's no good for a public package. Alternatively I can klugde just three levels and forget about the .git directory, but that's not what I call a quality solution. Thanks anyway... – Brent.Longborough Feb 13 '13 at 16:51
With pdftex one can do \pdffilemoddate that expands to something if the file exists and to nothing if the file doesn't exist. The loop might end after a big, although finite, number of steps: 255 levels before reaching the top of the file system should be sufficient. – egreg Feb 13 '13 at 16:56

This works with pdflatex and lualatex:

\documentclass{article}
\usepackage{pdftexcmds}
\makeatletter
\newcount\Brent@level
\newcommand\BrentInput[1]{%
\Brent@level=\z@
\def\Brent@prefix{}%
\Brent@Input{#1}%
}
\def\Brent@Input#1{%
\edef\Brent@temp{\pdf@filemoddate{\Brent@prefix/.git/description}}%
\ifx\Brent@temp\@empty
% there's no .git/description file at this level
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{%
\ifnum\Brent@level<255
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{\InputIfFileExists{\Brent@prefix#1}{}
{%
% go up one level and retry
\edef\Brent@prefix{../\Brent@prefix}%
\Brent@Input{#1}%
}%
}
{\errmessage{Too many levels}}
}
{\errmessage{.git found}}
}
\makeatother

\begin{document}
\BrentInput{file}

\BrentInput{foo}
\end{document}


I set a limit of 255 levels up from the current one. With XeLaTeX one has to rely on -shell-escape.

Since directories can't be found (at least with \pdffilemoddate), the .git directory must contain a file named description.

-
As always, thanks, @egreg . I'll have a play with this and see if I can break it (before it breaks me) :) – Brent.Longborough Feb 13 '13 at 18:35