% \iffalse meta-comment
%
% Copyright 1993 1994 1995 1996 1997
% The LaTeX3 Project and any individual authors listed elsewhere
% in this file. 
% 
% For further copyright information, and conditions for modification
% and distribution, see the file legal.txt, and any other copyright
% notices in this file.
% 
% This file is part of the LaTeX2e system.
% ----------------------------------------
%   This system is distributed in the hope that it will be useful,
%   but WITHOUT ANY WARRANTY; without even the implied warranty of
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
% 
%   For error reports concerning UNCHANGED versions of this file no
%   more than one year old, see bugs.txt.
% 
%   Please do not request updates from us directly.  Primary
%   distribution is through the CTAN archives.
% 
% 
% IMPORTANT COPYRIGHT NOTICE:
% 
% You are NOT ALLOWED to distribute this file alone.
% 
% You are allowed to distribute this file under the condition that it
% is distributed together with all the files listed in manifest.txt.
% 
% If you receive only some of these files from someone, complain!
% 
% 
% Permission is granted to copy this file to another file with a
% clearly different name and to customize the declarations in that
% copy to serve the needs of your installation, provided that you
% comply with the conditions in the file legal.txt.
% 
% However, NO PERMISSION is granted to produce or to distribute a
% modified version of this file under its original name.
%  
% You are NOT ALLOWED to change this file.
% 
% 
% 
% \fi
\catcode`\{=1
\catcode`\}=2
\def\filename{docstrip.dtx}
\def\fileversion{2.4h}
\def\filedate{1997/07/07}
\def\docdate {1997/07/07}
% \CheckSum{2407}
%% \CharacterTable
%%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%%   Digits        \0\1\2\3\4\5\6\7\8\9
%%   Exclamation   \!     Double quote  \"     Hash (number) \#
%%   Dollar        \$     Percent       \%     Ampersand     \&
%%   Acute accent  \'     Left paren    \(     Right paren   \)
%%   Asterisk      \*     Plus          \+     Comma         \,
%%   Minus         \-     Point         \.     Solidus       \/
%%   Colon         \:     Semicolon     \;     Less than     \<
%%   Equals        \=     Greater than  \>     Question mark \?
%%   Commercial at \@     Left bracket  \[     Backslash     \\
%%   Right bracket \]     Circumflex    \^     Underscore    \_
%%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%%   Right brace   \}     Tilde         \~}
%%
%
%\iffalse
%
%% The docstrip program for use with TeX.
%% Copyright (C) 1989-1991 Frank Mittelbach
%% Copyright (C) 1992-1995 Johannes Braams, Denys Duchier, 
%%                         Frank Mittelbach
%% Copyright (C) 1995 Marcin Woli\'nski
%% Copyright (C) 1996-1997 Mark Wooding, Marcin Woli\'nski
%% All rights are reserved.
%%
%
% \fi
%
% \changes{2.0b}{1991/05/29}{Added bugfix from Denys}
% \changes{2.0c}{1991/05/29}{Allow almost all characters in guard (DD)}
% \changes{2.0d}{1991/05/31}{Started merging in some of Franks code}
% \changes{2.0j}{1992/03/05}{Wrote introduction}
% \changes{2.0m}{1992/04/21}{Renamed all macros that deal with the
%                           parsing of boolean expressions}
% \changes{2.0m}{1992/04/25}{Removed dependency from ltugboat,
%                          incorporated driver file into source.}
% \changes{2.0m}{1992/04/25}{Added some missing percents; corrected some
%                          typos}
% \changes{2.0m-DL}{1992/05/08}{Various small corrections to English and
%                           typos}
% \changes{2.0q}{1992/07/01}{Changed all dates to yy/mm/dd for better
%                          sorting}
% \changes{2.2a}{1993/12/02}{Update for LaTeX2e}
% \changes{2.2c}{1993/12/17}{Renamed texsys.tex to texsys.cfg.}
% \changes{2.3a}{1995/08/17}{Swapped Primary with Secondary since
%                         expressions are generally described bottom-up}
% \changes{2.3b}{1995/08/22}{Completely changed expressions parser}
% \changes{2.3b}{1995/08/23}{Removed mechanism for checking if  previous
%                    one-line guard is same as current (\cs{testOption},
%                    \cs{closeOption})---this is not a common
%                    case and testing complicates things unnecessarily}
% \changes{2.3c}{1995/08/24}{When file is multiply listed in \cs{file}
%                         clause it \emph{is} multiply read}
% \changes{2.3c}{1995/09/04}{Changed   some   dirty  tricks  to  be
%                         less/more dirty---all uses of \cs{afterfi}}
% \changes{2.3e}{1995/09/25}{Directories support}
% \changes{2.3e}{1995/10/24}{added \cs{makepathname} to support
%                         systems with bizzare pathnames}
% \changes{2.3e}{1995/10/25}{batch files work by \cs{input}}
% \changes{2.3e}{1996/10/02}{Introduced ``open lists''}
% \changes{2.4a}{1996/06/06}{Add stream limits (MDW)}
% \changes{2.4c}{1996/06/11}{Add initex support (DPC)}
%
% \DoNotIndex{\#,\$,\%,\&,\@,\\,\{,\},\^,\_,\~,\ }
% \DoNotIndex{\@ne}
% \DoNotIndex{\advance,\begingroup,\catcode,\closein,\closeout}
% \DoNotIndex{\day,\def,\edef,\else,\empty,\endgroup,\errmessage}
% \DoNotIndex{\expandafter,\fi,\futurelet,\gdef,\global,\if,\ifeof}
% \DoNotIndex{\ifx,\immediate,\let,\loop,\m@ne,\message,\month}
% \DoNotIndex{\newcount}
% \DoNotIndex{\newif,\newlinechar,\newread,\newtoks,\newwrite}
% \DoNotIndex{\noexpand,\openin,\openout,\par,\read,\relax,\repeat}
% \DoNotIndex{\space,\the,\undefined,\write,\xdef,\year,\z@}
%
% ^^A some definitions for this documentation
%
% \newcommand{\ds}{\textsf{DocStrip}} ^^A maybe?
% \newcommand{\bsl}{\protect\bslash}
% \newcommand{\note}[1]{\marginpar{\textbf{#1}}}
% \newcommand{\netaddress}[1]{\texttt{#1}}
%
% ^^A override the default in doc.sty
% \makeatletter
% \renewenvironment{theglossary}{%
%    \glossary@prologue%
%    \GlossaryParms \let\item\@idxitem \ignorespaces}%
%   {}
% \makeatother
%
%
% \changes{2.1c}{1993/02/25}{Added a setting for StandardModuleDepth}
% \setcounter{StandardModuleDepth}{1}
%
% \title{The \ds{} program%
%         \thanks{This file has version number \fileversion,
%                 last revised \filedate,
%                 documentation dated \docdate.}}
%
% \changes{2.1b}{1993/02/23}{modified mailaddress of Johannes}
% \author{%
%   Frank Mittelbach \\
%   \netaddress{Mittelbach@mzdmza.zdv.uni-mainz.de}
%  \and
%   Denys Duchier \\
%   \netaddress{duchier-denys@cs.yale.edu}
%  \and
%   Johannes Braams \\
%   TeXniek \\
%          Kooienswater 62 \\
%          2715 AJ Zoetermeer\\
%   \netaddress{JLBraams@cistron.nl}
%  \and
%   Marcin Woli\'nski \\
%   \netaddress{wolinski@mimuw.edu.pl}
%  \and
%   Mark Wooding \\
%   \netaddress{mdw@excessus.demon.co.uk}}
%
% \date{Printed \today}
%
% \maketitle
% 
% \begin{abstract}
%    This document describes the implementation of the \ds{} program.
%    The original version of this program was developed by Frank
%    Mittelbach to accompany his \texttt{doc.sty} which enables literate
%    programming in \LaTeX\@. Denys Duchier rewrote it to run either
%    with \TeX\ or with \LaTeX, and to allow full boolean expressions in
%    conditional guards instead of just comma-separated lists.
%    Johannes Braams re-united the two implementations, documented and
%    debugged the code.
%
%    In September 1995 Marcin Woli\'nski changed many parts of the
%    program to make use of \TeX's ability to write to multiple files
%    at the same time to avoid re-reading sources.  The performance
%    improvement of version~2.3 came at a price of compatibility with
%    some more obscure operating systems which limit the number of
%    files a process can keep open. This was corrected in September
%    1996 by Mark Wooding and his changes were ``creatively merged''
%    by Marcin Woli\'nski who made at the same time changes in batch
%    files processing, handling of preambles and introduced ``verbatim
%    mode''. After all that, David Carlisle merged the new version into
%    the \LaTeX\ sources, and made a few other changes, principally
%    making \ds{} work under initex, and removing the need for
%    batch files to say \verb|\def\batchfile{...}|.
% \end{abstract}
%
% \section{Introduction}
%
% \subsection{Why the \ds{} program?} When Frank Mittelbach created
%    the \texttt{doc} package, he invented a way to combine \TeX\ code
%    and its documentation. From then on it was more or less possible
%    to do literate programming in \TeX.
%
%    This way of writing \TeX\ programs obviously has great
%    advantages, especially when the program becomes larger than a
%    couple of macros.  There is one drawback however, and that is
%    that such programs may take longer than expected to run because
%    \TeX\ is an interpreter and has to decide for each line of the
%    program file what it has to do with it. Therefore, \TeX\ programs
%    may be speeded up by removing all comments from them.
%
%    By removing the comments from a \TeX\ program a new problem is
%    introduced. We now have two versions of the program and both of
%    them {\em have\/} to be maintained. Therefore it would be nice to
%    have a possibility to remove the comments automatically, instead
%    of doing it by hand. So we need a program to remove comments from
%    \TeX\ programs. This could be programmed in any high level
%    language, but maybe not everybody has the right compiler to
%    compile the program.  Everybody who wants to remove comments from
%    \TeX\ programs has \TeX\@.  Therefore the \ds{} program is
%    implemented entirely in \TeX.
%
% \subsection{Functions of the \ds{} program} 
%
%    Having created the \ds{} program to remove comment lines from
%    \TeX\ programs\footnote{Note that only comment lines, that is
%    lines that start with a single \texttt{\%} character, are removed;
%    all other comments stay in the code.} it became feasible to do more
%    than just strip comments.\\ Wouldn't it be nice to have a way to
%    include parts of the code only when some condition is set true?
%    Wouldn't it be as nice to have the possibility to split the
%    source of a \TeX\ program into several smaller files and combine
%    them later into one `executable'?\\ Both these wishes have been
%    implemented in the \ds{} program.
%
% \section{How to use the \ds{} program}
%    A number of ways exist to use the \ds{} program:
%    \begin{enumerate}
% \item The usual way to use \ds{} is to write a \emph{batch file}
%        in such a way that it can be directly processed by \TeX{}.
%       The batch file should contain the commands described below for
%       controlling the \ds{} program.
%    This allows you to set up a distribution where you can instruct
%        the user to simply run
%      \begin{quote}
%        \texttt{TEX} \meta{batch file}
%      \end{quote}
%        to generate the executable versions of your files from the
%        distribution sources.
%        Most of the \LaTeX\  distribution is packaged this way.
%        To produce such a batch file include a statement in your 
%         `batch file' that
%        instructs \TeX\ to read \texttt{docstrip.tex}. 
%        The beginning of such a file would look like:
%\begin{verbatim}
%    \input docstrip
%    ...
%\end{verbatim}
%    Normally the batch file should have extension |.ins|. If it has
%    a different extension, you should specify the name of the
%    batchfile first, before inputting \ds. This is done by adding a
%    line  such as
%\begin{verbatim}
%    \def\batchfile{install.me}
%\end{verbatim}
%    if the file is called |install.me|.
%
%
%    \item Alternatively you can instruct \TeX\ to read the file
%        \texttt{docstrip.tex} and to see what happens. \TeX\ will ask
%        you a few questions about the file you would like to be
%        processed. When you have answered these questions it does
%        its job and strips the comments from your \TeX\ code.
%    \end{enumerate}
%
% \section{Configuring \ds}
% \subsection{Selecting output directories}
% \changes{2.3e}{1996/09/19}{Added documentation}
%    Inspired by a desire to simplify reinstallations of \LaTeXe{} and
%    to support operating systems which have an upper limit on the
%    number of files allowed in a directory, \ds\ now allows
%    installation scripts to specify output directories for files it
%    creates. We suggest using TDS (\TeX\ directory structure) names
%    of directories relative to \texttt{texmf} here. However these
%    names should be thought of as a labels rather than actual names
%    of directories. They get translated to actual system-dependent
%    pathnames according to commands contained in a configuration file
%    named \texttt{docstrip.cfg}.
%
%    The configuration file is read by \ds{} just before it starts to
%    process any batch file commands.
%
%    If this file is not present \ds{} uses some default settings which
%    ensure that files are only written to the current directory.
%    However by use of this configuration file, a site maintainer can
%    `enable' features of \ds{} that allow files to be written to
%    alternative directories.
%
% \DescribeMacro{\usedir}
%    Using this macro package author can tell where a file should be
%    installed. All |\file|s generated in the scope of that
%    declaration are written to a directory specified by its one
%    argument. For example in \LaTeXe{} installation following
%    declarations are used:
%\begin{verbatim}
%    \usedir{tex/latex/base}
%    \usedir{makeindex}
%\end{verbatim}
%    And standard packages use
%\begin{verbatim}
%    \usedir{tex/latex/tools}
%    \usedir{tex/latex/babel} 
%\end{verbatim}
%    etc.
%
% \DescribeMacro{\showdirectory}
%    Used to display directory names in messages. If some label is not
%    defined it expands to |UNDEFINED (label is ...)| otherwise to a
%    directory name. It is probably a good idea for every installation
%    script to display at startup list of all directories that would
%    be used and asking user to confirm that.
%
%    The above macros are used by package/installation script
%    author. The following macros are used in a configuration file,
%    |docstrip.cfg|, by a system administrator to
%    describe her/his local directory structure.
%
% \DescribeMacro{\BaseDirectory} This macro is administrator's way of
%    saying ``yes, I want to use that directories support of
%    yours''. \ds{} will write only to current directory unless your
%    config has a call to this macro. (This means \ds{} won't write to
%    random directories unless you tell it to, which is nice.) Using
%    this macro you can specify a base directory for \TeX-related
%    stuff. E.g., for many Unix systems that would be
%\begin{verbatim}
%    \BaseDirectory{/usr/local/lib/texmf}
%\end{verbatim}
%    and for standard em\TeX{} installation 
%\begin{verbatim}
%    \BaseDirectory{c:/emtex}
%\end{verbatim}
%
% \DescribeMacro{\DeclareDir} 
%    Having specified the base directory you should tell \ds{} how to
%    interpret labels used in |\usedir| commands. This is done with
%    |\DeclareDir| with two arguments. The first is the label and the
%    second is actual name of directory relative to base
%    directory. For example to teach \ds{} using standard em\TeX{}
%    directories one would say:
%\begin{verbatim}
%    \BaseDirectory{c:/emtex}
%    \DeclareDir{tex/latex/base}{texinput/latex2e}
%    \DeclareDir{tex/latex/tools}{texinput/tools}
%    \DeclareDir{makeindex}{idxstyle}
%\end{verbatim}
%    This will cause base latex files and font descriptions to be
%    written to directory |c:\emtex\texinput\latex2e|, files of
%    \texttt{tools} package to |c:\emtex\texinput\tools| and makeindex
%    files to |c:\emtex\idxstyle|.
%
%    Sometimes it is desirable to put some files outside of the base
%    directory. For that reason |\DeclareDir| has a star form
%    specifying absolute pathname. For example one could say
%\begin{verbatim}
%    \DeclareDir*{makeindex}{d:/tools/texindex/styles}
%\end{verbatim}
%
%    \DescribeMacro{\UseTDS}
%    Users of systems conforming to TDS may well ask here ``do I
%    really need to put a dozen of lines like
%\begin{verbatim}
%    \DeclareDir{tex/latex/base}{tex/latex/base}
%\end{verbatim}
%    in my config file''. The answer is |\UseTDS|. This macro causes
%    \ds{} to use labels themselves for any directory you haven't
%    overriden with |\DeclareDir|. The default behaviour is to raise
%    an error on undefined labels because some users may want to know
%    exactly where files go and not to allow \ds{} to write to random
%    places. However I (MW) think this is pretty cool and my
%    config says just (I'm running te\TeX{} under Linux)
%\begin{verbatim}
%    \BaseDirectory{/usr/local/teTeX/texmf}
%    \UseTDS
%\end{verbatim}
%
%    The important thing to note here is that it is impossible to create
%    a new directory from inside \TeX{}. So however you configure
%    \ds, you need to create all needed directories before running
%    the installation.  Authors may want to begin
%    every installation script by displaying a list of directories
%    that will be used and asking user if he's sure all of them
%    exist.
%
%    Since file name syntax is OS specific \ds{} tries to guess it
%    from the current directory syntax. It should succeed for Unix,
%    MSDOS, Macintosh and VMS. However \ds{} will only initially
%    know the current directory syntax if it is used with \LaTeX.
%    If used with plain\TeX\ or initex it will not have this
%    information\footnote{Except when processing the main
%    \texttt{unpack.ins} batch file for the \LaTeX\ distribution, which
%    takes special measures so that initex can learn the directory
%    syntax.}.
%    If you often use \ds{} with formats other than \LaTeX\ you should
%    \emph{start} the file |docstrip.cfg| with a definition of
%    |\WriteToDir|.  E.g.,
%   |\def\WriteToDir{./}| on MSDOS/Unix,
%   |\def\WriteToDir{:}| on Macintosh,
%   |\def\WriteToDir{[]}| on VMS.
%  
%    If your system requires something
%    completely different you can define in |docstrip.cfg| macros
%    |\dirsep| and |\makepathname|. Check for their definition in the
%    implementation part. If you want some substantially different
%    scheme of translating |\usedir| labels into directory names try
%    redefining macro |\usedir|. 
%
% \subsection{Setting maximum numbers of streams}
%
% \DescribeMacro{\maxfiles}
%    In support of some of the more obscure operating systems, there's
%    a limit on the number of files a program can have open.  This can
%    be expressed to \ds\ through the |\maxfiles| macro.  If the number
%    of streams \ds\ is allowed to open is $n$, your configuration file
%    can say |\maxfiles{|$n$|}|, and \ds\ won't try to open more files
%    than this.  Note that this limit won't include files which are
%    already open.  There'll usually be two of these: the installation
%    script which you started, and the file |docstrip.tex| which it
%    included; you must bear these in mind yourself.  \ds\ assumes
%    that it can open at least four files before it hits some kind of
%    maximum: if this isn't the case, you have real problems.
%
% \DescribeMacro{\maxoutfiles}
%    Maybe instead of having a limit on the number of files \TeX\ can
%    have open, there's a limit on the number of files it can write
%    to (e.g., \TeX\ itself imposes a limit of 16~files being written
%    at a time).  This can be expressed by saying |\maxoutfiles{|$m$|}|
%    in a configuration file.  You must be able to have at least one
%    output file open at a time; otherwise \ds\ can't do anything at
%    all.
%
%    Both these options would typically be put in the |docstrip.cfg|
%    file.
%
%
% \section{The user interface}
%
% \subsection{The main program}
% \DescribeMacro{\processbatchFile} The `main program' starts with
%    trying to process a batch file, this is accomplished by calling
%    the macro |\processbatchFile|. It counts the number of batch
%    files it processes, so that when the number of files processed is
%    still zero after the call to |\processbatchFile| appropriate
%    action can be taken.
%
% \DescribeMacro{\interactive} When no batch files have been processed
%    the macro |\interactive| is called. It prompts the user for
%    information. First the extensions of the input and output files
%    is determined. Then a question about optional code is asked and
%    finally the user can give a list of files that have to be
%    processed.
%
% \DescribeMacro{\ReportTotals} When the \texttt{stats} option is
%    included in the \ds{}-program it keeps a record of the number of
%    files and lines that are processed.  Also the number of comments
%    removed and passed as well as the number of code lines that were
%    passed to the output are accounted. The macro |\ReportTotals|
%    shows a summary of this information.
%
% \subsection{Batchfile commands}
%
%    The commands described in this section are available to build a
%    batch file for \TeX.
%
% \DescribeMacro{\input}
% All \ds{} batch files should start with the line: |\input docstrip| 
%
% Do not use the  \LaTeX\ syntax |\input{docstrip}| as batch files may
% be used with plain~\TeX\ or ini\TeX.
% You may that old batch files always have a line
% |\def\batchfile{|\meta{filename}|}|
% just before the input.
% Such usage is still supported but is now discouraged, as it causes
% \TeX\ to re-input the same file, using up one of its limited number
% of input streams.
%
% \DescribeMacro{\endbatchfile}
% All batch files should end with this command. Any lines after this
% in the file are ignored. In old files that start
% |\def\batchfile{|\ldots\ this command is optional, but is a good
% idea anyway. If this command is omitted from a batchfile then
% normally \TeX\ will go to its interactive |*| prompt, so you may 
% stop \ds{} by typing |\endbatchfile| to this prompt.
%
% \DescribeMacro{\generate}
% \DescribeMacro{\file}
% \DescribeMacro{\from}
%    The main reason for constructing a \ds{} command file is to
%    describe what files should be generated, from what sources and
%    what optional (`guarded') pieces of code should be included. The
%    macro |\generate| is used to give \TeX\ this information. Its
%    syntax is:
%    \begin{quote}
%    |\generate{|[|\file{|\meta{output}|}{|[|\from{|^^A
%                    \meta{input}|}{|\meta{optionlist}|}|]*|}|]*|}|
%    \end{quote}
%    The \meta{output} and \meta{input} are normal file specifications
%    as are appropriate for your computer system. The
%    \meta{optionlist} is a comma separated list of `options' that
%    specify which optional code fragments in \meta{input} should be
%    included in \meta{output}. Argument to |\generate| may contain
%    some local declarations (e.g., the |\use...| commands described
%    below) that will apply to all |\file|s after them. Argument to
%    |\generate| is executed inside a group, so all local declarations
%    are undone when |\generate| concludes.
%
%    It is possible to specify multiple input files, each with its own
%    \meta{optionlist}. This is indicated by the notation [\ldots]*.
%    Moreover there can be many |\file| specifications in one
%    |\generate| clause. This means that all these \meta{output} files
%    should be generated while reading each of \meta{input} files
%    once. Input files are read in order of first appearance in this
%    clause. E.g.
%\begin{verbatim}
%    \generate{\file{p1.sty}{\from{s1.dtx}{foo,bar}}
%              \file{p2.sty}{\from{s2.dtx}{baz}
%                            \from{s3.dtx}{baz}}
%              \file{p3.sty}{\from{s1.dtx}{zip}
%                            \from{s2.dtx}{zip}}
%             }
%\end{verbatim}
%    will cause \ds{} to read files \texttt{s1.dtx}, \texttt{s2.dtx},
%    \texttt{s3.dtx} (in that order) and produce files
%    \texttt{p1.sty}, \texttt{p2.sty}, \texttt{p3.sty}.
%
%    The restriction to at most 16 output streams open in a while
%     does not mean that you can produce at most 16 files with one
%    |\generate|. In the example above only 2 streams are needed,
%    since while \texttt{s1.dtx} is processed only \texttt{p1.sty} and
%    \texttt{p3.sty} are being generated; while reading
%    \texttt{s2.dtx} only \texttt{p2.sty} and \texttt{p3.sty}; and
%    while reading \texttt{s3.dtx} file \texttt{p2.sty} . However
%    example below needs 3 streams:
%\begin{verbatim}
%    \generate{\file{p1.sty}{\from{s1.dtx}{foo,bar}}
%              \file{p2.sty}{\from{s2.dtx}{baz}
%                            \from{s3.dtx}{baz}}
%              \file{p3.sty}{\from{s1.dtx}{zip}
%                            \from{s3.dtx}{zip}}
%             }
%\end{verbatim}
%    Although while reading \texttt{s2.dtx} file \texttt{p3.sty} is
%    not written it must remain open since some parts of
%    \texttt{s3.dtx} will go to it later.
%
%    Sometimes it is not possible to create a file by reading  all
%    sources once. Consider the following example:
%\begin{verbatim}
%    \generate{\file{p1.sty}{\from{s1.dtx}{head}
%                            \from{s2.dtx}{foo}
%                            \from{s1.dtx}{tail}}
%              \file{s1.drv}{\from{s1.dtx}{driver}}
%             }
%\end{verbatim}
%    To generate \texttt{p1.sty} file \texttt{s1.dtx} must be read
%    twice: first time with option \texttt{head}, then file
%    \texttt{s2.dtx} is read and then \texttt{s1.dtx} again this time
%    with option \texttt{tail}.  \ds{} handles this case correctly: if
%    inside one |\file| declaration there are multiple |\from|es with
%    the same input file this file \emph{is} read multiple times.
%
%    If the order of |\from|s specified in one of your |\file|
%    specifications does not match the order of input files
%    established by previous |\file|s, \ds{} will raise an error and
%    abort. Then you may either read one of next sections or give up
%    and put that file in separate |\generate| (but then sources will
%    be read again just for that file).
%
%    \paragraph{For impatient.} Try following algorithm: Find
%    file that is generated from largest number of sources, start
%    writing |\generate| clause with this file and its sources in
%    proper order. Take other files that are to be generated and add
%    them checking if they don't contradict order of sources for the
%    first one. If this doesn't work read next sections.
%
%    \paragraph{For mathematicians.} Relation ``file $A$ must  be
%    read before file $B$'' is a partial order on the set of all your
%    source files.  Each |\from| clause adds a chain to this order.
%    What you have to do is to perform a topological sort i.e. to
%    extend partial order to linear one.  When you have done it just
%    list your source files in |\generate| in such a way that order of
%    their first appearance in the clause matches linear order. If
%    this cannot be achieved read next paragraph. (Maybe future
%    versions of \ds{} will perform this sort automatically, so all
%    these troubles will disappear.)
%
%    \paragraph{For that who must know that all.} There  is  a
%    diverse case when it's not possible to achieve proper order of
%    reading source files. Suppose you have to generate two files,
%    first from \texttt{s1.dtx} and \texttt{s3.dtx} (in that order)
%    and second from \texttt{s2.dtx} and \texttt{s3.dtx}.  Whatever
%    way you specify this the files will be read in either as
%    \texttt{s1 s3 s2} or \texttt{s2 s3 s1}. The key to solution is
%    magical macro |\needed| that marks a file as needed to be input
%    but not directing any output from it to current |\file|. In our
%    example proper specification is:
%\begin{verbatim}
%    \generate{\file{p1.sty}{\from{s1.dtx}{foo}
%                            \needed{s2.dtx}
%                            \from{s3.dtx}{bar}}
%              \file{p2.sty}{\from{s2.dtx}{zip}
%                            \from{s3.dtx}{zap}}
%             }
%\end{verbatim}
%
%
%  \DescribeMacro{\askforoverwritetrue}
%  \DescribeMacro{\askforoverwritefalse}
%    These macros specify what should happen if a file that is to be
%    generated already exists. If |\askforoverwritetrue| is active
%    (the default) the user is asked whether the file should be
%    overwritten. If however |\askforoverwritefalse| was issued
%    existing files will be overwritten silently.  These switches are
%    local and can be issued in any place in the file even inside
%    |\generate| clause (between |\file|s however).
%
%  \DescribeMacro{\askonceonly}
%  You might not want to set |\askforoverwritefalse| in a batch file
%  as that says that it us always all right to overwrite other people's
%  files. However for large installations, such as the base \LaTeX\
%  distribution,  being asked individually about hundreds of files
%  is not very helpful either. A batchfile may therefore specify
%  |\askonceonly|. This means that after the first time the batchfile
%  asks the user a question, the user is given an option of to change
%  the behaviour so that `yes' will be automatically assumed for all
%  future questions. This applies to any use of the \ds{} commamnd
%  |\Ask| including, but not restricted to, the file overwrite
%  questions controlled by |\askforoverwritetrue|.
%
% \DescribeMacro{\preamble}
% \DescribeMacro{\endpreamble}
% \DescribeMacro{\postamble}
% \DescribeMacro{\endpostamble}
%    It is possible to add a number of lines to the output of the
%    \ds{} program. The information you want to add to the start of
%    the output file should be listed between the |\preamble| and
%    |\endpreamble| commands; the lines you want to add to the end of
%    the output file should be listed between the |\postamble| and
%    |\endpostamble| commands. Everything that \ds{} finds for both
%    the pre- and postamble it writes to the output file, but preceded
%    with value of |\MetaPrefix| (default is two \%-characters). If
%    you include a |^^J| character in one of these lines, everything
%    that follows it on the same line is written to a new line in the
%    output file.  This `feature' can be used to add a |\typeout| or
%    |\message| to the the stripped file.
%
% \DescribeMacro{\declarepreamble}
% \DescribeMacro{\declarepostamble}
% \DescribeMacro{\usepreamble}
% \DescribeMacro{\usepostamble}
%    Sometimes it is desirable to have different preambles for different
%    files  of  a  larger  package  (e.g.,  because  some  of them are
%    customisable  configuration  files and they should be marked as
%    such). In such a case one can say |\declarepreamble\somename|,
%    then type in his/her preamble, end it with |\endpreamble|,
%    and  later  on  |\usepreamble\somename|  to  switch   to   this
%    preamble.  The  same  mechanism works for postambles, |\use...|
%    declarations are local and can appear inside |\generate|.
%
%    Commands   |\preamble|   and   |\postamble| define and  activate
%    pre(post)ambles named |\defaultpreamble| and |\defaultpostamble|. 
%
% \DescribeMacro{\batchinput} 
%    The batch file commands can be put into several batch files which
%    are then executed from a master batch file. This is, for example,
%    useful if a distribution consists of several distinct parts. You
%    can then write individual batch files for every part and in
%    addition a master file that simply calls the batch files for the
%    parts.  For this, call the individual batch files from the master
%    file with the command |\batchinput{|\meta{file}|}|. Don't use
%    |\input| for this purpose, this command 
%    should be used only for calling the \ds{} program as explained
%    above and is ignored when used for any other purpose.
%
% \DescribeMacro{\ifToplevel} 
%    When batch files are nested you may want to suppress certain
%    commands in the lower-level batch files such as terminal
%    messages. For this purpose you can use the |\ifToplevel| command
%    which executes its argument only if the current batch file is the
%    outermost one. Make sure that you put the opening brace of the
%    argument into the same line as the command itself, otherwise the
%    \ds{} program will get confused.
%
% \DescribeMacro{\showprogress}
% \DescribeMacro{\keepsilent}
%    When the option \texttt{stats} is included in \ds{} it can
%    write message to the terminal as each line of the input file(s) is
%    processed. This message consists of a single character, indicating
%    kind of that particular line. We use the
%    following characters:
%    \begin{itemize}
% \item[\texttt{\%}] Whenever an input line is a comment
%        \texttt{\%}-character is written to the terminal.
% \item[\texttt{.}] Whenever a code line is encountered
%        a \texttt{.}-character is written on the terminal.
% \item[\texttt{/}] When a number of empty lines appear in a row in the
%        input file, at most one of them is retained. The \ds{}
%        program signals the removal of an empty line with the 
%        \texttt{/}-character.
% \item[\texttt{<}] When a `guard line' is found in the input and it
%        starts a block of optionally included code, this is signalled
%        on the terminal by showing the \texttt{<}-character, together
%        with the boolean expression of the guard.
% \item[\texttt{>}] The end of a conditionally included block of code is
%        indicated by showing the \texttt{>}-character.
%    \end{itemize}
%    This feature is turned on by default when the option
%    \texttt{stats} is included, otherwise it is turned off. The
%    feature can be toggled with the commands |\showprogress| and
%    |\keepsilent|.
%
%
%  \subsubsection{Supporting old interface}
%
% \DescribeMacro{\generateFile}
%    Here is the old syntax for specifing  what  files  are  to  be
%    generated. It allows specification of just one output file.
%    \begin{quote}
%    |\generateFile{|\meta{output}|}{|\meta{ask}|}{|[|\from{|^^A
%                    \meta{input}|}{|\meta{optionlist}|}|]*|}|
%    \end{quote}
%    The meaning of \meta{output}, \meta{input} and
%    \meta{optionslist} is just as for |\generate|.  With
%    \meta{ask} you can instruct \TeX\ to either silently overwrite a
%    previously existing file (|f|) or to issue a warning and ask you
%    if it should overwrite the existing file (|t|) (it overrides the
%    |\askforoverwrite| setting).
%
% \DescribeMacro{\include}
% \DescribeMacro{\processFile}
%    The earlier version of the \ds{} program supported a
%    different kind of command to tell \TeX\ what to do. This command
%    is less powerful than |\generateFile|; it can be used when
%    \meta{output} is created from one \meta{input}. The syntax is:
%    \begin{quote}
%    |\include{|\meta{optionlist}|}|
%
%    |\processFile{|\meta{name}|}{|\meta{inext}^^A
%                              |}{|\meta{outext}^^A
%                              |}{|\meta{ask}|}|
%    \end{quote}
%    This command is based on environments where filenames are
%    constructed of two parts, the name and the extension, separated
%    with a dot. The syntax of this command assumes that the
%    \meta{input} and \meta{output} share the same name and only
%    differ in their extension. This command is retained to be
%    backwards compatible with the older version of \ds{}, but its use
%    is not encouraged.
%
% \section{Conditional inclusion of code}
%
%    When you use the \ds{} program to strip comments out of
%    \TeX\ macro files you have the possibility to make more than one
%    stripped macro file from one documented file. This is achieved by
%    the support for optional code. The optional code is marked
%    in the documented file with a `guard'.
%
%    A guard is a boolean expression that is enclosed in |<| and |>|.
%    It also {\em has\/} to follow the |%| at the beginning of the line.
%    For example:
%\begin{verbatim}
%    ...
%    %<bool>\TeX code
%    ...
%\end{verbatim}
%    In this example the line of code will be included in \meta{output}
%    if the option \texttt{bool} is present in the \meta{optionlist} of
%    the |\generateFile| command.
%
%    The syntax for the boolean expressions is:
%
%\DeleteShortVerb\|
%    \begin{tabular}{lcl}
%    \meta{Expression} & $::=$ & \meta{Secondary}
%                            [\{\texttt{|}, \texttt{,}\} 
%                            \meta{Secondary}]*\\
%    \meta{Secondary}    & $::=$ & 
%                        \meta{Primary} [\texttt{\&}
%                         \meta{Primary}]*\\
%    \meta{Primary}  & $::=$ & 
%                        \meta{Terminal} $|$ \texttt{!}\meta{Primary}
%                        $|$ \texttt{(}\meta{Expression}\texttt{)}\\
%    \end{tabular}
%
%    The \texttt{|} stands for disjunction, the \texttt{\&} stands for
%    conjunction and the \texttt{!}\ stands for negation. The
%    \meta{Terminal} is any sequence of letters and evaluates to
%    \meta{true} iff\footnote{iff stands for `if and only if'} it
%    occurs in the list of options that have to be included.
%\MakeShortVerb\|
%
%    Two kinds of optional code are supported: one can either have
%    optional code that `fits' on one line of text, like the example
%    above, or one can have blocks of optional code.
%
%    To distinguish both kinds of optional code the `guard modifier'
%    has been introduced. The `guard modifier' is one character that
%    immediately follows the |<| of the guard. It can be either |*|
%    for the beginning of a block of code, or |/| for the end of a
%    block of code\footnote{To be compatible with the earlier version
%    of \ds{} also \texttt{+} and \texttt{-} are supported as `guard
%    modifiers'.  However, there is an incompatibility with the
%    earlier version since a line with a \texttt{+}-modified guard is
%    not included inside a block with a guard that evaluates to false,
%    in contrast to the previous behaviour.}.  The beginning and
%    ending guards for a block of code have to be on a line by
%    themselves.
%
%    When a block of code is {\em not\/} included, any guards that occur
%    within that block are {\em not\/} evaluated.
% 
% \section{Those other languages}
%    Since \TeX\ is an open system some of \TeX\ packages include
%    non-\TeX\ files. Some authors use \ds\ to generate PostScript
%    headers, shell scripts or programs in other languages. For them
%    the comments-stripping activity of \ds\ may cause some
%    trouble. This section describes how to produce non-\TeX\ files
%    with \ds\ effectively.
%
% \subsection{Stuff \ds\ puts in every file}
%    First problem when producing files in ``other'' languages is that
%    \ds\ adds some bits to the begining and end of every generated
%    file that may not fit with the syntax of the language in
%    question. So we'll study carefully what exactly goes where.
%
%    The whole text put on begining of file is kept in a macro defined
%    by |\declarepreamble|. Every line of input presented to
%    |\declarepreamble| is prepended with current value of
%    |\MetaPrefix|. Standard \ds\ header is inserted before your text,
%    and macros |\inFileName|, |\outFileName| and |\ReferenceLines|
%    are used as placeholders for information which will be filled in
%    later (specifically for each output file). Don't try to redefine
%    these macros. After
%\begin{verbatim}
%    \declarepreamble\foo
%    ____________________________
%    Package FOO for use with TeX
%    \endpreamble 
%\end{verbatim}
%    macro |\foo| is defined as
%\begin{verbatim}
%    %%^^J
%    %% This is file `\outFileName ',^^J
%    %% generated with the docstrip utility.^^J
%    \ReferenceLines^^J
%    %% ____________________________^^J
%    %% Package FOO for use with TeX.
%\end{verbatim}
%    You can play with it freely or even define it from scratch. To
%    embed the preamble in Adobe structured comments just use |\edef|:
%\begin{verbatim}
%    \edef\foo{\perCent!PS-Adobe-3.0^^J%
%              \DoubleperCent\space Title: \outFileName^^J%
%              \foo^^J%
%              \DoubleperCent\space EndComments}
%\end{verbatim}
%    After that use |\usepreamble\foo| to select your new preamble.
%    Everything above works as well for postambles.
%
%    You may also prevent \ds\ from adding anything to your file, and
%    put any language specific invocations directly in your code:
%\begin{verbatim}
%    \generate{\usepreamble\empty
%              \usepostamble\empty
%              \file{foo.ps}{\from{mypackage.dtx}{ps}}}
%\end{verbatim}
%
% \subsection{Meta comments}
%    You can change the prefix used for putting meta comments to
%    output files by redefining |\MetaPrefix|. Its default value is
%    |\DoubleperCent|. The preamble uses value of |\MetaPrefix|
%    current at time of |\declarepreamble| while meta comments in the
%    source file use value current at time of |\generate|. Note that
%    this means that you cannot produce concurrently two files using
%    different |\MetaPrefix|es.
%    
% \subsection{Verbatim mode}
%    If your programming language uses some construct that can
%    interferes badly with \ds\ (e.g., percent in column one) you may
%    need a way for preventing it from being stripped off. For that
%    purpose \ds\ features `verbatim mode'.
%
%    A `Guard expression' of the form |%<<|\meta{END-TAG} marks
%    the start of a section that will be copied verbatim upto a line
%    containing only a percent in column 1 followed by \meta{END-TAG}. 
%    You can select any \meta{END-TAG} you want, but note that spaces
%     count here. Example:
%\begin{verbatim}
%    %<*myblock>
%    some stupid()
%       #computer<program>
%    %<<COMMENT
%    % These two lines are copied verbatim (including percents
%    %% even if \MetaPrefix is something different than %%).
%    %COMMENT
%       using*strange@programming<language>
%    %</myblock>
%\end{verbatim}
%    And the output is (when stripped with \texttt{myblock} defined):
%\begin{verbatim}
%    some stupid()
%       #computer<program>
%    % These two lines are copied verbatim (including percents
%    %% even if \MetaPrefix is something different than %%).
%       using*strange@programming<language>
%\end{verbatim}
%
%\StopEventually{%
%^^A \section{Conclusion}
%  \PrintIndex
%  \PrintChanges
%^^A \makesignature
% }
%
% \section{Producing the documentation}
%
%    We provide a short driver file that can be extracted by the
%    \ds{} program using the the conditional `\textsf{driver}'.  To
%    allow the use of \texttt{docstrip.dtx} as a program at Ini\TeX{}
%    time (e.g., to strip
%    off its own comments) we need to add a bit of primitive code.
%    With this extra checking it is still possible to process this
%    file with \LaTeXe{} to typeset the documentation.
% \changes{2.1b}{1993/02/23}{Added fontdefinitions for doc to the driver
%                          file, in order to get the layout of the code
%                          right; also added the layout definitions
%                          that are in effect in \texttt{doc.drv}}
% \changes{2.1c}{1993/02/23}{Remove definitions for fonts again}
% \changes{2.2f}{1994/02/26}{Allow direct processing of source}
%    \begin{macrocode}
%<*driver>
%    \end{macrocode}
%    If |\documentclass| is undefined, e.g., if Ini\TeX{} or plain
%    \TeX{} is used for formatting, we bypass the driver file.
%
% \changes{2.3a}{1995/08/20}{Changed driver}
%    We use some trickery to avoid issuing |\end{document}| when
%    the |\ifx| construction is unfinished. If condition below is
%    true a |\fi| is constructed on the fly, the |\ifx| is completed,
%    and the real |\fi| will never be seen as it comes after 
%    |\end{document}|. On the other hand if condition is false
%    \TeX\ skips over |\csname fi\endcsname| having no idea that
%    this could stand for |\fi|, driver is skipped and only then
%    the condition completed.
%
%    Additional guard |gobble| prevents \ds\ from extracting
%    these tricks to real driver file.
%    \begin{macrocode}
%<*gobble>
\ifx\jobname\relax\let\documentclass\undefined\fi
\ifx\documentclass\undefined
\else \csname fi\endcsname
%</gobble>
%    \end{macrocode}
%    Otherwise we process the following lines which will result in
%    formatting the documentation.
%    \begin{macrocode}
 \documentclass{ltxdoc}
    \EnableCrossrefs 
 % \DisableCrossrefs 
 % use \DisableCrossrefs if the 
 % index is ready 
 \RecordChanges 
 % \OnlyDescription
 \typeout{Expect some Under- and overfull boxes}
 \begin{document}
   \DocInput{docstrip.dtx}
 \end{document}
%<*gobble>
\fi
%</gobble>
%</driver>
%    \end{macrocode}
%
%
% \section{The implementation}
%
% \subsection{Initex initializations}
% Allow this program to run with |initex|.
% The |Z| trickery saves the need to worry about |\outer| stuff in
% plain \TeX.
%    \begin{macrocode}
%<*initex>
\catcode`\Z=\catcode`\%
\ifnum13=\catcode`\~{\egroup\else
  \catcode`\Z=9
Z
Z  \catcode`\{=1  \catcode`\}=2 
Z  \catcode`\#=6  \catcode`\^=7
Z  \catcode`\@=11 \catcode`\^^L=13
Z  \let\bgroup={  \let\egroup=}
Z
Z  \dimendef\z@=10 \z@=0pt \chardef\@ne=1 \countdef\m@ne=22 \m@ne=-1
Z  \countdef\count@=255
Z
Z  \def\wlog{\immediate\write\m@ne} \def\space{ }
Z
Z  \count10=22 % allocates \count registers 23, 24, ...
Z  \count15=9 % allocates \toks registers 10, 11, ...
Z  \count16=-1 % allocates input streams 0, 1, ...
Z  \count17=-1 % allocates output streams 0, 1, ...
Z
Z  \def\alloc@#1#2#3{\advance\count1#1\@ne#2#3\count1#1\relax}
Z
Z  \def\newcount{\alloc@0\countdef} \def\newtoks{\alloc@5\toksdef}
Z  \def\newread{\alloc@6\chardef}   \def\newwrite{\alloc@7\chardef}
Z
Z \def\newif#1{%
Z   \count@\escapechar \escapechar\m@ne
Z     \let#1\iffalse
Z     \@if#1\iftrue
Z     \@if#1\iffalse
Z   \escapechar\count@}
Z \def\@if#1#2{%
Z   \expandafter\def\csname\expandafter\@gobbletwo\string#1%
Z                     \expandafter\@gobbletwo\string#2\endcsname
Z                        {\let#1#2}}
Z 
Z  \def\@gobbletwo#1#2{}
Z  \def\@gobblethree#1#2#3{}
Z
Z  \def\loop#1\repeat{\def\body{#1}\iterate}
Z  \def\iterate{\body \let\next\iterate \else\let\next\relax\fi \next}
Z  \let\repeat\fi
Z
Z  \def\empty{}
Z
Z  \def\tracingall{\tracingcommands2 \tracingstats2 
Z    \tracingpages1 \tracingoutput1 \tracinglostchars1 
Z    \tracingmacros2 \tracingparagraphs1 \tracingrestores1 
Z    \showboxbreadth 10000 \showboxdepth 10000 \errorstopmode
Z    \errorcontextlines 10000 \tracingonline1 }
Z
\bgroup}\fi\catcode`\Z=11
\let\bgroup={  \let\egroup=}
%</initex>
%    \end{macrocode}
%
% \subsection{Declarations and initializations}
%
%    In order to be able to include the \texttt{@}-sign in control
%    sequences its category code is changed to \meta{letter}.  The
%    `program' guard here allows most of the code to be excluded when
%    extracting the driver file.
%    \begin{macrocode}
%<*program>
\catcode`\@=11
%    \end{macrocode}
%
%    When we want to write multiple lines to the terminal with one
%    statement, we need a character that tells \TeX\ to break the lines.
%    We use \verb=^^J= for this purpose.
%    \begin{macrocode}
\newlinechar=`\^^J
%    \end{macrocode}
%
% \subsubsection{Switches}
% \begin{macro}{\ifGenerate}
%    The program will check if a
%    file of the same name as the file it would be creating already
%    exists. The switch |\ifGenerate| is used to indicate if the
%    stripped file has to be generated.
%    \begin{macrocode}
\newif\ifGenerate
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ifContinue}
%    The switch |\ifContinue| is used in various places in the
%    program to indicate if a |\loop| has to end.
%    \begin{macrocode}
\newif\ifContinue
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ifForlist}
% \changes{2.0g}{1991/06/05}{Macro added.}
%    The program contains an implementation of a for-loop, based on
%    plain \TeX{}'s |\loop| macros. The implementation needs a
%    switch to terminate the loop.
%    \begin{macrocode}
\newif\ifForlist
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ifDefault}
%    The switch |\ifDefault| is used to indicate whether the
%    default batch file has to be used.
% \changes{2.0f}{1991/06/04}{Macro added.} 
%    \begin{macrocode}
\newif\ifDefault
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ifMoreFiles}
%    The switch |\ifMoreFiles| is used to decide if the user
%    wants more files to be processed. It is used only in interactive
%    mode; initially it evaluates to \meta{true}.
% \changes{2.0h}{1991/06/19}{Macro added.}
%    \begin{macrocode}
\newif\ifMoreFiles \MoreFilestrue
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\ifaskforoverwrite}
%    The switch |\askforoverwrite| is used to  decide  if  the  user
%    should be asked when a file is to be overwritten.
%    \begin{macrocode}
\newif\ifaskforoverwrite \askforoverwritetrue
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{Count registers}
% \begin{macro}{\blockLevel}
%    Optionally included blocks of code can be nested. The counter
%    |\blockLevel| will be used to keep track of the level of
%    nesting.  Its initial value is zero.
%    \begin{macrocode}
\newcount\blockLevel \blockLevel\z@
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\emptyLines}
%    The count register |\emptyLines| is used to count the number
%    of consecutive empty input lines. Only the first will be copied
%    to the output file.
% \changes{2.0i}{1990/06/27}{Macro added}
%    \begin{macrocode}
\newcount\emptyLines \emptyLines \z@
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\processedLines}
% \begin{macro}{\commentsRemoved}
% \begin{macro}{\commentsPassed}
% \begin{macro}{\codeLinesPassed}
%    To be able to provide the user with some statistics about the
%    stripping process four counters are allocated if the statistics
%    have been included when this program was \ds{}ped.  The number of
%    lines processed is stored in the counter |\processedLines|.
%    The number of lines containing comments that are not written on
%    the output file is stored in the counter |\commentsRemoved|;
%    the number of comments copied to the output file is stored in the
%    counter |\commentsPassed|.  The number of lines containing
%    macro code that are copied to the output file is stored in the
%    counter |\codeLinesPassed|.
%    \begin{macrocode}
%<*stats>
\newcount\processedLines   \processedLines  \z@
\newcount\commentsRemoved  \commentsRemoved \z@
\newcount\commentsPassed   \commentsPassed  \z@
\newcount\codeLinesPassed  \codeLinesPassed \z@
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \changes{2.0e}{1991/05/31}{Added counter allocation for the processing
%                           of multiple files}
% \begin{macro}{\TotalprocessedLines}
% \begin{macro}{\TotalcommentsRemoved}
% \begin{macro}{\TotalcommentsPassed}
% \begin{macro}{\TotalcodeLinesPassed}
%    When more than one file is processed and when statistics have
%    been included we provide the user also with information about the
%    total amount of lines processed. For this purpose four more count
%    registers are allocated here.
%    \begin{macrocode}
\newcount\TotalprocessedLines   \TotalprocessedLines  \z@
\newcount\TotalcommentsRemoved  \TotalcommentsRemoved \z@
\newcount\TotalcommentsPassed   \TotalcommentsPassed  \z@
\newcount\TotalcodeLinesPassed  \TotalcodeLinesPassed \z@
%</stats>
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\NumberOfFiles}
%    When more than one file is processed, the number of files is
%    stored in the count register |\NumberOfFiles|.
% \changes{2.4h}{1997/07/07}{Declare counter always pr/2429}
%    \begin{macrocode}
\newcount\NumberOfFiles \NumberOfFiles\z@
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{I/O streams}
% \begin{macro}{\inFile}
%    For reading the file with documented \TeX-code, an input stream
%    |\inFile| is allocated.
%    \begin{macrocode}
\newread\inFile
%    \end{macrocode}
% \end{macro}
%
% \changes{2.3a}{1995/08/18}{No allocated streams for console}
% \begin{macro}{\ttyin}
% \begin{macro}{\ttyout}
%    Communication with the user goes through (nonexistent) stream 16.
%    \begin{macrocode}
\chardef\ttyin16
\chardef\ttyout16
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\inputcheck}
%    This stream is only used for checking for existence of files. 
%    \begin{macrocode}
\newread\inputcheck
%    \end{macrocode}
% \end{macro}
%
%  \begin{macro}{\ifToplevel}
%    Execute the argument if current batch file is the outermost one.
%    Otherwise suppress it.
%    \begin{macrocode}
\newif\iftopbatchfile \topbatchfiletrue
\def\ifToplevel{\relax\iftopbatchfile
   \expandafter\iden \else \expandafter\@gobble\fi}
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\batchinput}
% \changes{2.0n}{1992/04/26}{Added macro}
% \changes{2.1a}{1993/02/22}{Completely redefined (so that it works)}
%
%    When the file \texttt{docstrip.tex} is read because of an
%    |\input| statement in a batch file we have to prevent an
%    endless loop (well, limited by \TeX's stack). Therefore we save
%    the original primitive |\input| and define a new macro with
%    an argument delimited by \verb*= = (i.e.\ a space) that just
%    gobbles the argument.  Since the end-of-line character is
%    converted by \TeX{} to a space.  This means that |\input| is not
%    available as a command within batch files. 
%
% \begin{macro}{\@@input}
% \changes{2.1a}{1993/02/22}{Macro added}
%    We therefore keep a copy of the original under the name
%    |\@@input| for internal use. If \ds{} runs under \LaTeX{} this
%    command is already defined, so we make a quick test.
%    \begin{macrocode}
\ifx\undefined\@@input \let\@@input\input\fi
%    \end{macrocode}
% \end{macro}
%    
%    To allow the nesting of batch files the |\batchinput| command is
%    provided it takes one argument, the name of the batch file to
%    switch to.
%    \begin{macrocode}
\def\batchinput#1{%
%    \end{macrocode}
%    We start a new group and locally redefine |\batchFile| to hold
%    the new batch file name. We toggle the |\iftopbatchfile| switch
%    since this definitely is not top batch file.
%    \begin{macrocode}
   \begingroup
     \def\batchfile{#1}%
     \topbatchfilefalse
     \Defaultfalse
     \usepreamble\org@preamble
     \usepostamble\org@postamble
     \let\destdir\WriteToDir
%    \end{macrocode}
%    After this we can simply call |\processbatchFile| which will
%    open the new batch file and read it until it
%    is exhausted. Note that if the batch file is not available, or
%    misspelled this routine will produce a warning and return.
%    \begin{macrocode}
     \processbatchFile
%    \end{macrocode}
%    The value of |\batchfile| as well as local definitions of
%    preambles, directories etc. will be restored
%    at this  closing |\endgroup|, so that further processing
%    continues in the calling batch file.
%    \begin{macrocode}
   \endgroup
}
%    \end{macrocode}
% \begin{macro}{\skip@input}
% \changes{2.0j}{1992/03/03}{Added macro}
% \changes{2.0n}{1992/04/26}{Argument delimited by space not \cs{relax}}
% \changes{2.0n}{1992/04/26}{Macro renamed from \cs{skipinput}} 
%    And here is the promised redefinition of |\input|:
%    \begin{macrocode}
\def\skip@input#1 {}
\let\input\skip@input
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \subsubsection{Empty macros and macros that expand to a string}
% \begin{macro}{\guardStack}
%    \changes{2.0k}{1992/04/06}{Renamed from \texttt{\bsl blockStack}}
%    Because blocks of code that will conditionally be included in the
%    output can be nested, a stack is maintained to keep track of
%    these blocks. The main reason for this is that we want to be able
%    to check if the blocks are properly nested. The stack itself is
%    stored in |\guardStack|.
%    \begin{macrocode}
\def\guardStack{}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\blockHead}
%    The macro |\blockHead| is used for storing and retrieving
%    the boolean expression that starts a block.
%    \begin{macrocode}
\def\blockHead{}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\yes}
% \begin{macro}{\y}
%    When the user is asked a question that he has to answer with either
%    \meta{yes} or \meta{no}, his response has to be evaluated. For this
%    reason the macros |\yes| and |\y| are defined.
%    \begin{macrocode}
\def\yes{yes}
\def\y{y}
%    \end{macrocode}
% \begin{macro}{\n}
%    We also define |\n| for use in \ds{} command files.
% \changes{2.1e}{1993/03/09}{Macro added}
%    \begin{macrocode}
\def\n{n}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\Defaultbatchile}
% \changes{2.0f}{1991/06/04}{Macro added.}
%    When the \ds{} program has to process a batch file it
%    can look for a batch file with a default name. This name
%    is stored in |\DefaultbatchFile|.
%    \begin{macrocode}
\def\DefaultbatchFile{docstrip.cmd}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\perCent}
% \begin{macro}{\DoubleperCent}
% \begin{macro}{\MetaPrefix}
%    To be able to display percent-signs on the terminal, a
%    \texttt{\%} with category code 12 is stored in |\perCent| and
%    |\DoubleperCent|. The macro |\MetaPrefix| is put on begining of
%    every meta-comment line. It is defined indirect way since some
%    applications need redefining it.
%    \begin{macrocode}
{\catcode`\%=12
 \gdef\perCent{%}
 \gdef\DoubleperCent{%%}
}
\let\MetaPrefix\DoubleperCent
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%    In order to allow formfeeds in the input we define a one-character
%    control sequence \verb=^^L=.
%    \begin{macrocode}
\def^^L{ }
%    \end{macrocode}
%
%    The only result of using |\Name| is slowing down execution since
%    its typical use (e.g., |\Name\def{foo bar}...|) has exactly the
%    same number of tokens as its expansion. However I think that it's
%    easier to read. The meaning of |\Name| as a black box is:
%    ``construct a name from second parameter and then pass it to your
%    first parameter as a parameter''.
%
%    |\@stripstring| is used to get tokens building name of a macro
%    without leading backslash.
%    \begin{macrocode}
\def\Name#1#2{\expandafter#1\csname#2\endcsname}
\def\@stripstring{\expandafter\@gobble\string}
%    \end{macrocode}
%
% \subsubsection{Miscellaneous variables}
% \begin{macro}{\sourceFileName}
%    The macro |\sourceFileName| is used to store the name of the
%    current input file.
% \end{macro}
% \begin{macro}{\batchfile}
%    The macro |\batchfile| is used to store the name of the
%    batch file.
% \end{macro}
% \begin{macro}{\inLine}
%    The macro |\inLine| is used to store the lines, read from
%    the input file, before further processing.
% \end{macro}
% \begin{macro}{\answer}
%    When some interaction with the user is needed the macro
%    |\answer| is used to store his response.
% \end{macro}
% \begin{macro}{\tmp}
%    Sometimes something has to be temporarily stored in a control
%    sequence.  For these purposes the control sequence |\tmp| is
%    used.
% \end{macro}
%
% \subsection{Support macros}
%    \subsubsection{The stack mechanism}
%
%    It is possible to have `nested guards'. This means that within a
%    block of optionally included code a subgroup is only included
%    when an additional option is specified. To keep track of the
%    nesting of the guards the currently `open' guard can be pushed on
%    the stack |\guardStack| and later popped off the stack again. The
%    macros that implement this stack mechanism are loosely based on
%    code that is developed in the context of the \LaTeX3 project.
%
%    To be able to implement a stack mechanism we need a couple of
%    support macros.
% \begin{macro}{\eltStart}
%    \changes{2.0k}{1992/04/06}{Macro added}
% \begin{macro}{\eltEnd}
%    \changes{2.0k}{1992/04/06}{Macro added}
%    The macros |\eltStart| and |\eltEnd| are used to delimit a stack
%    element. They are both empty.
%    \begin{macrocode}
\def\eltStart{}
\def\eltEnd{}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\qStop}
%    \changes{2.0k}{1992/04/06}{Macro added}
%    The macro |\qStop| is a so-called `quark', a macro that expands to
%    itself\footnote{The concept of `quarks' is developed for the
%    \LaTeX3 project.}.
%    \begin{macrocode}
\def\qStop{\qStop}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\pop}
%    \changes{2.0k}{1992/04/06}{Macro added} The macro
%    |\pop|\meta{stack}\meta{cs} `pops' the top element from the
%    stack. It assigns the value of the top element to \meta{cs} and
%    removes it from \meta{stack}. When \meta{stack} is empty a
%    warning is issued and \meta{cs} is assigned an empty value.
%    \begin{macrocode}
\def\pop#1#2{%
  \ifx#1\empty
    \Msg{Warning: Found end guard without matching begin}%
    \let#2\empty
  \else
%    \end{macrocode}
%    To be able to `peel' off the first guard we use an extra macro
%    |\popX| that receives both the expanded and the unexpanded stack
%    in its arguments. The expanded stack is delimited with the quark
%    |\qStop|.
%    \begin{macrocode}
    \def\tmp{\expandafter\popX #1\qStop #1#2}%
    \expandafter\tmp\fi}
%    \end{macrocode}
% \begin{macro}{\popX}
%    \changes{2.0k}{1992/04/06}{Macro added} When the stack is expanded
%    the elements are surrounded with |\eltStart| and |\eltEnd|. The
%    first element of the stack is assigned to |#4|.
%    \begin{macrocode}
\def\popX\eltStart #1\eltEnd #2\qStop #3#4{\def#3{#2}\def#4{#1}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\push}
%    \changes{2.0k}{1992/04/06}{Macro added}
%    Guards can be pushed on the stack using the macro
%    |\push|\meta{stack}\meta{guard}. Again we need a secondary macro
%    (|\pushX|) that has both the expanded and the unexpanded stack as
%    arguments.
%    \begin{macrocode}
\def\push#1#2{\expandafter\pushX #1\qStop #1{\eltStart #2\eltEnd}}
%    \end{macrocode}
% \begin{macro}{\pushX}
%    \changes{2.0k}{1992/04/06}{Macro added}
%    The macro |\pushX| picks up the complete expansion of the stack as
%    its first argument and places the guard in |#3| on the `top'.
%    \begin{macrocode}
\def\pushX #1\qStop #2#3{\def #2{#3#1}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \subsubsection{Programming structures}
%
% \begin{macro}{\forlist}
% \changes{2.0g}{1991/06/05}{Macro added.}
%    When the program is used in interactive mode the
%    user can supply a list of files that have to be processed.
%    In order to process this list a for-loop is needed. This
%    implementation of such a programming construct is based on the
%    use of the \verb=\loop{=\meta{body}\verb=}\repeat= macro that
%    is defined in plain \TeX\@. The syntax for this loop is:
%    \begin{flushleft}
%    |\for|\meta{control sequence} |:=| \meta{list} 
%    |\do|\\
%    \meta{body}\\
%    |\od|
%    \end{flushleft}
%    The \meta{list} should be a comma separated list.
%
%    The first actions that have to be taken are to set the switch
%    |\ifForlist| to \meta{true} and to store the loop condition
%    in the macro |\ListCondition|. This is done using an
%    |\edef| to allow for a control sequence that contains a
%    \meta{list}.
%    \begin{macrocode}
\def\forlist#1:=#2\do#3\od{%
    \edef\ListCondition{#2}%
    \Forlisttrue
%    \end{macrocode}
%    Then we start the loop.
%    We store the first element from the |\ListCondition| in the
%    macro that was supplied as the first argument to |\forlist|.
%    This element is then removed from the |\ListCondition|.
%    \begin{macrocode}
    \loop
      \edef#1{\expandafter\FirstElt\ListCondition,\empty.}%
      \edef\ListCondition{\expandafter\OtherElts\ListCondition,\empty.}%
%    \end{macrocode}
%    When the first element from the \meta{list} is empty, we are done
%    processing, so we switch |\ifForlist| to \meta{false}.
%    When it is not empty we execute the third argument that should
%    contain \TeX\ commands to execute.
%    \begin{macrocode}
      \ifx#1\empty \Forlistfalse \else#3\fi
%    \end{macrocode}
%    Finally we test the switch |\ifForlist| to decide whether the
%    loop has to be continued.
%    \begin{macrocode}
      \ifForlist
    \repeat}
%    \end{macrocode}
% \begin{macro}{\FirstElt}
% \changes{2.0g}{1991/06/05}{Macro added.}
%    The macro |\FirstElt| is used to get the first element from a
%    comma-separated list.
%    \begin{macrocode}
\def\FirstElt#1,#2.{#1}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\OtherElts}
% \changes{2.0g}{1991/06/05}{Macro added.}
%    The macro |\OtherElts| is used to get all elements {\em but\/}
%    the first element from a comma-separated list.
%    \begin{macrocode}
\def\OtherElts#1,#2.{#2}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\whileswitch}
% \changes{2.0h}{1991/06/19}{Macro added.} When the program is used in
%    interactive mode the user might want to process several files
%    with different options or extensions.  This goal could be reached
%    by running the program several times, but it is more
%    user-friendly to ask if he would like to process more files when
%    we are done processing his last request.  To accomplish this we
%    need the implementation of a \texttt{while}-loop.  Again plain
%    \TeX's \verb=\loop{=\meta{body}\verb=}\repeat= is used to
%    implement this programming structure.
%
%    The syntax for this loop is:
%    \begin{flushleft}
%    |\whileswitch|\meta{switch} \verb|\fi| \meta{list}
%    \verb={=\meta{body}\verb=}=\\
%    \end{flushleft}
%    The first argument to this macro has to be a switch, defined
%    using |\newif|; the second argument contains the statements
%    to execute while the switch evaluates to \meta{true}.
%    \begin{macrocode}
\def\whileswitch#1\fi#2{#1\loop#2#1\repeat\fi}
%    \end{macrocode}
% \end{macro}
%
% \changes{2.3a}{1995/08/18}{New mechanism: output streams allocation}
% 
% \subsubsection{Output streams allocator}
% 
% For each of sixteen output streams  available  we  have  a  macro
% named |\s@0| through |\s@15| saying if the stream is assigned to a
% file~(1) or not~(0). Initially all streams are not assigned.
%
% We also declare 16 counters which will be needed by the conditional
% code inclusion algorithm.
% 
%    \begin{macrocode}
\ifx\@tempcnta\undefined \newcount\@tempcnta \fi
\@tempcnta=0
\loop
\Name\chardef{s@\number\@tempcnta}=0
\csname newcount\expandafter\endcsname%
  \csname off@\number\@tempcnta\endcsname
\advance\@tempcnta1
\ifnum\@tempcnta<16\repeat
%    \end{macrocode}
% 
% We will use \emph{The \TeX book} style list to search through streams.
% 
%    \begin{macrocode}
\let\s@do\relax
\edef\@outputstreams{%
  \s@do\Name\noexpand{s@0}\s@do\Name\noexpand{s@1}%
  \s@do\Name\noexpand{s@2}\s@do\Name\noexpand{s@3}%
  \s@do\Name\noexpand{s@4}\s@do\Name\noexpand{s@5}%
  \s@do\Name\noexpand{s@6}\s@do\Name\noexpand{s@7}%
  \s@do\Name\noexpand{s@8}\s@do\Name\noexpand{s@9}%
  \s@do\Name\noexpand{s@10}\s@do\Name\noexpand{s@11}%
  \s@do\Name\noexpand{s@12}\s@do\Name\noexpand{s@13}%
  \s@do\Name\noexpand{s@14}\s@do\Name\noexpand{s@15}%
  \noexpand\@nostreamerror
  }
%    \end{macrocode}
%
% \begin{macro}{\@nostreamerror}\begin{macro}{\@streamfound}
% When |\@outputstreams| is executed |\s@do| is defined to do
% something on condition   of   some   test.    If   condition
% always   fails   macro |\@nostreamerror| on the end of the list
% causes an error. When condition succeeds  |\@streamfound|  is
% called,  which  gobbles  rest of the list including the ending
% |\@nostreamerror|. It also gobbles |\fi| ending the condition, so
% the |\fi| is reinserted.
% 
%    \begin{macrocode}
\def\@nostreamerror{\errmessage{No more output streams!}}
\def\@streamfound#1\@nostreamerror{\fi}
%    \end{macrocode}
% \end{macro}\end{macro}
% 
% |\@stripstr| is auxiliary macro eating characters |\s@|
% (backslash,s,@). It is defined in somewhat strange way since |\s@|
% must have all category code  12  (other).  This  macro  is  used to
% extract stream numbers from stream names.
% 
%    \begin{macrocode}
\bgroup\edef\x{\egroup
 \def\noexpand\@stripstr\string\s@{}}
\x
%    \end{macrocode}
%
% \begin{macro}{\StreamOpen}\begin{macro}{\StreamPut}
% \begin{macro}{\StreamClose}
% Here is stream opening operator. Its parameter should be a  macro
% named the  same  as  the  external  file  being  opened. E.g., to
% write to file |foo.tex|   use    |\StreamOpen\foo|,    then
% |\StreamPut\foo|    and |\StreamClose\foo|.
% 
%    \begin{macrocode}
\chardef\stream@closed=16
\def\StreamOpen#1{%
  \chardef#1=\stream@closed 
  \def\s@do##1{\ifnum##1=0
    \chardef#1=\expandafter\@stripstr\string##1 %
    \global\chardef##1=1 %
    \immediate\openout#1=\csname pth@\@stripstring#1\endcsname %
    \@streamfound
    \fi}
  \@outputstreams
  }
\def\StreamClose#1{%
  \immediate\closeout#1%
  \def\s@do##1{\ifnum#1=\expandafter\@stripstr\string##1 %
    \global\chardef##1=0 %
    \@streamfound
    \fi}
  \@outputstreams
  \chardef#1=\stream@closed
  }
\def\StreamPut{\immediate\write}
%    \end{macrocode}
% \end{macro}\end{macro}\end{macro}
% 
% \subsubsection{Input and Output}
%
% \begin{macro}{\maybeMsg}
% \begin{macro}{\showprogress}
% \begin{macro}{\keepsilent}
%    When this program is used it can optionally show its progress on
%    the terminal. In that case it will write a special character to
%    the terminal (and the transcript file) for each input line. This
%    option is on by default when statistics are included in 
%    \texttt{docstrip.tex}. It is off when statistics are excluded. The
%    commands |\showprogress| and |\keepsilent| can be used
%    to choose otherwise.
%    \begin{macrocode}
\def\showprogress{\let\maybeMsg\message}
\def\keepsilent{\let\maybeMsg\@gobble}
%<*stats>
\showprogress
%</stats>
%<-stats>\keepsilent
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\Msg}
%    For displaying messages on the terminal the macro |\Msg| is
%    defined to write {\em immediately\/} to |\ttyout|.
%    \begin{macrocode}
\def\Msg{\immediate\write\ttyout}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\Ask}
%    The macro
%    \verb=\Ask{=\meta{cs}\verb=}{=\meta{string}\verb=}= is a
%    slightly modified copy of the \LaTeX\ macro |\typein|. It is
%    used to ask the user a question.  The \meta{string} will be
%    displayed on his terminal and the response will be stored in the
%    \meta{cs}. The trailing space left over from the carriage return
%    is stripped off by the macro |\strip|. If the user just
%    types a carriage return, the result will be an empty macro.
% \changes{2.0i}{1991/06/27}{Added check for just \protect\meta{CR}}
%    \begin{macrocode}
\def\iden#1{#1}
\def\strip#1#2 \@gobble{\def #1{#2}}
\def\@defpar{\par}
\def\Ask#1#2{%
    \message{#2}\read\ttyin to #1\ifx#1\@defpar\def#1{}\else
    \iden{\expandafter\strip
       \expandafter#1#1\@gobble\@gobble} \@gobble\fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\OriginalAsk}
% \changes{2.4e}{1996/10/24}{macro added (was in unpack.ins) (DPC)}
%    \begin{macrocode}
\let\OriginalAsk=\Ask
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\askonceonly}
% \changes{2.4e}{1996/10/22}
%      {macro added (essentially from unpack.ins) (DPC)}
%    \begin{macrocode}
\def\askonceonly{%
  \def\Ask##1##2{%
    \OriginalAsk{##1}{##2}%
    \global\let\Ask\OriginalAsk
    \Ask\noprompt{%
      By default you will be asked this question for every file.^^J%
      If you enter `y' now,^^J%
      I will asssume `y' for all future questions^^J%
      without prompting.}%
    \ifx\y\noprompt\let\noprompt\yes\fi
    \ifx\yes\noprompt\gdef\Ask####1####2{\def####1{y}}\fi}}
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{Miscellaneous}
%
% \begin{macro}{\@gobble}
% \changes{2.0a}{1991/05/25}{Macro added.}
%    A macro that has an argument and puts it in the bitbucket.
%    \begin{macrocode}
\def\@gobble#1{}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\Endinput}
% \changes{2.0f}{1991/06/04}{Macro added.} When a \texttt{doc} file
%    contains a \verb+\endinput+ on a line by itself this normally
%    means that anything following in this file should be ignored.
%    Therefore we need a macro containing |\endinput| as its
%    replacement text to check this against |\inLine| (the
%    current line from the current input file). Of course the
%    backslash has to have the correct |\catcode|. One way of
%    doing this is feeding \verb=\\= to the |\string| operation
%    and afterwards removing one of the |\| characters.
%    \begin{macrocode}
\edef\Endinput{\expandafter\@gobble\string\\endinput}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\makeOther}
%    During the process of reading a file with \TeX\ code the category
%    code of all special characters has to be changed to \meta{other}.
%    The macro |\makeOther| serves this purpose.
%    \begin{macrocode}
\def\makeOther#1{\catcode`#1=12\relax}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\end}
% \changes{2.0h}{1991/06/19}{Macro added.} For now we want the \ds{}
%    program to be compatible with both plain \TeX\ and \LaTeX\@.
%    \LaTeX\  hides plain \TeX{}'s |\end| command and
%    calls it |\@@end|. We unhide it here.
%    \begin{macrocode}
\ifx\undefined\@@end\else\let\end\@@end\fi
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@addto}
%    A macro extending macro's definition. The trick with |\csname|
%    is necessary to get around |\newtoks| being outer in plain \TeX{}
%    and \LaTeX\ version 2.09.
%    \begin{macrocode}
\ifx\@temptokena\undefined \csname newtoks\endcsname\@temptokena\fi
%    \end{macrocode}
%
%    \begin{macrocode}
\def\@addto#1#2{%
  \@temptokena\expandafter{#1}%
  \edef#1{\the\@temptokena#2}}
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\@ifpresent}
%    This macro checks if its first argument  is  present  on  a
%    list passed as the second argument. Depending on the result
%    it executes either its third or fourth argument.
% 
%    \begin{macrocode}
\def\@ifpresent#1#2#3#4{%
  \def\tmp##1#1##2\qStop{\ifx!##2!}%
  \expandafter\tmp#2#1\qStop #4\else #3\fi
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\tospaces}
%    This macro converts its argument delimited with |\secapsot| to
%    appropriate number of spaces. We need this for smart displaying
%    messages on the screen.
%
%    |\@spaces| are used when we need many spaces in a row.
%    \begin{macrocode}
\def\tospaces#1{%
  \ifx#1\secapsot\secapsot\fi\space\tospaces}
\def\secapsot\fi\space\tospaces{\fi}
\def\@spaces{\space\space\space\space\space}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\uptospace}
% \changes{2.3c}{1995/08/24}{Macro added}
%    This  macro extracts from its argument delimited with |\qStop|
%    part up to first occurence of space.
%    \begin{macrocode}
\def\uptospace#1 #2\qStop{#1}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\afterfi}
% \changes{2.3c}{1995/09/04}{Macro added}
%    This macro can be used in conditionals to perform some actions
%    (its  first  parameter) after the condition is completed (i.e.
%    after  reading the matching |\fi|. Second parameter is used to
%    gobble the rest of |\if ... \fi|  construction  (some  |\else|
%    maybe). Note that this won't work in nested |\if|s!
%    \begin{macrocode}
\def\afterfi#1#2\fi{\fi#1}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\@ifnextchar}
% \changes{2.3e}{1995/09/25}{Macro added}
%    This is one of \LaTeX's  macros  not  defined  by  plain.   My
%    devious   definition   differs   from  the  standard  one  but
%    functionality is the same.
%    \begin{macrocode}
\def\@ifnextchar#1#2#3{\bgroup
  \def\reserved@a{\ifx\reserved@c #1 \aftergroup\@firstoftwo
    \else \aftergroup\@secondoftwo\fi\egroup
    {#2}{#3}}%
  \futurelet\reserved@c\@ifnch
  }
\def\@ifnch{\ifx \reserved@c \@sptoken \expandafter\@xifnch
      \else \expandafter\reserved@a
      \fi}
\def\@firstoftwo#1#2{#1}
\def\@secondoftwo#1#2{#2}
\iden{\let\@sptoken= } %
\iden{\def\@xifnch} {\futurelet\reserved@c\@ifnch}
%    \end{macrocode}
% \end{macro}
%
%
% \subsection{The evaluation of boolean expressions}
% 
%    For clarity we repeat here the syntax for the boolean expressions
%    in a somewhat changed but equivalent way:
% 
% \DeleteShortVerb\|
%    \begin{tabular}{lcl}
%    \meta{Expression} & $::=$ & \meta{Secondary} $|$
%                            \meta{Secondary} \{\texttt{|}, \texttt{,}\}
%                              \meta{Expression}\\
%    \meta{Secondary}    & $::=$ & \meta{Primary} $|$
%                         \meta{Primary} \texttt{\&}
%                              \meta{Secondary}\\
%    \meta{Primary}  & $::=$ & 
%                         \meta{Terminal} $|$ \texttt{!}\meta{Primary}
%                                  $|$ 
%                         \texttt{(}\meta{Expression}\texttt{)}\\
%    \end{tabular}
% 
%    The \texttt{|} stands for disjunction, the \texttt{\&} stands for
%    conjunction and the \texttt{!}\ stands for negation. The
%    \meta{Terminal} is any sequence of letters and evaluates to
%    \meta{true} iff it occurs in the list of options that have to be
%    included.
% \MakeShortVerb\|
% 
%    Since we can generate multiple output files  from  one  input,
%    same  guard  expressions  can  be  computed several times with
%    different options. For that reason we  first  ``compile''  the
%    expression   to  the  form  of  one  parameter  macro  |\Expr|
%    expanding to nested |\if|s that when  given  current  list  of
%    options  produces  1  or  0  as  a  result. The idea is to say
%    |\if1\Expr{|\meta{current set  of  options}|}...\fi|  for  all
%    output files.
% 
%    Here is a table recursively defining  translations  for  right
%    sides  of the grammar. $\tau(X)$ denotes translation of~$X$.
%    
% \DeleteShortVerb\|
% \MakeShortVerb\"
%    \begingroup
%     \addtolength\arraycolsep{-2.1pt}
%    \begin{eqnarray*}
%    \tau(\meta{Terminal})&=&"\t@<Terminal>,#1,<Terminal>,\qStop"\\
%   \tau(!\meta{Primary})&=&"\if1"\,\tau(\meta{Primary})\,"0\else1\fi"\\
%    \tau(\mbox{\texttt{(}\meta{Expression}\texttt{)}})
%                         &=&\tau(\meta{Expression})\\
%    \tau(\mbox{\meta{Primary}\texttt{\&}\meta{Secondary}})
%                         &=&"\if0"\,\tau(\meta{Primary})\,"0\else"
%                             \,\tau(\meta{Secondary})\,"\fi"\\
%    \tau(\mbox{\meta{Secondary}\texttt{|}\meta{Expression}})
%                         &=&"\if1"\,\tau(\meta{Secondary})\,"1\else"
%                            \,\tau(\meta{Expression})\,"\fi"
%    \end{eqnarray*}
%    \endgroup
% \DeleteShortVerb\"
% \MakeShortVerb\|
%    |\t@<Terminal>|  denotes macro with name constructed from |t@|
%    with appended tokens of terminal. E.g., for terminal |foo|  the
%    translation would be
%\begin{verbatim}
%    \t@foo,#1,foo,\qStop
%\end{verbatim}
%    This will  end up in definition of |\Expr|,  so |#1| here will
%    be substituted by current list  of  options  when  |\Expr|  is
%    called. Macro |\t@foo| would be defined as
%\begin{verbatim}
%    \def\t@foo#1,foo,#2\qStop{\ifx>#2>0\else1\fi}
%\end{verbatim}
%    When  called  as  above  this  will  expand to |1| if |foo| is
%    present on current list of options and to |0| otherwise.
% 
%    Macros  below  work  in  ``almost  expand-only''   mode   i.e.
%    expression is analyzed only by expansion but we have to define
%    some macros on the way (e.g., |\Expr| and |\t@foo|).
% 
%    The   first   parameter   of   each   of   these   macros   is
%    ``continuation''   (in  the  sense  similar  to  the  language
%    \textsc{Scheme}). Continuation is a function of at  least  one
%    argument  (parameter)  being  the  value  of previous steps of
%    computation.   For   example   macro   |\Primary|   constructs
%    translation of \meta{Primary} expression. When it decides that
%    expression is completed it calls its continuation  (its  first
%    argument)   passing   to  it  whole  constructed  translation.
%    Continuation may expect more arguments if it wants to see what
%    comes next on the input.
% 
%    We  will perform recursive descent parse, but definitions will
%    be presented in bottom-up order.
% 
% \begin{macro}{\Terminal}
% 
%    \meta{Terminal}s are  recognized  by  macro  |\Terminal|.  The
%    proper   way   of   calling  it  is  |\Terminal{|\meta{current
%    continuation}|}{}|.     Parameters     are:      continuation,
%    \meta{Terminal}  so  far  and  next  character from the input.
%    Macro checks if |#3| is one of terminal-ending characters  and
%    then  takes  appropriate  actions.  Since  there  are 7 ending
%    chars  and probably one |\csname| costs  less  than  7  nested
%    |\if|s we construct a name and check if it is defined.
% 
%    We must expand |\ifx| completely before taking next actions so
%    we use |\afterfi|.
%    \begin{macrocode}
\def\Terminal#1#2#3{%
  \expandafter\ifx\csname eT@#3\endcsname\relax
%    \end{macrocode}
%    If condition is true |#3| belongs to  current  \meta{Terminal}
%    so we append it to \meta{Terminal}-so-far and call |\Terminal|
%    again. 
%    \begin{macrocode}
    \afterfi{\Terminal{#1}{#2#3}}\else
%    \end{macrocode}
%    When condition is false it's time to end  the  \meta{Terminal}
%    so we call macro |\TerminalX|. Next character is reinserted to
%    the input.
% 
%    In both cases continuation is passed unchanged.
%    \begin{macrocode}
    \afterfi{\TerminalX{#1}{#2}#3}\fi
  }
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\eT@}
%    Here we define macros marking characters  that  cannot  appear
%    inside  terminal.  The value is not important as long as it is
%    different from |\relax|.
%    \begin{macrocode}
\Name\let{eT@>}=1
\Name\let{eT@&}=1 \Name\let{eT@!}=1
\Name\let{eT@|}=1 \Name\let{eT@,}=1
\Name\let{eT@(}=1 \Name\let{eT@)}=1
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\TerminalX}
%    This macro should end scanning of \meta{Terminal}.  Parameters
%    are continuation and gathered tokens of \meta{Terminal}.
% 
%    Macro starts by issuing an error message if \meta{Terminal} is
%    empty.
%    \begin{macrocode}
\def\TerminalX#1#2{%
  \ifx>#2> \errmessage{Error in expression: empty terminal}\fi
%    \end{macrocode}
%    Then  a  macro  is  constructed  for  checking   presence   of
%    \meta{Terminal} in options list.
%    \begin{macrocode}
  \Name\def{t@#2}##1,#2,##2\qStop{\ifx>##2>0\else1\fi}%
%    \end{macrocode}
%    And  then  current  continuation is called with translation of
%    \meta{Terminal} according to formula
%    $$\tau(\meta{Terminal})=|\t@<Terminal>,#1,<Terminal>,\qStop|$$
%    \begin{macrocode}
  #1{\Name\noexpand{t@#2},##1,#2,\noexpand\qStop}%
  }
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\Primary}
%    Parameters are continuation and next character from the input.
%    
%    According to the syntax \meta{Primari}es can have three forms.
%    This  makes us use even more dirty tricks than usual. Note the
%    |\space| after a series of |\ifx|s. This  series  produces  an
%    one  digit  number of case to be executed. The number is given
%    to  |\ifcase|  and  |\space|  stops  \TeX{}  scanning  for   a
%    \meta{number}.  Use of |\ifcase| gives possibility to have one
%    of three actions  selected  without  placing  them  in  nested
%    |\if|s and so to use |\afterfi|.
%    \begin{macrocode}
\def\Primary#1#2{%
  \ifcase \ifx!#20\else\ifx(#21\else2\fi\fi\space 
%    \end{macrocode}
%    First case is for |!| i.e.  negated \meta{Primary}.   In  this
%    case   we  call  |\Primary|  recursively  but  we  create  new
%    continuation:   macro  |\NPrimary|  that  will  negate  result
%    passed  by  |\Primary|  and  pass  it  to current continuation
%    (|#1|).
%    \begin{macrocode}
  \afterfi{\Primary{\NPrimary{#1}}}\or
%    \end{macrocode}
%    When next character is |(| we call |\Expression| giving it  as
%    continuation  macro  |\PExpression|  which  will just pass the
%    result up but ensuring first that a |)| comes next.
%    \begin{macrocode}
  \afterfi{\Expression{\PExpression{#1}}}\or
%    \end{macrocode}
%    Otherwise we start a \meta{Terminal}. |#2| is  not  passed  as
%    \meta{Terminal}-so-far  but reinserted to input since we didn't
%    check if it can appear in a \meta{Terminal}.
%    \begin{macrocode}
  \afterfi{\Terminal{#1}{}#2}\fi
  }
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\NPrimary}
%    Parameters    are   continuation   and   previously   computed
%    \meta{Primary}.
%    
%    This macro negates result of previous  computations  according
%    to the rule
%    $$\tau(!\meta{Primary})
%         =|\if1|\,\tau(\meta{Primary})\,|0\else1\fi|$$
%    \begin{macrocode}
\def\NPrimary#1#2{%
  #1{\noexpand\if1#20\noexpand\else1\noexpand\fi}%
  }
%    \end{macrocode}   
% \end{macro}
% 
% \begin{macro}{\PExpression}
%    Parameters: continuation,  \meta{Expression},  next  character
%    from  input. We are checking if character is |)| and then pass
%    unchanged result to our continuation.
%    \begin{macrocode}
\def\PExpression#1#2#3{% 
  \ifx)#3\else
    \errmessage{Error in expression: expected right parenthesis}\fi
  #1{#2}}
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\Secondary}
%    Each \meta{Secondary} expression starts  with  \meta{Primary}.
%    Next checks will be performed by |\SecondaryX|.
%    \begin{macrocode}
\def\Secondary#1{%
  \Primary{\SecondaryX{#1}}}
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\SecondaryX}
%    Parameters:  continuation, translation of \meta{Primary}, next
%    character. We start by checking if next character is |&|.
%    \begin{macrocode}
\bgroup\catcode`\&=12
\gdef\SecondaryX#1#2#3{%
  \ifx&#3%
%    \end{macrocode}
%    If it is  we  should  parse  next  \meta{Secondary}  and  then
%    combine  it with results so far. Note that |\SecondaryXX| will
%    have 3 parameters.
%    \begin{macrocode}
  \afterfi{\Secondary{\SecondaryXX{#1}{#2}}}\else
%    \end{macrocode}
%    Otherwise   \meta{Secondary}   turned   out   to    be    just
%    \meta{Primary}. We call continuation passing to it translation
%    of that \meta{Primary} not forgetting to reinsert |#3| to  the
%    input as it does not belong here.
%    \begin{macrocode}
  \afterfi{#1{#2}#3}\fi
  }
\egroup
%    \end{macrocode}   
% \end{macro}
% 
% \begin{macro}{\SecondaryXX}
%    Parameters:   continuation,   translation  of  \meta{Primary},
%    translation of \meta{Secondary}. We construct  translation  of
%    whole construction according to the rule:
%    $$\tau(\mbox{\meta{Primary}\texttt{\&}\meta{Secondary}})
%                         =|\if0|\,\tau(\meta{Primary})\,|0\else|
%                             \,\tau(\meta{Secondary})\,|\fi| $$
%    and pass it to our continuation.
%    \begin{macrocode}
\def\SecondaryXX#1#2#3{%
  #1{\noexpand\if0#20\noexpand\else#3\noexpand\fi}}
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\Expression}
%    Every   \meta{Expression}  starts  with  \meta{Secondary}.  We
%    construct new continuation and pass it to |\Secondary|.
%    \begin{macrocode}
\def\Expression#1{%
  \Secondary{\ExpressionX{#1}}}
%    \end{macrocode}   
% \end{macro}
% 
% \begin{macro}{\ExpressionX}
%    Parameters:  continuation,  translation  of  \meta{Secondary},
%    next   character.   We   perform   check   if   character   is
%    \texttt{\char`\|} or |,|.
%    \begin{macrocode}
\def\ExpressionX#1#2#3{%
  \if0\ifx|#31\else\ifx,#31\fi\fi0
%    \end{macrocode}
%    If it is not \meta{Expression} is just a \meta{Secondary}.  We
%    pass its translation to continuation and reinsert |#3|.
%    \begin{macrocode}
  \afterfi{#1{#2}#3}\else
%    \end{macrocode}
%    If  we  are  dealing  with complex \meta{Expression} we should
%    parse another |\Expression| now.
%    \begin{macrocode}
  \afterfi{\Expression{\ExpressionXX{#1}{#2}}}\fi
  }
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\ExpressionXX}
%    Parameters:  continuation,  translation  of  \meta{Secondary},
%    translation of \meta{Expression}.
%    We finish up translating  of  \meta{Expression}  according  to   
%    the formula:
%    $$\tau(\mbox{\meta{Secondary}\texttt{\char`\|}\meta{Expression}})
%                         =|\if1|\,\tau(\meta{Secondary})\,|1\else|
%                            \,\tau(\meta{Expression})\,|\fi|$$
%    \begin{macrocode}
\def\ExpressionXX#1#2#3{%
  #1{\noexpand\if1#21\noexpand\else#3\noexpand\fi}}
%    \end{macrocode}   
% \end{macro}
% 
% \begin{macro}{\StopParse}
%    Here is initial continuation for whole parse process. It  will
%    be  used  by  |\Evaluate|. Note that we assume that expression
%    has |>| on its end.  This macro  eventually  defines  |\Expr|.
%    Parameters:   translation  of whole \meta{Expression} and next
%    character from input.
%    \begin{macrocode}
\def\StopParse#1#2{%
  \ifx>#2 \else\errmessage{Error in expression: spurious #2}\fi
  \edef\Expr##1{#1}}
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\Evaluate}   
%    This macro is used to start  parsing.  We  call  |\Expression|
%    with  continuation  defined  above.   On  end of expression we
%    append a |>|.
%    \begin{macrocode}
\def\Evaluate#1{%
  \Expression\StopParse#1>}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Processing the input lines}
%
% \begin{macro}{\normalLine}
%    The macro |\normalLine| writes its argument (which has to be
%    delimited with |\endLine|) on all active output files i.e.
%    those with off-counters equal to zero.
%    If statistics are included, the counter
%    |\codeLinesPassed| is incremented by $1$.
%    \begin{macrocode}
\def\normalLine#1\endLine{%
%<*stats>
  \advance\codeLinesPassed\@ne
%</stats>
  \maybeMsg{.}%
  \def\inLine{#1}%
  \let\do\putline@do
  \activefiles
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\putline@do}
% \changes{2.3b}{1995/08/22}{Change for pre-constructed
%                            off-counters' names}
%    This is a value for |\do| when copying line to output files.
%    \begin{macrocode}
\def\putline@do#1#2#3{%
  \StreamPut#1{\inLine}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\removeComment}
%    The macro |\removeComment| throws its argument (which has to be
%    delimited with |\endLine|) away. When statistics are included
%    in the program the removed comment is counted.
%    \begin{macrocode}
%
\def\removeComment#1\endLine{%
%<*stats>
    \advance\commentsRemoved\@ne
%</stats>
    \maybeMsg{\perCent}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\putMetaComment}
% \changes{2.3e}{1996/09/16}{Introduced \cs{MetaPrefix}}
%    If a line starts with two consecutive percent signs, it is
%    considered to be a {\em MetaComment\/}. Such a comment line is
%    passed on to the output file unmodified.
%    \begin{macrocode}
\bgroup\catcode`\%=12
\iden{\egroup
\def\putMetaComment%}#1\endLine{%
%    \end{macrocode}
%    If statistics are included the line is counted.
%    \begin{macrocode}
%<*stats>
  \advance\commentsPassed\@ne
%</stats>
%    \end{macrocode}
%    The macro |\putMetaComment| has one argument, delimited with
%    |\endLine|. It brings the source line with |%%| stripped. We
%    prepend to it |\MetaPrefix| (which can be different from |%%|)
%    and send the line to all active files. 
%    \begin{macrocode}
  \edef\inLine{\MetaPrefix#1}%
  \let\do\putline@do
  \activefiles
  }
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\processLine}
% \changes{2.3a}{1995/08/18}{Adaptation for concurrent version}
% \changes{2.3a}{1995/08/20}{Trying to avoid assignments}
%    Each line that is read from the input stream has to be processed
%    to see if it has to be written on the output stream. This task
%    is performed by calling the macro |\processLine|.
%    In order to do
%    that, it needs to check whether the line starts with a
%    `\texttt{\%}'.  Therefore the macro is globally defined within a
%    group. Within this group the category code of `\texttt{\%}' is
%    changed to 12 (other).  Because a comment character is needed,
%    the category code of `\texttt{*}' is changed to 14 (comment
%    character).
%
%    The macro increments counter |\processedLines| by $1$ if
%    statistics are included. We cannot include this line with
%    |%<*stats>| since the category of \texttt{\%} is changed and the
%    file must be loadable unstripped. So the whole definition is
%    repeated embedded in guards.
%
%    The next token from the input stream is passed in |#1|. If it is
%    a `\texttt{\%}' further processing has to be done by
%    |\processLineX|; otherwise this is normal (not commented out)
%    line.
%    
%    In either case the character read is reinserted to the input
%    as it may have to be written out.
%
%    \begin{macrocode}
%<*!stats>
\begingroup
\catcode`\%=12 \catcode`\*=14
\gdef\processLine#1{*
  \ifx%#1
    \expandafter\processLineX
  \else
    \expandafter\normalLine
  \fi
  #1}
\endgroup
%</!stats>
%<*stats>
\begingroup
\catcode`\%=12 \catcode`\*=14
\gdef\processLine#1{*
  \advance\processedLines\@ne
  \ifx%#1
    \expandafter\processLineX
  \else
    \expandafter\normalLine
  \fi
  #1}
\endgroup
%</stats>
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\processLineX}
% \changes{2.3a}{1995/08/20}{Trying to avoid assignments}
%    This macro is also defined within a group, 
%    because it also has to check if the next
%    token in the input stream is a `\texttt{\%}' character.
%
%    If the second token in the current line happens to be a
%    `\texttt{\%}', a \meta{MetaComment} has been found. This has to
%    be copied in its entirety to the output.  Another possible second
%    character is `\texttt{<}', which introduces a guard expression.
%    The processing of such an expression is started by calling
%    |\checkOption|.
%
%    When the token was neither a `\texttt{\%}' nor a `\texttt{<}',
%    the line contains a normal comment that has to be removed.
%
%    We express conditions in such a way that all actions appear
%    on first nesting level of |\if|s. In such conditions just one
%    expandafter pushes us outside whole construction. A thing to
%    watch here is |\relax|. It stops search for numeric constant.
%    If it wasn't here \TeX\ would expand the first case of |\ifcase|
%    before knowing the value.
%
%    \begin{macrocode}
\begingroup
\catcode`\%=12 \catcode`\*=14
\gdef\processLineX%#1{*
  \ifcase\ifx%#10\else
         \ifx<#11\else 2\fi\fi\relax
    \expandafter\putMetaComment\or
    \expandafter\checkOption\or
    \expandafter\removeComment\fi
  #1}
\endgroup
%    \end{macrocode}
% \end{macro}
%
% \subsection{The handling of options}
%
% \begin{macro}{\checkOption}
%    \changes{2.3a}{1995/08/18}{Adapted to concurrent version}
%  \changes{2.3a}{1995/08/20}{Trying to avoid assignments}
%  \changes{2.3e}{1996/09/16}{Verbatim mode}
%    When the macros that process a line have found that the line
%    starts with `\texttt{\%<}', a guard line has been encountered.
%    The first character of a guard can be an asterisk (\texttt{*}), a
%    slash (\texttt{/}) a plus (\texttt{+}), a minus (\texttt{-}), a
%    less-than sign (\texttt{<}) starting verbatim mode or
%    any other character that can be found in an option name. This
%    means that we have to peek at the next token and 
%    decide what kind of guard we have. 
%    
%    We reinsert |#1| as it may be needed by |\doOption|.
%    \begin{macrocode}
\def\checkOption<#1{%
  \ifcase
    \ifx*#10\else \ifx/#11\else
    \ifx+#12\else \ifx-#13\else
    \ifx<#14\else 5\fi\fi\fi\fi\fi\relax
  \expandafter\starOption\or
  \expandafter\slashOption\or
  \expandafter\plusOption\or
  \expandafter\minusOption\or
  \expandafter\verbOption\or
  \expandafter\doOption\fi
  #1}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\doOption}
%    When no guard modifier is found by |\checkOptions|, the
%    macro |\doOption| is called. It evaluates a boolean
%    expression. The result of this evaluation is stored in 
%    |\Expr|. The guard only affects the current
%    line,  so  |\do|  is  defined in such a way that depending on the
%    result of the  test |\if1\Expr{|\meta{options}|}|,  the  current
%    line is either copied to the output stream or removed. Then
%    the test is computed for all active output files.
%    \begin{macrocode}
\def\doOption#1>#2\endLine{%
  \maybeMsg{<#1 . >}%
  \Evaluate{#1}%
  \def\do##1##2##3{%
    \if1\Expr{##2}\StreamPut##1{#2}\fi
    }%
  \activefiles
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\plusOption}
%    When a `\texttt{+}' is found as a guard modifier,
%    |\plusOption| is called. This macro is very similar to
%    |\doOption|, the only difference being that displayed
%    message now contains `\texttt{+}'.
%    \begin{macrocode}
\def\plusOption+#1>#2\endLine{%
  \maybeMsg{<+#1 . >}%
  \Evaluate{#1}%
  \def\do##1##2##3{%
    \if1\Expr{##2}\StreamPut##1{#2}\fi
    }%
  \activefiles
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\minusOption}
%    When a `\texttt{-}' is found as a guard modifier,
%    |\minusOption| is called. This macro is very similar to
%    |\plusOption|, the difference is that condition is negated.
%    \begin{macrocode}
\def\minusOption-#1>#2\endLine{%
  \maybeMsg{<-#1 . >}%
  \Evaluate{#1}%
  \def\do##1##2##3{%
    \if1\Expr{##2}\else \StreamPut##1{#2}\fi
    }%
  \activefiles
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\starOption}
%    \changes{2.3a}{1995/08/18}{Adapted to concurrent version}
%    When a `\texttt{*}' is found as a guard modifier,
%    |\starOption| is called. In this case a block of code will
%    be included in the output on the condition that the guard
%    expression evaluates to \meta{true}.
%
%    The current line is gobbled as |#2|, because it only contains
%    the guard and possibly a comment.
%
%    \begin{macrocode}
\def\starOption*#1>#2\endLine{%
%    \end{macrocode}
%    First we optionally write
%    a message to the terminal to indicate that a new option starts
%    here.
%    \begin{macrocode}
  \maybeMsg{<*#1}%
%    \end{macrocode}
%    Then we push the current contents of |\blockHead| on the
%    stack of blocks, |\guardStack| and increment  the counter
%    |\blockLevel| to indicate that we are now one level of
%    nesting deeper.
% \changes{2.0k}{1992/04/06}{Use new stack mechanism}
% \changes{2.0k}{1992/04/09}{The macro that holds the guard needs to be
%    expanded}
%    \begin{macrocode}
  \expandafter\push\expandafter\guardStack\expandafter{\blockHead}%
  \advance\blockLevel\@ne
%    \end{macrocode}
%    The guard for this block of code is now stored in
%    |\blockHead|.
%    \begin{macrocode}
  \def\blockHead{#1}%
%    \end{macrocode}
%    Now we evaluate guard expression for all output files 
%    updating off-counters. Then we create new list of active
%    output files. Only files that were active in the outer block
%    can remain active now.
%    \begin{macrocode}
  \Evaluate{#1}%
  \let\do\checkguard@do
  \outputfiles
  \let\do\findactive@do
  \edef\activefiles{\activefiles}
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\checkguard@do}
% \changes{2.3b}{1995/08/22}{Change for pre-constructed
%                            off-counters' names}
%    This form of |\do| updates off-counts according to the value of
%    guard expression.
%    \begin{macrocode}
\def\checkguard@do#1#2#3{%
%    \end{macrocode}
%    If this block of code occurs inside another block of code that is
%    {\em not\/} included in the output, we increment the off counter.
%    In that case the guard expression will not be
%    evaluated, because a block inside another block that is excluded
%    from the output will also be excluded, regardless of the
%    evaluation of its guard.
%    \begin{macrocode}
  \ifnum#3>0
    \advance#3\@ne
%    \end{macrocode}
%    When the off count has  value 0, we have
%    to evaluate the guard expression. If the result is \meta{false}
%    we increase the off-counter.
%    \begin{macrocode}
  \else
    \if1\Expr{#2}\else
      \advance#3\@ne\fi
  \fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\findactive@do}
% \changes{2.3b}{1995/08/22}{Change for pre-constructed
%                            off-counters' names}
%    This form of |\do| picks elements of output files list which
%    have off-counters equal to zero.
%    \begin{macrocode}
\def\findactive@do#1#2#3{%
  \ifnum#3=0
    \noexpand\do#1{#2}#3\fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\slashOption}
%    \changes{2.3a}{1995/08/18}{Adapted for concurrent version}
%    The macro |\slashOption| is the counterpart to
%    |\starOption|.  It indicates the end of a block of
%    conditionally included code.  We store the argument in the
%    temporary control sequence |\tmp|.
%    \begin{macrocode}
\def\slashOption/#1>#2\endLine{%
  \def\tmp{#1}%
%    \end{macrocode}
%    When the counter |\blockLevel| has a value less than $1$,
%    this `end-of-block' line has no corresponding `start-of-block'.
%    Therefore we signal an error and ignore this end of block.
%    \begin{macrocode}
  \ifnum\blockLevel<\@ne
    \errmessage{Spurious end block </\tmp> ignored}%
%    \end{macrocode}
%    Next we compare the contents of |\tmp| with the contents
%    of |\blockHead|. The latter macro contains the last guard for
%    a block of code that was encountered. If the contents match, we
%    pop the previous guard from the stack.
%    \changes{2.0k}{1992/04/06}{Use new stack mechanism}
%    \begin{macrocode}
  \else
    \ifx\tmp\blockHead
      \pop\guardStack\blockHead
%    \end{macrocode}
%    When the contents of the two macros don't match something is
%    amiss. We signal this to the user, but accept the `end-of-block'.
%\note{Is this the desired behaviour??}
%    \begin{macrocode}
    \else
      \errmessage{Found </\tmp> instead of </\blockHead>}%
    \fi
%    \end{macrocode}
%    When the end of a block of optionally included code is encountered
%    we optionally signal this on the terminal and decrement the counter
%    |\blockLevel|.
%    \begin{macrocode}
    \maybeMsg{>}%
    \advance\blockLevel\m@ne
%    \end{macrocode}
%    The last thing that has to be done is to decrement off-counters and
%    make new list of active files. Now whole list of output files has
%    to be searched since some inactive files could have been
%    reactivated.
%    \begin{macrocode}
  \let\do\closeguard@do
  \outputfiles
  \let\do\findactive@do
  \edef\activefiles{\outputfiles}
  \fi
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\closeguard@do}
% \changes{2.3b}{1995/08/22}{Change for pre-constructed
%                            off-counters' names}
%    This macro decrements non-zero off-counters.
%    \begin{macrocode}
\def\closeguard@do#1#2#3{%
  \ifnum#3>0
    \advance#3\m@ne
  \fi}
%    \end{macrocode}
% \end{macro}
%
%
%  \begin{macro}{\verbOption}
%  \changes{2.3e}{1996/09/16}{Macro added}
%  \changes{2.4g}{1996/12/13}{Reset \cs{putline@do} for /2340}
%    This macro is called when a line starts with |%<<|. It reads a
%    bunch of lines in verbatim mode: the lines are passed unchanged
%    to the output without even checking for starting |%|. This way of
%    processing ends when a line containing only a percent sign
%    followed by stop mark given on the |%<<| line is found.
%    \begin{macrocode}
\def\verbOption<#1\endLine{{%
  \edef\verbStop{\perCent#1}\maybeMsg{<<<}%
  \let\do\putline@do
  \loop
    \ifeof\inFile\errmessage{Source file ended while in verbatim
                             mode!}\fi
    \read\inFile to \inLine
  \if 1\ifx\inLine\verbStop 0\fi 1% if not inLine==verbStop
    \activefiles
    \maybeMsg{.}%
  \repeat
  \maybeMsg{>}%
  }}
%    \end{macrocode}
%  \end{macro}
%
% \subsection{Batchfile commands}
% \changes{2.3e}{1996/10/02}{Added doc}
%    \ds{} keeps information needed to control inclusion of sources in
%    several list structures. Lists are macros expanding to a series
%    of calls to macro |\do| with two or three parameters. 
%    Subsequently |\do| is redefined in various ways and list
%    macros sometimes are executed to perform some action on every
%    element, and sometimes are used inside an |\edef| to make new
%    list of elements having some properties. For every input file
%    \meta{infile} the following lists are kept:
%    \begin{itemize}
%    \item[\cs{b@}\meta{infile}] the ``open list''---names of all output
%               files such that their generation should start with
%               reading of \meta{infile},
%    \item[\cs{o@}\meta{infile}] the ``output list''---names of all
%               output files generated from that source together with
%               suitable sets of options (guards),
%    \item[\cs{e@}\meta{infile}] the ``close list''---names of all
%               output files that should be closed when this source is
%               read.
%    \end{itemize}
%
%    For every output file name \meta{outfile} \ds{} keeps following
%    information: 
%    \begin{itemize}
%    \item[\cs{pth@}\meta{outfile}] full pathname (including file name),
%    \item[\cs{ref@}\meta{outfile}] reference lines for the file,
%    \item[\cs{in@}\meta{outfile}] names of all source files separated
%               with spaces (needed by \cs{InFileName}),
%    \item[\cs{pre@}\meta{outfile}] preamble template (as defined with
%               |\declarepreamble|),
%    \item[\cs{post@}\meta{outfile}] postamble template. 
%    \end{itemize}
%
% \begin{macro}{\generate}
% \changes{2.3a}{1995/08/20}{Messages changed}
% \changes{2.4a}{1996/06/06}{Repeat processing of files until all
%                           done (MDW)}
%    This macro executes its argument in a group. |\inputfiles| is
%    a list of files to be read, |\filestogenerate| list of names
%    of output files (needed for the message below). |\file|s
%    contained in |#1| define |\inputfiles| in such a way that all
%    that has to be done when the parameter is executed is to call
%    this macro. |\inputfiles| command is called over and over again
%    until no output files had to be postponed.
%    \begin{macrocode}
\def\generate#1{\begingroup
  \let\inputfiles\empty \let\filestogenerate\empty
  \let\file\@file
  #1
  \ifx\filestogenerate\empty\else
  \Msg{^^JGenerating file(s) \filestogenerate}\fi
  \def\inFileName{\csname in@\outFileName\endcsname}%
  \def\ReferenceLines{\csname ref@\outFileName\endcsname}%
  \processinputfiles
  \endgroup}
%    \end{macrocode}
% \end{macro}
%
%  \begin{macro}{\processinputfiles}
% \changes{2.4a}{1996/10/02}{Macro added (MW)}
%    This is a recurrent function which processes input files until
%    they are all gone.
%    \begin{macrocode}
\def\processinputfiles{%
  \let\newinputfiles\empty
  \inputfiles
  \let\inputfiles\newinputfiles
  \ifx\inputfiles\empty\else
    \expandafter\processinputfiles
  \fi
  }
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\file}
%    The first argument is the file to produce, the second
%    argument contains the list of input files. Each entry should have
%    the format
%    \verb=\from{=\meta{filename.ext}\verb=}{=\meta{options}\verb=}=.
%
% \changes{2.3a}{1995/08/20}{Messages changed}
% ^^A   The macro starts by displaying a message on the terminal to
% ^^A   indicate which file is going to be made.
%    The switch |\ifGenerate| is initially set to \meta{true}.
%    \begin{macrocode}
\def\file#1#2{\errmessage{Command `\string\file' only allowed in
                          argument to `\string\generate'}}
\def\@file#1{%
  \Generatetrue
%    \end{macrocode}
%    Next we construct full path name for output file and check if we
%    have to be careful about overwriting existing files. If the user
%    specified |\askforoverwritetrue| we will ask him if he wants to
%    overwrite an existing file. Otherwise we simply go ahead.
%    \begin{macrocode}
  \makepathname{#1}%
  \ifaskforoverwrite
%    \end{macrocode}
%    We try to open a file with the name of the output file for
%    reading.  If this succeeds the file exists and we ask the user if
%    he wants to overwrite the file.
% \changes{2.0p}{1992/06/26}{Added \cs{WriteToDir} (FMi).}
% \changes{2.3a}{1995/08/18}{Changed \cs{@empty} (which was undefined)
%                            to \cs{empty}}
% \changes{2.3e}{1995/09/25}{Changed \cs{WriteToDir} to \cs{destdir}}
%    \begin{macrocode}
    \immediate\openin\inFile\@pathname\relax
    \ifeof\inFile\else
      \Ask\answer{File \@pathname\space already exists 
                  \ifx\empty\destdir somewhere \fi
                  on the system.^^J% 
                  Overwrite it%
                  \ifx\empty\destdir\space if necessary\fi
                  ? [y/n]}%
%    \end{macrocode}
%    We set the switch |\ifGenerate| according to his answer. We
%    allow for both ``\texttt{y}'' and ``\texttt{yes}''.
%    \begin{macrocode}
      \ifx\y  \answer \else
      \ifx\yes\answer \else
                      \Generatefalse\fi\fi\fi
%    \end{macrocode}
%    Don't forget to close the file just opened as we want to write
%    to it.
%    \begin{macrocode}
    \closein\inFile
  \fi
%    \end{macrocode}
% \changes{2.3e}{1995/09/25}{Destination directory handling}
%   If file is to be generated we save its destination pathname  and
%   pass control to macro |\@fileX|.
%   Note that file name is turned into control sequence and |\else|
%   branch is skipped before calling |\@fileX|.
%    \begin{macrocode}
  \ifGenerate
  \Name\let{pth@#1}\@pathname
  \@addto\filestogenerate{\@pathname\space}%
  \Name\@fileX{#1\expandafter}%
  \else
%    \end{macrocode}
%    In case we were not allowed to overwrite an existing file
%    we inform the user that we are {\em not\/} generating his file
%    and we gobble |\from| specifications.
%    \begin{macrocode}
    \Msg{Not generating file \@pathname^^J}%
  \expandafter\@gobble
  \fi
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@fileX}
%    We put name of current output file in |\curout| and initialize
%    |\curinfiles|  (the list of source files for this output file)
%    to empty---these will be needed  by  |\from|.  Then  we  start
%    defining preamble for the current file.
%    \begin{macrocode}
\def\@fileX#1#2{%
  \chardef#1=\stream@closed
  \def\curout{#1}%
  \let\curinfiles\empty
  \let\curinnames\empty
  \def\curref{\MetaPrefix ^^J%
              \MetaPrefix\space The original source files were:^^J%
              \MetaPrefix ^^J}%
%    \end{macrocode}
%    Next we execute second parameter. |\from|s will add reference
%    lines to the preamble.
%    \begin{macrocode}
  \let\from\@from \let\needed\@needed
  #2%
  \let\from\err@from \let\needed\err@needed
%    \end{macrocode}
%    We check order of input files.  
%    \begin{macrocode}
  \checkorder
%    \end{macrocode}
%    Each |\from| clause defines |\curin| to be its first parameter.
%    So now |\curin| holds name of last input file for current output
%    file. This means that current output file should be closed after
%    processing |\curin|. We add |#1| to proper `close list'.
%    \begin{macrocode}
  \Name\@addto{e@\curin}{\noexpand\closeoutput{#1}}%
%    \end{macrocode}
%    Last we save all the interesting information about current file.
%    \begin{macrocode}
  \Name\let{pre@\@stripstring#1\expandafter}\currentpreamble
  \Name\let{post@\@stripstring#1\expandafter}\currentpostamble
  \Name\edef{in@\@stripstring#1}{\expandafter\iden\curinnames}
  \Name\edef{ref@\@stripstring#1}{\curref}
  }
%    \end{macrocode}
% \end{macro}
%
%  \begin{macro}{\checkorder}
%    This macro checks  if  the order  of  files  in  |\curinfiles|
%    agrees  with that of |\inputfiles|. The coding is somewhat
%    clumsy.
%    \begin{macrocode}
\def\checkorder{%
  \expandafter\expandafter\expandafter
  \checkorderX\expandafter\curinfiles
  \expandafter\qStop\inputfiles\qStop
  }
\def\checkorderX(#1)#2\qStop#3\qStop{%
  \def\tmp##1\readsource(#1)##2\qStop{%
    \ifx!##2! \order@error
    \else\ifx!#2!\else 
       \checkorderXX##2%
    \fi\fi}%
  \def\checkorderXX##1\readsource(#1)\fi\fi{\fi\fi
    \checkorderX#2\qStop##1\qStop}%
  \tmp#3\readsource(#1)\qStop
  }
\def\order@error#1\fi\fi{\fi
  \errmessage{DOCSTRIP error: Incompatible order of input
              files specified for file
              `\iden{\expandafter\uptospace\curin} \qStop'.^^J
              Read DOCSTRIP documentation for explanation.^^J
              This is a serious problem, I'm exiting}\end
  }
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\needed}
% \changes{2.3c}{1995/08/24}{Macro added}     
% \changes{2.3e}{1996/09/12}{Forced expansion of argument to fix a bug
%                with filenames containing macros}
% \begin{macro}{\@needed}
%    This  macro  uniquizes  name  of  an  input  file  passed as a
%    parameter and marks it as needed to  be  input.  It  is  used
%    internally  by  |\from|, but can also be issued in argument to
%    |\file| to influence the order in which files are read.
%    \begin{macrocode}
\def\needed#1{\errmessage{\string\needed\space can only be used in
               argument to \string\file}}
\let\err@needed\needed
\def\@needed#1{%
  \edef\reserved@a{#1}%
  \expandafter\@need@d\expandafter{\reserved@a}}
\def\@need@d#1{%
  \@ifpresent{(#1)}\curinfiles
%    \end{macrocode}
%    If  |#1|  is present on list of input files for current output
%    file we add a space on end of its name and try again. The idea
%    is  to construct a name that will look different for \TeX\ but
%    will lead to the same file when seen by operating system.
%    \begin{macrocode}
    {\@need@d{#1 }}%
%    \end{macrocode}
%    When it is not we check if |#1| is  present  in  the  list  of
%    files to be processed. If not we add it and initialize list of
%    output files for that input and  list  of  output  files  that
%    should   be  closed  when  this  file  closes.   We  also  add
%    constructed name to |\curinfiles| and define  |\curin|  to  be
%    able to access constructed name from |\@from|.
%    \begin{macrocode}
    {\@ifpresent{\readsource(#1)}\inputfiles
       {}{\@addto\inputfiles{\noexpand\readsource(#1)}%
       \Name\let{b@#1}\empty
       \Name\let{o@#1}\empty
       \Name\let{e@#1}\empty}%
     \@addto\curinfiles{(#1)}%
     \def\curin{#1}}%
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\from}
% \changes{2.3c}{1995/08/24}{part of code moved to \cs{needed}}     
%    |\from| starts by adding a line to  preamble for output file.
%    \begin{macrocode}
\def\from#1#2{\errmessage{Command `\string\from' only allowed in
                          argument to `\string\file'}}
\let\err@from\from
\def\@from#1#2{%
  \@addto\curref{\MetaPrefix\space #1 \if>#2>\else
                              \space (with options: `#2')\fi^^J}%
%    \end{macrocode}
%    Then we mark the file as needed input file.
%    \begin{macrocode}
  \needed{#1}%
%    \end{macrocode}
% \changes{2.3e}{1996/10/02}{Introduced ``open list''}
%    If this is the first |\from| in current |\file| (i.e. if the
%    |\curinnames| so far is empty) the file name is added to the
%    ``open list'' for the current input file.
%    And |\do|\meta{current output}|{|\meta{options}|}| is appended
%    to the list of output files for current input file.
%    \begin{macrocode}
  \ifx\curinnames\empty
     \Name\@addto{b@\curin}{\noexpand\openoutput\curout}%
  \fi
  \@addto\curinnames{ #1}%
  \Name\@addto{o@\curin}{\noexpand\do\curout{#2}}%
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\readsource}
% \changes{2.4a}{1996/06/06}{Extensively hacked to honour stream
%                            limits (MDW)}
% \changes{2.3a}{1995/08/18}{Renamed to \cs{readsource}; adaptation for
%                            concurrent version}
% \changes{2.0f}{1991/06/04}{Added check for lines with \texttt{\bsl
%    endinput}} This macro is called for each input file that
%    is to be processed.
%
%    \begin{macrocode}
\def\readsource(#1){%
%    \end{macrocode}
%    We try to open the input file. If this doesn't succeed, we
%    tell the user so and nothing else happens.
%    \begin{macrocode}
  \immediate\openin\inFile\uptospace#1 \qStop\relax
  \ifeof\inFile
    \errmessage{Cannot find file \uptospace#1 \qStop}%
  \else
%    \end{macrocode}
%    If statistics are included we nullify line counters
%    \begin{macrocode}
%<*stats>
    \processedLines\z@
    \commentsRemoved\z@
    \commentsPassed\z@
    \codeLinesPassed\z@
%</stats>
%    \end{macrocode}
% \changes{2.3b}{1995/08/22}{Change for pre-constructed
%                            off-counters' names}
% \changes{2.3e}{1996/10/02}{Introduced ``open list''}
%    When the input file was successfully opened, we try to open all
%    needed output files by executing the ``open list''. 
%    If any of files couldn't be opened because of number of streams
%    limits, their names are put into |\refusedfiles| list. This list
%    subsequently becomes the open list for the next pass.
%    \begin{macrocode}
    \let\refusedfiles\empty
    \csname b@#1\endcsname
    \Name\let{b@#1}\refusedfiles
%    \end{macrocode}
%    Now all output files that could be opened are open. So we go
%    through the ``output list'' and for every open file we display a
%    message and zero the off-counter, while closed files are appended
%    to |\refusedfiles|. 
%    \begin{macrocode}
    \Msg{} \def\@msg{Processing file \uptospace#1 \qStop}
    \def\change@msg{%
      \edef\@msg{\@spaces\@spaces\@spaces\space
        \expandafter\tospaces\uptospace#1 \qStop\secapsot}
      \let\change@msg\relax}
    \let\do\showfiles@do
    \let\refusedfiles\empty
    \csname o@#1\endcsname
%    \end{macrocode}
%    If |\refusedfiles| is nonempty current source file needs reread,
%    so we append it to |\newinputfiles|.
%    \begin{macrocode}
    \ifx\refusedfiles\empty\else
      \@addto\newinputfiles{\noexpand\readsource(#1)}
    \fi
%    \end{macrocode}
%    Finally we define |\outputfiles| and construct off-counters
%    names. Now |\do|s will have 3 parameters! All output files become
%    active.
%    \begin{macrocode}
    \let\do\makeoutlist@do
    \edef\outputfiles{\csname o@#1\endcsname}%
    \let\activefiles\outputfiles
    \Name\let{o@#1}\refusedfiles
%    \end{macrocode}
%    Now we change the category code of a lot of characters to
%    \meta{other} and make sure that no extra spaces appear in the
%    lines read by setting the |\endlinechar| to $-1$.
%    \begin{macrocode}
    \makeOther\ \makeOther\\\makeOther\$%
    \makeOther\#\makeOther\^\makeOther\^^K%
    \makeOther\_\makeOther\^^A\makeOther\%%
    \makeOther\~\makeOther\{\makeOther\}\makeOther\&%
    \endlinechar-1\relax
%    \end{macrocode}
%    Then we start a loop to process the lines in the file one by one.
%    \begin{macrocode}
    \loop
      \read\inFile to\inLine
%    \end{macrocode}
%    The first thing we check is whether the current line
%    contains an |\endinput|. To allow also real |\endinput|
%    commands in the source file, |\endinput| is only recognized
%    when it occurs directly at the beginning of a line.
%    \begin{macrocode}
      \ifx\inLine\Endinput
%    \end{macrocode}
%    In this case we output a message to inform the programmer (in
%    case this was a mistake) and end the loop immediately by setting
%    \verb=Continue= to \meta{false}. Note that |\endinput| is
%    not placed into the output file. This is important in cases where
%    the output file is generated from several \texttt{doc} files.
%    \begin{macrocode}
        \Msg{File #1 ended by \string\endinput.}%
        \Continuefalse
      \else
%    \end{macrocode}
% \changes{2.0j}{1992/03/03}{First check for end of file before check
%    for empty lines} When the end of the file is found we have to
%    interrupt the loop.
%    \begin{macrocode}
       \ifeof\inFile
         \Continuefalse
%    \end{macrocode}
% \changes{2.0i}{1991/06/27}{Added check for consecutive empty lines}
%    If the file did not end we check if the input line is empty.
%    If it is, the counter |\emptyLines| is incremented.
%    \begin{macrocode}
       \else
         \Continuetrue
         \ifx\inLine\empty
            \advance\emptyLines\@ne
          \else
            \emptyLines\z@
          \fi
%    \end{macrocode}
%    When the number of empty lines seen so far exceeds 1, we skip them.
%    If it doesn't, the expansion of |\inLine| is fed to |\processLine|
%    with |\endLine| appended to indicate the end of the line.
%    \begin{macrocode}
          \ifnum \emptyLines<2
            \expandafter\processLine\inLine\endLine
          \else
            \maybeMsg{/}%
          \fi
       \fi
      \fi
%    \end{macrocode}
%    When the processing of the line is finished, we check if there is
%    more to do, in which case we repeat the loop.
%    \begin{macrocode}
    \ifContinue
    \repeat
%    \end{macrocode}
%    The input file is closed.
%    \begin{macrocode}
    \closein\inFile
%    \end{macrocode}
%    We close output files for which this was the last input file.
%    \begin{macrocode}
  \csname e@#1\endcsname
%    \end{macrocode}
%    If the user was interested in statistics, we inform him of the
%    number of lines processed, the number of comments that were
%    either removed or passed and the number of codelines that were
%    written to the output file. Also the totals are updated.
%    \begin{macrocode}
%<*stats>
    \Msg{Lines \space processed: \the\processedLines^^J%
         Comments removed: \the\commentsRemoved^^J%
         Comments \space passed: \the\commentsPassed^^J%
         Codelines passed: \the\codeLinesPassed^^J}%
      \global\advance\TotalprocessedLines  by \processedLines
      \global\advance\TotalcommentsRemoved by \commentsRemoved
      \global\advance\TotalcommentsPassed  by \commentsPassed
      \global\advance\TotalcodeLinesPassed by \codeLinesPassed
%</stats>
%    \end{macrocode}
%    The |\NumberOfFiles| need to be known even if no statistics are
%    gathered so we update it always.
% \changes{2.4h}{1997/07/07}{update \cs{NumberOfFiles} even if stats are
%      not gathered pr/2429}
%    \begin{macrocode}
      \global\advance\NumberOfFiles by \@ne
    \fi}
%    \end{macrocode}
% \end{macro}
%
%  \begin{macro}{\showfiles@do}
% \changes{2.4a}{1996/10/02}{Macro added (MW)} 
%    A message is displayed on the terminal telling the user what we
%    are about to do. For each open output file we display one line
%    saying what options it is generated with and the off-counter
%    associated with the file is zeroed. First line contains also name
%    of input file.
%    Names of output files that are closed are appended to
%    |\refusedfiles|. 
%    \begin{macrocode}
\def\showfiles@do#1#2{%
  \ifnum#1=\stream@closed
    \@addto\refusedfiles{\noexpand\do#1{#2}}%
  \else
    \Msg{\@msg
         \ifx>#2>\else\space(#2)\fi
         \space -> \@stripstring#1}
    \change@msg
  \csname off@\number#1\endcsname=\z@
  \fi
}
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\makeoutlist@do}
% \changes{2.3b}{1995/08/22}{Macro added --- pre-constructed
%                            off-counters' names}
%   This macro selects only open output files and constructs names for
%   off-counters.
%    \begin{macrocode}
\def\makeoutlist@do#1#2{%
  \ifnum#1=\stream@closed\else
    \noexpand\do#1{#2}\csname off@\number#1\endcsname
  \fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\openoutput}
% \changes{2.3e}{1996/10/02}{Change for ``open lists'' -- renamed from
%                            \cs{ensureopen@do}} 
% \changes{2.4a}{1996/06/06}{Check whether there are streams left (MDW)}
%    This macro opens output streams if possible.
%    \begin{macrocode}
\def\openoutput#1{%
%    \end{macrocode}
%    If both maxfile counters are non-zero\dots
%    \begin{macrocode}
  \if 1\ifnum\@maxfiles=\z@ 0\fi
       \ifnum\@maxoutfiles=\z@ 0\fi1%
%    \end{macrocode}
%    \dots the stream may be opened and counters decremented. But if
%    that cannot be done\dots
%    \begin{macrocode}
    \advance\@maxfiles\m@ne
    \advance\@maxoutfiles\m@ne
    \StreamOpen#1%
    \WritePreamble#1%
  \else
%    \end{macrocode}
%    \dots the file is added to the ``refuse list''.
%    \begin{macrocode}
     \@addto\refusedfiles{\noexpand\openoutput#1}%
  \fi
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\closeoutput}
% \changes{2.4a}{1996/06/06}
%      {Don't close the file if it's not open (MDW)} 
%    This macro closes open output stream when it is no longer
%    needed and increments maxfiles counters.
%    \begin{macrocode}
\def\closeoutput#1{%
  \ifnum#1=\stream@closed\else
    \WritePostamble#1%
    \StreamClose#1%
    \advance\@maxfiles\@ne
    \advance\@maxoutfiles\@ne
  \fi}
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{Preamble and postamble}
%
%  \begin{macro}{\ds@heading}
% \changes{2.3e}{1996/09/16}{Macro added.}
%    This is a couple of lines, stating what file is being written and
%    how it was created. 
%    \begin{macrocode}
\def\ds@heading{%
  \MetaPrefix ^^J%
  \MetaPrefix\space This is file `\outFileName',^^J%
  \MetaPrefix\space  generated with the docstrip utility.^^J%
  }
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\AddGenerationDate}
% \changes{2.3d}{1995/11/17}{(DPC) Macro added.}
%  Older versions of \ds{} added the date that any file was generated
% and the version number of \ds{}. This confused some people as they
% mistook this for the version/date of the file that was being
% written. So now this information is not normally written, but
% a batch file may call this to get an old style header.
%    \begin{macrocode}
\def\AddGenerationDate{%
  \def\ds@heading{%
    \MetaPrefix ^^J%
    \MetaPrefix\space This is file `\outFileName', generated %
           on <\the\year/\the\month/\the\day> ^^J%
    \MetaPrefix\space with the docstrip utility (\fileversion).^^J%
 }}
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\declarepreamble}
% \changes{2.3a}{1995/08/18}{renamed from \cs{preamble};
%                            interface changed}
% \changes{2.0e}{1991/06/01}{Macro added.} 
% \changes{2.3e}{1995/09/25}
%     {Change for batchfiles working by \cs{input}}
% \changes{2.3e}{1996/09/16}{Change to allow customization.}
%    When a batch file is used the
%    user can specify a preamble of his own that will be written to
%    each file that is created. This can be useful to include an extra
%    copyright notice in the stripped version of a file.  Also a
%    warning that both versions of a file should {\em always\/} be
%    distributed together could be written to a stripped file by
%    including it in such a preamble.
%
%    Every line that is written to |\outFile| that belongs to the
%    preamble is preceded by two percent characters. This will prevent
%    \ds{} from stripping these lines off the file.
%
%    The preamble should be started with the macro
%    |\declarepreamble|; it is ended by |\endpreamble|. All
%    processing is done within a group in order to be able to locally
%    change some values.
%
%    |\ReferenceLines| is let equal |\relax| to be unexpandable.
%    \begin{macrocode}
\let\inFileName\relax
\let\outFileName\relax
\let\ReferenceLines\relax
\def\declarepreamble{\begingroup
\catcode`\^^M=13 \catcode`\ =12 %
\declarepreambleX}
{\catcode`\^^M=13 %
\gdef\declarepreambleX#1#2
\endpreamble{\endgroup%
  \def^^M{^^J\MetaPrefix\space}%
  \edef#1{\ds@heading%
          \ReferenceLines%
          \MetaPrefix\space\checkeoln#2\empty}}%
\gdef\checkeoln#1{\ifx^^M#1\else\expandafter#1\fi}%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\declarepostamble}
% \changes{2.0e}{1991/06/01}{Macro added.}
% \changes{2.3e}{1995/09/25}
%     {Change for batchfiles working by \cs{input}}
%    Just as a preamble can be
%    specified in a batch file, the same can be done for a {\em
%    post\/}amble.
%
%    The definition of |\declarepostamble| is very much like the
%    definition above of |\declarepreamble|.
%    \begin{macrocode}
\def\declarepostamble{\begingroup
\catcode`\ =12 \catcode`\^^M=13
\declarepostambleX}
{\catcode`\^^M=13 %
\gdef\declarepostambleX#1#2
\endpostamble{\endgroup%
  \def^^M{^^J\MetaPrefix\space}%
  \edef#1{\MetaPrefix\space\checkeoln#2\empty^^J%
          \MetaPrefix ^^J%
          \MetaPrefix\space End of file `\outFileName'.%
  }}%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\usepreamble}
% \begin{macro}{\usepostamble}
%    Macros for selecting [pre/post]amble to be used.
%    \begin{macrocode}
\def\usepreamble#1{\def\currentpreamble{#1}}
\def\usepostamble#1{\def\currentpostamble{#1}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\preamble}
% \changes{2.3c}{1995/08/28}{Bug fixed: default preamble is now selected
%                             not only defined}
% \begin{macro}{\postamble}
% \changes{2.3c}{1995/08/28}{As for \cs{preamble}}
%    For backward compatibility we provide these macros defining
%    default preamble and postamble.
%    \begin{macrocode}
\def\preamble{\usepreamble\defaultpreamble
  \declarepreamble\defaultpreamble}
\def\postamble{\usepostamble\defaultpostamble
  \declarepostamble\defaultpostamble}
%    \end{macrocode}   
% \end{macro}
% \end{macro}
% \begin{macro}{\org@preamble}
%  \changes{2.3a}{1995/08/18}{Macro added}
% \changes{2.3c}{1995/11/16}{With \cs{inFileName} again}
% \begin{macro}{\org@postamble}
%  \changes{2.3a}{1995/08/18}{Macro added}
%    Default values to use if nothing different is provided.
% \changes{2.2j}{1995/08/06}{Updated default preamble}
%    \begin{macrocode}
\declarepreamble\org@preamble

IMPORTANT NOTICE:

For the copyright see the source file.

You are *not* allowed to modify this file.

You are *not* allowed to distribute this file.
For distribution of the original source see the terms
for copying and modification in the file \inFileName.

\endpreamble     
\edef\org@postamble{\string\endinput^^J%
  \MetaPrefix ^^J%
  \MetaPrefix\space End of file `\outFileName'.%
  }

\let\defaultpreamble\org@preamble
\let\defaultpostamble\org@postamble
\usepreamble\defaultpreamble
\usepostamble\defaultpostamble
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\WritePreamble}
% \changes{2.0e}{1991/06/01}{Macro added.}
% \changes{2.3c}{1995/11/16}{Added definitions of \cs{inFileName} and
%                            \cs{outFileName}}
% \changes{2.3d}{1995/11/17}{(DPC) Macro added.}
%    \begin{macrocode}
\def\WritePreamble#1{%
    \edef\outFileName{\@stripstring#1}%
%    \end{macrocode}
%    Then the reference lines that tell from what source file(s) the
%    stripped file was created and user supplied preamble.
%    \begin{macrocode}
    \StreamPut#1{\csname pre@\@stripstring#1\endcsname}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\WritePostamble}
% \changes{2.0e}{1991/06/01}{Macro added.}
% \changes{2.3c}{1995/11/16}{Added defs of \cs{inFileName} and
%                            \cs{outFileName}}
%    Postamble attributed to |#1| is written out. The
%    last line written identifies the file again.
%    \begin{macrocode}
\def\WritePostamble#1{%
    \edef\outFileName{\@stripstring#1}%
    \StreamPut#1{\csname post@\@stripstring#1\endcsname}}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Support for writing to specified directories}
% 
%    As we've seen before every output file is written to  directory
%    specifed  by  the  value of |\destdir| current at the moment of
%    this file's  |\file|  declaration.
%
% \begin{macro}{\usedir}
%  \changes{2.3e}{1995/09/15}{Macro added}
%    This macro when called should translate its one argument into a
%    directory name and define |\destdir| to that value.  The default
%    for |\usedir| is to ignore its argument and return name of
%    current directory (if known).  This can be changed by commands
%    from |docstrip.cfg| file.
%
%    |\showdirectory| is used just to display directory name for
%    user's information.
%    \begin{macrocode}
\def\usedir#1{\edef\destdir{\WriteToDir}}
\def\showdirectory#1{\WriteToDir}
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\BaseDirectory}
% \changes{2.3e}{1995/09/15}{Macro added}
% \changes{2.4e}{1996/10/22}{\cs{@setwritetodir} added (DPC)}
%    This is config file command for specifing root directory of the 
%    \TeX{}  hierarchy.  It enables the whole directory
%    selecting mechanism by redefining |\usedir|.
%    First make sure that the directory syntax commands have been set
%    up by calling |\@setwritedir|, so that the value of |\dirsep|
%   used by the |\edef| is (hopefully) correct.
%    \begin{macrocode}
\def\BaseDirectory#1{%
  \@setwritetodir
  \let\usedir\alt@usedir
  \let\showdirectory\showalt@directory
  \edef\basedir{#1\dirsep}}
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\convsep}
% \changes{2.3e}{1995/09/15}{Macro added}
%    This macro loops through slashes in its argument replacing them
%    with  current  |\dirsep|.  It  should   be   called
%    |\convsep some/directory/name/\qStop| (with slash on the end).
%    \begin{macrocode}
\def\convsep#1/#2\qStop{%
  #1\ifx\qStop#2\qStop \pesvnoc\fi\convsep\dirsep#2\qStop}
\def\pesvnoc#1\qStop{\fi}
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\alt@usedir}
% \changes{2.3e}{1995/09/15}{Macro added}
%    Directory name construction macro enabling writing to various
%    directories. 
%    \begin{macrocode}
\def\alt@usedir#1{%
  \Name\ifx{dir@#1}\relax
    \undefined@directory{#1}%
  \else 
    \edef\destdir{\csname dir@#1\endcsname}%
  \fi}
\def\showalt@directory#1{%
  \Name\ifx{dir@#1}\relax
    \showundef@directory{#1}%
  \else\csname dir@#1\endcsname\fi}
%    \end{macrocode}
% \end{macro}
% 
%  \begin{macro}{\undefined@directory}
% \changes{2.4a}{1996/10/04}{Macro added (MW)}
% \changes{2.4e}{1996/10/22}{Help text added (DPC)}
%    This macro comes into action when undefined label is spotted. The
%    action is to raise an error and define |\destdir| to point to the
%    current directory.
%    \begin{macrocode}
\def\undefined@directory#1{%
  \errhelp{docstrip.cfg should specify a target directory for^^J%
   #1 using \DeclareDir or \UseTDS.}%
  \errmessage{You haven't defined output directory for `#1'.^^J%
            Subsequent files will be written to the current directory.}%
  \let\destdir\WriteToDir
  }
\def\showundef@directory#1{UNDEFINED (label is #1)}
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\undefined@TDSdirectory}
% \changes{2.4a}{1996/10/04}{Macro added (MW)}
%    This happens when label is undefined while using TDS. The label
%    is converted to use proper separators and appended to base
%    directory name.
%    \begin{macrocode}
\def\undefined@TDSdirectory#1{%
  \edef\destdir{%
    \basedir\convsep#1/\qStop
  }}
\def\showundef@TDSdirectory#1{\basedir\convsep#1/\qStop}
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\UseTDS}
% \changes{2.4a}{1996/10/04}{Macro added (MW)}
% \changes{2.4e}{1996/10/22}{\cs{@setwritetodir} added (DPC)}
%    Change of behaviour for undefined labels is done simply:
%    \begin{macrocode}
\def\UseTDS{%
  \@setwritetodir
  \let\undefined@directory\undefined@TDSdirectory
  \let\showundef@directory\showundef@TDSdirectory
  }
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\DeclareDir}
% \changes{2.3e}{1995/09/15}{Macro added}
% \changes{2.4e}{1996/10/22}{\cs{@setwritetodir} added (DPC)}
%    This macro remaps some directory name to another.
%    \begin{macrocode}
\def\DeclareDir{\@ifnextchar*{\DeclareDirX}{\DeclareDirX\basedir*}}
\def\DeclareDirX#1*#2#3{%
  \@setwritetodir
  \Name\edef{dir@#2}{#1#3}}
%    \end{macrocode}
% \end{macro}
%
%
% \subsubsection{Compatibility with older versions}
%
% \begin{macro}{\generateFile}
%    Main macro of previous versions of \ds.
%    \begin{macrocode}
\def\generateFile#1#2#3{{%
  \ifx t#2\askforoverwritetrue
  \else\askforoverwritefalse\fi
  \generate{\file{#1}{#3}}%
  }}    
%    \end{macrocode}
% \end{macro}
%
%    To support command files that were written for the first version
%    of \ds{} the commands |\include| and |\processFile|
%    are defined here. The use of this interface is not recommended
%    as it may be removed in a future release of \ds{}.
%
% \begin{macro}{\include}
% \changes{2.0f}{1991/06/04}{Macro added} To provide the \ds{} program
%    with a list of options that should be included in the output the
%    command \verb=\include{=\meta{Options}\verb=}= can be used. This
%    macro is meant to be used in conjunction with the
%    |\processFile| command.
%    \begin{macrocode}
\def\include#1{\def\Options{#1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\processFile}
% \changes{2.0f}{1991/06/04}{Supply \texttt{\bsl generateFile} with
%                          \texttt{\bsl Options}}
%\DeleteShortVerb\|
%    The macro
%    \verb=\processFile{=\meta{filename}\verb=}{=\meta{inext}\verb=}{=%
%\unskip\meta{outext}\verb=}{=\meta{t{\fontshape{n}\ttfamily|}f}\verb=}=
%    can be used when a single input file is used to produce
%    a single output file. The macro is also used in the interactive
%    mode of the \ds{} program.
%\MakeShortVerb\|
%
%    The arguments \meta{inext} and \meta{outext} denote the
%    extensions of the input and output files respectively. The fourth
%    argument can be used to specify if an existing file should be
%    overwritten without asking. If \meta{t} is specified the program
%    will ask for permission before overwriting an existing file.
%
%    This macro is defined using the more generic macro |\generateFile|.
%    \begin{macrocode}
\def\processFile#1#2#3#4{%
  \generateFile{#1.#3}{#4}{\from{#1.#2}{\Options}}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\processfile}
% \begin{macro}{\generatefile}
% \changes{2.0m}{1991/04/23}{Now issue a warning when \cs{processfile}
%     or \cs{generatefile} are used}
%    Early
%    versions of \ds{} defined |\processfile| and
%    |\generatefile| instead of the commands as they are defined in
%    this version. To remain upwards compatible, we still provide
%    these commands, but issue a warning when they are used.
%    \begin{macrocode}
\def\processfile{\Msg{%
    ^^Jplease use \string\processFile\space instead of 
       \string\processfile!^^J}%
    \processFile}
\def\generatefile{\Msg{%
    ^^Jplease use \string\generateFile\space instead of 
      \string\generatefile!^^J}%
    \generateFile}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
% \subsection{Limiting open file streams}
%
% (This section was written by Mark Wooding)
%
% \begin{macro}{\maxfiles}
% \changes{2.4a}{1996/06/06}{Macro added (MDW)}
% Some operating systems with duff libraries or other restrictions
% can't cope with all the files which \ds\ tries to output at once.
% A configuration file can say |\maxfiles{|\meta{number}|}| to
% describe the maximum limit for the environment.
%
% I'll need a counter for this value, so I'd better allocate one.
%
%    \begin{macrocode}
\newcount\@maxfiles
%    \end{macrocode}
%
% The configuration command |\maxfiles| is just slightly prettier than
% an assignment, for \LaTeX\ people.  It also gives me an opportunity
% to check that the limit is vaguely sensible.  I need at least 4
% streams: 
% \begin{enumerate}
% \item A batch file.
% \item A sub batch file, which \LaTeX's installation utility uses.
% \item An input stream for reading an unstripped file.
% \item An output stream for writing a stripped file.
% \end{enumerate}
%
%    \begin{macrocode}
\def\maxfiles#1{%
  \@maxfiles#1\relax
  \ifnum\@maxfiles<4
    \errhelp{I'm not a magician.  I need at least four^^J%
             streams to be able to work properly, but^^J%
             you've only let me use \the\@maxfiles.}%
    \errmessage{\noexpand\maxfiles limit is too strict.}%
    \@maxfiles4
  \fi
}
%    \end{macrocode}
%
% \changes{2.4a}{1996/10/03}{No default limit since batchfiles are now
%                            \cs{input} (MW)} 
% Since batchfiles are now |\input|ed there should be no default limit
% here. I'll just use some abstract large number.
%    \begin{macrocode}
\maxfiles{1972} % year of my birth (MW)
%    \end{macrocode}
%
% \end{macro}
%
% \begin{macro}{\maxoutfiles}
% \changes{2.4a}{1996/06/06}{Macro added (MDW)}
%
% Maybe there's a restriction on just output streams.  (Well, there is:
% I know, because \TeX\ only allows 16.)  I may as well allow the
% configuration to set this up.
%
% Again, I need a counter.
%
%    \begin{macrocode}
\newcount\@maxoutfiles
%    \end{macrocode}
%
% And now the macro.  I need at least one output stream which I think is
% reasonable.
%
%    \begin{macrocode}
\def\maxoutfiles#1{%
  \@maxoutfiles=#1\relax
  \ifnum\@maxoutfiles<1
    \@maxoutfiles1
    \errhelp{I'm not a magician.  I need at least one output^^J%
             stream to be able to do anything useful at all.^^J%
             Please be reasonable.}%
    \errmessage{\noexpand\maxoutfiles limit is insane}%
  \fi
}
%    \end{macrocode}
%
% The default limit is 16, because that's what \TeX\ says.
%
%    \begin{macrocode}
\maxoutfiles{16}
%    \end{macrocode}
%
% \end{macro}
%
% \begin{macro}{\checkfilelimit}
%
% This checks the file limit when a new batch file is started.  If
% there's fewer than two files left here, we're not going to be able
% to strip any files.  The file limit counter is local to the group
% which is set up around |\batchinput|, so that's all pretty cool.
%
%    \begin{macrocode}
\def\checkfilelimit{%
  \advance\@maxfiles\m@ne
  \ifnum\@maxfiles<2 %
    \errhelp{There aren't enough streams left to do any unpacking.^^J%
             I can't do anything about this, so complain at the^^J%
             person who made such a complicated installation.}%
    \errmessage{Too few streams left.}%
    \end
  \fi
}
%    \end{macrocode}
%
% \end{macro}
%
% \subsection{Interaction with the user}
%
% \begin{macro}{\strip@meaning}
% Throw away the first part of |\meaning| output.
% \changes{2.4c}{1996/06/11}{Macro added (DPC)}
%    \begin{macrocode}
\def\strip@meaning#1>{}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\processbatchFile}
% \changes{2.0f}{1991/06/04}{Macro added.}
% \changes{2.3e}{1995/09/25}{Batch file is \cs{input}ed not \cs{read}}
%    When \ds{} is run it always tries to use a batch file.
%
%    For this purpose it calls the macro |\processbatchFile|. 
%
% \changes{2.4a}{1996/06/06}
%      {Added check for file limits (MDW)}
% \changes{2.4c}{1996/06/11}
%      {Add \cs{jobname} checks (DPC)}
% \changes{2.4d}{1996/06/17}
%      {Move \cs{jobname} checks to top level (DPC)}
%    The first thing is to check if there are any input streams left.
%    \begin{macrocode}
\def\processbatchFile{%
  \checkfilelimit
  \let\next\relax
%    \end{macrocode}
%    Now we try to open the batch file for reading.
%    \begin{macrocode}
  \openin\inputcheck \batchfile\relax
  \ifeof\inputcheck
%    \end{macrocode}
%    If we didn't succeed in opening the file, we assume that it does
%    not exist. If we tried the default filename, we silently
%    continue; the \ds{} program will switch to interactive mode in
%    this case.
%    \begin{macrocode}
    \ifDefault
    \else
%    \end{macrocode}
% \changes{2.4d}{1996/10/17}{Missing batchfile an error (DPC)}
%    If we failed to open the user-supplied file, something is wrong
%    and we warn him about it. This will also result in a switch to
%    interactive mode.
%    \begin{macrocode}
      \errhelp
        {A batchfile specified in \batchinput could not be found.}%
      \errmessage{^^J%
           **************************************************^^J%
           * Could not find your \string\batchfile=\batchfile.^^J%
           **************************************************}%
    \fi
  \else
%    \end{macrocode}
%    When we were successful in opening a file, we again have to check
%    whether it was the default file. In that case we tell the user
%    we found that file and ask him if he wants to use it.
%    \begin{macrocode}
    \ifDefault
      \Msg{**************************************************^^J%
           * Batchfile \DefaultbatchFile\space found Use it? (y/n)?}%
      \Ask\answer{%
             **************************************************}%
    \else
%    \end{macrocode}
%    When it was the user-supplied file we can safely assume he wants
%    to use it so we set |\answer| to \texttt{y}.
%    \begin{macrocode}
      \let\answer\y
    \fi
%    \end{macrocode}
% If the macro |\answer| contains  a  \texttt{y}  we  can  read  in  the
% batchfile. We do it in an indirect way---after completing |\if|s.
%    \begin{macrocode}
    \ifx\answer\y
      \closein\inputcheck
      \def\next{\@@input\batchfile\relax}%
    \fi
  \fi
  \next}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ReportTotals}
% \changes{2.0g}{1991/06/05}{Macro added.} The macro
%    |\ReportTotals| can be used to report total statistics for
%    all files processed. This code is only included in the program if
%    the option \texttt{stats} is included.
%    \begin{macrocode}
%<*stats>
\def\ReportTotals{%
  \ifnum\NumberOfFiles>\@ne
    \Msg{Overall statistics:^^J%
         Files \space processed: \the\NumberOfFiles^^J%
         Lines \space processed: \the\TotalprocessedLines^^J%
         Comments removed: \the\TotalcommentsRemoved^^J%
         Comments \space passed: \the\TotalcommentsPassed^^J%
         Codelines passed: \the\TotalcodeLinesPassed}%
  \fi}
%</stats>
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\SetFileNames}
%    The macro |\SetFileNames| is used when the program runs in
%    interactive mode and the user was asked to supply extensions and
%    a list of filenames.
%    \begin{macrocode}
\def\SetFileNames{%
    \edef\sourceFileName{\MainFileName.\infileext}%
    \edef\destFileName{\MainFileName.\outfileext}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\CheckFileNames}
%    In interactive mode, the user gets asked for the extensions for
%    the input and output files. Also the name or names of the input
%    files (without extension) is asked for. Then the names of the
%    input and output files are constructed from this information by
%    |\SetFileNames|. This assumes that the name of the input file is
%    the same as the name of the output file. But we should not write
%    to the same file we're reading from so the extensions should
%    differ.
%
%    The macro |\CheckFileNames| makes sure that the output goes to a
%    different file to the one where the input comes from.
%    \begin{macrocode}
\def\CheckFileNames{%
    \ifx\sourceFileName\destFileName
%    \end{macrocode}
%    If input and output files are the same we signal an error and stop
%    processing.
%    \begin{macrocode}
      \Msg{^^J%
     !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!^^J%
     ! It is not possible to read from and write to the same file !^^J%
     !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!^^J}%
      \Continuefalse
    \else
%    \end{macrocode}
%    If they are not the same we check if the input file exists by
%    trying to open it for reading.
%    \begin{macrocode}
      \Continuetrue
      \immediate\openin\inFile \sourceFileName\relax
      \ifeof\inFile
%    \end{macrocode}
%    If an end of file was found, the file couldn't be opened, so we
%    signal an error and stop processing.
%    \begin{macrocode}
        \Msg{^^J%
              !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!^^J%
              ! Your input file `\sourceFileName' was not found !^^J%
              !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!^^J}%
        \Continuefalse
      \else
%    \end{macrocode}
%    The last check we have to make is if the output file already
%    exists.  Therefore we try to open it for reading.
%    As a precaution we first close the input stream.
% \changes{2.0p}{1992/06/26}{Added \cs{WriteToDir} (FMi).}
% \changes{2.0r}{1992/08/17}{Use \cs{inFile} for reading}
% \changes{2.0r}{1992/08/17}{Moved \cs{closein} statements}
%    \begin{macrocode}
        \immediate\closein\inFile
        \immediate\openin\inFile\destdir \destFileName\relax
        \ifeof\inFile
%    \end{macrocode}
%    If this fails, it didn't exist and all is well.
%    \begin{macrocode}
          \Continuetrue
        \else
%    \end{macrocode}
%    If opening of the output file for reading succeeded we have to
%    ask the user if he wants to overwrite it. We assume he doesn't
%    want to overwrite it, so the switch |\ifContinue| is initially
%    set to \meta{false}. Only if he answers the question positively
%    with `\texttt{y}' or `\texttt{yes}' we set the switch back to
%    \meta{true}.
% \changes{2.0p}{1992/06/26}{Changed question about overwriting.}
%    \begin{macrocode}
          \Continuefalse
          \Ask\answer{File \destdir\destFileName\space already 
                      exists 
                      \ifx\empty\destdir somewhere \fi
                      on the system.^^J% 
                      Overwrite it%
                      \ifx\empty\destdir\space if necessary\fi
                      ? [y/n]}%
          \ifx\y  \answer \Continuetrue \else
          \ifx\yes\answer \Continuetrue \else
          \fi\fi
        \fi
%    \end{macrocode}
%    All checks have been performed now, so we can close any file that
%    was opened just for this purpose.
%    \begin{macrocode}
      \fi
    \fi
    \closein\inFile}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\interactive}
%    The macro |\interactive| implements the interactive mode of the
%    \ds{} program. The macro is implemented using the
%    \meta{while} construction. While the switch |\ifMoreFiles| remains
%    true, we continue processing.
%    \begin{macrocode}
\def\interactive{%
  \whileswitch\ifMoreFiles\fi%
%    \end{macrocode}
%    To keep macro redefinitions local we start a group and ask the
%    user some questions about what he wants us to do.
%    \begin{macrocode}
   {\begingroup
      \AskQuestions
%    \end{macrocode}
%    The names of the files that have to be processed are stored as a
%    comma-separated list in the macro |\filelist| by |\AskQuestions|.
%    We use a \meta{for} loop to process the files one by one.
%    \begin{macrocode}
      \forlist\MainFileName:=\filelist
      \do
%    \end{macrocode}
%    First the names of the input and output files are constructed
%    and a check is made if all filename information is correct.
%    \begin{macrocode}
        \SetFileNames
        \CheckFileNames
        \ifContinue
%    \end{macrocode}
%    If everything was well, produce output file.
% \changes{2.0q}{1992/07/01}{Preceded filename by \cs{WriteToDir}}
%    \begin{macrocode}
        \generateFile{\destFileName}{f}%
                     {\from{\sourceFileName}{\Options}}
        \fi%
%    \end{macrocode}
%    This process is repeated until |\filelist| is exhausted.
%    \begin{macrocode}
      \od
    \endgroup
%    \end{macrocode}
%    Maybe the user wants more files to be processed, possibly with
%    another set of options, so we give him the opportunity.
%    \begin{macrocode}
    \Ask\answer{More files to process (y/n)?}%
    \ifx\y  \answer\MoreFilestrue \else
    \ifx\yes\answer\MoreFilestrue \else
%    \end{macrocode}
%    If he didn't want to process any more files, the switch
%    |\ifMoreFiles| is set to \meta{false} in order to interrupt the
%    \meta{while} loop.
%    \begin{macrocode}
                   \MoreFilesfalse\fi\fi
   }}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\AskQuestions}
% \changes{2.0e}{1991/06/01}{Macro added.}
%    The macro |\AskQuestions| is called by |\interactive| to get
%    some information from the user concerning the files that need
%    to be processed.
%    \begin{macrocode}
\def\AskQuestions{%
    \Msg{^^J%
         ****************************************************}%
%    \end{macrocode}
%    We want to know the extension of the input files,
%    \begin{macrocode}
    \Ask\infileext{%
         * First type the extension of your input file(s): \space  *}%
    \Msg{****************************************************^^J^^J%
         ****************************************************}%
%    \end{macrocode}
%    the extension of the output files,
%    \begin{macrocode}
    \Ask\outfileext{%
         * Now type the extension of your output file(s) \space: *}%
    \Msg{****************************************************^^J^^J%
         ****************************************************}%
%    \end{macrocode}
%    if options are to be included and
%    \begin{macrocode}
    \Ask\Options{%
       * Now type the name(s) of option(s) to include \space\space: *}%
    \Msg{****************************************************^^J^^J%
         ****************************************************^^J%
       * Finally give the list of input file(s) without \space\space*}%
%    \end{macrocode}
%    the name of the input file or a list of names, separated by commas.
%    \begin{macrocode}
    \Ask\filelist{%
         * extension seperated by commas if necessary %
                                  \space\space\space\space: *}%
    \Msg{****************************************************^^J}}%
%    \end{macrocode}
% \end{macro}
%
% \subsection{The main program}
%    When \TeX\ processes the \ds{} program it displays
%    a message about the version of the program and its function
%    on the terminal.
%    \begin{macrocode}
\Msg{Utility: `docstrip' \fileversion\space <\filedate>^^J%
     English documentation \space\space\space <\docdate>}%
\Msg{^^J%
     **********************************************************^^J%
     * This program converts documented macro-files into fast *^^J%
     * loadable files by stripping off (nearly) all comments! *^^J%
     **********************************************************^^J}%
%    \end{macrocode}
%
%
%  \begin{macro}{\WriteToDir}
%    Macro |\WriteToDir| is either empty or holds the prefix
%    necessary to read a file from the current directory. Under UNIX
%    this is |./| but a lot of other systems addopted this concept.
%    This macro is a default value for |\destdir|.
%
%    The definition of this macro is now delayed until |\@setwritedir|
%    is called.
% \changes{2.0p}{1992/06/26}{Macro added (FMi).}
% \changes{2.2a}{1993/12/02}{check texsys file}
% \changes{2.2d}{1994/01/20}{do not read dircheck/texsys file}
% \changes{2.4e}{1996/10/22}{set in \cs{@setwritedir} (DPC)}
%  \end{macro}
%
% \begin{macro}{\makepathname}
% \changes{2.3e}{1995/10/24}{Macro added}
% \changes{2.4e}{1996/10/22}{set in \cs{@setwritedir} (DPC)}
%    This macro should define |\@pathname| to full path name made by
%    combining current value of |\destdir| with its one argument being
%    a file name.  Its default value defined here is suitable for
%    \textsc{unix, ms-dos} and Macintosh, but for some systems it may
%    be needed to redefine this in \texttt{docstrip.cfg} file.  We
%    provide such redefinition for VMS here.  
%
%    Macro |\dirsep| holds directory separator specific for a
%    system. Default value suitable for UNIX and DOS is slash. It
%    comes in action when |\usedir| labels are used directly.
%
%    The definition of this macro is now delayed until |\@setwritedir|
%    is called.
% \end{macro}
% 
% \begin{macro}{\@setwritedir}
% \changes{2.4e}{1996/10/22}{macro added (DPC)}
% The following tests try to automatically set |\WriteToDir|,
% |\dirname| and |\makepathname| in Unix, Mac, or VMS style.
% The tests are not run at the top level but held in this macro
% so that a configuration file has a chance to define |\WriteToDir|
% which allows the other two to be set automatically. The tests could
% more simply be run after the configuration file is read, but the
% configuration commands like |\BaseDirectory| need (at least at
% present)  to have |\dirsep| correctly defined. It does not define
% any command that is already defined, so by defining these commands
% a configuration file can produce different effects for special needs.
% So this command is called by |BaseDirectory|, |\UseTDS|,
% |\DeclareDir| and finally at the top level after the cfg is run.
% It begins by redefining itself to be a no-op so it effectively is
% only called once.
%    \begin{macrocode}
\def\@setwritetodir{%
  \let\setwritetodir\relax
%    \end{macrocode}
%
%    \begin{macrocode}
  \ifx\WriteToDir\@undefined
    \ifx\@currdir\@undefined
      \def\WriteToDir{}%
    \else
      \let\WriteToDir\@currdir
    \fi
  \fi
%    \end{macrocode}
%
%    \begin{macrocode}
  \let\destdir\WriteToDir
%    \end{macrocode}
%
% VMS Style.
%    \begin{macrocode}
  \def\tmp{[]}%
  \ifx\tmp\WriteToDir
    \ifx\dirsep\@undefined
      \def\dirsep{.}%
    \fi
    \ifx\makepathname\@undefined
      \def\makepathname##1{%
        \edef\@pathname{\ifx\WriteToDir\destdir
          \WriteToDir\else[\destdir]\fi##1}}%
    \fi
  \fi
%    \end{macrocode}
%
% Unix and Mac styles.
%    \begin{macrocode}
  \ifx\dirsep\@undefined
    \def\dirsep{/}%
    \def\tmp{:}%
    \ifx\tmp\WriteToDir
      \def\dirsep{:}%
    \fi
  \fi
%    \end{macrocode}
%
%    \begin{macrocode}
  \ifx\makepathname\@undefined
    \def\makepathname##1{%
      \edef\@pathname{\destdir\ifx\empty\destdir\else
           \ifx\WriteToDir\destdir\else\dirsep\fi\fi##1}}%
  \fi}
%    \end{macrocode}
% \end{macro}
%
%
% If the user has a |docstrip.cfg| file, use it now.
% \changes{2.4d}{1995/10/17}{Move config file test to outer level (DPC)}
%    This macro tries to read \texttt{docstrip.cfg} file.  If this 
%    succeeds executes its first argument, otherwise the second.
%    \begin{macrocode}
\immediate\openin\inputcheck=docstrip.cfg\relax
\ifeof\inputcheck
  \Msg{%
     ********************************************************^^J%
     * No Configuration file found, using default settings. *^^J%
     ********************************************************^^J}%
\else
  \Msg{%
     ******************************************^^J%
     * Using Configuration file docstrip.cfg. *^^J%
     ******************************************^^J}%
  \closein\inputcheck
  \afterfi{\@@input docstrip.cfg\relax}
\fi
%    \end{macrocode}
%
% Now run |\@setwritedir| in case it has not already been run
% by a command in a configuration file.
%    \begin{macrocode}
\@setwritetodir
%    \end{macrocode}
%
% \begin{macro}{\process@first@batchfile}
% \changes{2.4d}{1996/10/17}
%      {Macro added (DPC)}
% Process the batch file, and then terminate cleanly.
% This may be set to |\relax| for `new style' batch files that
% do not start with |\def\batchfile{|\ldots
%    \begin{macrocode}
\def\process@first@batchfile{%
  \processbatchFile  
  \ifnum\NumberOfFiles=\z@
    \interactive
  \fi
  \endbatchfile}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\endbatchfile}
% \changes{2.4d}{1996/10/17}
%      {Macro added (DPC)}
% User level command to end batch file processing.
% At the top level, returns totals and then stops \TeX.
% At nested levels just does |\endinput|.
%    \begin{macrocode}
\def\endbatchfile{%
  \iftopbatchfile
%<*stats>
    \ReportTotals
%</stats>
    \expandafter\end
  \else
    \endinput
  \fi}
%    \end{macrocode}
% \end{macro}
%
%    Now we see whether to process a batch file.
% \changes{2.4d}{1996/10/17}
%      {Move default batchfile check to outer level (DPC)}
%
%
% \begin{macro}{\@jobname}
% \changes{2.4d}{1996/10/17}
%      {Macro added (DPC)}
% Jobname (catcode 12)
%    \begin{macrocode}
\edef\@jobname{\lowercase{\def\noexpand\@jobname{\jobname}}}%
\@jobname
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\@docstrip}
% \changes{2.4d}{1996/10/17}
%      {Macro added (DPC)}
% docstrip (catcode 12)
%    \begin{macrocode}
\def\@docstrip{docstrip}%
\edef\@docstrip{\expandafter\strip@meaning\meaning\@docstrip}
%    \end{macrocode}
% \end{macro}
%
%    First check whether the user has
%    defined the control sequence |\batchfile|. If he did, it should
%    contain the name of the file to process. 
%    If he didn't, try the current file, unless that is |docstrip.tex|
%    in which case a default name is tried. 
%    Whether or not the default batch file is used is
%    remembered by setting the switch |\ifDefault| to \meta{true} or
%    \meta{false}.
%    \begin{macrocode}
\Defaultfalse
%    \end{macrocode}
%
%    \begin{macrocode}
\ifx\undefined\batchfile
%    \end{macrocode}
% |\@jobname| is lowercase jobname (catcode 12)\\
% |\@docstrip| is docstrip (catcode 12)
%    \begin{macrocode}
  \ifx\@jobname\@docstrip
%    \end{macrocode}
% Set the batchfile to the default
%    \begin{macrocode}
    \let\batchfile\DefaultbatchFile
    \Defaulttrue
%    \end{macrocode}
%  Else don't process a new batchfile, just carry on with past the end
% of this file. In this case processing will move to the initial
% batchfile which \emph{must} then be terminated by |\endbatchfile| or
% \TeX\ will fall to the star prompt.
%    \begin{macrocode}
  \else
    \let\process@first@batchfile\relax
  \fi
\fi
\process@first@batchfile
%    \end{macrocode}
%
%    \begin{macrocode}
%</program>
%    \end{macrocode}
%
% \Finale
\endinput
