# Using CWEB

## Prerequisites

Here is the CWEB software and files used for these notes

• f.w - The CWEB document used in these notes.
• f.ch - A CWEB change file.
• cwebmac.tex - This is needed when compiling TeX output, and I don't know why. The file is part of the CWEB distribution (linked above). Put this in the directory where you compile the TeX files into PDFs.

Write out a simple CWEB document, name the file f.w

``````@* A Simple CWEB Document. This is a simple CWEB document that
incorporates documentation and code for a short C program that prints
square roots of real numbers. Running `./sqrt 25.0' at the shell will
print 5.

@c
@<Program@>@/

#include <stdio.h>
#include <stdlib.h>

@* The Program. Here is the program to find the square root of a number.

@<Program@>=
int main(int argc, char* argv[])
{
if (argc < 2)
{
printf("Usage: sqrt <n>\n");
exit(1);
}
printf("%15s %15s\n", "NUMBER", "SQUARE ROOT");
for (; argc > 1; --argc)
{
double n = atof(argv[argc - 1]);
printf("%15.4f %15.4f\n", n, sqrt(n));
}
return 0;
}

@ Now that we have used the |sqrt()| function, we need to include the

#include <math.h>
``````

then weave, that is, compile the CWEB document

``````cweave f.w
``````

which says, if f.w is a syntactically correct CWEB program,

``````This is CWEAVE (Version 3.64)
*1*3
Writing the output file...*1*3
Writing the index...
Done.
(No errors were found.)
``````

cweave outputs a text file f.tex, which is compiled to a PDF

``````tex f.tex
dvipdf f.dvi
gv f.pdf
``````

(Here I use gv, a Postscript and PDF viewer on any Linux system)

To pull out the C code from the CWEB program tangle the CWEB document

`````` ctangle f.w
``````

which, like cweave tells you if extraction worked correctly

``````This is CTANGLE (Version 3.64)
*1*3
Writing the output file (f.c):
Done.
(No errors were found.)
``````

The output of ctangle is a C file, f.c, which is compiled with a C compiler and run

`````` gcc f.c -lm -o sqrt
./sqrt 23 53 83
``````

to output

``````     NUMBER     SQUARE ROOT
83.0000          9.1104
53.0000          7.2801
23.0000          4.7958
``````

## Alternative Ways to Compile the PDF

Compile PDF after cweave has produced the TeX file

``````tex "let\pdf+ \input f"
dvipdfm f
``````

or

``````pdftex f
``````

## Using "Change Files"

Lines in a CWEB file can be replaced with lines specified in a change file. This is what a change file looks like, where we want to change a line specified by @x with the new line @y. The lines have to match with space, tabs and all. The change block ends with a @z. There can be more than one such block in the change file. The rest of the line after @x or @y is ignored, so you can put your own comments there. In the example below, I have used tabs/spaces at the beginning of the lines to match the indented C code in the CWEB document. (This is the contents of the file f.ch mentioned at the beginning of these notes.)

``````@x
for (; argc > 1; --argc)
@y
for (int i = argc - 1; i > 0; --i)
@z

@x
double n = atof(argv[argc - 1]);
@y
double n = atof(argv[i]);
@z
``````

Assuming we put this in a file called f.ch, we weave with the change

``````cweave f.w f.ch
``````

which produces output with the changes incorporated. In the final output (dvi/pdf) the section that has the above change is marked with an asterisk * sitting just next to the section number (in all places in the document where the section number appears).

The change file can also be used to tangle

``````ctangle f.w f.ch
``````

## The CWEB Parser

You can see exactly how CWEAVE is parsing your C code by preceding it with the line

``````@ @c @2
int main(int argc, char* argv[])
{
for (; argc > 0; argc--)
printf("%s\n", argv[argc - 1]);
}
``````

which outputs

``````[...]
4:*exp ( +exp+ )...
11:*exp +exp+ int...
5:*+exp+ int +unorbinop+...
[...]
60: +fn_decl+*+{+ -stmt- +}-
55:*+fn_decl+ -stmt-
52:*+function-
[...]
``````

## References

The CWEB System of Structured Documentation