home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 2
/
FFMCD02.bin
/
new
/
dev
/
misc
/
p2c
/
src
/
out.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-12-21
|
36KB
|
1,597 lines
/* "p2c", a Pascal to C translator.
Copyright (C) 1989, 1990, 1991 Free Software Foundation.
Author's address: daveg@csvax.caltech.edu; 256-80 Caltech/Pasadena CA 91125.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation (any version).
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* This needs to go before trans.h (and thus p2c.proto) is read */
typedef struct S_paren {
struct S_paren *next;
int pos, indent, qmindent, flags;
} Paren;
#define PROTO_OUT_C
#include "trans.h"
#ifndef USETIME
# if defined(BSD) || defined(hpux)
# define USETIME 1
# else
# define USETIME 0
# endif
#endif
#if USETIME
# include <sys/time.h>
#else
# include <time.h>
#endif
/* Output control characters:
\001 \B Possible break point
\002 \X Break point in parentheses
\003 \( Invisible open paren
\004 \) Invisible close paren
\005 \T Set left margin
\006 \F Forced break point
\007 \A Preceding paren requires all-or-none breaking
\010 \[ Invisible open paren, becomes visible if not all on one line
\011 \S Break point after last "special argument" of a function
\012 \n (newline)
\013 \E Preceding break has extra penalty
\014 \f (form-feed)
\015 \H Hang-indent the preceding operator
\016 \. (unused)
\017 \C Break point for last : of a ?: construct
*/
char spchars[] = ".BX()TFA[SnEfH.C................";
Static int testinglinebreaker = 0;
Static int deltaindent, thisindent, thisfutureindent;
Static int sectionsize, blanklines, codesectsize, hdrsectsize;
Static int codelnum, hdrlnum;
#define MAXBREAKS 200
Static int numbreaks, bestnumbreaks;
Static double bestbadness;
Static int breakpos[MAXBREAKS], breakindent[MAXBREAKS];
Static int breakcount[MAXBREAKS], breakparen[MAXBREAKS];
Static int bestbreakpos[MAXBREAKS], bestbreakindent[MAXBREAKS];
Static int breakerrorflag;
#define MAXEDITS 200
Static int numedits, bestnumedits;
Static int editpos[MAXEDITS], besteditpos[MAXEDITS];
Static char editold[MAXEDITS], editnew[MAXEDITS];
Static char besteditold[MAXEDITS], besteditnew[MAXEDITS];
Static Paren *parenlist;
Static long numalts, bestnumalts;
Static int randombreaks;
Static char *outbuf;
Static int outbufpos, outbufcount, outbufsize;
Static int suppressnewline, lastlinelength;
Static int eatblanks;
Static int embeddedcode;
Static int showingsourcecode = 0;
#define BIGBADNESS (1e20)
void setup_out()
{
end_source();
if (!nobanner)
fprintf(outf, "/* From input file \"%s\" */\n", infname);
outf_lnum++;
hdrlnum = 1;
outindent = 0;
deltaindent = 0;
thisindent = 0;
thisfutureindent = -1;
sectionsize = 2;
blanklines = 0;
dontbreaklines = 0;
embeddedcode = 0;
outputmode = 0;
suppressnewline = 0;
eatblanks = 0;
outbufsize = 1000;
outbuf = ALLOC(outbufsize, char, misc);
outbufpos = 0;
outbufcount = 0;
srand(17);
}
void select_outfile(fp)
FILE *fp;
{
if (outf == codef) {
codesectsize = sectionsize;
codelnum = outf_lnum;
} else {
hdrsectsize = sectionsize;
hdrlnum = outf_lnum;
}
outf = fp;
if (outf == codef) {
sectionsize = codesectsize;
outf_lnum = codelnum;
} else {
sectionsize = hdrsectsize;
outf_lnum = hdrlnum;
}
}
void start_source()
{
if (!showingsourcecode) {
fprintf(outf, "\n#ifdef Pascal\n");
showingsourcecode = 1;
}
}
void end_source()
{
if (showingsourcecode) {
fprintf(outf, "#endif /*Pascal*/\n\n");
showingsourcecode = 0;
}
}
int line_start()
{
return (outbufcount == 0);
}
int cur_column()
{
if (outbufpos == 0)
return outindent;
else
return thisindent + outbufcount;
}
int lookback(n)
int n;
{
if (n <= 0 || n > outbufpos)
return 0;
else
return outbuf[outbufpos - n];
}
int lookback_prn(n)
int n;
{
for (;;) {
if (n <= 0 || n > outbufpos)
return 0;
else if (outbuf[outbufpos - n] >= ' ')
return outbuf[outbufpos - n];
else
n++;
}
}
/* Combine two indentation adjustments */
int adddeltas(d1, d2)
int d1, d2;
{
if (d2 >= 1000)
return d2;
else
return d1 + d2;
}
/* Apply an indentation delta */
int applydelta(i, d)
int i, d;
{
if (d >= 1000)
return d - 1000;
else
return i + d;
}
/* Adjust the current indentation by delta */
void moreindent(delta)
int delta;
{
outindent = applydelta(outindent, delta);
}
/* Adjust indentation for just this line */
void singleindent(delta)
int delta;
{
deltaindent = adddeltas(deltaindent, delta);
}
/* Predict indentation for next line */
void futureindent(num)
int num;
{
thisfutureindent = applydelta(applydelta(outindent, deltaindent), num);
}
int parsedelta(cp, def)
char *cp;
int def;
{
if (!cp || !*cp)
return def;
if ((*cp == '+' || *cp == '-') && isdigit(cp[1]))
return atoi(cp);
if (*cp == '*' && isdigit(cp[1]))
return 2000 + atoi(cp+1);
else
return 1000 + atoi(cp);
}
Static void leading_tab(col)
int col;
{
if (col > maxlinewidth)
return; /* something wrong happened! */
if (phystabsize > 0) {
while (col >= phystabsize) {
putc('\t', outf);
col -= phystabsize;
}
}
while (col > 0) {
putc(' ', outf);
col--;
}
}
void eatblanklines()
{
eatblanks = 1;
}
Static void flush_outbuf(numbreaks, breakpos, breakindent,
numedits, editpos, editold, editnew)
int numbreaks, *breakpos, *breakindent, numedits, *editpos;
char *editold, *editnew;
{
unsigned char ch, ch2;
char *cp;
int i, j, linelen = 0, spaces, hashline;
int editsaves[MAXEDITS];
end_source();
if (outbufcount > 0) {
for (i = 0; i < numedits; i++) {
editsaves[i] = outbuf[editpos[i]];
outbuf[editpos[i]] = editnew[i];
}
leading_tab(thisindent);
cp = outbuf;
hashline = (*cp == '#'); /* a preprocessor directive */
spaces = 0;
j = 1;
for (i = 0; i < outbufpos; ) {
if (j < numbreaks && i == breakpos[j]) {
if (hashline)
fprintf(outf, " \\"); /* trailing backslash required */
putc('\n', outf);
outf_lnum++;
leading_tab(breakindent[j]);
linelen = breakindent[j];
j++;
while (i < outbufpos && *cp == ' ')
i++, cp++; /* eat leading spaces */
spaces = 0; /* eat trailing spaces */
} else {
ch = *cp++;
if (ch == ' ') {
spaces++;
} else if (ch > ' ') {
linelen += spaces;
while (spaces > 0)
putc(' ', outf), spaces--;
linelen++;
if (ch == '\\' && embeddedcode) {
if (*cp == '[') {
putc('{', outf);
cp++, i++;
} else if (*cp == ']') {
putc('}', outf);
cp++, i++;
} else
putc(ch, outf);
} else
putc(ch, outf);
} else if (testinglinebreaker >= 3) {
linelen += spaces;
while (spaces > 0)
putc(' ', outf), spaces--;
linelen++;
putc('\\', outf);
ch2 = spchars[ch];
if (ch2 != '.')
putc(ch2, outf);
else {
putc('0' + ((ch >> 6) & 7), outf);
putc('0' + ((ch >> 3) & 7), outf);
putc('0' + (ch & 7), outf);
}
}
i++;
}
}
for (i = 0; i < numedits; i++)
outbuf[editpos[i]] = editsaves[i];
eatblanks = 0;
} else if (eatblanks) {
return;
}
if (suppressnewline) {
lastlinelength = linelen;
} else
putc('\n', outf);
outf_lnum++;
}
#define ISQUOTE(ch) ((ch)=='"' || (ch)=='\'')
#define ISOPENP(ch) ((ch)=='(' || (ch)=='[' || (ch)=='\003' || (ch)=='\010')
#define ISCLOSEP(ch) ((ch)==')' || (ch)==']' || (ch)=='\004')
#define ISBREAK(ch) ((ch)=='\001' || (ch)=='\002' || (ch)=='\006' || (ch)=='\011' || (ch)=='\017')
Static int readquotes(posp, err)
int *posp, err;
{
int pos;
char quote;