diff options
author | Karl Berry <karl@freefriends.org> | 2007-10-24 23:29:14 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2007-10-24 23:29:14 +0000 |
commit | c5199a08bb8edc16006e6a5fc72cc704d7eae776 (patch) | |
tree | 729971967a99529b74598d27dd7cc585e0218e41 /Master/texmf-dist/doc/latex/cweb-latex/examples/compare/wcltx.tex | |
parent | bfaf341636c39818969bd384bb1e5fda9195f3a5 (diff) |
new (to TL) cweb-latex package (4feb07)
git-svn-id: svn://tug.org/texlive/trunk@5271 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/doc/latex/cweb-latex/examples/compare/wcltx.tex')
-rw-r--r-- | Master/texmf-dist/doc/latex/cweb-latex/examples/compare/wcltx.tex | 412 |
1 files changed, 412 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/latex/cweb-latex/examples/compare/wcltx.tex b/Master/texmf-dist/doc/latex/cweb-latex/examples/compare/wcltx.tex new file mode 100644 index 00000000000..58a91af0247 --- /dev/null +++ b/Master/texmf-dist/doc/latex/cweb-latex/examples/compare/wcltx.tex @@ -0,0 +1,412 @@ +\input cwebmac +% $Id: wcltx.w,v 1.4 1995/08/29 17:27:57 schrod Exp $ +%------------------------------------------------------------ + +% +% wc: An example of CWEB by Silvio Levy and Donald E. Knuth +% +% [LaTeX] +% (history at end) + + +%% -js: +%% should rework it: ANSI C compliance, POSIX.2 compliant option +%% parsing with getopt(), including *all* required header files (ie, +%% POSIX.1 compliance), using POSIX return codes and types, etc. + + + +\documentclass{cweb} + +\usepackage{rcs} + + +% +% some tags for this document +% +\def\CEE/{C\spacefactor 1000 } +\def\cweb{{\tt CWEB\/}} +\def\SPARC{SPARC\-\kern.1em station} +\def\UNIX/{{\small UNIX\/}} +\def\wc{{\tt wc\/}} +\def\WEB{{\tt WEB\/}} + +\hfuzz=0.5pt + + + + +\begin{document} + + + +\title{Counting words} +\author{Silvio Levy\and Donald E. Knuth} +\begingroup +\def\thefootnote{\hbox{$^*$}} +\footnotetext[0]{\LaTeX{} markup by Joachim Schrod.} +\endgroup +\RCSdate $Date: 1995/08/29 17:27:57 $ + +\maketitle + +% not very interesting, only one starred section +% \tableofcontents + + + + +\N{1}{1}An example of \cweb{}. This example, based on a program by +Klaus Guntermann and Joachim Schrod~\cite{litprog:schrod:cweb} +presents the ``word count'' program from \UNIX/, rewritten in +\cweb{} to demonstrate literate programming in \CEE/.% +\footnote{% +Incidentally, Klaus Guntermann and Joachim Schrod are now +using this \cweb{} and have stopped the support for their version. +Joachim Schrod contributed the \LaTeX{} style used for the markup of +this document. +} +The level of detail in this document is intentionally high, for +didactic purposes; many of the things spelled out here don't need to +be explained in other programs. + +The purpose of \wc{} is to count lines, words, and/or characters in a +list of files. The number of lines in a file is the number of newline +characters it contains. The number of characters is the file length in bytes. +A ``word'' is a maximal sequence of consecutive characters other than +newline, space, or tab, containing at least one visible ASCII code. +(We assume that the standard ASCII code is in use.) + +\fi + +\M{2}Most \cweb{} programs share a common structure. It's probably a +good idea to state the overall structure explicitly at the outset, +even though the various parts could all be introduced in unnamed +sections of the code if we wanted to add them piecemeal. + +Here, then, is an overview of the file \texttt{wcltx.c} that is +defined by this \cweb{} program \texttt{wcltx.w}: + +\Y\B\X3:Header files to include\X\6 +\X4:Global variables\X\6 +\X20:Functions\X\6 +\X5:The main program\X\par +\fi + +\M{3}We must include the standard I/O definitions, since we want to send +formatted output to \PB{\\{stdout}} and \PB{\\{stderr}}. + +\Y\B\4\X3:Header files to include\X${}\E{}$\6 +\8\#\&{include} \.{<stdio.h>}\par +\U2.\fi + +\M{4} The \PB{\\{status}} variable will tell the operating system if the run +was +successful or not, and \PB{\\{prog\_name}} is used in case there's an error +message to +be printed. + +\Y\B\4\D$\.{OK}$ \5 +\T{0}\C{ \PB{\\{status}} code for successful run }\par +\B\4\D$\\{usage\_error}$ \5 +\T{1}\C{ \PB{\\{status}} code for improper syntax }\par +\B\4\D$\\{cannot\_open\_file}$ \5 +\T{2}\C{ \PB{\\{status}} code for file access error }\par +\Y\B\4\X4:Global variables\X${}\E{}$\6 +\&{int} \\{status}${}\K\.{OK}{}$;\C{ exit status of command, initially \PB{% +\.{OK}} }\6 +\&{char} ${}{*}\\{prog\_name}{}$;\C{ who we are }\par +\A14. +\U2.\fi + +\M{5}Now we come to the general layout of the \PB{\\{main}} function. + +\Y\B\4\X5:The main program\X${}\E{}$\6 +$\\{main}(\\{argc},\39\\{argv}){}$\1\1\6 +\&{int} \\{argc};\C{ the number of arguments on the \UNIX/ command line }\6 +\&{char} ${}{*}{*}\\{argv}{}$;\C{ the arguments themselves, an array of strings +}\2\2\6 +${}\{{}$\1\6 +\X6:Variables local to \PB{\\{main}}\X\6 +${}\\{prog\_name}\K\\{argv}[\T{0}];{}$\6 +\X7:Set up option selection\X;\6 +\X8:Process all the files\X;\6 +\X19:Print the grand totals if there were multiple files\X;\6 +\\{exit}(\\{status});\6 +\4${}\}{}$\2\par +\U2.\fi + +\M{6}If the first argument begins with a `\texttt{-}', the user is choosing +the desired counts and specifying the order in which they should be +displayed. Each selection is given by the initial character +(lines, words, or characters). For example, `\texttt{-cl}' would cause +just the number of characters and the number of lines to be printed, +in that order. + +We do not process this string now; we simply remember where it is. +It will be used to control the formatting at output time. + +\Y\B\4\X6:Variables local to \PB{\\{main}}\X${}\E{}$\6 +\&{int} \\{file\_count};\C{ how many files there are }\6 +\&{char} ${}{*}\\{which}{}$;\C{ which counts to print }\par +\As9\ET12. +\U5.\fi + +\M{7}\B\X7:Set up option selection\X${}\E{}$\6 +$\\{which}\K\.{"lwc"}{}$;\C{ if no option is given, print all three values }\6 +\&{if} ${}(\\{argc}>\T{1}\W{*}\\{argv}[\T{1}]\E\.{'-'}){}$\5 +${}\{{}$\1\6 +${}\\{which}\K\\{argv}[\T{1}]+\T{1};{}$\6 +${}\\{argc}\MM;{}$\6 +${}\\{argv}\PP;{}$\6 +\4${}\}{}$\2\6 +${}\\{file\_count}\K\\{argc}-\T{1}{}$;\par +\U5.\fi + +\M{8}Now we scan the remaining arguments and try to open a file, if +possible. The file is processed and its statistics are given. +We use a \PB{\&{do}}~\dots~\PB{\&{while}} loop because we should read from the +standard input if no file name is given. + +\Y\B\4\X8:Process all the files\X${}\E{}$\6 +$\\{argc}\MM;{}$\6 +\&{do}\5 +${}\{{}$\1\6 +\X10:If a file is given, try to open \PB{${*}(\PP\\{argv})$}; \PB{\&{continue}} +if unsuccessful\X;\6 +\X13:Initialize pointers and counters\X;\6 +\X15:Scan file\X;\6 +\X17:Write statistics for file\X;\6 +\X11:Close file\X;\6 +\X18:Update grand totals\X;\C{ even if there is only one file }\6 +\4${}\}{}$\5 +\2\5 +\&{while} ${}(\MM\\{argc}>\T{0}){}$;\par +\U5.\fi + +\M{9}Here's the code to open the file. A special trick allows us to +handle input from \PB{\\{stdin}} when no name is given. +Recall that the file descriptor to \PB{\\{stdin}} is~0; that's what we +use as the default initial value. + +\Y\B\4\X6:Variables local to \PB{\\{main}}\X${}\mathrel+\E{}$\6 +\&{int} \\{fd}${}\K\T{0}{}$;\C{ file descriptor, initialized to \PB{\\{stdin}} +}\par +\fi + +\M{10}\B\D$\.{READ\_ONLY}$ \5 +\T{0}\C{ read access code for system \PB{\\{open}} routine }\par +\Y\B\4\X10:If a file is given, try to open \PB{${*}(\PP\\{argv})$}; \PB{% +\&{continue}} if unsuccessful\X${}\E{}$\6 +\&{if} ${}(\\{file\_count}>\T{0}\W(\\{fd}\K\\{open}({*}(\PP\\{argv}),\39\.{READ% +\_ONLY}))<\T{0}){}$\5 +${}\{{}$\1\6 +${}\\{fprintf}(\\{stderr},\39\.{"\%s:\ cannot\ open\ fil}\)\.{e\ \%s\\n"},\39% +\\{prog\_name},\39{*}\\{argv});{}$\6 +${}\\{status}\MRL{{\OR}{\K}}\\{cannot\_open\_file};{}$\6 +${}\\{file\_count}\MM;{}$\6 +\&{continue};\6 +\4${}\}{}$\2\par +\U8.\fi + +\M{11}\B\X11:Close file\X${}\E{}$\6 +\\{close}(\\{fd});\par +\U8.\fi + +\M{12}We will do some homemade buffering in order to speed things up: +Characters +will be read into the \PB{\\{buffer}} array before we process them. +To do this we set up appropriate pointers and counters. + +\Y\B\4\D$\\{buf\_size}$ \5 +\.{BUFSIZ}\C{ \texttt{stdio.h}'s \PB{\.{BUFSIZ}} is chosen for efficiency }\par +\Y\B\4\X6:Variables local to \PB{\\{main}}\X${}\mathrel+\E{}$\6 +\&{char} \\{buffer}[\\{buf\_size}];\C{ we read the input into this array }\6 +\&{register} \&{char} ${}{*}\\{ptr}{}$;\C{ the first unprocessed character in % +\PB{\\{buffer}} }\6 +\&{register} \&{char} ${}{*}\\{buf\_end}{}$;\C{ the first unused position in % +\PB{\\{buffer}} }\6 +\&{register} \&{int} \|c;\C{ current character, or number of characters just +read }\6 +\&{int} \\{in\_word};\C{ are we within a word? }\6 +\&{long} \\{word\_count}${},{}$ \\{line\_count}${},{}$ \\{char\_count};\C{ +number of words, lines, and characters found in the file so far }\par +\fi + +\M{13}\B\X13:Initialize pointers and counters\X${}\E{}$\6 +$\\{ptr}\K\\{buf\_end}\K\\{buffer};{}$\6 +${}\\{line\_count}\K\\{word\_count}\K\\{char\_count}\K\T{0};{}$\6 +${}\\{in\_word}\K\T{0}{}$;\par +\U8.\fi + +\M{14}The grand totals must be initialized to zero at the beginning of the +program. If we made these variables local to \PB{\\{main}}, we would have to +do this initialization explicitly; however, \CEE/'s globals are automatically +zeroed. (Or rather, ``statically zeroed.'') (Get it?) +%% -js: The joke would be better if the vars would be static, which +%% they aren't in the C sense... + +\Y\B\4\X4:Global variables\X${}\mathrel+\E{}$\6 +\&{long} \\{tot\_word\_count}${},{}$ \\{tot\_line\_count}${},{}$ \\{tot\_char% +\_count};\C{ total number of words, lines, and chars }\par +\fi + +\M{15}The present section, which does the counting that is \wc{}'s \emph{raison +d'\^etre}, was actually one of the simplest to write. We look at each +character and change state if it begins or ends a word. + +\Y\B\4\X15:Scan file\X${}\E{}$\6 +\&{while} (\T{1})\5 +${}\{{}$\1\6 +\X16:Fill \PB{\\{buffer}} if it is empty; \PB{\&{break}} at end of file\X;\6 +${}\|c\K{*}\\{ptr}\PP;{}$\6 +\&{if} ${}(\|c>\.{'\ '}\W\|c<\T{\~177}){}$\5 +${}\{{}$\C{ visible ASCII codes }\1\6 +\&{if} ${}(\R\\{in\_word}){}$\5 +${}\{{}$\1\6 +${}\\{word\_count}\PP;{}$\6 +${}\\{in\_word}\K\T{1};{}$\6 +\4${}\}{}$\2\6 +\&{continue};\6 +\4${}\}{}$\2\6 +\&{if} ${}(\|c\E\.{'\\n'}){}$\1\5 +${}\\{line\_count}\PP;{}$\2\6 +\&{else} \&{if} ${}(\|c\I\.{'\ '}\W\|c\I\.{'\\t'}){}$\1\5 +\&{continue};\2\6 +${}\\{in\_word}\K\T{0}{}$;\C{ \PB{\|c} is newline, space, or tab }\6 +\4${}\}{}$\2\par +\U8.\fi + +\M{16}Buffered I/O allows us to count the number of characters almost for free. + +\Y\B\4\X16:Fill \PB{\\{buffer}} if it is empty; \PB{\&{break}} at end of file% +\X${}\E{}$\6 +\&{if} ${}(\\{ptr}\G\\{buf\_end}){}$\5 +${}\{{}$\1\6 +${}\\{ptr}\K\\{buffer};{}$\6 +${}\|c\K\\{read}(\\{fd},\39\\{ptr},\39\\{buf\_size});{}$\6 +\&{if} ${}(\|c\Z\T{0}){}$\1\5 +\&{break};\2\6 +${}\\{char\_count}\MRL{+{\K}}\|c;{}$\6 +${}\\{buf\_end}\K\\{buffer}+\|c;{}$\6 +\4${}\}{}$\2\par +\U15.\fi + +\M{17}It's convenient to output the statistics by defining a new function +\PB{\\{wc\_print}}; then the same function can be used for the totals. +Additionally we must decide here if we know the name of the file +we have processed or if it was just \PB{\\{stdin}}. + +\Y\B\4\X17:Write statistics for file\X${}\E{}$\6 +$\\{wc\_print}(\\{which},\39\\{char\_count},\39\\{word\_count},\39\\{line% +\_count});{}$\6 +\&{if} (\\{file\_count})\1\5 +${}\\{printf}(\.{"\ \%s\\n"},\39{*}\\{argv}){}$;\C{ not \PB{\\{stdin}} }\2\6 +\&{else}\1\5 +\\{printf}(\.{"\\n"});\C{ \PB{\\{stdin}} }\2\par +\U8.\fi + +\M{18}\B\X18:Update grand totals\X${}\E{}$\6 +$\\{tot\_line\_count}\MRL{+{\K}}\\{line\_count};{}$\6 +${}\\{tot\_word\_count}\MRL{+{\K}}\\{word\_count};{}$\6 +${}\\{tot\_char\_count}\MRL{+{\K}}\\{char\_count}{}$;\par +\U8.\fi + +\M{19}We might as well improve a bit on \UNIX/'s \wc{} by displaying the +number of files too. + +\Y\B\4\X19:Print the grand totals if there were multiple files\X${}\E{}$\6 +\&{if} ${}(\\{file\_count}>\T{1}){}$\5 +${}\{{}$\1\6 +${}\\{wc\_print}(\\{which},\39\\{tot\_char\_count},\39\\{tot\_word\_count},\39% +\\{tot\_line\_count});{}$\6 +${}\\{printf}(\.{"\ total\ in\ \%d\ files\\}\)\.{n"},\39\\{file\_count});{}$\6 +\4${}\}{}$\2\par +\U5.\fi + +\M{20}Here now is the function that prints the values according to the +specified options. The calling routine is supposed to supply a +newline. If an invalid option character is found we inform +the user about proper usage of the command. Counts are printed in +8-digit fields so that they will line up in columns. + +\Y\B\4\D$\\{print\_count}(\|n)$ \5 +$\\{printf}(\.{"\%8ld"},\39\|n{}$)\par +\Y\B\4\X20:Functions\X${}\E{}$\6 +$\\{wc\_print}(\\{which},\39\\{char\_count},\39\\{word\_count},\39\\{line% +\_count}){}$\1\1\6 +\&{char} ${}{*}\\{which}{}$;\C{ which counts to print }\6 +\&{long} \\{char\_count}${},{}$ \\{word\_count}${},{}$ \\{line\_count};\C{ +given totals }\2\2\6 +${}\{{}$\1\6 +\&{while} ${}({*}\\{which}){}$\1\6 +\&{switch} ${}({*}\\{which}\PP){}$\5 +${}\{{}$\1\6 +\4\&{case} \.{'l'}:\5 +\\{print\_count}(\\{line\_count});\6 +\&{break};\6 +\4\&{case} \.{'w'}:\5 +\\{print\_count}(\\{word\_count});\6 +\&{break};\6 +\4\&{case} \.{'c'}:\5 +\\{print\_count}(\\{char\_count});\6 +\&{break};\6 +\4\&{default}:\6 +\&{if} ${}((\\{status}\AND\\{usage\_error})\E\T{0}){}$\5 +${}\{{}$\1\6 +${}\\{fprintf}(\\{stderr},\39\.{"\\nUsage:\ \%s\ [-lwc]\ }\)\.{[filename\ ...]% +\\n"},\39\\{prog\_name});{}$\6 +${}\\{status}\MRL{{\OR}{\K}}\\{usage\_error};{}$\6 +\4${}\}{}$\2\6 +\4${}\}{}$\2\2\6 +\4${}\}{}$\2\par +\U2.\fi + +\M{21}Incidentally, a test of this program against the system \wc{} +command on a \SPARC\ showed that the ``official'' \wc{} was slightly +slower. Furthermore, although that \wc{} gave an appropriate error +message for the options `\texttt{-abc}', it made no complaints about the +options `\texttt{-labc}'! Dare we suggest that the system routine +might have been +better if its programmer had used a more literate approach? + + + +\bibliographystyle{plain} +\bibliography{wcltx} + + +\fi + +\M{22} + +\cwebIndexIntro{% +Here is a list of the identifiers used, and where they appear. +Underlined entries indicate the place of definition. Error messages +are also shown. +} + +\end{document} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% $Log: wcltx.w,v $ +% Revision 1.4 1995/08/29 17:27:57 schrod +% Recoded to LaTeX2e markup. +% +% Revision 1.3 1993/06/15 14:01:14 schrod +% Renamed document to wcltx, must change \bibliography tag, too. +% +% Revision 1.2 1993/06/15 13:35:12 schrod +% `cweb' is now a style, was an option formerly. +% +% Revision 1.1 1993/04/09 15:00:37 schrod +% Initial revision +% +\fi + + +\inx +\fin +\con |