% \iffalse
%%
%% File `bitfield.dtx'.
%% Copyright (C) 1997-2001 Reuben Thomas (rrt@sc3d.org)
%% Copyright (C) 2001      Roland Illig
%% This file is distributed under the LaTeX Project Public License,
%% and comes with no warranty.
%%
%
%<*dtx>
\ProvidesFile{bitfield.dtx}
%</dtx>
%<driver> \ProvidesFile{bitfield.drv}
% \fi
%
% \iffalse
%<*driver>
\documentclass{ltxdoc}
\usepackage{url,dashbox,bitfield}
\begin{document}
\DocInput{bitfield.dtx}
\end{document}
%</driver>
% \fi
%
% \GetFileInfo{bitfield.dtx}
% \CheckSum{243}
%
% \MakeShortVerb{\|}
%
% \changes{v1.00}{1 Mar 97}{First version (unreleased)}
% \changes{v1.17}{2 Jun 99}{Dashed boxes, stacks and sub-columns
% added; various bugs fixed}
% \changes{v1.18}{28 Jul 01}{Made into a doc package; documentation
% added. At signs inserted into private macro names. Tidied up some
% infelicities.}
% \changes{v1.19}{8 Aug 01}{Changed some references to dashbox that
% should be to bitfield, and changed ``dashdbox'' refs to ``dashbox''
% to cope with the renaming of that package. Uncommented the commands
% starting |\NeedsTeXFormat| so they are copied into the package.}
% \changes{v2.00}{12 Dec 01}{Added the option to have a plain label
% above the box rather than a rule (thanks to Roland Illig); changed
% the bit field commands to take a style string rather than having
% variants of the commands, renamed internal and external commands to
% start with |bit| rather than |bits|, to avoid confusion. Corrected
% description of package in |\ProvidesPackage| (it was using that for
% dashbox!). Made the package require calc 4.1b (to avoid a bug in
% 4.1a), and the most recent version of dashbox.}
%
% \title{Bit field diagrams}
% \author{Reuben Thomas\\\url{rrt@sc3d.org}\and Roland Illig}
% \date{12th December 2001}
% \maketitle
%
% \begin{abstract}
% |bitfield| provides an environment and commands for drawing
% bit field diagrams, which can be used to describe instruction sets,
% object code formats, and other bit field based data structures.
% \end{abstract}
%
% \section{User interface}
%
% \subsection{Bit field environment}
%
% \DescribeEnv{bitfield}
% Bit field diagrams are drawn in the |bitfield| environment, which
% takes two arguments. The first, optional argument gives the width of
% a word (default 4in), and the second the number of bits per word.
% Each word comprises a number of bit fields, and the words are drawn
% as a column. Words are ended by |\\|.
%
% \DescribeEnv{xbitfield}
% The |bitfield| environment is actually written in terms of the
% |xbitfield| environment, which has an extra parameter (the second),
% giving the left and right margin (the |bitfield| environment uses
% |\layersize|).
%
% \DescribeMacro{\bits}
% The basic bit field command is |\bits|.
% |\bits[|\textit{style}|]{|\textit{label}|}{|\textit{bits}|}{|\textit{contents}|}|
% draws a bit field with the given label, number of bits and contents.
% The optional argument gives the bit field style, which is a string of
% flag letters. |d| draws the box dashed, useful for indicating
% optional structures. and |r| puts the label text in a rule
% which spans the box.
%
% \DescribeMacro{\bitstack}
% To indicate plurals, for example, where a particular word or data
% structure may be repeated, |\bitstack| can be used, which produces
% the appearance of a stack of bit fields. It may only be used once
% per word (i.e.\ once per line).
% |\bitstack[|\textit{style}|]{|\textit{label}|}{|\textit{bits}|}{|\textit{contents}|}|
% draws a stack of width \textit{bits}. The first three arguments are
% as for |\bits|. The \textit{contents} will typically be a |\bits|
% command; |\bitstack| itself only draws the stack effect. The
% enclosed |\bits| should not have a label.
%
% For technical reasons, the first bit field on each line is
% |\fboxrule| narrower than it should be; this should not be
% noticeable for typical values of |\fboxrule|. (See
% section~\ref{fudge} for the full story.)
%
% \subsection{Alternatives}
%
% \DescribeMacro{\bitsub}
% Sometimes a data structure may have its bit fields divided in
% different ways according to circumstances, or a particular field may
% hold one of a small range of values. To show these sorts of
% alternatives, you can use |\bitsub|, which produces a sub-column of
% bit fields, vertically centred on the current word.
% |\bitsub[|\textit{style}|]{|\textit{label}|}{|\textit{bits}|}{|\textit{contents}|}|
% makes a sub-column of width \textit{bits}. The first three arguments
% are as for |\bits|, and \textit{contents} is the series of bit
% fields to go in the column, as if in a |bitfield| environment,
% separated by |\\|.
%
% \DescribeMacro{\bitsubspaced}
% |\bitsub| draws the alternative bit fields contiguously; to make
% room for a label on each bit field, use |\bitsubspaced|. 
% |\bitsubspaced| is the same as |\bitsub|, except that the second
% argument is omitted; a label can be given as that of the top-most
% bit field in the contents.
%
% \subsection{Helper commands}
%
% Some other commands are provided to help draw bit field diagrams.
% \DescribeMacro{\bitdots} |\bitdots| draws a vertical ellipsis,
% like |\vdots|, but centred on the column of words.
% \DescribeMacro{\bittext} |\bittext{|\textit{text}|}| allows text
% to be inserted between words in a column, adding appropriate
% vertical spacing.
%
% \subsection{Style parameters}
%
% There are many style parameters that allow the layout of bit field
% diagrams to be customised:
%
% \begin{itemize}
% \item[]\hskip-\leftmargin
% \DescribeMacro{\bitalign}
%    |\bitalign| gives the alignment within the |bitfield|
%    environment; defaults to |\centering|.
% \item[]\hskip-\leftmargin
% \DescribeMacro{\bitboxsep}
%    |\bitboxsep| is the width of the left and right margins of the
%    bit field box; defaults to |\fboxsep|.
% \item[]\hskip-\leftmargin
% \DescribeMacro{\bitboxdepth}
%    |\bitboxdepth| is the depth of a bit field box; defaults to
%    0.9ex. 
% \item[]\hskip-\leftmargin
% \DescribeMacro{\bitboxheight}
%    |\bitboxheight| is the height of bit field box; defaults to
%    3.2ex. 
% \item[]\hskip-\leftmargin
% \DescribeMacro{\bitskip}
%    |\bitskip| is the vertical space between words; defaults to
%    0.8ex. 
% \item[]\hskip-\leftmargin
% \DescribeMacro{\bitrule}
%    |\bitrule| is the thickness of the label rule; defaults to
%    |\fboxrule|.
% \item[]\hskip-\leftmargin
% \DescribeMacro{\bitlabellift}
%    |\bitlabellift| is the lift of the label above the top of
%    the box; defaults to 0.4ex.
% \item[]\hskip-\leftmargin
% \DescribeMacro{\bitruleheight}
%    |\bitruleheight| is the height of the label rule above the
%    baseline (top of the box); defaults to 0.6ex.
% \item[]\hskip-\leftmargin
% \DescribeMacro{\bitruleendlift}
%    |\bitruleendlift| is the height of the ends of the label
%    rule above the baseline; defaults to 0.2ex.
% \end{itemize}
% \StopEventually{}
%
%
% \section{Example}
%
% Here is an example showing most of the features of the |bitfield|
% package:
%
% \begin{center}
% \begin{bitfield}{32}
% \bits{31}{1}{s}
% \bits{30 \hfill 23}{8}{eeeeeeee}
% \bits{22 \hfill 0}{23}{mmmmmmmmmmmmmmmmmmmmmm} \\
% \end{bitfield}
% \end{center}
%
% \begin{center}
% \begin{bitfield}{16}
% \bits[r]{sixteen}{16}{16 bits wide}\\
% \bits[d]{}{4}{optional}\bitstack{}{4}{\bits{}{4}{many}}\\
% \bits[r]{}{8}{fixed}%
%   \bitsubspaced{8}{\bits{}{8}{optional 1}\\\bits{}{8}{optional 2}}\\
% \end{bitfield}
% \end{center}
%
%
% \section{Implementation}
%
% \subsection{Preliminaries}
%
% Make sure we've got what we need, and announce the package.
%
%    \begin{macrocode}
%<*package>
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{bitfield}[2001/12/12 v2.00 Bit field diagrams]
\RequirePackage{dashbox}[2001/12/11]
\RequirePackage{calc}[1998/07/07]
\RequirePackage{ifthen}
%    \end{macrocode}
%
% \subsection{Style parameters}
%
% Define and give the default values of the style parameters.
%
% \begin{macro}{\bitalign}
%    \begin{macrocode}
\newcommand{\bitalign}{\centering}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\bitboxsep}
%    \begin{macrocode}
\newlength{\bitboxsep} \setlength{\bitboxsep}{\fboxsep}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\bitboxdepth}
%    \begin{macrocode}
\newlength{\bitboxdepth} \setlength{\bitboxdepth}{0.9ex}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\bitboxheight}
%    \begin{macrocode}
\newlength{\bitboxheight} \setlength{\bitboxheight}{3.2ex}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\bitskip}
%    \begin{macrocode}
\newlength{\bitskip} \setlength{\bitskip}{0.8ex}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\bitrule}
%    \begin{macrocode}
\newlength{\bitrule} \setlength{\bitrule}{\fboxrule}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\bitlabellift}
%    \begin{macrocode}
\newlength{\bitlabellift} \setlength{\bitlabellift}{0.4ex}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\bitruleheight}
%    \begin{macrocode}
\newlength{\bitruleheight} \setlength{\bitruleheight}{0.6ex}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\bitruleendlift}
%    \begin{macrocode}
\newlength{\bitruleendlift} \setlength{\bitruleendlift}{0.2ex}
%    \end{macrocode}
% \end{macro}
%
% In addition, define some private variables:
%
% \begin{itemize}
% \item[]\hskip-\leftmargin
% \DescribeMacro{\bitw@dth}
%    |\bitw@dth| is the width of a bit in the current word.
% \item[]\hskip-\leftmargin
% \DescribeMacro{\bitb@xwidth}
%    |\bitb@xwidth| is the width of the current field, excluding
%    margins.
% \item[]\hskip-\leftmargin
% \DescribeMacro{\bitw@dthwidth}
%    |\bitw@dthwidth| is the width of the label rule.
% \item[]\hskip-\leftmargin
% \DescribeMacro{\bitruled@pth}
%    |\bitruled@pth| is  the depth of the label rule, which is
%    the thickness minus the height.
% \item[]\hskip-\leftmargin
% \DescribeMacro{\bitrule@ndheight}
%    |\bitrule@ndheight| is the height of the ends of the rule.
% \item[]\hskip-\leftmargin
% \DescribeMacro{bitb@xfirst}
%    |bitb@xfirst| is a boolean that is true when the first bit field
%    in a word is being set.
% \item[]\hskip-\leftmargin
% \DescribeMacro{\bitb@x}
%    |\bitb@x| is a save box used to hold a bitfield while the rule
%    is being added.
% \end{itemize}
%
% \begin{macro}{\bitw@dth}
%    \begin{macrocode}
\newlength{\bitw@dth}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\bitb@xwidth}
%    \begin{macrocode}
\newlength{\bitb@xwidth}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\bitw@dthwidth}
%    \begin{macrocode}
\newlength{\bitw@dthwidth}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\bitruled@pth}
%    \begin{macrocode}
\newlength{\bitruled@pth}
    \setlength{\bitruled@pth}{\bitrule-\bitruleheight}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\bitrule@ndheight}
%    \begin{macrocode}
\newlength{\bitrule@ndheight}
    \setlength{\bitrule@ndheight}%
    {\bitruleheight*2-\bitrule-\bitruleendlift*2}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{bitb@xfirst}
%    \begin{macrocode}
\newboolean{bitb@xfirst}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\bitb@x}
%    \begin{macrocode}
\newsavebox{\bitb@x}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Internal commands}
%
% Some internal helper commands are defined first.
%
% \begin{macro}{\bitdec@destyle}
% |\bitdec@destyle| decodes a style string. Three commands are set
% up: |\bitb@xcmd|, to draw the box, |\bitst@ckcmd|, to draw a bit
% stack box, and |\bitl@belcmd|, to draw a label.
%
%    \begin{macrocode}
\newcommand{\bitb@xcmd}{\framebox}%
\newcommand{\bitst@ckcmd}{\lbox}%
\newcommand{\bitl@belcmd}{\bitl@bel}%
\newcommand{\bitdec@destyle}[1]{%
%    \end{macrocode}
%
% First, the commands are initialised with their default values.
%
%    \begin{macrocode}
    \renewcommand{\bitb@xcmd}{\framebox}%
    \renewcommand{\bitst@ckcmd}{\lbox}%
    \renewcommand{\bitl@belcmd}{\bitpl@inlabel}%
%    \end{macrocode}
%
% The style string is then scanned, and the commands altered
% accordingly. The code here is adapted from that for the
% picture version of |\makebox|.
%
%    \begin{macrocode}
    \@tfor\reserved@a :=#1\do{%
      \if d\reserved@a
            \renewcommand{\bitb@xcmd}{\dashbox}%
            \renewcommand{\bitst@ckcmd}{\dlbox}%
        \else
            \if r\reserved@a%
                \renewcommand{\bitl@belcmd}{\bitrulel@bel}%
            \fi
        \fi}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\bitle@der}
% |\bitle@der| produces the middle sections of label rules.
%
%    \begin{macrocode}
\newcommand{\bitle@der}{%
    \cleaders\hrule height \bitruleheight depth \bitruled@pth%
    \hfill}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\bitpl@inlabel}
% |\bitpl@inlabel| draws a label over a bit field box. The first argument
% gives the width of the label, and the second the label text. The
% label text is set at |\footnotesize|.
%
%    \begin{macrocode}
\newcommand{\bitpl@inlabel}[2]{%
    \makebox[#1]{\footnotesize #2}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\bitrulel@bel}
% |\bitrulel@bel| draws a label with a rule. The first argument gives
% the width, and the second the text to go in the middle.
%
%    \begin{macrocode}
\newcommand{\bitrulel@bel}[2]{%
%    \end{macrocode}
%
% The rule is typeset in a box of the given width
%
%    \begin{macrocode}
    \makebox[#1]{%
%    \end{macrocode}
%
% The label text is set at |\footnotesize|; the left-hand end is drawn,
% followed by the left-hand horizontal, then a thin space, the
% contents, another thin space, the right-hand horizontal, and finally
% the right-hand end.
%
%    \begin{macrocode}
        \footnotesize%
        \rule[\bitruleendlift]{\bitrule}{\bitrule@ndheight}%
        \bitle@der\,#2\,\bitle@der%
        \rule[\bitruleendlift]{\bitrule}{\bitrule@ndheight}}%
    }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\bitl@bel}
% |\bitl@bel| labels a bit field box. The first, optional, argument
% gives an increment to add to the width of the label; this is used
% for drawing stacks. The second argument gives the label text; the
% third is the width of the box in bits, and the fourth is the box
% itself.
%
%    \begin{macrocode}
\newcommand{\bitl@bel}[4][0pt]{%
%    \end{macrocode}
%
% The bit field box is saved.
%
%    \begin{macrocode}
    \sbox{\bitb@x}{#4}%
%    \end{macrocode}
%
% |\bitw@dthwidth| is calculated from the size of the box; the first
% argument, if any, is added to it.
%
%    \begin{macrocode}
     \setlength{\bitw@dthwidth}{\wd\bitb@x-\bitboxsep*2-\fboxrule*2}%
     \addtolength{\bitw@dthwidth}{#1}%
%    \end{macrocode}
%
% The label is drawn in a zero-width box, so that it takes up no space,
% to avoid formatting problems.
%
%    \begin{macrocode}
     \ifthenelse{\equal{#2}{}}{\relax}{\makebox[0pt][l]{%
%    \end{macrocode}
%
% The label is raised by |\bitlabellift|, and the given horizontal
% margin is left.
%
%    \begin{macrocode}
         \raisebox{\ht\bitb@x}{\raisebox{\bitlabellift}{%
             {\hspace*{\fboxrule}\hspace*{\bitboxsep}%
%    \end{macrocode}
%
% The label is drawn.
%
%    \begin{macrocode}
             \bitl@belcmd{\bitw@dthwidth}{#2}%
         }}}}}%
%    \end{macrocode}
%
% The box is now drawn underneath.
%
%    \begin{macrocode}
    \usebox{\bitb@x}%
    }%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\m@kebits}
% |\m@kebits| draws a bit field box. The arguments are the label
% text, the number of bits in the field, and the contents of the field.
%
%    \begin{macrocode}
\newcommand{\m@kebits}[3]{%
%    \end{macrocode}
%
% |\bitb@xwidth| is set; the length is incremented by |\fboxrule| if
% this box is not the first on the current line. This is because the
% first box has two sides drawn; the rest only have the right-hand
% side (subsequent box's left-hand sides overlap with the previous
% box's right-hand side). |bitb@xfirst| is set to |false|, as the
% next box cannot be the first!
%
%    \begin{macrocode}
    \setlength{\bitb@xwidth}{\bitw@dth*#2}%
    \ifthenelse{\boolean{bitb@xfirst}}%
        {}%
        {\addtolength{\bitb@xwidth}{\fboxrule}}%
    \setboolean{bitb@xfirst}{false}%
%    \end{macrocode}
%
% |\fboxsep| is locally set to 0pt, and the label and box are drawn.
% The contents of the box is centred, and a margin of |\bitboxsep| is
% left around it. 
%
%    \begin{macrocode}
    \setlength{\fboxsep}{0pt}%
    \bitl@bel{#1}{#2}{\bitb@xcmd[\bitb@xwidth]%
        {\rule[-\bitboxdepth]{0pt}{\bitboxheight}%
        \hspace*{\bitboxsep}\hfill#3\hfill\hspace*{\bitboxsep}}%
%    \end{macrocode}
%
% A negative space is left so that the next box's left-hand side
% overlaps with this box's right-hand side.
%
%    \begin{macrocode}
    \hspace*{-\fboxrule}}%
    }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\m@kestack}
% |\m@kestack| draws a bit field stack; it takes the same arguments as
% |\m@kebits|.
%
%    \begin{macrocode}
\newcommand{\m@kestack}[3]{%
    \setlength{\fboxsep}{0pt}%
    \bitl@bel[-2\layersize]{#1}{#2}{\bitst@ckcmd{#3\hspace*{\fboxrule}}}%
    }
%    \end{macrocode}
% \end{macro}
%
% \subsection{User commands}
%
% Most of the user commands are just wrappers for the internal
% commands.
%
% \begin{macro}{\bits}
%    \begin{macrocode}
\newcommand{\bits}[4][]{%
    \bitdec@destyle{#1}%
    \m@kebits{#2}{#3}{#4}}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\bitstack}
%    \begin{macrocode}
\newcommand{\bitstack}[4][]{%
    \bitdec@destyle{#1}%
    \m@kestack{#2}{#3}{#4}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\bitsubspaced}
% |\bitsubspaced| sets its third argument in an |xbitfield|
% environment with 0pt margins and no alignment, and ends with the
% same negative kern as |\bits|.
%
%    \begin{macrocode}
\newcommand{\bitsubspaced}[3][]{%
    \bitdec@destyle{#1}%
    \renewcommand{\bitalign}{\relax}%
    \begin{xbitfield}[#2\bitw@dth]{0pt}{#2}#3\end{xbitfield}%
    \hspace*{-\fboxrule}}
%    \end{macrocode}
% \end{macro}
%
% \label{fudge}
% \begin{macro}{\bitsub}
% |\bitsub| is written using |\bitsubspaced| by changing |\bitskip| to
% $-$|\fboxrule|, so that the boxes overlap vertically in the same way
% that bit fields normally do horizontally. Note the extra level of
% bracketing so that the |\setlength| has only a local effect.
%
%    \begin{macrocode}
\newcommand{\bitsub}[4][]{%
    {\setlength{\bitskip}{-\fboxrule}%
    \bitl@bel{#2}{#3}{\bitsubspaced[#1]{#3}{#4}}}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\bitdots}
% |\bitdots| simply draws a centred vertical ellipsis, 2.5ex high,
% centred in a parbox of width |\textwidth|.
%
%    \begin{macrocode}
\newcommand{\bitdots}{%
    \parbox{\textwidth}{%
        \centering\vbox to 2.5ex{%
            \cleaders\vbox to 0.8ex{\vfill.\vfill}\vfill}}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\bittext}
% |\bittext| draws a zero-width rule of the correct height and depth
% for a box next to the given text.
%
%    \begin{macrocode}
\newcommand{\bittext}[1]{%
    \rule[-\bitboxdepth]{0pt}{\bitboxheight}#1}
%    \end{macrocode}
% \end{macro}
%
% \subsection{The environments}
%
% \begin{environment}{xbitfield}
% The |xbitfield| environment provides the innards of the |bitfield|
% environment. It provides a little extra customization, by means of
% its second argument, which gives the left and right margin. The
% other two arguments are as for the |bitfield| environment.
%
%    \begin{macrocode}
\newenvironment{xbitfield}[3][4in]%
%    \end{macrocode}
%
% First, |\bitw@dth| is calculated.
%
%    \begin{macrocode}
    {\setlength{\bitw@dth}{(#1-#2*2)/#3}%
%    \end{macrocode}
%
% The words are set in a minipage; the alignment is set according to
% |\bitalign|, and inter-line spacing is turned off, so that only the
% bit field layout parameters affect the result. |\endlinechar| is set
% to $-1$ so that blank lines do not start a new paragraph. |\\| is
% redefined to set |bitb@xfirst| to |true| as well as ending the
% line, and |bitb@xfirst| is set to |true|.
%
%    \begin{macrocode}
    \begin{minipage}{#1}\bitalign%
    \offinterlineskip%
    \endlinechar=-1%
    \renewcommand{\\}%
        {\par\vspace{\bitskip}\setboolean{bitb@xfirst}{true}}%
    \setboolean{bitb@xfirst}{true}%
    }%
%    \end{macrocode}
%
% At the end of the environment, the minipage is closed, and
% |bitb@xfirst| is set to |false| in case a |\bits| command is used
% outside a |bitfield| environment (though that is not recommended).
%    \begin{macrocode}
    {\end{minipage}%
    \setboolean{bitb@xfirst}{false}}
%    \end{macrocode}
% \end{environment}
%
% \begin{environment}{bitfield}
% The |bitfield| environment simply invokes the |xbitfield|
% environment with a margin of |\layersize|.
%
%    \begin{macrocode}
\newenvironment{bitfield}[2][4in]%
    {\begin{xbitfield}[#1]{\layersize}{#2}}%
    {\end{xbitfield}}
%    \end{macrocode}
% \end{environment}