Using CWEB

Write and Compile a CWEB Document

Prerequisites

Here is the CWEB software and files used for these notes

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
@<Header files@>@/
@<Program@>@/

@ The standard headers are included to start with,

@<Header ...@>=
#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
appropriate header file.

@<Header ...@>=
#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