home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS - Coast to Coast
/
simteldosarchivecoasttocoast2.iso
/
sprint
/
imp123.zip
/
IMP123.C
next >
Wrap
Text File
|
1989-03-04
|
23KB
|
706 lines
/*==========================================================================*/
/* IMP123.C -- This progam generates an ASCII file from a 123 worksheet. */
/* It is intended for use with Sprint. Data regarding the */
/* format of a 123 file was taken from the WKS Library by */
/* Tenon Software. */
/* */
/* March 1, 1989 Thomas G. Ore */
/*==========================================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <dir.h>
#include <string.h>
#include <float.h>
/*.......................... Function prototypes ...........................*/
void RecRead(FILE *fin,int type,int len);
void ValPrint(unsigned char format,int width,double val);
void StringPrint(int width,char *strng);
void DatePrint(unsigned char format,int width,double val);
void CheckRow(int row);
void CheckCol(int col);
void EnCode(int col,char *code);
void DeCode(char *code,int *left,int *top,int *right,int *bott);
void Trim(char *strng);
void DumpZeros(char *strng);
void FltErrHnd(unsigned int stat,int row,int col);
/*.................. These are the record type structures ..................*/
struct { /* Record type 7 */
int CursCol; /* Cursor Column */
int CursRow; /* Cursor Row */
char Format; /* format */
char unused1; /* '\0' */
int GlobColWid; /* width */
int ColsOnScr; /* No columns in Window/width */
int RowsOnScr; /* 20 */
int LeftCol; /* 0 + title cols */
int TopRow; /* 0 + title rows */
int TitleCols; /* Title cols */
int TitleRows; /* Title rows */
int leftTitleCol; /* 0 */
int topTitleRow; /* 0 */
int topLeftCol; /* 04 */
int topLeftRow; /* 04 */
int ColsInWin; /* 72 */
char unused2; /* '\0' */
char unused3; /* '\0' */
} win;
struct { /* Record type 8 */
int col;
char wid;
} colwid;
struct { /* Record type 11 & 71 */
char name[16]; /* not sure what difference is */
int left;
int top;
int right;
int bott;
char unused;
} nrange[26];
struct { /* Record type 13 */
unsigned char format;
int col;
int row;
int val;
} integer;
struct { /* Record type 14 */
unsigned char format;
int col;
int row;
double val;
} real;
struct { /* Record type 15 */
unsigned char format;
int col;
int row;
char label[241];
} label;
struct { /* Record type 51 */
unsigned char format;
int col;
int row;
char strng[241];
} strng;
struct { /* Record type 16 */
unsigned char format;
int col;
int row;
double val;
int size;
char terms[500];
} formula;
/*......................... A few global variables .........................*/
char Width[240]; /* Max 240 columns */
char *ptr; /* This is just a pointer */
int currow; /* This is the current row */
int curcol; /* This is the current column */
char Text[1000]; /* Make it large */
char *ColText; /* Pointer to the start of range*/
char *ColEnd; /* Pointer to the end of range */
FILE *fout; /* This is the output file */
int rleft,rtop,rright,rbott; /* This is the range boundary */
int rnumb; /* This is the current range no.*/
/*--------------------------------------------------------------------------*/
void main(int argc, char *argv[])
{
char fname[MAXPATH],fname1[MAXPATH];
FILE *fin;
int stat,i,new,mask;
int type,len,selected=0;
char code1[15],code2[3];
char *tmp;
textattr(14+(1<<4));
clrscr();
cprintf("IMP123, A Worksheet Import Program - by Thomas G. Ore\n\r");
if(argc<2) {
cprintf("Enter the Lotus 123 filename\n\r");
scanf("%s",fname);
}
else strcpy(fname,argv[1]);
/*...................... These are defined in float.h ......................*/
new=MCW_EM;
mask=EM_INVALID+EM_DENORMAL+EM_ZERODIVIDE+
EM_OVERFLOW+EM_UNDERFLOW;
stat=_control87(new,mask); /* Set the 87 exception mask */
/*.......................... Open the input file ...........................*/
fin=fopen(fname,"rb"); /* Assume first arg is filename */
if(fin==NULL) {
printf("Failed to open worksheet file: %s\n",fname);
exit(1);
}
strcpy(fname1,"IMP123.TGO");
/*.......................... Open the output file ..........................*/
fout=fopen(fname1,"wb");
if(fout==NULL) {
printf("Failed to open worksheet file\n");
exit(1);
}
/*....................... Initialize some variables ........................*/
Text[0]=0;
ptr=Text; /* Start pointer at Text[0] */
ColText=Text;
curcol=0; /* Start current column at zero */
currow=-1; /* Start current row off page */
strcpy(nrange[0].name,"ENTIRE FILE");
strcpy(nrange[1].name,"User Input");
nrange[0].left=nrange[1].left=0;
nrange[0].top=nrange[1].top=0;
nrange[0].right=nrange[1].right=255;
nrange[0].bott=nrange[1].bott=8191;
rnumb=2; /* zero is entire worksheet */
/*........................ Read in all the records .........................*/
for(;;) {
stat=fread(&type,2,1,fin); /* Read in the record type */
if(stat==0) { /* End of the file yet? */
if(strlen(Text)>0&&(currow>=nrange[rnumb].top&&
currow<=nrange[rnumb].bott)) { /* Send the last row */
Trim(Text);
*ColEnd=0;
fprintf(fout,"%s\n",ColText);
}
break;
}
/*. . . . . . We are in the cells now, so get the range to read . . . . . . */
if(((type>=12&&type<=16)||type==51)&&!selected) {
selected=1; /* We've already got the range */
cprintf("\n\rThe valid ranges are:\n\r");
for(i=0;i<rnumb;i++) {
EnCode(nrange[i].left,code1);
EnCode(nrange[i].right,code2);
cprintf("%c: %-16.16s %s%d..%s%d\n\r",i+65,nrange[i].name,
code1,nrange[i].top+1,code2,nrange[i].bott+1);
}
do {
cprintf("\n\rEnter the range to read (%c-%c)",65,rnumb+64);
i=toupper(getch())-65;
} while(i<0||i>=rnumb);
rnumb=i;
if(rnumb==1) {
cprintf("\n\n\rEnter the range: ");
scanf("%s",code1);
DeCode(code1,&nrange[1].left,&nrange[1].top,&nrange[1].right,
&nrange[1].bott);
}
cprintf("\n\rReading the file ...");
tmp=Text;
for(i=0;i<nrange[rnumb].left;i++)
tmp+=Width[i];
ColText=tmp; /* Set the start of the range */
for(i=nrange[rnumb].left;i<=nrange[rnumb].right;i++)
tmp+=Width[i];
ColEnd=tmp; /* Set the end of the range */
}
fread(&len,2,1,fin); /* Read in the record length */
RecRead(fin,type,len); /* Read in the record */
}
fclose(fout); /* Close the output file */
}
/*--------------------------------------------------------------------------*/
/* This routine reads in all records and prints out the cells */
/*--------------------------------------------------------------------------*/
void RecRead(FILE *fin,int type,int len)
{
int i,stat;
char temp[500];
switch(type) {
case 7: /* Window */
fread(&win,len,1,fin);
for(i=0;i<240;i++) Width[i]=win.GlobColWid;
break;
case 8: /* Column width */
fread(&colwid,len,1,fin);
Width[colwid.col]=colwid.wid;
break;
case 71: /* SNRANGE */
case 11: /* NRANGE */
fread(&nrange[rnumb],len,1,fin);
nrange[rnumb].name[15]=0;
if(rnumb<25) rnumb++;
break;
case 12: /* Blank */
fread(&label,len,1,fin);
label.label[0]='\'';
label.label[1]=0;
CheckRow(label.row);
CheckCol(label.col);
StringPrint(Width[label.col],label.label);
break;
case 13: /* Integer record */
fread(&integer,len,1,fin);
if(integer.format==255) /* If it is default */
integer.format=0; /* Make it fixed, zero places */
CheckRow(integer.row);
CheckCol(integer.col);
ValPrint(integer.format,Width[integer.col],(double)integer.val);
break;
case 14: /* double record */
fread(&real,len,1,fin);
CheckRow(real.row);
CheckCol(real.col);
ValPrint(real.format,Width[real.col],real.val);
break;
case 15: /* Label record */
fread(&label,len,1,fin);
label.label[240]=0;
CheckRow(label.row);
CheckCol(label.col);
StringPrint(Width[label.col],label.label);
break;
case 51: /* String record */
fread(&strng,len,1,fin);
strng.strng[240]=0;
CheckRow(strng.row);
CheckCol(strng.col);
StringPrint(Width[strng.col],strng.strng);
break;
case 16: /* Formula record */
fread(&formula,len,1,fin);
formula.terms[formula.size]=0;
if(formula.val>1.e99) formula.val=0.;
stat=_status87(); /* See if we got an error */
if(stat&&stat!=SW_INEXACT) {
FltErrHnd(stat,formula.row,formula.col);
formula.val=0.;
}
else if(stat==SW_INEXACT) _clear87();
CheckRow(formula.row);
CheckCol(formula.col);
ValPrint(formula.format,Width[formula.col],formula.val);
break;
case 0: /* Open the worksheet */
case 1: /* Close the worksheet */
case 36: /* Global protection */
default: /* Assume 500 is large enough */
fread(&temp,len,1,fin);
break;
}
}
/*--------------------------------------------------------------------------*/
/* This routine prints numeric cells */
/*--------------------------------------------------------------------------*/
void ValPrint(unsigned char format,int width,double val)
{
unsigned char dec,style,special;
char temp[241];
char *tmp;
int i;
double max;
dec=(format&15); /* Digits to right of dec. pt. */
style=((format>>4)&7); /* Get the style */
switch(style) {
case 0: /* Fixed */
sprintf(ptr,"%*.*lf ",width-1,dec,val);
break;
case 1: /* Scientific */
sprintf(ptr,"%*.*le ",width-1,dec,val);
break;
case 2: /* Currency */
if(val>=0.)
sprintf(ptr," %*.*lf ",width-2,dec,val);
else
sprintf(ptr," %*.*lf)",width-3,dec,-val);
tmp=ptr; /* Define a temporary pointer */
while(*tmp==32) tmp+=1; /* Move over to first digit */
tmp-=1; /* Back up one character */
*tmp='$'; /* Insert the dollar sign */
if(val<0.) { /* Put in the ( if it is a */
tmp-=1; /* negative number */
*tmp='(';
}
break;
case 3: /* Percent */
sprintf(ptr,"%*.*lf%",width-1,dec,val*100.);
break;
case 4: /* Comma - This is not correct */
sprintf(ptr,"%*.*lf ",width-1,dec,val);
break;
case 7: /* Special */
special=dec;
switch(special) { /* First three are not correct */
case 0: /* Plus-Minus */
case 5: /* Text */
case 6: /* Hidden */
case 1: /* General */
case 15: /* Default */
max=1.;
for(i=0;i<width-1;i++) max*=10.;
if(val<max) {
sprintf(temp,"%*lf ",width-1,val);
temp[width]=0; /* Make sure val isn't too long */
strcpy(ptr,temp); /* Store it */
DumpZeros(ptr); /* Remove extra zeros */
}
else
sprintf(ptr,"%*.*G ",width,width-7,val);
break;
default: /* Must be a date format */
DatePrint(format,width,val);
break;
}
}
}
/*--------------------------------------------------------------------------*/
/* This routine prints string cells */
/*--------------------------------------------------------------------------*/
void StringPrint(int width,char *strng)
{
char fmt,*tmpptr;
char temp[2]={" "};
int pad,pad1,i;
tmpptr=ptr; /* Set a temporary pointer */
fmt=*strng; /* Get the format character */
strng++; /* Move to start of string */
pad=width-strlen(strng)-1; /* Assume right justified */
if(pad<0) pad=0; /* Is string longer than col */
if(fmt=='\'') pad=0; /* Left justified */
else if(fmt=='^') pad=(pad+1)/2; /* Centered */
else if(fmt=='\\') pad=0; /* Repetitive character */
pad1=width-strlen(strng)-pad; /* Get right side spaces */
if(pad1<0) pad1=0;
if(fmt=='\\') pad1=0; /* Don't pad if repetitive */
if(pad>0) /* Print the left pad */
sprintf(tmpptr,"%-*.*s",pad,pad,temp);
tmpptr+=pad;
if(fmt!='\\') { /* Print the string */
sprintf(tmpptr,"%s",strng);
tmpptr+=strlen(strng);
}
else
for(i=0;i<width;i++) {
sprintf(tmpptr,"%c",*strng);
tmpptr++;
}
if(pad1>0) /* Print the right pad */
sprintf(tmpptr,"%-*.*s",pad1,pad1,temp);
}
/*--------------------------------------------------------------------------*/
/* This routine does the formatted date print */
/*--------------------------------------------------------------------------*/
void DatePrint(unsigned char format,int width,double val)
{
int i,j,special;
int hr,min,sec;
int yr,mon,day;
unsigned int date;
double time;
static char months[12][4]={
"Jan","Feb","Mar","Apr","May","Jun",
"Jul","Aug","Sep","Oct","Nov","Dec"};
static int mlen[12]={0,31,28,31,30,31,30,31,31,30,31,30};
char *tmp;
tmp=ptr;
/*............................ Decode the date .............................*/
date=(int)val; /* The date is the integer part */
yr=(date-(date/365/4+1)-1)/365; /* This is the year 0=1900 */
day=date-yr*365-yr/4-1; /* Find day of year */
if(day<59&&yr==0) day+=1; /* Haven't hit first leap year */
for(i=0;i<12;i++) {
j=mlen[i];
if(i==2&&yr/4*4==yr) j++; /* Add leap day */
if(day-j>0) {
day-=mlen[i];
mon=i; /* This is the month */
}
else break;
}
if(yr>99) yr+=1900; /* Put year in the 2000's */
/*............................ Decode the time .............................*/
time=val-(int)val; /* Time is the fractional part */
hr=time*24.; /* Get the hour */
min=(int)((time*24-(float)hr)*60.); /* Get the minute */
sec=(int)((time*24-(float)hr-(float)min/60.)*3600.);
/*..................... Print with the correct format ......................*/
special=(format&15);
sprintf(ptr,"%-*.*s",width,width," "); /* Blank the field */
switch(special) {
case 2: /* Day-Month-Year */
tmp+=width-10;
sprintf(tmp,"%02d-%-3.3s-%02d ",day,months[mon],yr);
break;
case 3: /* Day-Month */
tmp+=width-7;
sprintf(tmp,"%02d-%-3.3s ",day,months[mon]);
break;
case 4: /* Month-Year */
tmp+=width-7;
sprintf(tmp,"%-3.3s-%02d ",months[mon],yr);
break;
case 7: /* Hr-min-sec AM/PM */
i=hr;
tmp+=width-12;
if(i>11) {
i-=11;
if(i==0) i=12;
sprintf(tmp,"%02d:%02d:%02d PM ",i,min,sec);
}
else {
if(i==0) i=12;
sprintf(tmp,"%02d:%02d:%02d AM ",i,min,sec);
}
break;
case 8: /* Hr-min AM/PM */
i=hr;
tmp+=width-9;
if(i>11) {
i-=11;
if(i==0) i=12;
sprintf(tmp,"%02d:%02d PM ",i,min);
}
else {
if(i==0) i=12;
sprintf(tmp,"%02d:%02d AM ",i,min);
}
break;
case 9: /* Date-International 1 */
tmp+=width-9;
sprintf(tmp,"%02d/%02d/%02d ",mon+1,day,yr);
break;
case 10: /* Date-International 2 */
tmp+=width-6;
sprintf(tmp,"%02d/%02d ",mon+1,day);
break;
case 11: /* Time-International 1 */
tmp+=width-9;
sprintf(tmp,"%02d:%02d:%02d ",hr,min,sec);
break;
case 12: /* Time-International 2 */
tmp+=width-6;
sprintf(tmp,"%02d:%02d ",hr,min);
break;
}
}
/*--------------------------------------------------------------------------*/
/* This routine decides if a row should be printed */
/* row is the new row, before we start it we have to print the old row */
/*--------------------------------------------------------------------------*/
void CheckRow(int row)
{
register int i;
if(row>currow) { /* Are we on a new row? */
if(currow>=0) { /* And it isn't the first row? */
while(currow<row) {
Trim(Text); /* Strip trailing blanks */
*ColEnd=0; /* End the line at range end */
if(currow>=nrange[rnumb].top&&
currow<=nrange[rnumb].bott) /* If the line is in valid range*/
fprintf(fout,"%s\n",ColText); /* Print the text */
*ColText=0; /* Only print text on first line*/
currow++; /* Increment the current row */
}
for(i=0;i<1000;i++)
Text[i]=32;
ptr=Text; /* Reset the column pointer */
curcol=0;
}
else currow=row;
}
}
/*--------------------------------------------------------------------------*/
/* This routine decides if blank columns should be filled in */
/*--------------------------------------------------------------------------*/
void CheckCol(int col)
{
register int i,j;
for(i=curcol;i<col-1;i++) { /* Move over amount of each col */
ptr+=Width[i]; /* Update the pointer */
for(j=0;j<Width[i+1];j++) /* Blank out skipped columns */
if(*(ptr+j)==0) *(ptr+j)=32;
}
if(col>0&&col!=curcol)
ptr+=Width[col-1]; /* Update the pointer */
curcol=col; /* Save the column */
}
/*--------------------------------------------------------------------------*/
/* This routine converts the zero based column number to 123 alpha style */
/*--------------------------------------------------------------------------*/
void EnCode(int col,char *code)
{
code[1]=code[2]=0;
if(col<26) code[0]=col+65;
else {
code[0]=(int)(col/26)+64;
code[1]=col-(code[0]-64)*26+65;
}
}
/*--------------------------------------------------------------------------*/
/* This routine splits a range string up into numbers */
/*--------------------------------------------------------------------------*/
void DeCode(char *code,int *left,int *top,int *right,int *bott)
{
char *ptr;
int i;
for(i=0;i<strlen(code);i++)
code[i]=toupper(code[i]);
ptr=code+strlen(code)-1;
while(*ptr>='0'&&*ptr<='9'&&ptr!=code) /* Get the bottom row */
ptr-=1;
ptr+=1;
*bott=atoi(ptr)-1;
if(ptr==code) return; /* Error check */
*ptr=0;
ptr-=1;
*right=*ptr-65; /* Get part of the right side */
ptr-=1;
if(*ptr>='A'&&*ptr<='I') /* Get the rest of right side */
*right=*right+(*ptr-64)*26;
if(ptr==code) return; /* Error check */
while((*ptr>'9'||*ptr<'0')&&ptr!=code) /* Trash the ..'s */
ptr-=1;
*(ptr+1)=0;
if(ptr==code) return; /* Error check */
while(*ptr>='0'&&*ptr<='9'&&ptr!=code) /* Get the top row */
ptr-=1;
ptr+=1;
*top=atoi(ptr)-1;
if(ptr==code) return; /* Error check */
*ptr=0;
ptr-=1;
*left=*ptr-65; /* Get part of the left side */
if(ptr==code) return; /* Error check */
ptr-=1;
if(*ptr>='A'&&*ptr<='I') /* Get the rest of left side */
*left=*left+(*ptr-64)*26;
}
/*--------------------------------------------------------------------------*/
/* Strip the trailing zeros from the line */
/*--------------------------------------------------------------------------*/
void Trim(char *strng)
{
char *tmpptr;
tmpptr=strng;
tmpptr+=(strlen(strng)-1);
while(*tmpptr==32&&tmpptr!=strng) {
*tmpptr=0;
tmpptr-=1;
}
}
/*--------------------------------------------------------------------------*/
/* Remove the extraneous zeros from the end of an unformatted cell */
/*--------------------------------------------------------------------------*/
void DumpZeros(char *strng)
{
char *tmpptr;
int kntr,len,i;
tmpptr=strng;
while(*tmpptr!='.'&&*tmpptr) tmpptr+=1; /* First find the decimal point */
if(*tmpptr==0) return; /* No decimal point */
tmpptr=strng;
len=strlen(strng);
tmpptr+=(len-1);
if(*tmpptr!=32) { /* Should be a space */
*tmpptr=32; /* Just truncate the digit */
}
while((*tmpptr==32||*tmpptr=='0')&&tmpptr!=strng) {
*tmpptr=32;
tmpptr-=1;
}
if(*tmpptr=='.') *tmpptr=32; /* Take out the lone dec. pt. */
else tmpptr+=1; /* Move to first blank */
kntr=0;
while(*tmpptr) {
tmpptr+=1;
kntr+=1;
}
if(kntr>1) {
kntr--;
for(i=len-2;i>=kntr;i--)
strng[i]=strng[i-kntr];
for(i=0;i<kntr;i++)
strng[i]=32;
}
}
/*--------------------------------------------------------------------------*/
/* This routine prints the floating point error if one is found */
/*--------------------------------------------------------------------------*/
void FltErrHnd(unsigned int stat,int row,int col)
{
char code[3];
EnCode(col,code);
if((stat&SW_INVALID)) cprintf("");
/* cprintf("Invalid: Cell %s%d\n\r",code,row+1);*/
else if((stat&SW_DENORMAL))
cprintf("Denormal: Cell %s%d\n\r",code,row+1);
else if((stat&SW_ZERODIVIDE))
cprintf("Zero divide: Cell %s%d\n\r",code,row+1);
else if((stat&SW_OVERFLOW))
cprintf("Overflow\n\r: Cell %s%d",code,row+1);
else if((stat&SW_UNDERFLOW))
cprintf("Underflow: Cell %s%d\n\r",code,row+1);
else if((stat&SW_INEXACT))
cprintf("Inexact: Cell %s%d\n\r",code,row+1);
else
cprintf("Unknown %d: Cell %s%d\n\r",stat,code,row+1);
_clear87();
}