home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.cs.arizona.edu
/
ftp.cs.arizona.edu.tar
/
ftp.cs.arizona.edu
/
icon
/
historic
/
v92.tgz
/
v92.tar
/
v92
/
src
/
preproc
/
pout.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-03-22
|
8KB
|
231 lines
#include "::preproc:preproc.h"
#include "::preproc:ptoken.h"
#include "::preproc:pproto.h"
int line_cntrl;
/*
* output - output preprocessed tokens for the current file.
*/
novalue output(out_file)
FILE *out_file;
{
struct token *t, *t1;
struct token *saved_whsp;
char *fname;
char *s;
int line;
int nxt_line;
int trail_nl; /* flag: trailing character in output is a new-line */
int blank_ln; /* flag: output ends with blank line */
fname = "";
line = -1;
/*
* Suppress an initial new-line in the output.
*/
trail_nl = 1;
blank_ln = 1;
while ((t = preproc()) != NULL) {
if (t->flag & LineChk) {
/*
* This token is significant with respect to outputting #line
* directives.
*/
nxt_line = t->line;
if (fname != t->fname || line != nxt_line) {
/*
* We need a #line directive. Make sure it is preceeded by a
* blank line.
*/
if (!trail_nl) {
putc('\n', out_file);
++line;
trail_nl = 1;
}
if (!blank_ln && (line != nxt_line || fname != t->fname)) {
putc('\n', out_file);
++line;
blank_ln = 1;
}
/*
* Eliminate extra new-lines from the subsequent text before
* inserting line directive. This make the output look better.
* The line number for the directive will change if new-lines
* are eliminated.
*/
saved_whsp = NULL;
s = t->image;
while (t->tok_id == WhiteSpace && (*s == ' ' || *s == '\n' ||
*s == '\t')) {
if (*s == '\n') {
/*
* Discard any white space before the new-line and update
* the line number.
*/
free_t(saved_whsp);
saved_whsp = NULL;
t->image = s + 1;
++t->line;
++nxt_line;
}
++s;
if (*s == '\0') {
/*
* The end of the current white space token has been
* reached, see if the next token is also white space.
*/
free_t(saved_whsp);
t1 = preproc();
if (t1 == NULL) {
/*
* We are at the end of the input. Don't output
* a #line directive, just make sure the output
* ends with a new-line.
*/
free_t(t);
if (!trail_nl)
putc('\n', out_file);
return;
}
/*
* The previous token may contain non-new-line white
* space, if the new token is on the same line, save
* that previous token in case we want to print the
* white space (this will correctly indent the new
* token).
*/
if (*(t->image) != '\0' && t->line == t1->line &&
t->fname == t1->fname)
saved_whsp = t;
else {
free_t(t);
saved_whsp = NULL;
}
t = t1;
s = t->image;
nxt_line = t->line;
}
}
if (line_cntrl) {
/*
* We are supposed to insert #line directives where needed.
* However, one or two blank lines look better when they
* are enough to reestablish the correct line number.
*/
if (fname != t->fname || line > nxt_line ||
line + 2 < nxt_line) {
/*
* Normally a blank line is put after the #line
* directive; However, this requires decrementing
* the line number and a line number of 0 is not
* valid.
*/
if (nxt_line > 1)
fprintf(out_file, "#line %d \"", nxt_line - 1);
else
fprintf(out_file, "#line %d \"", nxt_line);
for (s = t->fname; *s != '\0'; ++s) {
if (*s == '"' || *s == '\\')
putc('\\',out_file);
putc(*s, out_file);
}
fprintf(out_file, "\"\n");
if (nxt_line > 1)
fprintf(out_file, "\n"); /* blank line after directive */
trail_nl = 1;
blank_ln = 1;
}
else /* adjust line number with blank lines */
while (line < nxt_line) {
putc('\n', out_file);
++line;
if (trail_nl)
blank_ln = 1;
trail_nl = 1;
}
}
/*
* See if we need to indent the next token with white space
* saved while eliminating extra new-lines.
*/
if (saved_whsp != NULL) {
fprintf(out_file, "%s", saved_whsp->image);
free_t(saved_whsp);
if (trail_nl) {
blank_ln = 1;
trail_nl = 0;
}
}
line = t->line;
fname = t->fname;
}
}
/*
* Print the image of the token.
*/
if (t->tok_id == WhiteSpace) {
/*
* Keep track of trailing blank lines and new-lines. This
* information is used to make the insertion of #line
* directives more intelligent and to insure that the output
* file ends with a new-line.
*/
for (s = t->image; *s != '\0'; ++s) {
putc(*s, out_file);
switch (*s) {
case '\n':
if (trail_nl)
blank_ln = 1;
trail_nl = 1;
++line;
break;
case ' ':
case '\t':
if (trail_nl)
blank_ln = 1;
trail_nl = 0;
break;
default:
trail_nl = 0;
}
}
}
else {
/*
* Add delimiters to string and character literals.
*/
switch (t->tok_id) {
case StrLit:
fprintf(out_file, "\"%s\"", t->image);
break;
case LStrLit:
fprintf(out_file, "L\"%s\"", t->image);
break;
case CharConst:
fprintf(out_file, "'%s'", t->image);
break;
case LCharConst:
fprintf(out_file, "L'%s'", t->image);
break;
default:
fprintf(out_file, "%s", t->image);
}
trail_nl = 0;
blank_ln = 0;
}
free_t(t);
}
/*
* Make sure output file ends with a new-line.
*/
if (!trail_nl)
putc('\n', out_file);
}