Push through clang-format.

This commit is contained in:
David Given 2016-08-21 19:34:54 +02:00
parent a4f136f999
commit 3584ddb6e9

View file

@ -31,39 +31,37 @@
#include "cf_idom.h" #include "cf_idom.h"
#include "cf_loop.h" #include "cf_loop.h"
#define newcfbx() (bext_p) newstruct(bext_cf) #define newcfbx() (bext_p) newstruct(bext_cf)
#define oldcfbx(x) oldstruct(bext_cf,x) #define oldcfbx(x) oldstruct(bext_cf, x)
extern char em_flag[]; extern char em_flag[];
STATIC cset lpi_set; /* set of procedures used in LPI instruction */ STATIC cset lpi_set; /* set of procedures used in LPI instruction */
STATIC cset cai_set; /* set of all procedures doing a CAI */ STATIC cset cai_set; /* set of all procedures doing a CAI */
/* The procedure getbblocks reads the EM textfile and /* The procedure getbblocks reads the EM textfile and
* partitions every procedure into a number of basic blocks. * partitions every procedure into a number of basic blocks.
*/ */
#define LABEL0 0 #define LABEL0 0
#define LABEL 1 #define LABEL 1
#define NORMAL 2 #define NORMAL 2
#define JUMP 3 #define JUMP 3
#define END 4 #define END 4
#define AFTERPRO 5 #define AFTERPRO 5
#define INIT 6 #define INIT 6
/* These global variables are used by getbblocks and nextblock. */ /* These global variables are used by getbblocks and nextblock. */
STATIC bblock_p b, *bp; /* b is the current basic block, bp is STATIC bblock_p b, *bp; /* b is the current basic block, bp is
* the address where the next block has * the address where the next block has
* to be linked. * to be linked.
*/ */
STATIC line_p lnp, *lp; /* lnp is the current line, lp is STATIC line_p lnp, *lp; /* lnp is the current line, lp is
* the address where the next line * the address where the next line
* has to be linked. * has to be linked.
*/ */
STATIC short state; /* We use a finite state machine with the STATIC short state; /* We use a finite state machine with the
* following states: * following states:
* LABEL0: after the first (successive) * LABEL0: after the first (successive)
* instruction label. * instruction label.
@ -77,7 +75,6 @@ STATIC short state; /* We use a finite state machine with the
* INIT: initial state * INIT: initial state
*/ */
STATIC nextblock() STATIC nextblock()
{ {
/* allocate a new basic block structure and /* allocate a new basic block structure and
@ -94,40 +91,44 @@ STATIC nextblock()
b->b_extend->bx_cf.bx_semi = 0; b->b_extend->bx_cf.bx_semi = 0;
lp = &lnp->l_next; lp = &lnp->l_next;
#ifdef TRACE #ifdef TRACE
fprintf(stderr,"new basic block, id = %d\n",lastbid); fprintf(stderr, "new basic block, id = %d\n", lastbid);
#endif #endif
} }
STATIC short kind(lnp) STATIC short kind(lnp)
line_p lnp; line_p lnp;
{ {
/* determine if lnp is a label, branch, end or otherwise */ /* determine if lnp is a label, branch, end or otherwise */
short instr; short instr;
byte flow; byte flow;
if ((instr = INSTR(lnp)) == op_lab) return (short) LABEL; if ((instr = INSTR(lnp)) == op_lab)
if (instr == ps_end) return (short) END; return (short)LABEL;
if (instr > sp_lmnem) return (short) NORMAL; /* pseudo */ if (instr == ps_end)
if ((flow = (em_flag[instr-sp_fmnem] & EM_FLO)) == FLO_C || return (short)END;
flow == FLO_T) return (short) JUMP; /* conditional/uncond. jump */ if (instr > sp_lmnem)
return (short) NORMAL; return (short)NORMAL; /* pseudo */
if ((flow = (em_flag[instr - sp_fmnem] & EM_FLO)) == FLO_C || flow == FLO_T)
return (short)JUMP; /* conditional/uncond. jump */
return (short)NORMAL;
} }
STATIC line_p doread_line(p_out) STATIC line_p doread_line(p_out)
proc_p *p_out; proc_p* p_out;
{ {
/* read a line, and check pseudos for procedure addresses */ /* read a line, and check pseudos for procedure addresses */
register line_p lnp = read_line(p_out); register line_p lnp = read_line(p_out);
if (lnp && TYPE(lnp) == OPLIST && INSTR(lnp) != ps_mes) { if (lnp && TYPE(lnp) == OPLIST && INSTR(lnp) != ps_mes)
{
register arg_p arg = ARG(lnp); register arg_p arg = ARG(lnp);
while (arg) { while (arg)
if (arg->a_type == ARGPROC) { {
if (arg->a_type == ARGPROC)
{
Cadd(arg->a_a.a_proc->p_id, &lpi_set); Cadd(arg->a_a.a_proc->p_id, &lpi_set);
arg->a_a.a_proc->p_flags1 |= PF_LPI; arg->a_a.a_proc->p_flags1 |= PF_LPI;
} }
@ -137,34 +138,36 @@ STATIC line_p doread_line(p_out)
return lnp; return lnp;
} }
STATIC bool getbblocks(fp,kind_out,n_out,g_out,l_out) STATIC bool getbblocks(fp, kind_out, n_out, g_out, l_out)
FILE *fp; FILE* fp;
short *kind_out; short* kind_out;
short *n_out; short* n_out;
bblock_p *g_out; bblock_p* g_out;
line_p *l_out; line_p* l_out;
{ {
bblock_p head = (bblock_p) 0; bblock_p head = (bblock_p)0;
line_p headl = (line_p) 0; line_p headl = (line_p)0;
curproc = (proc_p) 0; curproc = (proc_p)0;
/* curproc will get a value when we encounter a PRO pseudo. /* curproc will get a value when we encounter a PRO pseudo.
* If there is no such pseudo, we're reading only data * If there is no such pseudo, we're reading only data
* declarations or messages (outside any proc.). * declarations or messages (outside any proc.).
*/ */
curinp = fp; curinp = fp;
lastbid = (block_id) 0; /* block identier */ lastbid = (block_id)0; /* block identier */
state = INIT; /* initial state */ state = INIT; /* initial state */
bp = &head; bp = &head;
for (;;) { for (;;)
{
#ifdef TRACE #ifdef TRACE
fprintf(stderr,"state = %d\n",state); fprintf(stderr, "state = %d\n", state);
#endif #endif
switch(state) { switch (state)
{
case LABEL0: case LABEL0:
nextblock(); nextblock();
/* Fall through !! */ /* Fall through !! */
case LABEL: case LABEL:
lbmap[INSTRLAB(lnp)] = b; lbmap[INSTRLAB(lnp)] = b;
/* The lbmap table contains for each /* The lbmap table contains for each
@ -172,21 +175,26 @@ STATIC bool getbblocks(fp,kind_out,n_out,g_out,l_out)
*/ */
lnp = doread_line(&curproc); lnp = doread_line(&curproc);
state = kind(lnp); state = kind(lnp);
if (state != END) { if (state != END)
{
*lp = lnp; *lp = lnp;
lp = &lnp->l_next; lp = &lnp->l_next;
} }
break; break;
case NORMAL: case NORMAL:
lnp = doread_line(&curproc); lnp = doread_line(&curproc);
if ( (state = kind(lnp)) == LABEL) { if ((state = kind(lnp)) == LABEL)
{
/* If we come accross a label /* If we come accross a label
* here, it must be the beginning * here, it must be the beginning
* of a new basic block. * of a new basic block.
*/ */
state = LABEL0; state = LABEL0;
} else { }
if (state != END) { else
{
if (state != END)
{
*lp = lnp; *lp = lnp;
lp = &lnp->l_next; lp = &lnp->l_next;
} }
@ -194,9 +202,10 @@ STATIC bool getbblocks(fp,kind_out,n_out,g_out,l_out)
break; break;
case JUMP: case JUMP:
lnp = doread_line(&curproc); lnp = doread_line(&curproc);
/* fall through ... */ /* fall through ... */
case AFTERPRO: case AFTERPRO:
switch(state = kind(lnp)) { switch (state = kind(lnp))
{
case LABEL: case LABEL:
state = LABEL0; state = LABEL0;
break; break;
@ -209,24 +218,31 @@ STATIC bool getbblocks(fp,kind_out,n_out,g_out,l_out)
case END: case END:
*lp = lnp; *lp = lnp;
#ifdef TRACE #ifdef TRACE
fprintf(stderr,"at end of proc, %d blocks\n",lastbid); fprintf(stderr, "at end of proc, %d blocks\n", lastbid);
#endif #endif
if (head == (bblock_p) 0) { if (head == (bblock_p)0)
{
*kind_out = LDATA; *kind_out = LDATA;
*l_out = headl; *l_out = headl;
} else { }
else
{
*kind_out = LTEXT; *kind_out = LTEXT;
*g_out = head; *g_out = head;
*n_out = (short) lastbid; *n_out = (short)lastbid;
/* number of basic blocks */ /* number of basic blocks */
} }
return TRUE; return TRUE;
case INIT: case INIT:
lnp = doread_line(&curproc); lnp = doread_line(&curproc);
if (feof(curinp)) return FALSE; if (feof(curinp))
if (INSTR(lnp) == ps_pro) { return FALSE;
if (INSTR(lnp) == ps_pro)
{
state = AFTERPRO; state = AFTERPRO;
} else { }
else
{
state = NORMAL; state = NORMAL;
headl = lnp; headl = lnp;
lp = &lnp->l_next; lp = &lnp->l_next;
@ -236,9 +252,8 @@ STATIC bool getbblocks(fp,kind_out,n_out,g_out,l_out)
} }
} }
STATIC interproc_analysis(p) STATIC interproc_analysis(p)
proc_p p; proc_p p;
{ {
/* Interprocedural analysis of a procedure p determines: /* Interprocedural analysis of a procedure p determines:
* - all procedures called by p (the 'call graph') * - all procedures called by p (the 'call graph')
@ -255,7 +270,7 @@ STATIC interproc_analysis(p)
*/ */
bblock_p b; bblock_p b;
line_p lnp; line_p lnp;
bool inloop; bool inloop;
/* Allocate memory for structs and sets */ /* Allocate memory for structs and sets */
@ -265,85 +280,90 @@ STATIC interproc_analysis(p)
p->p_change->c_ext = Cempty_set(olength); p->p_change->c_ext = Cempty_set(olength);
p->p_calling = Cempty_set(plength); p->p_calling = Cempty_set(plength);
for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { for (b = p->p_start; b != (bblock_p)0; b = b->b_next)
inloop = (Lnrelems(b->b_loops) > 0); {
for (lnp = b->b_start; lnp != (line_p) 0; lnp = lnp->l_next) { inloop = (Lnrelems(b->b_loops) > 0);
/* for all instructions of p do */ for (lnp = b->b_start; lnp != (line_p)0; lnp = lnp->l_next)
switch(INSTR(lnp)) { {
case op_cal: /* for all instructions of p do */
Cadd(PROC(lnp)->p_id, &p->p_calling); switch (INSTR(lnp))
/* add called proc to p_calling */ {
if (inloop) { case op_cal:
CALLED_IN_LOOP(PROC(lnp)); Cadd(PROC(lnp)->p_id, &p->p_calling);
} /* add called proc to p_calling */
break; if (inloop)
case op_cai: {
Cadd(p->p_id,&cai_set); CALLED_IN_LOOP(PROC(lnp));
break; }
case op_lpi: break;
Cadd(PROC(lnp)->p_id, &lpi_set); case op_cai:
/* All procedures that have their names used Cadd(p->p_id, &cai_set);
break;
case op_lpi:
Cadd(PROC(lnp)->p_id, &lpi_set);
/* All procedures that have their names used
* in an lpi instruction, may be called via * in an lpi instruction, may be called via
* a cai instruction. * a cai instruction.
*/ */
PROC(lnp)->p_flags1 |= PF_LPI; PROC(lnp)->p_flags1 |= PF_LPI;
break; break;
case op_ste: case op_ste:
case op_sde: case op_sde:
case op_ine: case op_ine:
case op_dee: case op_dee:
case op_zre: case op_zre:
Cadd(OBJ(lnp)->o_id, &p->p_change->c_ext); Cadd(OBJ(lnp)->o_id, &p->p_change->c_ext);
/* Add changed object to c_ext */ /* Add changed object to c_ext */
break; break;
case op_lil: case op_lil:
case op_lof: case op_lof:
case op_loi: case op_loi:
case op_los: case op_los:
case op_lar: case op_lar:
p->p_use->u_flags |= UF_INDIR; p->p_use->u_flags |= UF_INDIR;
/* p does a load-indirect */ /* p does a load-indirect */
break; break;
case op_sil: case op_sil:
case op_stf: case op_stf:
case op_sti: case op_sti:
case op_sts: case op_sts:
case op_sar: case op_sar:
p->p_change->c_flags |= CF_INDIR; p->p_change->c_flags |= CF_INDIR;
/* p does a store-indirect */ /* p does a store-indirect */
break; break;
case op_blm: case op_blm:
case op_bls: case op_bls:
p->p_use->u_flags |= UF_INDIR; p->p_use->u_flags |= UF_INDIR;
p->p_change->c_flags |= CF_INDIR; p->p_change->c_flags |= CF_INDIR;
/* p does both */ /* p does both */
break; break;
case op_mon: case op_mon:
printf("mon not yet implemented\n"); printf("mon not yet implemented\n");
break; break;
case op_lxl: case op_lxl:
case op_lxa: case op_lxa:
curproc->p_flags1 |= PF_ENVIRON; curproc->p_flags1 |= PF_ENVIRON;
break; break;
case op_lor: case op_lor:
case op_str: case op_str:
if (SHORT(lnp) == 0) { if (SHORT(lnp) == 0)
curproc->p_flags1 |= PF_ENVIRON; {
curproc->p_flags1 |= PF_ENVIRON;
}
break;
case ps_mes:
if (aoff(ARG(lnp), 0) == ms_gto)
{
ENTERED_WITH_GTO(curproc);
}
break;
} }
break;
case ps_mes:
if (aoff(ARG(lnp),0) == ms_gto) {
ENTERED_WITH_GTO(curproc);
}
break;
} }
}
} }
} }
STATIC cf_cleanproc(p) STATIC cf_cleanproc(p)
proc_p p; proc_p p;
{ {
/* Remove the extended data structures of p */ /* Remove the extended data structures of p */
@ -351,26 +371,26 @@ STATIC cf_cleanproc(p)
register Lindex pi; register Lindex pi;
loop_p lp; loop_p lp;
for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) { for (b = p->p_start; b != (bblock_p)0; b = b->b_next)
{
oldcfbx(b->b_extend); oldcfbx(b->b_extend);
} }
for (pi = Lfirst(p->p_loops); pi != (Lindex) 0; pi = Lnext(pi, for (pi = Lfirst(p->p_loops); pi != (Lindex)0; pi = Lnext(pi,
p->p_loops)) { p->p_loops))
lp = (loop_p) Lelem(pi); {
lp = (loop_p)Lelem(pi);
oldcflpx(lp->lp_extend); oldcflpx(lp->lp_extend);
} }
} }
#define CH_CHANGE_INDIR(ch) ((ch->c_flags & CF_INDIR) != 0)
#define USE_INDIR(us) ((us->u_flags & UF_INDIR) != 0)
#define CALLS_UNKNOWN(p) (p->p_flags1 & (byte)PF_CALUNKNOWN)
#define ENVIRON(p) (p->p_flags1 & (byte)PF_ENVIRON)
STATIC bool add_info(q, p)
#define CH_CHANGE_INDIR(ch) ((ch->c_flags & CF_INDIR) != 0) proc_p q,
#define USE_INDIR(us) ((us->u_flags & UF_INDIR) != 0) p;
#define CALLS_UNKNOWN(p) (p->p_flags1 & (byte) PF_CALUNKNOWN)
#define ENVIRON(p) (p->p_flags1 & (byte) PF_ENVIRON)
STATIC bool add_info(q,p)
proc_p q,p;
{ {
/* Determine the consequences for used/changed variables info /* Determine the consequences for used/changed variables info
* of the fact that p calls q. If e.g. q changes a variable X * of the fact that p calls q. If e.g. q changes a variable X
@ -381,40 +401,48 @@ STATIC bool add_info(q,p)
*/ */
change_p chp, chq; change_p chp, chq;
use_p usp, usq; use_p usp, usq;
bool diff = FALSE; bool diff = FALSE;
chp = p->p_change; chp = p->p_change;
chq = q->p_change; chq = q->p_change;
usp = p->p_use; usp = p->p_use;
usq = q->p_use; usq = q->p_use;
if (!BODY_KNOWN(q)) { if (!BODY_KNOWN(q))
{
/* q is a procedure of which the body is not available /* q is a procedure of which the body is not available
* as EM text. * as EM text.
*/ */
if (CALLS_UNKNOWN(p)) { if (CALLS_UNKNOWN(p))
{
return FALSE; return FALSE;
/* p already called an unknown procedure */ /* p already called an unknown procedure */
} else { }
else
{
p->p_flags1 |= PF_CALUNKNOWN; p->p_flags1 |= PF_CALUNKNOWN;
return TRUE; return TRUE;
} }
} }
if (CALLS_UNKNOWN(q)) { if (CALLS_UNKNOWN(q))
{
/* q calls a procedure of which the body is not available /* q calls a procedure of which the body is not available
* as EM text. * as EM text.
*/ */
if (!CALLS_UNKNOWN(p)) { if (!CALLS_UNKNOWN(p))
{
p->p_flags1 |= PF_CALUNKNOWN; p->p_flags1 |= PF_CALUNKNOWN;
diff = TRUE; diff = TRUE;
} }
} }
if (IS_CALLED_IN_LOOP(p) && !IS_CALLED_IN_LOOP(q)) { if (IS_CALLED_IN_LOOP(p) && !IS_CALLED_IN_LOOP(q))
{
CALLED_IN_LOOP(q); CALLED_IN_LOOP(q);
diff = TRUE; diff = TRUE;
} }
if (!Cis_subset(chq->c_ext, chp->c_ext)) { if (!Cis_subset(chq->c_ext, chp->c_ext))
{
/* q changes global variables (objects) that /* q changes global variables (objects) that
* p did not (yet) change. Add all variables * p did not (yet) change. Add all variables
* changed by q to the c_ext set of p. * changed by q to the c_ext set of p.
@ -422,21 +450,24 @@ STATIC bool add_info(q,p)
Cjoin(chq->c_ext, &chp->c_ext); Cjoin(chq->c_ext, &chp->c_ext);
diff = TRUE; diff = TRUE;
} }
if (CH_CHANGE_INDIR(chq) && !CH_CHANGE_INDIR(chp)) { if (CH_CHANGE_INDIR(chq) && !CH_CHANGE_INDIR(chp))
{
/* q does a change-indirect (sil etc.) /* q does a change-indirect (sil etc.)
* and p did not (yet). * and p did not (yet).
*/ */
chp->c_flags |= CF_INDIR; chp->c_flags |= CF_INDIR;
diff = TRUE; diff = TRUE;
} }
if (USE_INDIR(usq) && !USE_INDIR(usp)) { if (USE_INDIR(usq) && !USE_INDIR(usp))
{
/* q does a use-indirect (lil etc.) /* q does a use-indirect (lil etc.)
* and p dis not (yet). * and p dis not (yet).
*/ */
usp->u_flags |= UF_INDIR; usp->u_flags |= UF_INDIR;
diff = TRUE; diff = TRUE;
} }
if (ENVIRON(q) && !ENVIRON(p)) { if (ENVIRON(q) && !ENVIRON(p))
{
/* q uses or changes local variables in its /* q uses or changes local variables in its
* environment while p does not (yet). * environment while p does not (yet).
*/ */
@ -446,94 +477,99 @@ STATIC bool add_info(q,p)
return diff; return diff;
} }
STATIC trans_clos(head) STATIC trans_clos(head)
proc_p head; proc_p head;
{ {
/* Compute the transitive closure of the used/changed /* Compute the transitive closure of the used/changed
* variable information. * variable information.
*/ */
register proc_p p,q; register proc_p p, q;
Cindex i; Cindex i;
bool changes = TRUE; bool changes = TRUE;
while(changes) { while (changes)
{
changes = FALSE; changes = FALSE;
for (p = head; p != (proc_p) 0; p = p->p_next) { for (p = head; p != (proc_p)0; p = p->p_next)
if (!BODY_KNOWN(p)) continue; {
for (i = Cfirst(p->p_calling); i != (Cindex) 0; if (!BODY_KNOWN(p))
i = Cnext(i,p->p_calling)) { continue;
q = pmap[Celem(i)]; for (i = Cfirst(p->p_calling); i != (Cindex)0;
if (add_info(q,p)) { i = Cnext(i, p->p_calling))
changes = TRUE; {
q = pmap[Celem(i)];
if (add_info(q, p))
{
changes = TRUE;
}
} }
}
} }
} }
} }
indir_calls() indir_calls()
{ {
Cindex i; Cindex i;
proc_p p; proc_p p;
for (i = Cfirst(cai_set); i != (Cindex) 0; i = Cnext(i,cai_set)) { for (i = Cfirst(cai_set); i != (Cindex)0; i = Cnext(i, cai_set))
p = pmap[Celem(i)]; /* p does a CAI */ {
p = pmap[Celem(i)]; /* p does a CAI */
Cjoin(lpi_set, &p->p_calling); Cjoin(lpi_set, &p->p_calling);
} }
Cdeleteset(lpi_set); Cdeleteset(lpi_set);
Cdeleteset(cai_set); Cdeleteset(cai_set);
} }
main(argc, argv) int argc;
char* argv[];
main(argc,argv)
int argc;
char *argv[];
{ {
FILE *f, *f2, *gf2; /* The EM input, EM output, basic block output */ FILE* f, *f2, *gf2; /* The EM input, EM output, basic block output */
bblock_p g; bblock_p g;
short n, kind; short n, kind;
line_p l; line_p l;
linecount = 0; linecount = 0;
fproc = getptable(pname); /* proc table */ fproc = getptable(pname); /* proc table */
fdblock = getdtable(dname); /* data block table */ fdblock = getdtable(dname); /* data block table */
lpi_set = Cempty_set(plength); lpi_set = Cempty_set(plength);
cai_set = Cempty_set(plength); cai_set = Cempty_set(plength);
if ((f = fopen(lname,"r")) == NULL) { if ((f = fopen(lname, "r")) == NULL)
{
error("cannot open %s", lname); error("cannot open %s", lname);
} }
if ((f2 = fopen(lname2,"w")) == NULL) { if ((f2 = fopen(lname2, "w")) == NULL)
{
error("cannot open %s", lname2); error("cannot open %s", lname2);
} }
if ((gf2 = fopen(bname2,"w")) == NULL) { if ((gf2 = fopen(bname2, "w")) == NULL)
error("cannot open %s",bname2); {
error("cannot open %s", bname2);
} }
while (getbblocks(f,&kind,&n,&g,&l)) { while (getbblocks(f, &kind, &n, &g, &l))
{
/* read EM text of one unit and /* read EM text of one unit and
* (if it is a procedure) * (if it is a procedure)
* partition it into n basic blocks. * partition it into n basic blocks.
*/ */
if (kind == LDATA) { if (kind == LDATA)
putunit(LDATA,(proc_p) 0,l,gf2,f2); {
} else { putunit(LDATA, (proc_p)0, l, gf2, f2);
}
else
{
curproc->p_start = g; curproc->p_start = g;
/* The global variable curproc points to the /* The global variable curproc points to the
* current procedure. It is set by getbblocks * current procedure. It is set by getbblocks
*/ */
control_flow(g); /* compute pred and succ */ control_flow(g); /* compute pred and succ */
dominators(g,n); /* compute immediate dominators */ dominators(g, n); /* compute immediate dominators */
loop_detection(curproc); /* compute loops */ loop_detection(curproc); /* compute loops */
interproc_analysis(curproc); interproc_analysis(curproc);
/* Interprocedural analysis */ /* Interprocedural analysis */
cf_cleanproc(curproc); cf_cleanproc(curproc);
putunit(LTEXT,curproc,(line_p) 0,gf2,f2); putunit(LTEXT, curproc, (line_p)0, gf2, f2);
/* output control flow graph + text */ /* output control flow graph + text */
} }
} }
@ -545,13 +581,15 @@ main(argc,argv)
/* Compute transitive closure of used/changed /* Compute transitive closure of used/changed
* variables information for every procedure. * variables information for every procedure.
*/ */
if ((f = fopen(dname2,"w")) == NULL) { if ((f = fopen(dname2, "w")) == NULL)
error("cannot open %s",dname2); {
error("cannot open %s", dname2);
} }
putdtable(fdblock,f); putdtable(fdblock, f);
if ((f = fopen(pname2,"w")) == NULL) { if ((f = fopen(pname2, "w")) == NULL)
error("cannot open %s",pname2); {
error("cannot open %s", pname2);
} }
putptable(fproc,f,TRUE); putptable(fproc, f, TRUE);
exit(0); exit(0);
} }