University of Calgary

pretty printer: comment formatter

"Pretty-Printer: Comment Formatter"
source: Katrin Becker, 2001

You are to write an efficient program that will take as it's input a file containing a program and produce as output a new program with the in-line comments (// this kind) RIGHT-justified.

Your program should be run like a command, and take two (command-line) arguments:

1. the name of a C++ source program (<name>.cc, <name>.cpp)
2. an output name for the processed version of the program (same suffix assumed if not given)

Assumptions:

- you may assume the original source compiled without errors or warnings
Specifications:
- your program may not terminate abnormally. (It can give up; claim to have found no comments, etc. but it cannot bomb)
- any messages produced by your program should be written to the monitor.
- the output file must compile and run as the original (i.e. the new program must be semantically identical to the original)
- you do not need to design this as an OO program.
- this 'utility' must not over-write the original source program unless explicitly asked to do so, for example:
./Format encrypt.cc encrypt.cc
will cause the original source file to be over-written.
 
- if only one argument is provided, the utility will print an error message
- if no arguments are provided, the utility will print a brief message outlining how it is used. (For a UNIX example, try typing cp with no arguments)
- choose a reasonable default value for the right margin. Standard paper has about 80 columns.
- if a line containing an in-line comment is already longer than 80 columns, leave it as it is

Example BEFORE processing:

#include <iostream.h>

short count1; // A global variable, not explicitly initialized
short count2 = 5; // A global variable, explicitly initialized

short func1()
{
short count3; // A local auto_ variable, not explicitly initialized
short count4 = 22; // A local auto_ variable, explicitly initialized
static short count5; // A local static_ variable, not explicitly initialized
static short count6 = 9; // A local static_ variable, explicitly initialized

count1 ++; // Incrementing the global variable count1_.
count2 ++; // Incrementing the global variable count2_.
count3 ++; // Incrementing the local uninitialized auto_ variable count3_.
count4 ++; // Incrementing the local auto_ variable count4_.
count5 ++; // Incrementing the local static_ variable count5_.
count6 ++; // Incrementing the local static_ variable count6_.

cout << "count1 = " << count1 << endl;
cout << "count2 = " << count2 << endl;
cout << "count3 = " << count3 << endl;
cout << "count4 = " << count4 << endl;
cout << "count5 = " << count5 << endl;
cout << "count6 = " << count6 << endl;
cout << endl;

return 0;
}

int main()
{
func1();
func1();

return 0;
}


Example AFTER processing:

#include <iostream.h>

short count1;              // A global variable, not explicitly initialized
short count2 = 5;              // A global variable, explicitly initialized

short func1()
{
short count3;         // A local auto_ variable, not explicitly initialized
short count4 = 22;        // A local auto_ variable, explicitly initialized
static short count5;// A local static_ variable, not explicitly initialized
static short count6 = 9;// A local static_ variable, explicitly initialized

count1 ++;                     // Incrementing the global variable count1_.
count2 ++;                     // Incrementing the global variable count2_.
count3 ++;  // Incrementing the local uninitialized auto_ variable count3_.
count4 ++;                // Incrementing the local auto_ variable count4_.
count5 ++;              // Incrementing the local static_ variable count5_.
count6 ++;              // Incrementing the local static_ variable count6_.

cout << "count1 = " << count1 << endl;
cout << "count2 = " << count2 << endl;
cout << "count3 = " << count3 << endl;
cout << "count4 = " << count4 << endl;
cout << "count5 = " << count5 << endl;
cout << "count6 = " << count6 << endl;
cout << endl;

return 0;
}

int main()
{
func1();
func1();

return 0;
}


Testing:

1. your own source 

BONUSES:

1. allow the user to specify the "line-length" as a command-line argument (if the value is unreasonable - it should default)

2. distinguish between in-line comments that appear on the same line as other code and those that do not. The second type should be left where they are.

count++; // this one is one the same line as code
// this one refers to the next statement but is on a line alone
count--;

3. for comments that appear alone on a line: if there is no blank line preceding them, put one in. NOTE: make sure multiple comment lines like this do not end up double-spaced.

x = 45;
// stand-alone comment right after code
// and another one
for ( i = 0; i < count; i++)

4. also for comments that appear alone on a line: if they appear immediately after a block begin "{" leave them alone. This bonus only applies if you implement bonus #3.

5. make sure the contents of strings are ignored:

" here is a string // with what looks like a comment in it"

6. make sure inline comments that have been "commented out" are ignored:

/* beginning of comment block
   some_old_code = 0;
   // in-line comment
   som_more_old_code = 5;
*/

7. If you are still looking for more to do, you need to get a hobby.



Updated: August 10, 2005 09:18 AM