/* repeat of last x or y = '&' */
/* redundant last 3 values in rectangle poly = '|' */
/* a repeat of the value inthe same position in the last poly = '^' */
/* the pattern "^&^" is shortened to '%' */
/* the Xn-X(n-2) is the same in this poly as it was in the last P = '@' */
/* if PnX0 - P(n-1)X0 == P(n-1)X0 - P(n-2)X0 then */
/* PnX0 is replaced by '~' */
/* The group "~%@|" is a common pattern and is replaced by '+' */
/* The group "@&&" is a common pattern and is replaced by '!' */
/* To be done:
* extend P+ to cover non rectangle shapes.
* common deltas
* n == one before last
* detect/compress ^!^! type sequence?
* replace polys by boxes when only 50% compressed
* put sequence compression on output stream
*/
static char compdracif_c_Sccs[] = "@(#)compdracif.c 1.7 10/4/89" ;
#include <stdio.h>
#include <ctype.h>
#include <time.h>
/* AUG/24/89 == 620005589 in time(0) form */
#define bombDate 620005589 + 3600*24*100
#define version 5
#define numpoints 2000
#define boxnums 10
#define numlayers 'z'-'a'
#define buf_len 10000
#define pi points[i]
#define opi opoints[i]
#define oopi oopoints[i]
#define bi b[i]
#define obi ob[i]
#define oobi oob[i]
#define ci c[i]
#define oci oc[i]
#define ooci ooc[i]
#define delOk(r,v) ( (abs( (v)/abs((v)-(r)) )>9) ? true : false )
/* set up parser vars */
char cmt_start_ch = '(',
cmt_end_ch = ')',
line_cmt_ch = '#',
x_id_start_chs[] = {'$','\0'},
x_id_chs[] = {'$','\0'},
x_space_chs[] = {',',':','@','\0'},
op_chs[] = {'T','R',';','-','/','\0'};
char *keys[] = {"DUMMY"};
#include "procs6.h"
FILE *fo,*fs;
/* poly point data */
typedef struct { int v,used; char vtype,txt[N_L]; } point;
point points[numpoints], opoints[numpoints], oopoints[numpoints];
boo lastWasArray=false;
/* box data */
point b[boxnums], ob[boxnums], oob[boxnums];
boo lastWasArrayBox=false;
/* C data */
point c[boxnums], oc[boxnums], ooc[boxnums];
/* char buffer */
char buf[buf_len]; int ix=0;
init_data()
{int i;
for(i=0;i<numpoints;i++)
{pi.v=0; pi.vtype=' '; pi.used=false; opi.v=0;}
for(i=0;i<=boxnums;i++)
{ bi.v=0L; obi.v=0L; bi.vtype=' '; bi.used=false;
ci.v=0L; oci.v=0L; ci.vtype=' '; ci.used=false; ci.txt[0]='\0'; }
}
/*
boo delOk(r,v)
long r,v;
{
if(r-v==0) return(true);
if(abs( v/abs(v-r))>11) return true;
return false;
}
*/
/*-----------------------------------------------------------------------*/
write_call()
{int i,j=0,nosemi=false; char spacer[1];
spacer[0]='\0';
spacer[1]='\0';
rmchar(' ',buf);
for(i=0;ci.used;i++)
if(ci.vtype==' ')
{ if(ci.v == oci.v) ci.vtype = '^';
else if(ci.v-oci.v == oci.v-ooci.v) ci.vtype='~';
else if(i>0 && ci.v==c[i-1].v) ci.vtype='&';
/* equals one before last */
else if(ci.v == ooci.v) ci.vtype='=';
/* vertical delta */
else if(delOk(oci.v,ci.v))
{ if(ci.v>oci.v) ci.vtype = '{'; else ci.vtype = '}'; }
}
/* for(i=0;ci.used;i++) printf("%d%c",ci.v,ci.vtype); printf("\n"); */
/* write out the call */
fpf(fo,"%s",buf);
for(i=0;ci.used;i++)
{if(ci.vtype!=' ')
{
if(i>0 && (ci.vtype == '[' || ci.vtype == ']'))
{ spacer[0]=' ';
fpf(fo,"%c%d",ci.vtype,abs(ci.v-c[i-1].v)); }
else if(ci.vtype == 'T' &&
c[i+1].vtype == '^' &&
c[i+2].vtype == '^' &&
!c[i+3].used )
{ fpf(fo,"|"); i += 2; nosemi=true; }
else if(ci.vtype == '{' || ci.vtype == '}')
{ spacer[0]=' ';
fpf(fo,"%c%d",ci.vtype,abs(ci.v-oci.v)); }
else if(ci.vtype == 't')
{ spacer[0]=' ';
fpf(fo," %s ",ci.txt); }
else { fputc(ci.vtype,fo); spacer[0]='\0'; }
}
else { if(ci.v<0) fpf(fo,"%d",ci.v);
else fpf(fo,"%s%d",spacer,ci.v); spacer[0]=' '; }
} /* for */
if(!nosemi) fpf(fo,";");
buf[ix++]=ch;
lastWasArray=false;
lastWasArrayBox=false;
}
/*-----------------------------------------------------------------------*/
process_call()
{int i;
for(i=0;i<boxnums;i++)
{ ooci.v=oci.v; oci.v=ci.v; ci.vtype=' '; ci.used=false; ci.txt[0]='\0'; }
xg(); g_s();
for(i=0;s[0]!=';' && i<boxnums;i++)
{
if(s[0]=='-') { ci.v = -get_int(); if(s[0]=='-') error("syntax"); }
else if(t==integer) ci.v = atoi(s);
else if(t==chopp) ci.vtype=s[0];
else if(t==ident) { ci.vtype='t'; SCY(ci.txt,s); }
else error("box syntax");
ci.used=true;
g_s();
}
if(!feof(fin)) write_call();
} /* process_box */
/*-----------------------------------------------------------------------*/
process_layer()
{int i;
static char layers[numlayers][N_L];
static boo firstCall=true;
static char x[N_L];
if(firstCall)
{ for(i=0;i<=numlayers;i++) layers[i][0]='\0'; firstCall = false; }
i=0;
while(ch!=';') x[i++]=xg();
xg();
x[i]='\0';
for(i=0;i<=numlayers&&layers[i][0]!='\0'&&SNE(x,layers[i]);i++) ;
if(layers[i][0]=='\0')
{ SCY(layers[i],x); /* enter to tab */
rmchar(' ',buf); fpf(fo,"%s",buf);
fpf(fo,"%s",x);
}
else
{ rmchar(' ',buf); fpf(fo,"%s",buf);
fpf(fo,"%c",'a'+i); }
ix=0;
buf[ix++]=ch;
lastWasArray=false; lastWasArrayBox=false;
/*
i=0;
printf("l\n");
while(layers[i][0]!='\0') printf("%s\n",layers[i++]);
*/
}
process_poly()
{int i;
/* copy last P to opoints */
for(i=0;i<numpoints,pi.used;i++)
{ oopi.v = opi.v; opi.v = pi.v; pi.used = false; pi.vtype = ' '; }
xg(); g_s();
for(i=0;!feof(fin) && s[0]!=';';i++) /* read coords into points */
{
if(s[0]=='-') pi.v = -get_int();
else if(t==integer) pi.v = atoi(s);
pi.used = true;
g_s();
if(i>numpoints-10) error("Too many points in the polygon");
}
if(!feof(fin)) wp();
}
/*-----------------------------------------------------------------------*/
write_box()
{int i,j=0,nosemi=false; char spacer[1];
spacer[0]='\0';
spacer[1]='\0';
rmchar(' ',buf);
for(i=0;bi.used;i++)
if(bi.vtype==' ')
{ if(bi.v == obi.v) bi.vtype = '^';
else if(bi.v-obi.v == obi.v-oobi.v) bi.vtype='~';
/* equals last num */
else if(i>0 && bi.v==b[i-1].v) bi.vtype='&';
/* equals one before last */
else if(bi.v == oobi.v) bi.vtype='=';
/* vertical delta */
else if(delOk(obi.v,bi.v))
{ if(bi.v>obi.v) bi.vtype = '{'; else bi.vtype = '}'; }
/* horiz delta */
else if(i>0 && delOk(b[i-1].v,bi.v))
{ if(bi.v>b[i-1].v) bi.vtype = '['; else bi.vtype = ']'; }
}
/* for(i=0;bi.used;i++) printf("%d%c",bi.v,bi.vtype); printf("\n"); */
/* write out the box */
/* This is the detection of a regular array box '+' */
if(b[0].vtype == '^' &&
b[1].vtype == '^' &&
b[2].vtype == '~' &&
b[3].vtype == '^' )
{ if(lastWasArrayBox) fputc('+',fo);
else { fpf(fo,"%s+",buf); }
lastWasArrayBox = true; nosemi=true; }
else
if(b[0].vtype == '^' &&
b[1].vtype == '^' &&
b[2].vtype == '^' &&
b[3].vtype == '~' )
{ if(lastWasArrayBox) fputc('*',fo);
else { fpf(fo,"%s*",buf); }
lastWasArrayBox = true; nosemi=true; }
else
{fpf(fo,"%s",buf);
lastWasArrayBox = false;
for(i=0;bi.used;i++)
{if(bi.vtype!=' ')
{
if( b[i].vtype == '^' &&
b[i+1].vtype == '^' )
{fputc('_',fo); i+=1; spacer[0]='\0';}
else if(i>0 && (bi.vtype == '[' || bi.vtype == ']'))
{spacer[0]=' ';
fpf(fo,"%c%d",bi.vtype,abs(bi.v-b[i-1].v)); }
else if(bi.vtype == '{' || bi.vtype == '}')
{ spacer[0]=' ';
fpf(fo,"%c%d",bi.vtype,abs(bi.v-obi.v)); }
else { fputc(bi.vtype,fo); spacer[0]='\0'; }
}
else { if(bi.v<0) fpf(fo,"%d",bi.v);
else fpf(fo,"%s%d",spacer,bi.v); spacer[0]=' '; }
} /* for */
} /*else */
if(!nosemi) fpf(fo,";");
buf[ix++]=ch;
lastWasArray=false;
}
/*-----------------------------------------------------------------------*/
process_box()
{int i;
for(i=0;i<boxnums;i++)
{ oobi.v=obi.v; obi.v=bi.v; bi.vtype=' '; bi.used=false; }
xg(); g_s();
for(i=0;s[0]!=';' && i<boxnums;i++)
{
if(s[0]=='-') bi.v = -get_int();
else if(t==integer) bi.v = atoi(s);
else if(t==chopp) bi.vtype=s[0];
else error("box syntax");
bi.used=true;
g_s();
}
if(!feof(fin)) write_box();
} /* process_box */
/*-----------------------------------------------------------------------*/
process_com()
{int i;
/* locate and read if valid com */
while (isspace(ch) && !feof(fin)) buf[ix++]=xg();
buf[ix] = '\0';
ix=0;
if (ch=='P') process_poly();
else if(ch=='B') process_box();
else if(ch=='L') process_layer();
else if(ch=='C') process_call();
else {/* copy to next ';' */
fpf(fo,"%s",buf);
while (ch!=';' && !feof(fin)) { xg(); if(!feof(fin)) fputc(ch,fo); }
if(!feof(fin)) {xg(); fputc(ch,fo);}
lastWasArray = false;
lastWasArrayBox = false;
}
/* for(i=0;pi.used;i++) printf("p %d ",pi.v); printf("\n");
printf("exit rp with ch=%c\n",ch); */
} /* pc */
/*-----------------------------------------------------------------------*/
wp()
{int i,j=0,nosemi=false; char spacer[1];
spacer[0]='\0';
spacer[1]='\0';
rmchar(' ',buf);
/* is it the same val as last poly? */
for(i=0;pi.used;i++)
if(pi.v == opi.v) pi.vtype = '^';
/* put in the & */
for(i=2;pi.used;i++)
if(pi.v == points[i-2].v) pi.vtype = '&';
/* detection of last 3 redundant values in rectangle */
i--;
if(pi.v == points[1].v) pi.vtype = '<';
if(points[i-1].v == points[0].v) points[i-1].vtype = '<';
/* put in the '@' */
for(i=2;pi.used;i++)
if(pi.vtype==' ')
if(points[i-2].v-points[i].v == opoints[i-2].v-opoints[i].v)
points[i].vtype = '@';
/* put in the '~' */
if(points[0].v-opoints[0].v == opoints[0].v-oopoints[0].v)
points[0].vtype='~';
/* vertical delta */
for(i=0;pi.used;i++)
if(pi.vtype==' ')
if(delOk(opi.v,pi.v))
if(pi.v>opi.v) pi.vtype = '{'; else pi.vtype = '}';
/* horiz delta */
for(i=2;pi.used;i++)
if(pi.vtype==' ')
if(delOk(points[i-2].v,pi.v))
if(pi.v>points[i-2].v) pi.vtype = '['; else pi.vtype = ']';
/* for(i=0;pi.used;i++) printf("%d%c",pi.v,pi.vtype); printf("\n"); */
/* write out the poly */
/* This is the detection of a regular array rectangle '+' */
if(points[0].vtype == '~' &&
points[1].vtype == '^' &&
points[2].vtype == '&' &&
points[3].vtype == '^' &&
points[4].vtype == '@' &&
points[5].vtype == '&' &&
points[6].vtype == '&' &&
points[7].vtype == '<' &&
points[8].used == false )
{ if(lastWasArray) fputc('+',fo);
else { fpf(fo,"%s+",buf); }
lastWasArray = true; nosemi=true; }
else
{fpf(fo,"%s",buf);
lastWasArray = false;
for(i=0;pi.used;i++)
{if(pi.vtype!=' ')
{
if(pi.vtype == '^' &&
points[i+1].vtype == '&' &&
points[i+2].vtype == '^' &&
points[i+3].vtype == '@' &&
points[i+4].vtype == '&' &&
points[i+5].vtype == '&' &&
points[i+6].vtype == '<' &&
points[i+7].used == false )
{fputc('?',fo); i+=6; spacer[0]='\0'; nosemi=true;}
else if(pi.vtype == '^' &&
points[i+1].vtype == '&' &&
points[i+2].vtype == '^')
{fputc('%',fo); i+=2; spacer[0]='\0';}
else if(pi.vtype == '&' &&
points[i+1].vtype == '&' &&
points[i+2].vtype == '<' &&
points[i+3].used == false )
{fpf(fo,"|"); i+=2; spacer[0]='\0'; nosemi=true;}
else if(pi.vtype == '@' &&
points[i+1].vtype == '&' &&
points[i+2].vtype == '&' &&
points[i+3].vtype != '<' )
{fputc('!',fo); i+=2; spacer[0]='\0';}
else if(pi.vtype == '[' || pi.vtype == ']')
{spacer[0]=' ';
fpf(fo,"%c%d",pi.vtype,abs(pi.v-points[i-2].v)); }
else if(pi.vtype == '{' || pi.vtype == '}')
{ spacer[0]=' ';
fpf(fo,"%c%d",pi.vtype,abs(pi.v-opi.v)); }
else { fputc(pi.vtype,fo); spacer[0]='\0'; }
}
else { if(pi.v<0) fpf(fo,"%d",pi.v);
else fpf(fo,"%s%d",spacer,pi.v); spacer[0]=' '; }
} /* for */
} /*else */
if(!nosemi) fpf(fo,";");
/* write the last ch read in process_poly */
buf[ix++]=ch;
lastWasArrayBox=false;
}
/*-----------------------------------------------------------------------*/
main(argc,argv)
int argc; char *argv[];
{
if(bombDate-3600*240 < time(0)) fpf(stderr,"Expires in < 10days.\n");
if(bombDate < time(0)) error("Version has expired. Contact US2.");
/* command line parsing */
if (arg_num(argc,argv,"-i*d")) {printf("Version %d\n",version); exit(0);}
if (argc <2) error("USAGE: compdracif infile");
fin=efopen(argv[1],"r");
fo=efopen(cf(argv[1],".R"),"w");
init();
fpf(fo,"VERSION %d\n",version);
SCY(s,"%");
init_data();
while(!feof(fin)) process_com();
} /* main */
/*------------------------------------------------------------------*/