cgal/Packages/Manual_tools/format/cc_manual.sty

1238 lines
53 KiB
TeX

% +----------------------------------------
% | new commands needed in the new mechamism
% | 03.08.1995 Berlin Lutz Kettner
% | $Revision$
% | $Date$
% +----------------------------------------
{ \catcode`\$=12
\def\cs #1$#2${\gdef#1{#2}}
\cs\CCrevision$Revision$
\cs\CCdate$Date$
}
%\tracingmacros=1
% +--------------------------------------------------------------------------
% | Dimensions (from the LEDA Manual):
% +--------------------------------------------------------------------------
%\hoffset=-0.5truemm \voffset=0.5truecm
%\hsize=16truecm \vsize=23.5truecm
%\hsize=13.3truecm \vsize=19.8truecm
\baselineskip 14pt
\spaceskip .4em plus .25em minus .25em
\xspaceskip .65em
\parskip 11pt plus 1pt minus 1pt
\parindent 0pt
% +--------------------------------------------------------------------------
% | New Dimensions (for the CGAL Manual):
% | Especially to format all multi column declarations.
% |
% | The dimensions \CCfirst and \CCsecond are set to the appropriate
% | values. Afterwards, the \CCinitWidths does the rest.
% +--------------------------------------------------------------------------
% redefine this macro to be \CCtrue to switch the alternative
% three column formatting on.
\def\CCalternateThreeColumn{\CCfalse}
\newdimen\CCWindent
\newdimen\CCWfirst
\newdimen\CCWfirstlong
\newdimen\CCWsecond
\newdimen\CCWsecondlong
\newdimen\CCWcomment
\newdimen\CCWbetween
\newdimen\CCWparam
\newdimen\CCWparamindent
\newdimen\CCWfunctionfirst
\newdimen\CCWfunctionsecond
\newdimen\CCWconstructorfirst
\newdimen\CCWconstructorsecond
% init them
% ---------
\CCWindent = 0pt
\CCWbetween = 0.5cm
\CCWparamindent = 1.2cm
\CCWfunctionfirst = 2.5cm
\CCWfunctionsecond = 4.5cm
\CCWconstructorfirst = 0pt
\CCWconstructorsecond = 2.5cm
\def\CCinitWidths{%
\CCWfirstlong = \textwidth
\advance\CCWfirstlong -\CCWindent
\CCWsecondlong = \CCWfirstlong
\advance\CCWsecondlong -\CCWfirst
\advance\CCWsecondlong -\CCWbetween
\CCWcomment = \CCWsecondlong
\advance\CCWcomment -\CCWsecond
\advance\CCWcomment -\CCWbetween
\CCWparam = \CCWfirst
\advance\CCWparam \CCWbetween
\advance\CCWparam \CCWparamindent
}
\CCinitWidths
% define macros for the vertical structuring
% ------------------------------------------
\def\CCtopskip{\smallskip}
\def\CCreturnskip{\par\hspace*{\CCWindent}\hspace*{\CCWfirst}%
\hspace*{\CCWbetween}}
\def\CCmiddleskip{\par\hspace*{1cm}\hfill}
\def\CCbottomskip{\par\smallskip}
\def\CCbottombigskip{\par\bigskip}
% +--------------------------------------------------------------------------
% | Original LEDA Manual macros (shortcuts):
% | Several new shortcuts for CGAL
% |
% | \CC, \gg, \nat, \real, \boxit
% | \leda, \cgal, \protocgal, \plageo
% +--------------------------------------------------------------------------
\def\CC{C\raise.08ex\hbox{\tt ++}}
\def\gg{g\hbox{\tt ++}}
\def\nat{\hbox{\rm I\kern-0.045em N}}
\def\real{\hbox{\rm I\kern-0.035em R}}
% \def\boxit#1{\vbox{\hrule\hbox{\vrule\kern3pt\vbox{#1}\kern3pt\vrule}\hrule}}
\newcommand{\leda}{{\sc Leda}}
\newcommand{\cgal}{{\sc Cgal}}
\newcommand{\protocgal}{{\sc C++gal}}
\newcommand{\plageo}{{\sc Plageo}}
% +--------------------------------------------------------------------------
% | Structuring macros (similar to LEDA Manual):
% |
% | \CCsection, \definition, \creation, \operations, \implementation,
% | \example, \precond
% +--------------------------------------------------------------------------
\def\CCsection #1{%
\section[#1 (\protect\CCprintSingleToken \pureclassname;)]%
{#1 (\classname)}
\label{#1}}
\def\definition {\bigskip\pagebreak[1]
{\bf 1. Definition}
\par\nopagebreak }
\def\creation {\bigskip\pagebreak[1]
{\bf 2. Creation}
\par\nopagebreak }
\def\operations {\bigskip\pagebreak[1]
{\bf 3. Operations}
\par\nopagebreak }
\def\implementation {\bigskip\pagebreak[1]
{\bf 4. Implementation}
\par\nopagebreak }
\def\example {\bigskip\pagebreak[1]
{\bf 5. Example}
\par\nopagebreak }
\def\precond {{\it Precondition}: }
% +--------------------------------------------------------------------------
% | C++ declarations for different C++ language elements:
% |
% | \begin{class}, \begin{classtemplate}, \end...
% | \creationvariable, \threecolumns, \constructor, \method, \function
% | \CCstyle
% +--------------------------------------------------------------------------
\newenvironment{class}{%
\begingroup\CCcatcode
\classX%
}{
\gdef\pureclassname{}%
\gdef\puretemplatename{}%
\gdef\classname{}%
\gdef\classtemplatename{}%
\gdef\purevar{}%
\gdef\var{}%
}
\def\classX #1{%
\endgroup
\classXX #1<\end}
\def\classXX #1<#2\end{%
\def\xparams{#2}\ifx\xparams\empty
\classXXX{#1}%
\else
\errmessage{Template parameters are not allowed
in a normal class. Use \begin{classtemplate}
instead}>%
\classXXX{#1<???>}%
\fi}
\def\classXXX #1{%
\gdef\pureclassname{#1}%
\gdef\puretemplatename{#1}%
\gdef\pureparameters{}%
\gdef\classname{\hbox{{\CCfont
\CCprintTokens #1\end\CCendfont}}}%
\gdef\classtemplatename{\hbox{{\CCfont
\CCprintTokens #1\end\CCendfont}}}%
}
\newenvironment{classtemplate}{%
\begingroup\CCcatcode
\classtemplateX%
}{
\gdef\pureclassname{}%
\gdef\puretemplatename{}%
\gdef\pureparameters{}%
\gdef\classname{}%
\gdef\classtemplatename{}%
\gdef\purevar{}%
\gdef\var{}%
}
\def\classtemplateX #1{%
\endgroup
\classtemplateXX #1<\end}
\def\classtemplateXX #1<#2\end{%
\def\xparams{#2}\ifx\xparams\empty
\errmessage{Template parameters missed for
class template}>%
\classtemplateXXX{#1}<???><\end%
\else
\classtemplateXXX{#1}<#2\end%
\fi}
\def\classtemplateXXX #1#2<\end{%
\gdef\pureclassname{#1}%
\gdef\puretemplatename{#1#2}%
\gdef\pureparameters{#2}%
\gdef\classname{\hbox{{\CCfont
\CCprintTokens #1\end\CCendfont}}}%
\gdef\classtemplatename{\hbox{{\CCfont
\CCprintTokens #1#2\end\CCendfont}}}%
}
\def\creationvariable {%
\begingroup\CCcatcode\creationvariableX}
\def\creationvariableX #1{%
\gdef\var{{\CCfont #1\CCendfont}}
\gdef\purevar{#1}
\endgroup}
\def\threecolumns #1#2{%
\global\CCWfunctionfirst=#1
\global\CCWfunctionsecond=#2
}
\def\constructor {%
\begingroup\CCcatcode\constructorX}
\def\constructorX #1{%
\endgroup
\constructorXX{#1}}
\long\def\constructorXX #1#2{%
\constructorcall {#2}#1\end}
% \CCglobalContinuation and \CCglobalDecl is used to fiddle an empty
% comment behind the other parameters of a declaration without parsing
% these parameters as arguments (the catcodes are not set yet).
% Compare the normal and the global version of a declaration macro.
\gdef\CCglobalDecl{\CCfalse}
\gdef\CCglobalContinuation #1{%
\ifnum\CCglobalDecl=\CCtrue
\def\CClocalCont{#1{}}
\let\continuation=\CClocalCont
\else
\def\CClocalCont{#1}
\let\continuation=\CClocalCont
\fi
\gdef\CCglobalDecl{\CCfalse}
\continuation
}
% Methods and functions can contain the active character or the comment
% character % of TeX's own character set. Therefore, we assign new
% \catcode values to them and parse the first argument after that, close
% the group and parse the second argument with the \CCcommentX macro.
\def\method {%
\begingroup\CCcatcode
\functionX{0}}
\def\function {%
\begingroup\CCcatcode
\functionX{1}}
\def\functionX #1#2{%
\endgroup
\CCglobalContinuation{\CCcomment{#1}{#2}}}
\long\def\CCcomment #1#2#3{%
\functioncall{#1}{#3}#2;\end}
% A three! parameter macro to format template functions
% o The 1st parameter contains the template parameters.
% o The 2nd parameter contains the function declaration.
% o The 3rd parameter contains the comment.
\def\functiontemplate #1{\function}
% typedef's, variables, and constants are like functions without parameters.
\def\variable {%
\begingroup\CCcatcode
\variableX}
\def\variableX #1{%
\endgroup
\CCglobalContinuation{\variableXX{#1}}}
\long\def\variableXX #1#2{%
\CCvariableDeclaration{#2}#1;\end}
\def\typedef {\variable}
% Enum's are formatted like constructors. There is exact one matching
% pair of braces in the declaration.
\def\enum {%
\begingroup\CCcatcode
\catcode`\[=1
\catcode`\]=2
\catcode`\{=12
\catcode`\}=12
\enumX}
\begingroup
\catcode`\[=1
\catcode`\]=2
\catcode`\{=12
\catcode`\}=12
\gdef\enumX {#1{#2}#3}[%
\endgroup
\CCglobalContinuation[\enumXX[#1\{#2\}#3]]]
\endgroup
\def\enumXX #1#2{%
\CCenumDeclaration {#2}#1\end}
% All simple macros work also at the global level. The following
% `global' versions are only shortcuts to omit the comment parameter,
% so that global declarations are always commented inbetween and not in
% the last column. Note hat declarations always can extend in the last
% column, so the previous column has not to be reshaped.
\def\globalfunction {\gdef\CCglobalDecl{\CCtrue}\function}
\def\globalfunctiontemplate {\gdef\CCglobalDecl{\CCtrue}\functiontemplate}
\def\globalenum {\gdef\CCglobalDecl{\CCtrue}\enum}
\def\globalvariable {\gdef\CCglobalDecl{\CCtrue}\variable}
\def\globaltypedef {\gdef\CCglobalDecl{\CCtrue}\typedef}
% Print one parameter in C++ style (including spaces).
\def\CCstyle {%
\begingroup\CCcatcode\CCstyleX}
\def\CCstyleX #1{%
{\CCfont \CCprintTokens #1\end\CCendfont}\endgroup}
% +--------------------------------------------------------------------------
% | Formatting styles:
% |
% | The style of the C++ formatting can be customized by redefining the
% | following macros.
% +--------------------------------------------------------------------------
\gdef\CCfont{\it} % font or style changing command in which all C++
% tokens will be typeset, including the variable names.
\gdef\CCendfont{\/} % will be used after a C++ text. For slanted fonts,
% here should stay \/ macro. The C++ code will be
% grouped, so this macros has not to restore the old
% font.
% The special characters in typical C++ declarations:
\gdef\CCopenangle {\CCendfont {\tt <}}
\gdef\CCcloseangle {\CCendfont {\tt >}}
\gdef\CCampersand {\CCendfont {\tt \&}}
\gdef\CCunderscore {\_}
\gdef\CChat {{\large $\;\,\hat{}\,\,$}}
\gdef\CCtilde {{\lower.3ex \hbox{\large$\,\tilde{}\,$}}}
% The sign for an empty parameter (i.e. of the type of the current class).
\gdef\CCemptyParameter {$\diamondsuit$}
% Set the catcodes according to the C++ character set (including operators).
\gdef\CCcatcode {%
\catcode`\~=12
\catcode`\_=12
\catcode`\^=12
\catcode`\#=12
\catcode`\%=12 }
% +--------------------------------------------------------------------------
% | Predicates:
% |
% | isEmpty, isLetter, hasLeadingSpace, isOperator, isParenthesisOperator
% | isConversionOperator
% |
% | All predicates uses pattern matching of TeX. The original predicate uses
% | a single parameter that should be in braces like in LaTeX. Internally,
% | they use a second, auxiliary macro with pattern matching where the
% | parameter has to be terminated by an \end token.
% |
% | Result is stored in the counter \CCbool. \CCfalse, \CCtrue are also
% | counters that are used in the \ifnum statement to test the result.
% +--------------------------------------------------------------------------
% The counter \CCbool contains the result of a couple of predicates
\newcount\CCbool % either 0 for false or 1 for true.
\newcount\CCfalse \CCfalse=0 % This must be constant 0 !!!
\newcount\CCtrue \CCtrue=1 % This must be constant 1 !!!
% A small macro to invert \CCbool
\def\CCinvert {%
\ifnum\CCbool=\CCfalse \CCbool=\CCtrue \else\CCbool=\CCfalse \fi}
% This macro test wheather its argument is empty or contains only spaces.
\def\isEmpty #1{%
\isEmptyX #1;\end}
\def\isEmptyX #1#2\end{%
\def\xparams{#2}\ifx\xparams\empty \CCbool=\CCtrue
\else \CCbool=\CCfalse \fi}
% This macro test wheather its argument starts (after leading spaces) with
% with a valid C++ letter.
\def\isLetter #1{%
\def\qparams{#1}\ifx\qparams\empty\CCbool=\CCfalse
\else\isLetterX #1\end\fi}
\def\isLetterX #1#2\end{%
\CCbool=\CCfalse
\ifcat#1A\CCbool=\CCtrue
\else\ifnum`#1>`/\ifnum`#1<`:\CCbool=\CCtrue \fi\fi
\if#1_\CCbool=\CCtrue \fi
\fi}
% These macros allow the characterwise parsing of an argument, where normally
% the spaces are ignored.
% Here, the first macro can be applied to the rest of the argument and
% will return \CCtrue in the \CCbool iff the rest starts with a space.
% The second macro will produce a space "\ " iff the rest starts with a space.
% The space of the rest will be skipped automatically in the next round.
\def\hasLeadingSpace #1{%
\def\qparams{#1}\ifx\qparams\empty\CCbool=\CCfalse
\else\compareSpace{#1}#1\end\fi}
\def\compareSpace #1#2#3\end{%
\def\xxparams{#1}\def\xxxparams{#2#3}\ifx\xxparams\xxxparams\CCbool=\CCfalse
\else\CCbool=\CCtrue \fi}
\def\testAndCopySpace #1{%
\def\qparams{#1}\ifx\qparams\empty\else\compareAndCopySpace{#1}#1\end\fi}
\def\compareAndCopySpace #1#2#3\end{%
\def\xxparams{#1}\def\xxxparams{#2#3}\ifx\xxparams\xxxparams\else\ \fi}
% This macro gets a complete C++ declaration and decides weather
% it is an operator declaration or not.
\def\isOperator #1{%
\isOperatorX{ #1 operator\end}}
% Note: the macro introduces a leading space to allow the matching process
% to find in any way the right " operator" string. This is necessary,
% because "operator" is allowed as a substring in a function name.
\def\isOperatorX #1{\isOperatorXX #1} % Now, we can match.
\def\isOperatorXX #1 operator#2\end{%
\isEmpty{#2}\ifnum\CCbool=\CCtrue \CCbool=\CCfalse
\else\hasLeadingSpace{#2}\ifnum\CCbool=\CCfalse
\isLetter{#2}\CCinvert
\fi
\fi}
% This macro gets a complete C++ declaration for an operator and has to
% decide weather it is the parenthesis () operator declaration or not.
\def\isParenthesisOperator #1{%
\isParenthesisOperatorX #1 ()\end}
\def\isParenthesisOperatorX #1operator#2(#3)#4(#5)#6\end{%
% if and only if #6 is non empty, we have the () operator.
\isEmpty{#6}\CCinvert}
% This macro gets a complete C++ declaration for an operator and has to
% decide weather it is the conversion operator declaration or not.
\def\isConversionOperator #1{%
\isConversionOperatorX #1\end}
\def\isConversionOperatorX #1operator#2\end{%
% if and only if #1 is empty, we have the conversion operator.
\isEmpty{#1}}
% +--------------------------------------------------------------------------
% | Toplevel declaration formatting:
% |
% | Here, constructors, methods, and functions are separated in there
% | building blocks: the return type, their name, and the parameter
% | list. An operator declaration will be detected.
% +--------------------------------------------------------------------------
% This box contains the formatting result. Its width influences the
% column layout for longish declarations.
\newbox\functioncallbox
\newbox\returntypebox % contains the return type
\newbox\functionnamebox % contains the function name
\newbox\callnamebox % contains the fct. name incl. variable for methods
% Formats a constructor call.
% o The 1st parameter contains the comment text (maybe empty).
% o The 2st parameter contains the name of the constructor
% o The 3rd parameter contains the parameter list (maybe empty).
% o The 4th parameter contains the optional const specifier for methods.
% The declaration has to be terminated with "\end".
\def\constructorcall #1#2(#3)#4\end {%
\CCWfirst =\CCWconstructorfirst
\CCWsecond =\CCWconstructorsecond
\CCinitWidths
\setbox\returntypebox=\hbox{}%
\setbox\callnamebox=\hbox{\classtemplatename
\ \ \CCfont\purevar}%
\setbox\functioncallbox=\hbox{\classtemplatename
\ \ \CCfont\purevar
\isEmpty{#3}\ifnum\CCbool=\CCfalse
( \CCprintParamList{#3})%
\fi
;}%
\CClayoutThreeColumns{(}{#3}{)}{#1}%
}
% Formats a method or a function call.
% o The 1st parameter contains a 0 for a method call, a 1 for a function.
% o The 2nd parameter contains the comment text (maybe empty).
% o The 3rd parameter contains the beginning of the type declaration.
% o The 4th parameter contains the rest of the type and the function name.
% o The 5th parameter contains the parameter list (maybe empty).
% o The 6th parameter contains the optional const specifier for methods.
% The declaration has to be terminated with ";;\end" where the first ";"
% has to be from the original call notation. The 7th parameter is there
% to check for this ";".
\def\functioncall #1#2#3 #4(#5)#6;#7\end{%
\CCWfirst =\CCWfunctionfirst
\CCWsecond =\CCWfunctionsecond
\CCinitWidths
\def\xparam{#7}\ifx\xparam\empty
\errmessage{Missing ";" at the end of the
declaration. A method or function
declaration has to end with a ";".
Go ahead, I've inserted one}%
\fi
\def\CCextendedFormat{\ }% Switches ext. format OFF.
\isOperator{#3 #4(#5)#6}\ifnum\CCbool=\CCtrue
\isConversionOperator{#3 #4(#5)#6}
\ifnum\CCbool=\CCtrue
\CCprintConversionOperator #3 #4(#5)#6\end
\else
\CCseparateOperator #3 #4\end%
\isParenthesisOperator{#3 #4(#5)#6}%
\ifnum\CCbool=\CCtrue
\setbox\functioncallbox=\hbox{{\CCfont
\CCprintParOperator #1#3 #4(#5)#6\end}}
\else
\setbox\functioncallbox=\hbox{{\CCfont
\CCprintOperator #1#3 #4(#5)#6\end}}
\fi
\fi
\else
\CCseparateFunction{}#3 #4::\end%
\setbox\functioncallbox=\hbox{{\CCfont
\ifnum#1=0 \purevar.\fi
\unhcopy\functionnamebox(%
\isEmpty{#5}\ifnum\CCbool=\CCfalse
\ \CCprintParamList{#5}%
\fi)}}
\fi
\setbox\callnamebox=\hbox{{\CCfont
\ifnum#1=0 \purevar.\fi
\unhbox\functionnamebox}}%
\CClayoutThreeColumns{(}{#5}{)}{#2}%
}
\def\CCextendedFormat{\ }% Default: Extended Format switched OFF.
% Formats a variable, typedef or constant.
% o The 1st parameter contains the comment text (maybe empty).
% o The 2nd parameter contains the beginning of the type declaration.
% o The 3rd parameter contains the rest of the type and the function name.
% The declaration has to be terminated with ";;\end" where the first ";"
% has to be from the original call notation. The 4th parameter is there
% to check for this ";".
\def\CCvariableDeclaration #1#2 #3;#4\end{%
\CCWfirst =\CCWfunctionfirst
\CCWsecond =\CCWfunctionsecond
\CCinitWidths
\def\xparam{#4}\ifx\xparam\empty
\errmessage{Missing ";" at the end of the
declaration. A variable, typedef, or constant
declaration has to end with a ";".
Go ahead, I've inserted one}%
\fi
\CCseparateVariable #2 #3=\end%
\setbox\functioncallbox=\hbox{{\CCfont
\unhcopy\functionnamebox;}}
\setbox\callnamebox=\hbox{{\CCfont
\unhbox\functionnamebox}}%
\CClayoutThreeColumns{}{}{}{#1}%
}
\def\CCseparateVariable #1 #2=#3\end{%
\CCseparateFunction{}#1 #2::\end%
\def\xparam{#3}\ifx\xparam\empty
\else
\CCseparateVariableX #3\end
\fi
}
\def\CCseparateVariableX #1=\end{%
{\setbox0=\hbox{\unhbox\functionnamebox\ =#1}%
\global\setbox\functionnamebox=\hbox{\unhbox0}}%
}
% Formats a enum declaration.
% o The 1st parameter contains the comment text (maybe empty).
% o The 2st parameter contains the `enum' keyword name.
% o The 3rd parameter contains the parameter list (maybe empty).
% o The 4th parameter contains an optional variable name.
% The declaration has to be terminated with "\end".
\def\CCenumDeclaration #1#2\{#3\}#4\end {%
\CCWfirst =\CCWconstructorfirst
\CCWsecond =\CCWconstructorsecond
\CCinitWidths
\setbox\returntypebox=\hbox{}%
\setbox\callnamebox=\hbox{\CCfont #2}%
\setbox\functioncallbox=\hbox{\CCfont #2\{\
\isEmpty{#3}\ifnum\CCbool=\CCfalse
\CCprintParamList{#3}%
\fi
\};}%
\CClayoutThreeColumns{\{}{#3}{\}}{#1}%
}
% Manual layout: generalized three column format
% o The 1st parameter contains the opening brace.
% o The 2nd parameter contains the parameter list, comma separated.
% o The 3rd parameter contains the closing brace.
% o The 4th parameter contains the comment.
% All paramters might be empty.
% Global variables:
% o \returntypebox contains the formatted returntype (maybe empty)
% o \callnamebox contains the function/method/constructorname.
% For methods, the variable is just prepended.
% o \functioncallbox contains the complete functioncall incl. parameters
% as a oneliner.
\def\CClayoutThreeColumns #1#2#3#4{%
\CCtopskip
\hspace*{\CCWindent}%
\ifdim\CCWfirst>0pt % check for constructors
\ifdim\wd\returntypebox>\CCWfirst
\unhbox\returntypebox\CCreturnskip
\else
\parbox[t]{\CCWfirst}{\sloppy
\unhbox\returntypebox}%
\hspace*{\CCWbetween}%
\fi
\fi
\ifdim\wd\functioncallbox>\CCWsecondlong
% Operators are assumed to fit in \CCWsecondlong.
% Otherwise, they are formatted as functions.
\ifnum\CCalternateThreeColumn=\CCtrue
% Switches ext. format ON.
{\setbox0=\hbox{\unhcopy\callnamebox #1 }%
\global\CCWparam=\wd0}%
\ifdim\CCWfirst>0pt % check for constructors
\global\advance\CCWparam \CCWfirst
\global\advance\CCWparam \CCWbetween
\fi
\def\CCextendedFormat{\\\hspace*{\CCWparam}}%
{\unhbox\callnamebox #1 }%
\else
% Switches ext. format ON.
\def\CCextendedFormat{\\\hspace*{\CCWparam}}%
{\CCfont \unhbox\callnamebox #1}%
\CCextendedFormat
\fi
{\CCfont
\isEmpty{#2}\ifnum\CCbool=\CCfalse
\CCprintParamList{#2}%
\fi
#3}\hfill
\isEmpty{#4}\ifnum\CCbool=\CCfalse
\CCmiddleskip
\parbox[t]{\CCWcomment}{\sloppy #4}\hfill
\fi
\def\CCextendedFormat{\ }% Switches ext. format OFF.
\CCbottombigskip
\else\ifdim\wd\functioncallbox>\CCWsecond
\parbox[t]{\CCWsecondlong}{\unhbox\functioncallbox}%
\hfill
\isEmpty{#4}\ifnum\CCbool=\CCfalse
\CCmiddleskip
\parbox[t]{\CCWcomment}{\sloppy #4}\hfill
\fi
\CCbottombigskip
\else
\parbox[t]{\CCWsecond}{\unhbox\functioncallbox}%
\hspace*{\CCWbetween}%
\parbox[t]{\CCWcomment}{\sloppy #4}\hfill
\CCbottomskip
\fi\fi
}
% Set the two boxes, returntype and functionname, for an operator declaration.
\def\CCseparateOperator #1operator#2\end{%
\setbox\returntypebox=\hbox{{\CCfont
\CCprintReturnType #1const.&.\end}}%
\setbox\functionnamebox=\hbox{{\CCfont
\CCprintTokens operator#2\end}}%
}
% Set the two boxes, returntype and functionname, for a function declaration.
% The part of the declaration has to be terminated with "::\end".
\def\CCseparateFunction #1#2::#3\end{%
\isEmpty{#3}\ifnum\CCbool=\CCtrue
\CCseparateFunctionXX{#1}#2 .\end%
\else
\hasLeadingSpace{#3}\ifnum\CCbool=\CCtrue
\CCseparateFunction{#1#2:: }#3\end%
\else
\CCseparateFunction{#1#2::}#3\end%
\fi
\fi}
% Set the two boxes, returntype and functionname, for a function declaration.
% This macro scans through the token list space by space. If the operators
% & or * occurs on the right side, they are shifted to the left.
% o The 1st parameter is the first part of the type.
% o The 2nd parameter is the next part of the type name.
% o The 3rd and 4th parameter are the next part of the return type or
% the name, if #4 is empty. Then, the 3rd parameter is the first
% character of it.
% The part of the declaration has to be terminated with " .\end".
\def\CCseparateFunctionXX #1#2 #3#4\end{%
\isEmpty{#4}\ifnum\CCbool=\CCtrue
\setbox\returntypebox=\hbox{{\CCfont
\CCprintReturnType #1const.&.\end}}%
\setbox\functionnamebox=\hbox{{\CCfont
\CCprintTokens #2\end}}%
\else
\def\xparams{#1}\ifx\xparams\empty
\if#3&%
\CCseparateFunctionXX{#2#3}#4\end%
\else\if#3*%
\CCseparateFunctionXX{#2#3}#4\end%
\else
\CCseparateFunctionXX{#2}#3#4\end%
\fi\fi
\else
\if#3&%
\CCseparateFunctionXX{#1#2#3}#4\end%
\else\if#3*%
\CCseparateFunctionXX{#1#2#3}#4\end%
\else
\CCseparateFunctionXX{#1#2}#3#4\end%
\fi\fi
\fi
\fi}
% +--------------------------------------------------------------------------
% | Formatting of simple C++ code:
% |
% | \CCprintChar, \CCprintSingleToken, \CCprintTokens
% +--------------------------------------------------------------------------
% Print a character of a C++ declaration. Special handling of _<>&.
\def\CCprintChar #1{%
\if_#1\CCunderscore
\else\if<#1\CCopenangle
\else\if>#1\CCcloseangle
\else\if&#1\CCampersand
\else\if^#1\CChat
\else #1%
\fi\fi\fi\fi\fi}
% Print a single C++ token (without spaces inbetween). Skip leading spaces.
% The token has to be delimited by "\end".
\def\CCprintSingleToken #1#2;{%CCtrue
\CCprintChar #1%
\def\xbody{\CCprintSingleToken #2;}%
\isEmpty{#2}\ifnum\CCbool=\CCtrue \let\xnext=\relax
\else\let\xnext=\xbody\fi
\xnext}
% Print C++ tokens (separated with spaces). Skip leading spaces.
% The tokens have to be delimited by "\end".
\def\CCprintTokens #1#2\end{%
\CCprintChar #1%
\def\xbody{\CCprintTokens #2\end}%
\isEmpty{#2}\ifnum\CCbool=\CCtrue
\let\xnext=\relax
\else
\compareAndCopySpace{#2}#2\end
\let\xnext=\xbody
\fi
\xnext}
% +--------------------------------------------------------------------------
% | Formatting of operator declarations:
% |
% | To distinguish all operators, the number of given parameters is
% | counted and two of the three possible operator characters are used.
% +--------------------------------------------------------------------------
% Formats an operator declaration:
% o The first parameter contains a 0 for a method call, a 1 for a function.
% o The second parameter contains the return type.
% o The third parameter contains the operator name.
% o The fourth parameter contains the parameter list (maybe empty).
% o The fifth parameter contains the optional const specifier for methods.
% The declaration has to be terminated with "\end".
\def\CCprintOperator #1#2operator#3(#4)#5\end{%
\ifnum#1=0
\CCprintOperatorOne{#1}{\purevar,}{#4}#3\end
\else
\CCprintOperatorOne{#1}{}{#4}#3\end
\fi}
% Formats a parenthesis () operator declaration:
% o The first parameter contains a 0 for a method call, a 1 for a function.
% o The second parameter contains the return type.
% o The third parameter contains the operator name.
% o The fourth parameter contains the parameter list (maybe empty).
% o The fifth parameter contains the optional const specifier for methods.
% The declaration has to be terminated with "\end".
\def\CCprintParOperator #1#2operator#3(#4)#5(#6)#7\end{%
\isEmpty{#3}\ifnum\CCbool=\CCfalse\errmessage{Malformed
parenthesis operator}\fi
\isEmpty{#4}\ifnum\CCbool=\CCfalse\errmessage{Malformed
parenthesis operator}\fi
\isEmpty{#5}\ifnum\CCbool=\CCfalse\errmessage{Malformed
parenthesis operator}\fi
\ifnum#1=0
\CCprintOperatorOne{#1}{\purevar,}{#6}()\end
\else
\CCprintOperatorOne{#1}{}{#6}()\end
\fi}
% Formats a conversion operator.
% Uses the returntypebox and the functioncallbox.
% The declaration ends with "\end".
\def\CCprintConversionOperator #1operator #2(#3)#4\end{%
\setbox\returntypebox=\hbox{{\CCfont
\CCprintTokens #2\end}}
\setbox\functioncallbox=\hbox{{\CCfont
\CCprintTokens #2(\purevar)\end}}
}
% An operator is detected and can be printed.
% o The first parameter contains a 0 for a method call, a 1 for a function.
% o The second parameter contains the \purevar if it is a method.
% o The third parameter contains the (maybe empty) parameter list.
% o The fourth parameter is the first character of the operator.
% o The fifth parameter contains the rest of the operator.
% The declaration ends with "\end".
\newcount\operatorerror
{
\CCcatcode \catcode`\#=6 \catcode`\@=14
\gdef\CCprintOperatorOne #1#2#3#4#5\end{@
\CCextractParamList{#2#3}@
\operatorerror=1
\isEmpty{#5}\ifnum\CCbool=\CCtrue
@ single character operations
\ifcase\NParameters @ no parameter
\or @ 1 parameter
\if~#4\CCoperatorpraefix{\mbox{\CCtilde}}\fi
\if!#4\CCoperatorpraefix{#4\,}\fi
\if-#4\CCoperatorpraefix{#4}\fi
\if+#4\CCoperatorpraefix{#4}\fi
\if&#4\CCoperatorpraefix{\mbox{{\CCfont
\CCampersand}}}\fi
\if*#4\CCoperatorpraefix{#4}\fi
\or @ 2 parameters
\if*#4\CCoperatorinfix{#4}\fi
\if/#4\CCoperatorinfix{\,#4}\fi
\if%#4\CCoperatorinfix{\,#4\,}\fi
\if+#4\CCoperatorinfix{#4}\fi
\if-#4\CCoperatorinfix{#4}\fi
\if<#4\CCoperatorinfix{#4}\fi
\if>#4\CCoperatorinfix{#4}\fi
\if&#4\CCoperatorinfix{\mbox{{ \CCfont
\CCampersand} }}\fi
\if^#4\CCoperatorinfix{\mbox{\CChat}}\fi
\if|#4\CCoperatorinfix{\;#4\;}\fi
\if=#4\CCoperatorinfix{#4}\fi
\if,#4\CCoperatorinfix{#4}\fi
\else @ 3 parameters
\fi
\else
@ two or more character operations
\CCprintOperatorTwo #4#5\end
\fi
\ifnum\operatorerror=1 \errmessage{Unknown
operator detected. Look out for the legal
operator overloading in C++. Maybe, not all
operators are currently supported by this
style, sorry. Go ahead, and I format it as
a function}@
\ifnum#1=0 {\CCfont \purevar.}\fi
\CCprintTokens operator #4#5\end@
(\isEmpty{#3}\ifnum\CCbool=\CCfalse
\CCprintParamList{#3}\fi
)@
\fi
}
@ An operator with two or more characters is detected and can be printed.
@ o The first parameter is the first character of the operator.
@ o The second parameter is the second character of the operator.
@ o The third parameter contains the rest of the operator.
@ The declaration ends with "\end".
\gdef\CCprintOperatorTwo #1#2#3\end{@
\isEmpty{#3}\ifnum\CCbool=\CCtrue
@ two character operations
\ifcase\NParameters @ no parameter
\or @ 1 parameter
\if-#1\if>#2\CCoperatorpostfix{\:#1\!\!\!#2}\fi\fi
\if(#1\if)#2\CCoperatorparX{(}{)}\fi\fi
\if+#1\if+#2\CCoperatorpraefix{#1\!#2}\fi\fi
\if-#1\if-#2\CCoperatorpraefix{#1\!#2}\fi\fi
\or @ 2 parameters
\if[#1\if]#2\CCoperatorparXX{\CCendfont[ }{]}\fi\fi
\if(#1\if)#2\CCoperatorparXX{( }{)}\fi\fi
\if+#1\if+#2\CCoperatorpostfix{#1\!#2}\fi\fi
\if-#1\if-#2\CCoperatorpostfix{#1\!#2}\fi\fi
\if>#1\if>#2\CCoperatorinfix{#1\!#2}\fi\fi
\if<#1\if<#2\CCoperatorinfix{#1\!#2}\fi\fi
\if<#1\if=#2\CCoperatorinfix{#1#2}\fi\fi
\if>#1\if=#2\CCoperatorinfix{#1#2}\fi\fi
\if=#1\if=#2\CCoperatorinfix{#1#2}\fi\fi
\if!#1\if=#2\CCoperatorinfix{\;#1\!#2}\fi\fi
\if&#1\if&#2\CCoperatorinfix{\mbox{ {\CCfont
\CCampersand}}\mbox{{\CCfont
\CCampersand} }}\fi\fi
\if|#1\if|#2\CCoperatorinfix{\;#1#2\;}\fi\fi
\if*#1\if=#2\CCoperatorinfix{\,#1\!#2}\fi\fi
\if/#1\if=#2\CCoperatorinfix{\,#1\!#2}\fi\fi
\if%#1\if=#2\CCoperatorinfix{\,#1\!#2}\fi\fi
\if+#1\if=#2\CCoperatorinfix{\,#1\!#2}\fi\fi
\if-#1\if=#2\CCoperatorinfix{\,#1\!#2}\fi\fi
\if&#1\if=#2\CCoperatorinfix{\mbox{ {\CCfont
\CCampersand}}\!#2}\fi\fi
\if|#1\if=#2\CCoperatorinfix{\;#1\!#2}\fi\fi
\if^#1\if=#2\CCoperatorinfix{\mbox{\CChat{}}\!\!
#2}\fi\fi
\else @ 3 parameters
\if(#1\if)#2\CCoperatorparXXX{( }{)}\fi\fi
\fi
\else
@ three or more character operations
\ifcase\NParameters @ no parameter
\or @ 1 parameter
\if-#1\if>#2\CCoperatorpostfix{\:#1\!\!\!#2\!
#3}\fi\fi
\or @ 2 parameters
\if#1n\if#2e\CCoperatornew{#1#2#3}\fi\fi
\if>#1\if>#2\CCoperatorinfix{#1\!#2#3}\fi\fi
\if<#1\if<#2\CCoperatorinfix{#1\!#2#3}\fi\fi
\else @ 3 parameters
\if#1d\if#2e\CCoperatordelete{#1#2#3}\fi\fi
\fi
\fi
}
}
\def\CCoperatorpraefix #1{%
$#1 \mbox{\unhbox\parameterX}$\operatorerror=0 }
\def\CCoperatorinfix #1{%
$\mbox{\unhbox\parameterX\CCendfont} #1
\mbox{\unhbox\parameterXX}$\operatorerror=0 }
\def\CCoperatorpostfix #1{%
$\mbox{\unhbox\parameterX} #1$\operatorerror=0 }
\def\CCoperatorappend #1#2{%
$\mbox{\unhbox\parameterX} #1#2$\operatorerror=0 }
\def\CCoperatorparX #1#2{%
\unhbox\parameterX#1#2\operatorerror=0 }
\def\CCoperatorparXX #1#2{%
\unhbox\parameterX#1\unhbox\parameterXX#2\operatorerror=0 }
\def\CCoperatorparXXX #1#2{%
\unhbox\parameterX\CCendfont#1\unhbox\parameterXX,
\unhbox\parameterXXX#2\operatorerror=0 }
\def\CCoperatornew #1{%
$ \mbox{{\CCfont #1} \classtemplatename}$\operatorerror=0 }
% $ * \mbox{{\CCfont ptr\_}\unhbox\parameterX} = \mbox{{\CCfont #1}
% \classtemplatename}$\operatorerror=0 }
\def\CCoperatordelete #1{%
$ \mbox{{\CCfont #1} \unhbox\parameterXX}$\operatorerror=0 }
% +--------------------------------------------------------------------------
% | Parameter list parsing:
% |
% | Parameter lists are commata separated parameters. Template
% | instantiation nesting is considered.
% +--------------------------------------------------------------------------
% Print a C++ parameter list (separated with commatas). The output formats
% with a space between commata and the parameter text.
\def\CCprintParamList #1{%
\nestinglevel=0
\CCprintParamListX{}#1\end}
% Support function:
% o The first parameter accumulates the so far parsed first parameter.
% o The second parameter contains the next character.
% o The third parameter contains the rest.
% The parsing process iterates characterwise.
% The parameter list has to be terminated with "\end".
\def\CCprintParamListX #1#2#3\end{%
\if<#2\advance\nestinglevel by1 \fi
\if>#2\advance\nestinglevel by-1 \fi
\if,#2%
\ifnum\nestinglevel=0
\CCprintParameter #1const.&.\end,\CCextendedFormat
\def\xxbody{\CCprintParamListX{}#3\end}%
\else\ifnum\nestinglevel<0
\errmessage{Unbalanced angles detected in
template types in the C++ parameter list}%
\def\xxbody{\CCprintParamListX{}#3\end}%
\else% comma within template parameter detected
\hasLeadingSpace{#3}\ifnum\CCbool=\CCtrue
\def\xxbody{\CCprintParamListX{#1#2 }#3\end}%
\else
\def\xxbody{\CCprintParamListX{#1#2}#3\end}%
\fi
\fi\fi
\else\isEmpty{#3}\ifnum\CCbool=\CCtrue
\ifnum\nestinglevel=0
\CCprintParameter #1#2const.&.\end%
\else
\errmessage{Unbalanced angles detected in
template types in the C++ parameter list}%
\fi
\def\xxbody{\CCprintParamListX{}#3\end}%
\else
\hasLeadingSpace{#3}\ifnum\CCbool=\CCtrue
\def\xxbody{\CCprintParamListX{#1#2 }#3\end}%
\else
\def\xxbody{\CCprintParamListX{#1#2}#3\end}%
\fi
\fi\fi
\isEmpty{#3}\ifnum\CCbool=\CCtrue \let\xxnext=\relax
\else\let\xxnext=\xxbody\fi
\xxnext}
% If an operator is used, a specialized parameter parsing macro counts
% the number of parameters and store the result in the three following boxes.
% \NParameters is one of 0,1,2,3. In the case of 3, there are three or more
% parameters, as it was possible for the ()-operator. Thei are all together
% stored in \box\parameterXXX.
\newcount\NParameters % counts number of parameters for operators
\newbox\parameterX % first parameter
\newbox\parameterXX % second parameter
\newbox\parameterXXX % third and rest of parameters
% Extract up to three parameters from a C++ parameter list
% (separated with commatas) within the \parameterX.. boxes.
\def\CCextractParamList #1{%
\nestinglevel=0
\NParameters=0
\isEmpty{#1}\ifnum\CCbool=\CCfalse \CCextractParamListX{}#1\end\fi}
% Support function:
% o The first parameter accumulates the so far parsed first parameter.
% o The second parameter contains the next character.
% o The third parameter contains the rest.
% The parsing process iterates characterwise.
% The parameter list has to be terminated with "\end".
\def\CCextractParamListX #1#2#3\end{%
\if<#2\advance\nestinglevel by1 \fi
\if>#2\advance\nestinglevel by-1 \fi
\if,#2%
\ifnum\nestinglevel=0
\advance\NParameters by1
\ifnum\NParameters=1 \setbox\parameterX=%
\hbox{\CCprintParameter #1const.&.\end}%
\def\xxxbody{\CCextractParamListX{}#3\end}%
\else\advance\NParameters by1
\setbox\parameterXX=%
\hbox{\CCprintParameter #1const.&.\end}%
\setbox\parameterXXX=%
\hbox{\CCprintParamList{#3}}%
\def\xxxbody{\relax}%
\fi
\else\ifnum\nestinglevel<0
\errmessage{Unbalanced angles detected in
template types in the C++ parameter list}%
\def\xxxbody{\CCextractParamListX{}#3\end}%
\else% comma within template parameter detected
\hasLeadingSpace{#3}\ifnum\CCbool=\CCtrue
\def\xxxbody{\CCextractParamListX{#1#2 }#3\end}%
\else
\def\xxxbody{\CCextractParamListX{#1#2}#3\end}%
\fi
\fi\fi
\else\isEmpty{#3}\ifnum\CCbool=\CCtrue
\ifnum\nestinglevel=0
\advance\NParameters by1
\ifnum\NParameters=1 \setbox\parameterX=%
\hbox{\CCprintParameter #1#2const.&.\end}%
\else\ifnum\NParameters=2 \setbox\parameterXX=%
\hbox{\CCprintParameter #1#2const.&.\end}%
\else\setbox\parameterXXX=%
\hbox{\CCprintParameter #1#2const.&.\end}%
\fi\fi
\else
\errmessage{Unbalanced angles detected in
template types in the C++ parameter list}%
\fi
\def\xxxbody{\CCextractParamListX{}#3\end}%
\else
\hasLeadingSpace{#3}\ifnum\CCbool=\CCtrue
\def\xxxbody{\CCextractParamListX{#1#2 }#3\end}%
\else
\def\xxxbody{\CCextractParamListX{#1#2}#3\end}%
\fi
\fi\fi
\isEmpty{#3}\ifnum\CCbool=\CCtrue \let\xxxnext=\relax
\else\let\xxxnext=\xxxbody\fi
\xxxnext}
% +--------------------------------------------------------------------------
% | Parameter Parsing:
% |
% | A single parameter consists of a type and optional of a variable name.
% | If the type contains a "const ... &" pair, it is removed. If the
% | the type is similar to the class that is currently declared, it is
% | also removed. (In that case it might result in an empty parameter
% | if no variable name is given. Then, a dummy "#" is printed instead.
% |
% | The return type of a method or function has no `variable name', so
% | only "const ... &" removal is done and no classname elimination.
% +--------------------------------------------------------------------------
% The parameter parsing macros counts the nesting level of
% template parameter instantiations.
\newcount\nestinglevel
\newcount\xnestinglevel
% Print a parameter where "const ...&" pairs are eliminated. Strips a
% leading type that equals the \classname. It is a four step process:
% 1. strip all in front of a "<" character.
% 2. extract the leading token without any space in it to decide,
% weather the type given is a templated type or not.
% 3. Compare the leading token with \classname
% 4. If true, strip the possible following template parameter.
% The parameter has to be delimited with "<>\end".
% Ignore leading spaces.
\def\CCprintOwnClassParameter #1#2<#3#4\end{%
\ifx\pureparameters\empty
\if>#3%
\CCprintOwnClassX #1#2 \end% no template case
\else
\CCprintOwnClassXQX #1#2<#3#4\end%
\fi
\else\if>#3%
\CCprintOwnClassX #1#2 \end% no template case
\else
\CCprintOwnClassXX{#1#2}<#3#4\end% template case ?
\fi\fi}
\def\CCprintOwnClassXQX #1#2<>\end{% strip the unneccessary <> from the end
\CCprintTokens #1#2\end}
\def\CCprintOwnClassX #1 #2\end{% check for \classname
\def\xparams{#1}\ifx\xparams\pureclassname
\isEmpty{#2}\ifnum\CCbool=\CCtrue
\CCemptyParameter
\else
\CCprintTokens #2\end%
\fi
\else
\CCprintTokens #1 #2\end%
\fi}
\def\CCprintOwnClassXX #1#2<>\end{% strip the unneccessary <> from the end
\CCprintOwnClassXXX {#2}#1 \end}
\def\CCprintOwnClassXXX #1#2 #3\end{%
% check \classname in the possible template case
% #1 is the parameter tail starting with the template params
% #2 is the leading class name
% #3 is inbetween and should be empty
\def\qqparams{#3}\ifx\qqparams\empty
\def\xparams{#2}\ifx\xparams\pureclassname
\xnestinglevel=0
\CCprintOwnClassXXXX #1\end% strip the template parameters
\else
\CCprintTokens #2#1\end% nothing stripped
\fi
\else
\errmessage{Confusing class name with a space before
the template parameters. The allowed syntax
is: name< params... }%
\fi}
\def\CCprintOwnClassXXXX #1#2\end{% strip a leading template parameter
\if<#1\advance\xnestinglevel by1 \fi
\if>#1\advance\xnestinglevel by-1 \fi
\ifnum\xnestinglevel=0
\isEmpty{#2}\ifnum\CCbool=\CCtrue
\CCemptyParameter
\else
\CCprintTokens #2\end%
\fi
\let\xnext=\relax
\else
\def\xparams{#2}%
\ifx\xparams\empty
\errmessage{Mismatching angles in template
parameter list}%
\fi
\def\xbody{\CCprintOwnClassXXXX #2\end}%
\let\xnext=\xbody
\fi
\xnext}
% Print a C++ function or method parameter. Strips a matching
% "const ...&" pair.
% The parameter has to be delimited with "const.&.\end".
\def\CCprintParameter #1const#2#3&#4#5\end{%
\if.#2\CCprintOwnClassParameter #1<>\end%
\else
\if&#2\CCprintParameter #1#3&#4#5\end%
\else
\if.#4\CCprintParameterXQ #1const #2#3&#4#5\end%
\else \CCprintParameter #1#2#3 #4#5\end%
\fi
\fi
\fi}
\def\CCprintParameterXQ #1const.&.\end{\CCprintOwnClassParameter #1<>\end}
% Print a C++ function or method return type. Strips a matching
% "const ...&" pair.
% The parameter has to be delimited with "const.&.\end".
\def\CCprintReturnType #1const#2#3&#4#5\end{%
\if.#2\CCprintTokens #1\end%
\else
\if&#2\CCprintReturnType #1#3&#4#5\end%
\else
\if.#4\CCprintReturnTypeXQ #1const #2#3&#4#5\end%
\else \CCprintReturnType #1#2#3 #4#5\end%
\fi
\fi
\fi}
\def\CCprintReturnTypeXQ #1const.&.\end{\CCprintTokens #1\end}