% \def\filename{ifoption.dtx}
% \def\fileversion{1.02}
% \def\filedate{2002/03/04}
%
% \iffalse meta-comment
%
% American Mathematical Society
% Technical Support
% Publications Technical Group
% 201 Charles Street
% Providence, RI 02904
% USA
% tel: (401) 455-4080
%      (800) 321-4267 (USA and Canada only)
% fax: (401) 331-3842
% email: tech-support@ams.org
%
% Copyright 2001, 2010 American Mathematical Society.
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3c
% of this license or (at your option) any later version.
% The latest version of this license is in
%   http://www.latex-project.org/lppl.txt
% and version 1.3c or later is part of all distributions of LaTeX
% version 2005/12/01 or later.
% 
% This work has the LPPL maintenance status `maintained'.
% 
% The Current Maintainer of this work is the American Mathematical
% Society.
%
% \fi
%
% \iffalse
%<*driver>
\NeedsTeXFormat{LaTeX2e}
\documentclass{amsdtx}
\providecommand{\mdash}{\textemdash}
\newcommand{\xt}[1]{\texttt{#1}}
\providecommand{\qq}[1]{``#1''}
\providecommand{\lat}[1]{\protect\LaTeX{}}
\begin{document}
\title{The \pkg{ifoption} package}
\author{Michael~J. Downes\\American Mathematical Society}
\date{Version \fileversion, \filedate}
\DocInput{ifoption.dtx}
\end{document}
%</driver>
% \fi
%
% \maketitle
% \section{Introduction}
%
%    The \pkg{ifoption} package provides an \cn{IfOption} command that
%    has certain advantages over the \cs{@ifpackagewith} command\mdash
%    e.g., default options specified with \cs{ExecuteOptions} test as
%    true rather than false. In order for this to work properly,
%    mutually exclusive options should be specified with
%    \cs{DeclareExclusiveOptions}, another command defined by the
%    \pkg{ifoption} package.
% \StopEventually{}
%
% \section{Implementation}
% \subsection{Package info}
%
%    Standard declaration of package name and date.
%    \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{ifoption}[2002/03/04 v1.02]
%    \end{macrocode}
%
% \subsection{Some utility functions}
%
%    \begin{macrocode}
\let\@xp\expandafter \let\@nx\noexpand
%    \end{macrocode}
%
%    \begin{macrocode}
\def\@True{00}
\def\@False{01}
%    \end{macrocode}
%
% \subsection{Background}
%    See the definitions of \cs{@onefilewithoptions} and
%    \cs{@pushfilename} in the \lat/ kernel.
%
%    When we have
%\begin{verbatim}
%\DeclareOption{foo}{some code}
%\end{verbatim}
%    in a file named \fn{bar.sty}, \lat/ defines \cs{ds@foo} to contain
%    \emph{some code}. Then if the package is invoked with
%\begin{verbatim}
%\usepackage[foo]{bar}
%\end{verbatim}
%    there are two consequences: \opt{foo} is added to the options list
%    for package \pkg{bar}, which is the control sequence
%    \cs{opt@bar.sty}; and when \cs{ProcessOptions} is called, it
%    executes \cs{ds@option-name} for each option found in the list.
%    When it is finished running the options, \cs{ProcessOptions}
%    undefines all the \cs{ds@whatever} for the current package, which
%    are listed in the control sequence \cs{@declaredoptions}. At the
%    end of \fn{bar.sty}, \cs{@declaredoptions} is globally reset to
%    empty. Thus subordinate packages with options cannot be loaded in
%    the \qq{first half} of a package that also has options, where first half
%    means the area leading up to the \cs{ProcessOptions} call.
%
%    For mutually exclusive options \xt{a}, \xt{b}, \xt{c}, when option
%    \xt{b} is invoked it should remove all of its sibling options from
%    the options-actually-used list and add itself to the list. For this
%    task we make use of the fact that \cs{ProcessOptions} ends by
%    undefining all the declared options of the current package or
%    documentclass.
%
%    \begin{macrocode}
\def\CurrentPackage{\@currname}
\let\CurrentClass\CurrentPackage
%    \end{macrocode}
%
%    \begin{macrocode}
\newcommand{\IfOption}{}
\def\IfPackageOption{\@ifpackagewith}
\def\IfClassOption{\@ifclasswith}
\def\IfOption{%
  \ifx\@currext\@pkgextension \@xp\IfPackageOption
  \else \@xp\IfClassOption
  \fi
  \@currname
}
%    \end{macrocode}
%
%    \begin{macrocode}
\newcommand{\DeclareExclusiveOptions}[1]{%
  \xdef\@declaredoptions{\@declaredoptions,#1}%
  \gdef\ProcessExclusiveOptions{\relax}%
  \@for\CurrOption:=#1\do{%
    \@xp\deo@a\csname ds@\CurrOption\@xp\endcsname\@xp{\CurrOption}{#1}%
  }%
}
\def\DeclareBooleanOption{\DeclareExclusiveOptions}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\deo@a#1#2#3{%
  \def#1{%
    \g@addto@macro\ProcessExclusiveOptions{\OptionsFalseTrue{#3}{#2}}%
  }%
}
%    \end{macrocode}
%
%    \begin{macrocode}
\def\cull@options#1,{%
  \@xp\ifx\csname ds@#1\@gobble\@percentchar\@empty\endcsname\@False
  \else #1,\fi
  \cull@options
}

\newcommand{\OptionsFalseTrue}[2]{%
  \begingroup
  \@for\CurrentOption:=#1\do{%
    \@xp\let\csname ds@\CurrentOption\endcsname\@False
  }%
  \let\ds@\@False
  \@xp\xdef\csname opt@\@currname.\@currext\endcsname{%
    \@xp\@xp\@xp\cull@options\csname opt@\@currname.\@currext\endcsname
%    \end{macrocode}
%    Lacking \cs{@secondofthree} and not keen on defining it \ldots
%    \begin{macrocode}
      ,\@firstoftwo\@firstoftwo,#2%
  }%
  \endgroup
}
%    \end{macrocode}
%
%    The usual \cs{endinput} to ensure that random garbage at the end of
%    the file doesn't get copied by \fn{docstrip}.
%    \begin{macrocode}
\endinput
%    \end{macrocode}
%
% \CheckSum{112}
% \Finale