From 34b1e4283eff39c9ea709a701e9b4098ef3ee873 Mon Sep 17 00:00:00 2001 From: Lutz Kettner Date: Tue, 15 Aug 1995 17:44:43 +0000 Subject: [PATCH] Reorganized top level: now using catcode to change special character behaviour from TeX. doc.tex file contains a rather complete documentation and test set. The % and the ~ operator are now usable in full generality without drawbacks in the TeX part. The macros are not usable within other macros. --- Packages/Manual_tools/format/cc_manual.sty | 1017 +++++++++++--------- 1 file changed, 562 insertions(+), 455 deletions(-) diff --git a/Packages/Manual_tools/format/cc_manual.sty b/Packages/Manual_tools/format/cc_manual.sty index 495dd9dce5c..23997df40f0 100644 --- a/Packages/Manual_tools/format/cc_manual.sty +++ b/Packages/Manual_tools/format/cc_manual.sty @@ -5,6 +5,12 @@ % | $Date$ % +---------------------------------------- +{ \catcode`\$=12 + \def\cs #1$#2${\gdef#1{#2}} + \cs\CCrevision$Revision$ + \cs\CCdate$Date$ +} + \tracingmacros=1 % +-------------------------------------------------------------------------- @@ -85,6 +91,123 @@ \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{}% + } + +\def\classX #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}}}% + \endgroup + } + +\newenvironment{classtemplate}{% + \begingroup\CCcatcode + \classtemplateX% + }{ + \gdef\pureclassname{}% + } + +\def\classtemplateX #1#2{% + \gdef\pureclassname{#1}% + \gdef\puretemplatename{#1<#2>}% + \gdef\pureparameters{#2}% + \gdef\classname{\hbox{{\CCfont + \CCprintTokens #1\end\CCendfont}}}% + \gdef\classtemplatename{\hbox{{\CCfont + \CCprintTokens #1\end}% + \CCopenangle{\CCfont #2}\CCcloseangle}}% + \endgroup + } + + +\def\creationvariable {% + \begingroup\CCcatcode\creationvariableX} + +\def\creationvariableX #1{% + \gdef\var{$#1$} + \gdef\purevar{#1} + \endgroup} + +\def\threecolumns #1#2{% + \global\typewidth=#1 + \global\callwidth=#2 + \global\descriptwidth=\textwidth + \global\advance\descriptwidth-\typewidth + \global\advance\descriptwidth-\callwidth + \global\advance\descriptwidth-0.5cm + \global\callwidthl=\textwidth + \global\advance\callwidthl-\typewidth + \global\advance\callwidthl-0.5cm + \global\callwidthext=\callwidthl + \global\advance\callwidthext-\extendedindent + \global\callindentext=\textwidth + \global\advance\callindentext -\callwidthext + } + +\def\constructor {% + \begingroup\CCcatcode\constructorX} + +\def\constructorX #1{% + \constructorcall #1\end + \endgroup + \constructorXX} + +\def\constructorXX #1{% + \isEmpty{#1}\ifnum\CCbool=\CCfalse + \hspace*{1cm}\hfill + \parbox[t]{\createtextwidth}{\sloppy #1}\par + \fi + \bigskip + } + + +% 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{% + \smallskip + \functioncall{#1}#2;\end + \endgroup + \CCcomment} + +\long\def\CCcommentX #1#2{% + \isEmpty{#2}\ifnum\CCbool=\CCfalse + #1\parbox[t]{\descriptwidth}{\sloppy #2}\hfill + \fi\par + \smallskip} + +% Print one parameter in C++ style (including spaces). +\def\CCstyle {% + \begingroup\CCcatcode\CCstyleX} + +\def\CCstyleX #1{% + {\CCfont \CCprintTokens #1\end\CCendfont}\endgroup} + + % +-------------------------------------------------------------------------- % | Formatting styles: % | @@ -98,12 +221,25 @@ % grouped, so this macros has not to restore the old % font. -% The four special characters in typical C++ declarations: +% The special characters in typical C++ declarations: \def\CCopenangle {\CCendfont {\tt <}} \def\CCcloseangle {\CCendfont {\tt >}} \def\CCampersand {\CCendfont {\tt \&}} \def\CCunderscore {\_} -\def\CChat {{\large $\hat{}$}} +\def\CChat {{\large $\;\,\hat{}\,\,$}} +\def\CCtilde {{\lower.3ex \hbox{\large$\,\tilde{}\,$}}} + +% The sign for an empty parameter (i.e. of the type of the current class). +\def\CCemptyParameter {$\;\Box$} + +% Set the catcodes according to the C++ character set (including operators). +\def\CCcatcode {% + \catcode`\~=12 + \catcode`\_=12 + \catcode`\^=12 + \catcode`\#=12 + \catcode`\%=12 } + % +-------------------------------------------------------------------------- % | Predicates: @@ -142,11 +278,9 @@ \else\isLetterX #1\end\fi} \def\isLetterX #1#2\end{% \CCbool=\CCfalse - \if#1\noexpand\else - \ifcat#1A\CCbool=\CCtrue - \else\ifnum`#1>`/\ifnum`#1<`:\CCbool=\CCtrue \fi\fi - \if#1_\CCbool=\CCtrue \fi - \fi + \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 @@ -190,6 +324,158 @@ \isEmpty{#6}\CCinvert} +% +-------------------------------------------------------------------------- +% | 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. +% +-------------------------------------------------------------------------- +\def\constructorcall #1(#2)#3\end {% + \isEmpty{#2}\ifnum\CCbool=\CCtrue + \mbox{\classtemplatename\ \ \CCfont\purevar ;}% + \else\mbox{\classtemplatename + \ \ {\CCfont \purevar(\CCprintParamList{#2});}}% + \fi\par } + +% 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 + +% 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 beginning of the type declaration. +% o The 3rd parameter contains the rest of the type and the function name. +% o The 4th parameter contains the parameter list (maybe empty). +% o The 5th 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 6th parameter is there +% to check for this ";". +\def\functioncall #1#2 #3(#4)#5;#6\end{% + \def\xparam{#6}\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{#2 #3(#4)#5}\ifnum\CCbool=\CCtrue + \CCseparateOperator #2 #3\end% + \isParanthesesOperator{#2 #3(#4)#5}% + \ifnum\CCbool=\CCtrue + \setbox\functioncallbox=\hbox{{\CCfont + \CCprintParOperator #1#2 #3(#4)#5\end}} + \else + \setbox\functioncallbox=\hbox{{\CCfont + \CCprintOperator #1#2 #3(#4)#5\end}} + \fi + \else + \CCseparateFunction #2 #3::\end% + \setbox\functioncallbox=\hbox{{\CCfont + \ifnum#1=0 \purevar.\fi + \unhcopy\functionnamebox(% + \isEmpty{#4}\ifnum\CCbool=\CCfalse + \CCprintParamList{#4}% + \fi)}} + \fi + \parbox[t]{\typewidth}{\sloppy + \unhbox\returntypebox\hfill} + \ifdim\wd\functioncallbox>\callwidthl + % Switches ext. format ON. + \def\CCextendedFormat{\\\hspace*{\callindentext}}% + % Operators are assumed to fit in \callwidthl. + % Otherwise, they are formatted as functions. + {\CCfont \ifnum#1=0 + \purevar.\fi\unhbox\functionnamebox(} + \CCextendedFormat + {\CCfont + \isEmpty{#4}\ifnum\CCbool=\CCfalse + \CCprintParamList{#4}% + \fi + )}\hfill + \gdef\CCcomment{\CCcommentX{\par + \hspace*{1cm}\hfill}} + \def\CCextendedFormat{\ }% Switches ext. format OFF. + \else\ifdim\wd\functioncallbox>\callwidth + \parbox[t]{\callwidthl}{\unhbox\functioncallbox} + \hfill + \gdef\CCcomment{\CCcommentX{\par + \hspace*{1cm}\hfill}} + \else + \parbox[t]{\callwidth}{\unhbox\functioncallbox} + \hfill + \gdef\CCcomment{\CCcommentX{}} + \fi\fi + } + +\def\CCextendedFormat{\ }% Default: Extended Format switched OFF. + +% 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\end{% + \isEmpty{#2}\ifnum\CCbool=\CCtrue + \CCseparateFunctionXX{}{}#1 .\end% + \else + \CCseparateFunctionX{#1}#2\end% + \fi} + +\def\CCseparateFunctionX #1#2::\end{% + \CCseparateFunctionXX{}{#2}#1 .\end} + + +% 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 last part of the function name. +% o The 3rd parameter is the next part of the type name. +% o The 4th and 5th parameter are the next part of the return type or +% the name, if #6 is empty. Then, the 4th parameter is the first +% character of it. +% o The 6th parameter is the rest of the type and name. +% The part of the declaration has to be terminated with " \end". +\def\CCseparateFunctionXX #1#2#3 #4#5\end{% + \isEmpty{#5}\ifnum\CCbool=\CCtrue + \setbox\returntypebox=\hbox{{\CCfont + \CCprintReturnType #1const.&.\end}}% + \def\xparams{#2}\ifx\xparams\empty + \setbox\functionnamebox=\hbox{{\CCfont + \CCprintTokens #3\end}}% + \else + \setbox\functionnamebox=\hbox{{\CCfont + \CCprintTokens #3::#2\end}}% + \fi + \else + \def\xparams{#1}\ifx\xparams\empty + \if#4&% + \CCseparateFunctionXX{#3#4}{#2}#5\end% + \else\if#4*% + \CCseparateFunctionXX{#3#4}{#2}#5\end% + \else + \CCseparateFunctionXX{#3}{#2}#4#5\end% + \fi\fi + \else + \if#4&% + \CCseparateFunctionXX{#1 #3#4}{#2}#5\end% + \else\if#4*% + \CCseparateFunctionXX{#1 #3#4}{#2}#5\end% + \else + \CCseparateFunctionXX{#1 #3}{#2}#4#5\end% + \fi\fi + \fi + \fi} + % +-------------------------------------------------------------------------- % | Formatting of simple C++ code: % | @@ -228,105 +514,187 @@ \xnext} % +-------------------------------------------------------------------------- -% | Parameter Parsing: +% | Formatting of operator declarations: % | -% | 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. +% | To distinguish all operators, the number of given parameters is +% | counted and two of the three possible operator characters are used. % +-------------------------------------------------------------------------- -% The parameter parsing macros counts the nesting level of -% template parameter instantiations. -\newcount\nestinglevel -\newcount\xnestinglevel +% 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} -% Print a parameter where "const ...&" pairs are eliminated. Strips a -% leading type that equals the \classname. It is a three 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 - \CCprintOwnClassX #1#2 \end% no template case - \else\if>#3% - \CCprintOwnClassX #1#2 \end% no template case - \else - \CCprintOwnClassXX{#1#2}<#3#4\end% template case ? - \fi\fi} -\def\CCprintOwnClassX #1 #2\end{% check for \classname - \def\xparams{#1}\ifx\xparams\pureclassname - \CCprintTokens #2\end% - \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 - \CCprintTokens #2\end% - \let\xnext=\relax - \else - \def\xparams{#2}% - \ifx\xparams\empty - \errmessage{Mismatching angles in template - parameter list}% +% Formats a paranthese () 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 + parantheses operator}\fi + \isEmpty{#4}\ifnum\CCbool=\CCfalse\errmessage{Malformed + parantheses operator}\fi + \isEmpty{#5}\ifnum\CCbool=\CCfalse\errmessage{Malformed + parantheses operator}\fi + \ifnum#1=0 + \CCprintOperatorOne{#1}{\purevar,}{#6}()\end + \else + \CCprintOperatorOne{#1}{}{#6}()\end + \fi} + +% 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\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\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{@ + \def\xparams{#3}@ + \ifx\xparams\empty + @ 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{[}{]}\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\if\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\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 - \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#5\end{% - \if.#2\CCprintOwnClassParameter #1<>\end% - \else - \if\CCprintParameter #1#3#5\end% - \else - \CCprintParameter #1#2#3 #4#5\end% - \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 } -% 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#5\end{% - \if.#2\CCprintTokens #1\end% - \else - \if\CCprintReturnType #1#3#5\end% - \else - \CCprintReturnType #1#2#3 #4#5\end% - \fi - \fi} % +-------------------------------------------------------------------------- % | Parameter list parsing: @@ -459,374 +827,113 @@ \else\let\xxxnext=\xxxbody\fi \xxxnext} - % +-------------------------------------------------------------------------- -% | Formatting of operator declarations: +% | Parameter Parsing: % | -% | To distinguish all operators, the number of given parameters is -% | counted and two of the three possible operator characters are used. +% | 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. % +-------------------------------------------------------------------------- -% 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} +% The parameter parsing macros counts the nesting level of +% template parameter instantiations. +\newcount\nestinglevel +\newcount\xnestinglevel -% Formats a paranthese () 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 - parantheses operator}\fi - \isEmpty{#4}\ifnum\CCbool=\CCfalse\errmessage{Malformed - parantheses operator}\fi - \isEmpty{#5}\ifnum\CCbool=\CCfalse\errmessage{Malformed - parantheses operator}\fi - \ifnum#1=0 - \CCprintOperatorOne{#1}{\purevar,}{#6}()\end +% 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 + \CCprintOwnClassX #1#2 \end% no template case + \else\if>#3% + \CCprintOwnClassX #1#2 \end% no template case + \else + \CCprintOwnClassXX{#1#2}<#3#4\end% template case ? + \fi\fi} +\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 - \CCprintOperatorOne{#1}{}{#6}()\end - \fi} - -% 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 -\catcode`\~=12 -\def\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{\large$\tilde{}\,$}}}\fi - \if!#4\CCoperatorpraefix{#4\,}\fi - \if-#4\CCoperatorpraefix{#4}\fi - \if+#4\CCoperatorpraefix{#4}\fi - \if\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\CCoperatorinfix{\mbox{{ \CCfont - \CCampersand} }}\fi - \if^#4\CCoperatorinfix{\;\,\hat{}\,\,}\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}% - \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". -\def\CCprintOperatorTwo #1#2#3\end{% - \def\xparams{#3}% - \ifx\xparams\empty - % 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{[}{]}\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\if\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\if=#2\CCoperatorinfix{\mbox{ {\CCfont - \CCampersand}}\!#2}\fi\fi - \if|#1\if=#2\CCoperatorinfix{\;#1\!#2}\fi\fi - \if^#1\if=#2\CCoperatorinfix{\;\,\hat{}#2}\fi\fi - \else % 3 parameters - \if(#1\if)#2\CCoperatorparXXX{(}{)}\fi\fi + \CCprintTokens #2\end% \fi + \let\xnext=\relax \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 + \def\xparams{#2}% + \ifx\xparams\empty + \errmessage{Mismatching angles in template + parameter list}% \fi + \def\xbody{\CCprintOwnClassXXXX #2\end}% + \let\xnext=\xbody \fi - } -\catcode`\~=13 + \xnext} -\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 } +% 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#5\end{% + \if.#2\CCprintOwnClassParameter #1<>\end% + \else + \if\CCprintParameter #1#3#5\end% + \else + \CCprintParameter #1#2#3 #4#5\end% + \fi + \fi} -% +-------------------------------------------------------------------------- -% | 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. -% +-------------------------------------------------------------------------- -\def\constructorcall #1(#2)#3\end {% - \isEmpty{#2}\ifnum\CCbool=\CCtrue - \mbox{\classtemplatename\ \ \CCfont\purevar ;}% - \else\mbox{\classtemplatename - \ \ {\CCfont \purevar(\CCprintParamList{#2});}}% - \fi\par } - -% 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 - -% 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 commenting text. -% 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{% - \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 - \CCseparateOperator #3 #4\end% - \isParanthesesOperator{#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 - \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 - \parbox[t]{\typewidth}{\sloppy - \unhbox\returntypebox\hfill} - \ifdim\wd\functioncallbox>\callwidthl - % Switches ext. format ON. - \def\CCextendedFormat{\\\hspace*{\callindentext}}% - % Operators are assumed to fit in \callwidthl. - % Otherwise, they are formatted as functions. - {\CCfont \ifnum#1=0 - \purevar.\fi\unhbox\functionnamebox(} - \CCextendedFormat - {\CCfont - \isEmpty{#5}\ifnum\CCbool=\CCfalse - \CCprintParamList{#5}% - \fi - )}\hfill - \hfill\isEmpty{#2}\ifnum\CCbool=\CCfalse - \par\hspace*{1cm}\hfill - \parbox[t]{\descriptwidth}{\sloppy #2}\hfill - \fi\par - \def\CCextendedFormat{\ }% Switches ext. format OFF. - \else\ifdim\wd\functioncallbox>\callwidth - \parbox[t]{\callwidthl}{\unhbox\functioncallbox} - \hfill\isEmpty{#2}\ifnum\CCbool=\CCfalse - \par\hspace*{1cm}\hfill - \parbox[t]{\descriptwidth}{\sloppy #2}\hfill - \fi\par - \else - \parbox[t]{\callwidth}{\unhbox\functioncallbox} - \hfill - \parbox[t]{\descriptwidth}{\sloppy #2}\hfill\par - \fi\fi - } - -\def\CCextendedFormat{\ }% Default: Extended Format switched OFF. - -% 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 - \setbox\returntypebox=\hbox{{\CCfont - \CCprintReturnType #1const.&.\end}}% - \setbox\functionnamebox=\hbox{{\CCfont - \CCprintTokens #2\end}}% - \else\CCseparateFunction{#1 #2}#3\end% - \fi} - -% +-------------------------------------------------------------------------- -% | C++ declarations for different C++ language elements: -% | -% | \begin{class}, \begin{classtemplate}, \end... -% | \creationvariable, \threecolumns, \constructor, \method, \function -% | \CCstyle -% +-------------------------------------------------------------------------- -\newenvironment{class}[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}}}% - \catcode`\~=12 - }{ - \catcode`\~=13 - \gdef\pureclassname{}% - } - -\newenvironment{classtemplate}[2]{% - \gdef\pureclassname{#1}% - \gdef\puretemplatename{#1<#2>}% - \gdef\pureparameters{#2}% - \gdef\classname{\hbox{{\CCfont - \CCprintTokens #1\end\CCendfont}}}% - \gdef\classtemplatename{\hbox{{\CCfont - \CCprintTokens #1\end}% - \CCopenangle{\CCfont #2}\CCcloseangle}}% - \catcode`\~=12 - }{ - \catcode`\~=13 - \gdef\pureclassname{}% - } - -\def\creationvariable #1{% - \gdef\var{$#1$} - \gdef\purevar{#1}} - -\def\threecolumns #1#2{\typewidth=#1 - \callwidth=#2 - \descriptwidth=\textwidth - \advance\descriptwidth-\typewidth - \advance\descriptwidth-\callwidth - \advance\descriptwidth-0.5cm - \callwidthl=\textwidth - \advance\callwidthl-\typewidth - \advance\callwidthl-0.5cm - \callwidthext=\callwidthl - \advance\callwidthext-\extendedindent - \callindentext=\textwidth - \advance\callindentext -\callwidthext - } - -\def\constructor #1#2{% - \constructorcall #1\end - \isEmpty{#2}\ifnum\CCbool=\CCfalse - \hspace*{1cm}\hfill - \parbox[t]{\createtextwidth}{\sloppy #2}\par - \fi - \bigskip - } -\def\method #1#2{% - \smallskip - \functioncall{0}{#2}#1;\end - \smallskip} - -\def\function #1#2{% - \smallskip - \functioncall{1}{#2}#1;\end - \smallskip} - -% Print one parameter in C++ style (including spaces). -\def\CCstyle #1{% - {\CCfont \CCprintTokens #1\end\CCendfont}} +% 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#5\end{% + \if.#2\CCprintTokens #1\end% + \else + \if\CCprintReturnType #1#3#5\end% + \else + \CCprintReturnType #1#2#3 #4#5\end% + \fi + \fi}