%D \module
%D   [       file=core-ctx,
%D        version=2006.08.16, % old stuff
%D          title=\CONTEXT\ Core Macros,
%D       subtitle=Job Control,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

\writestatus{loading}{Context Core Macros / Ctx Job Files}

%D After some experimenting this code moved into the core. It
%D overloades a few file reading macros and permits runtime
%D conversion and job control.

% todo: rewrite in lua

\unprotect

\chardef\preprocessmethod 2 % 0=no check 1=present_check 2=log_check
\chardef\preprocessstate  0 % 1=found 2=not_present (skip)
\chardef\preprocesslocal  0 % 0=no 1=yes
\def    \preprocesssuffix {.prep}

\def\loadctxpreplist
  {\begingroup
   \chardef\XMLtokensreduction\plusone
   \ifcase\preprocessmethod
     % no checking
   \or
     % simple checking
   \or
     \doiffileexistselse{./\jobname.ctl}
       {\bgroup
        \defineXMLenvironment[ctx:preplist][local=no]
          {\doifelse{\XMLop{local}}{yes}
              {\global\chardef\preprocesslocal\plusone
               \writestatus\m!systems{loading ctx log file (local)}}%
              {\writestatus\m!systems{loading ctx log file (specified)}}}
          \donothing
        \defineXMLenvironmentsave[ctx:prepfile][done=no]
          \donothing
          {\edef\readfilename{\XMLflush{ctx:prepfile}}%
           \ifcase\preprocesslocal\else
              \splitfilename\readfilename
              \let\readfilename\splitoffbase
           \fi
           \writestatus\m!systems{registering \readfilename\space -> \XMLop{done}}%
           \setxvalue{fp..\readfilename}{\XMLop{done}}}%
        \processXMLfile{./\jobname.ctl}%
        \egroup}%
       {\global\chardef\preprocessmode\plusone}%
   \fi
   \global\let\loadctxpreplist\relax
   \endgroup}

\appendtoks\loadctxpreplist\to\everystarttext % will become: \prependtoks\loadctxpreplist\to\everyjob

\def\docheckprepfile
  {\ifcase\preprocessmethod
     \iftracefiles\writestatus\m!systems{preprocessing - not needed}\fi
     % no preprocessing
   \or
     % only check for existence
     \iftracefiles\writestatus\m!systems{preprocessing - check exitence of \readfilename\preprocesssuffix}\fi
     \doiffileexistselse{\readfilename\preprocesssuffix}
       {\chardef\preprocessstate\plusone}
       \donothing
   \or
     % check when in list, otherwise assume normal file
     \bgroup
     \splitfilename\readfilename
     \ifx\splitofftype\empty
       % saveguard and speed up
       \iftracefiles\writestatus\m!systems{preprocessing - no suffix}\fi
       \egroup
     \else\ifcase\preprocesslocal
       % also ./ strippen
       \iftracefiles\writestatus\m!systems{preprocessing - check presence of \readfilename\preprocesssuffix}\fi
       \doifdefinedelse{fp..\readfilename}
         {\egroup
          \doiffileexistselse{\readfilename\preprocesssuffix}
            {\chardef\preprocessstate\plusone}
            {\chardef\preprocessstate\plustwo}}%
         {\doifdefinedelse{fp.../\readfilename}
            {\egroup
             \edef\readfilename{./\readfilename}%
             \doiffileexistselse{\readfilename\preprocesssuffix}
               {\chardef\preprocessstate\plusone}
               {\chardef\preprocessstate\plustwo}}%
            {\doifdefinedelse{fp..\splitoffbase}%
               {\egroup
                \doiffileexistselse{\readfilename\preprocesssuffix}
                  {\chardef\preprocessstate\plusone}
                  {\chardef\preprocessstate\plustwo}}%
               {\egroup}}}%
     \else
       % maybe just filecheck, why ctl
       \iftracefiles\writestatus\m!systems{preprocessing - check local presence of \readfilename\preprocesssuffix}\fi
       \doifdefinedelse{fp..\readfilename}
         {\egroup
          \doiffileexistselse{\readfilename\preprocesssuffix}
            {\chardef\preprocessstate\plusone}
            {\chardef\preprocessstate\plustwo}}%
         {\egroup}%
     \fi
   \fi\fi}

% beware, \readfilename keeps the original one, but we load and store the
% suffixed with .prep file (if present)

\def\doreadfile#1#2#3#4% beware, this one already works at format generation time!
  {\sanitizefilename#2\to\readfilename
   \ifx\readfilename\empty
     % silently ignore
   \else
     \let\trackedfilename\readfilename
     \chardef\preprocessstate\zerocount
     \ifconditional\trackfilenames
       \doifundefinedelse{fn..\trackedfilename}\donetrue\donefalse
     \else
       \donetrue
     \fi
     \ifdone
       \checkfilename\readfilename
       \ifcase\kindoffile
         % not a full path or url, check for existence
         \doifelsenothing{#1}
           {\iftracefiles\writestatus\m!systems{searching for \readfilename\space on tex path}\fi
            \def\next{\redoreadfile\readfilename{#3}{#4}}}%
           {\iftracefiles\writestatus\m!systems{searching for \readfilename\space on #1}\fi
            \def\next{\redoreadfile{\pathplusfile{#1}{\readfilename}}{#3}{#4}}}%
       \else
         % a full path or url, no further checking done
         \docheckprepfile
         \ifcase\preprocessstate
           \doiffileexistselse\readfilename
             {\iftracefiles\writestatus\m!systems{located \readfilename}\fi
              \def\next{#3\dodoreadfile}}%
             {\iftracefiles\writestatus\m!systems{not found \readfilename}\fi
              \def\next{#4}}%
         \or
           \iftracefiles\writestatus\m!systems{located \readfilename\preprocesssuffix}\fi
           \def\next{#3\dodoreadfile}%
         \or
           \iftracefiles\writestatus\m!systems{not found \readfilename\preprocesssuffix}\fi
           \def\next{#4}%
         \fi
       \fi
     \else
       \edef\readfilename{\getvalue{fn..\readfilename}}% ??? is done !
       \iftracefiles\writestatus\m!systems{already located \readfilename}\fi
       \def\next{#3\dodoreadfile}%
     \fi
     \expandafter\next
   \fi}

\def\redoreadfile#1#2#3%
  {\docheckprepfile
   \ifcase\preprocessstate
     \doiffileexistselse{#1}%
       {\edef\readfilename{#1}%
        \iftracefiles\writestatus\m!systems{#1 located}\fi
        \def\next{#2\dodoreadfile}}%
       {\iftracefiles\writestatus\m!systems{cannot locate #1}\fi
        \decrement\readlevel\relax
        \ifnum\readlevel>\zerocount
          \edef\readfilename{\pathplusfile{\f!parentpath}{\readfilename}}%
          \def\next{\redoreadfile\readfilename{#2}{#3}}%
        \else
          \def\next{#3}%
        \fi}%
   \or
     \ifcase\preprocesslocal
       \edef\readfilename{#1}% nor found
     \else
       % no path prepending
     \fi
     \iftracefiles\writestatus\m!systems{#1\preprocesssuffix\space located}\fi
     \def\next{#2\dodoreadfile}%
   \or
     \def\next{#3}%
   \fi
   \next}

\def\dodoreadfile % we provide hooks, for instance for \enableXML
  {\ifconditional\trackfilenames
     \setxvalue{fn..\trackedfilename}{\readfilename\ifcase\preprocessstate\or\preprocesssuffix\fi}%
   \fi
   \the\everybeforereadfile
   \ifcase\preprocessstate
     % no checking or not found when using method 1
     \def\dodoreadfileindeed{\inputgivenfile\readfilename}%
   \or
     % found when using method 1 or 2
     \def\dodoreadfileindeed{\inputgivenfile{\readfilename\preprocesssuffix}}%
   \or
     % not found when using method 2
     \let\dodoreadfileindeed\relax
   \fi
   \dodoreadfileindeed
   \relax
   \the\everyafterreadfile}

\protect \endinput
