CS 1713 Section 1, Summer 1997
Assignment 5: Strings: cindent.c
An important concept in computer programming is a program that accepts
another program as input. One example of such a program is the cc
compiler; it is a program, written in C, that accepts another program,
also written in C, and produces machine language output. Other such
program-processing-programs may do transformations on their input program;
for example, cfront is a popular C++ to C translator; the input
is a C++ program and the output is an equivalent C program.
Your assignment is to write a C program that accepts as input another
C program, specified on the command line (with argc and argv),
and prints a nicely indented version of the input program on the standard
output. "Nicely indented" for the purpose of this program means that
statements within a compound statement are tabbed over one to the right
of the statements above and below, for instance:
printf ("hello");
for (i=0; i<n; i++) {
printf ("%d\n", i);
scanf ("%d\n", &m);
for (j=0; j<m; j++) {
printf ("%d\n", j);
}
}
printf ("goodbye");
The statements between { and } are indented, with a
tab, one more level than the surrounding statements. This property holds
even for nested compound statements, as in the third printf
statement. The executable program cindent in ~djimenez/bin
does what your program is expected to do, so run it on a few sample C
programs with bad indenting (examples of which many of you may find
in abundance in your directories) and inspect the output.
Your program is required to:
- Handle arbitrary nesting of compound statements.
- Print statements with opening curly braces at the same level of
indentation as the previous statements, as in the example above.
- Print statements with closing curly braces at the next level of
indentation to the left, as in the example above.
- Warn the user on standard error (fprintf (stderr, ...))
if a program has unbalanced curly braces.
- Handle curly braces in comments (e.g. /* { */), single quotes
(e.g. '{'), and double quotes (e.g. "{") correctly, i.e.,
take no action unless the curly brace is part of the program code and not
part of a comment or quote.
- Warn the user on standard error (fprintf (stderr, ...))
if a program has unbalanced curly braces or quotes.
- Be able to work on itself as input, as well as any other reasonable
C program.
- Exit with an appropriate error message and an error code of 1 if the
wrong number of arguments is
supplied on the command line or if the file can't be opened for reading.
Some hints for writing this program:
- The basic idea is to read the program line by line with fgets(),
and for each line, examining it character by character in a for loop.
When you see a {, you know a compound statement is being
started.
When you see a }, you know a compound statement is being
ended.
- See strip.c for a C program that
strips the comments from a program named on the command line, writing the
results to the standard output. This will give you a framework within
which to write your program, and an idea of how to write a
program-processing-program. The Standard C Library
function perror used there prints
the supplied argument, followed by a colon, followed by an error message
indicating why the file could not be opened for input.
Note that your program should not strip
comments, simply ignore curly braces within them.
- Have an int variable called level that starts
out at zero and represents the number of tabs to be printed before the
current line. If a { occurs on the current line, increment
level after printing the current line.
If a } occurs on the current line, decrement level
before printing the current line.
- Make sure to remove any whitespace (spaces or tabs) preceding the
current line before printing your own tabs. Otherwise, any preexisting
indentation in the program will be printed along with your indentation.
You can do this using a for loop that examines the current string
character by character until a non-whitespace character is found, then
remembering that position and printing from there after doing your indentation.
The C notation for a tab is '\t'.
- Have a variable called quoting that is true if and only if
you are in the middle of a quote (single or double). If quoting
is true, don't pay attention to any curly braces. quoting is set
to true when it's false and you see a quote; it is set to false when it is
true and you see a quote.
- Your program does not need to be too smart about C; it just needs to
know about curly braces, comments, and quotes. Don't worry about indenting
if/else statements without compound statements. Don't worry about
syntax errors in the program to be processed; your program is not a C
compiler, just an indenting program.
- Don't worry about comments within quotes, that's getting a bit silly.
- The instructor's program is not named indent for a reason:
the name indent is an existing Unix program with a similar purpose.
If you name your program indent, chances are you will be executing
the other indent by mistake.
Turn in your program by e-mailing the C source (indented and commented nicely!)
to the instructor. Remember to post your progress report discussing this
program et cetera to the newsgroup by the due date.
This assignment is due at midnight on Monday, July 21, 1997.