home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / sprint / imp123.zip / IMP123.C next >
Text File  |  1989-03-04  |  23KB  |  706 lines

  1. /*==========================================================================*/
  2. /* IMP123.C  --  This progam generates an ASCII file from a 123 worksheet.  */
  3. /*         It is intended for use with Sprint.  Data regarding the    */
  4. /*         format of a 123 file was taken from the WKS Library by        */
  5. /*         Tenon Software.                        */
  6. /*                                        */
  7. /*         March 1, 1989        Thomas G. Ore                */
  8. /*==========================================================================*/
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <conio.h>
  12. #include <dir.h>
  13. #include <string.h>
  14. #include <float.h>
  15.  
  16. /*.......................... Function prototypes ...........................*/
  17.  
  18. void RecRead(FILE *fin,int type,int len);
  19. void ValPrint(unsigned char format,int width,double val);
  20. void StringPrint(int width,char *strng);
  21. void DatePrint(unsigned char format,int width,double val);
  22. void CheckRow(int row);
  23. void CheckCol(int col);
  24. void EnCode(int col,char *code);
  25. void DeCode(char *code,int *left,int *top,int *right,int *bott);
  26. void Trim(char *strng);
  27. void DumpZeros(char *strng);
  28. void FltErrHnd(unsigned int stat,int row,int col);
  29.  
  30. /*.................. These are the record type structures ..................*/
  31.  
  32. struct {                    /* Record type 7            */
  33.   int CursCol;                    /* Cursor Column            */
  34.   int CursRow;                    /* Cursor Row                   */
  35.   char Format;                    /* format                */
  36.   char unused1;                    /* '\0'                */
  37.   int GlobColWid;                /* width                */
  38.   int ColsOnScr;                /* No columns in Window/width   */
  39.   int RowsOnScr;                /* 20                */
  40.   int LeftCol;                    /* 0 + title cols            */
  41.   int TopRow;                    /* 0 + title rows            */
  42.   int TitleCols;                /* Title cols            */
  43.   int TitleRows;                /* Title rows            */
  44.   int leftTitleCol;                /* 0                */
  45.   int topTitleRow;                /* 0                */
  46.   int topLeftCol;                /* 04                */
  47.   int topLeftRow;                /* 04                */
  48.   int ColsInWin;                /* 72                */
  49.   char unused2;                    /* '\0'                */
  50.   char unused3;                    /* '\0'                */
  51. } win;
  52.  
  53. struct {                    /* Record type 8            */
  54.   int col;
  55.   char wid;
  56. } colwid;
  57.  
  58. struct {                    /* Record type 11 & 71          */
  59.   char name[16];                /* not sure what difference is  */
  60.   int left;
  61.   int top;
  62.   int right;
  63.   int bott;
  64.   char unused;
  65. } nrange[26];
  66.  
  67. struct {                    /* Record type 13            */
  68.   unsigned char format;
  69.   int col;
  70.   int row;
  71.   int val;
  72. } integer;
  73.  
  74. struct {                    /* Record type 14            */
  75.   unsigned char format;
  76.   int col;
  77.   int row;
  78.   double val;
  79. } real;
  80.  
  81. struct {                    /* Record type 15               */
  82.   unsigned char format;
  83.   int col;
  84.   int row;
  85.   char label[241];
  86. } label;
  87.  
  88. struct {                    /* Record type 51               */
  89.   unsigned char format;
  90.   int col;
  91.   int row;
  92.   char strng[241];
  93. } strng;
  94.  
  95. struct {                    /* Record type 16               */
  96.   unsigned char format;
  97.   int col;
  98.   int row;
  99.   double val;
  100.   int size;
  101.   char terms[500];
  102. } formula;
  103.  
  104. /*......................... A few global variables .........................*/
  105.  
  106. char Width[240];                /* Max 240 columns            */
  107. char *ptr;                    /* This is just a pointer        */
  108. int currow;                    /* This is the current row        */
  109. int curcol;                    /* This is the current column   */
  110. char Text[1000];                /* Make it large            */
  111. char *ColText;                    /* Pointer to the start of range*/
  112. char *ColEnd;                    /* Pointer to the end of range  */
  113. FILE *fout;                    /* This is the output file        */
  114. int rleft,rtop,rright,rbott;            /* This is the range boundary   */
  115. int rnumb;                    /* This is the current range no.*/
  116.  
  117. /*--------------------------------------------------------------------------*/
  118. void main(int argc, char *argv[])
  119. {
  120.   char fname[MAXPATH],fname1[MAXPATH];
  121.   FILE *fin;
  122.   int stat,i,new,mask;
  123.   int type,len,selected=0;
  124.   char code1[15],code2[3];
  125.   char *tmp;
  126.  
  127.   textattr(14+(1<<4));
  128.   clrscr();
  129.  
  130.   cprintf("IMP123, A Worksheet Import Program - by Thomas G. Ore\n\r");
  131.  
  132.   if(argc<2) {
  133.     cprintf("Enter the Lotus 123 filename\n\r");
  134.     scanf("%s",fname);
  135.   }
  136.   else strcpy(fname,argv[1]);
  137.  
  138. /*...................... These are defined in float.h ......................*/
  139.  
  140.   new=MCW_EM;
  141.   mask=EM_INVALID+EM_DENORMAL+EM_ZERODIVIDE+
  142.        EM_OVERFLOW+EM_UNDERFLOW;
  143.   stat=_control87(new,mask);             /* Set the 87 exception mask   */
  144.  
  145. /*.......................... Open the input file ...........................*/
  146.  
  147.   fin=fopen(fname,"rb");            /* Assume first arg is filename */
  148.   if(fin==NULL) {
  149.     printf("Failed to open worksheet file: %s\n",fname);
  150.     exit(1);
  151.   }
  152.  
  153.   strcpy(fname1,"IMP123.TGO");
  154.  
  155. /*.......................... Open the output file ..........................*/
  156.  
  157.   fout=fopen(fname1,"wb");
  158.   if(fout==NULL) {
  159.     printf("Failed to open worksheet file\n");
  160.     exit(1);
  161.   }
  162.  
  163. /*....................... Initialize some variables ........................*/
  164.  
  165.   Text[0]=0;
  166.   ptr=Text;                    /* Start pointer at Text[0]        */
  167.   ColText=Text;
  168.   curcol=0;                    /* Start current column at zero */
  169.   currow=-1;                    /* Start current row off page   */
  170.   strcpy(nrange[0].name,"ENTIRE FILE");
  171.   strcpy(nrange[1].name,"User Input");
  172.   nrange[0].left=nrange[1].left=0;
  173.   nrange[0].top=nrange[1].top=0;
  174.   nrange[0].right=nrange[1].right=255;
  175.   nrange[0].bott=nrange[1].bott=8191;
  176.   rnumb=2;                    /* zero is entire worksheet        */
  177.  
  178. /*........................ Read in all the records .........................*/
  179.  
  180.   for(;;) {
  181.     stat=fread(&type,2,1,fin);            /* Read in the record type        */
  182.     if(stat==0) {                /* End of the file yet?        */
  183.       if(strlen(Text)>0&&(currow>=nrange[rnumb].top&&
  184.        currow<=nrange[rnumb].bott)) {    /* Send the last row        */
  185.     Trim(Text);
  186.     *ColEnd=0;
  187.     fprintf(fout,"%s\n",ColText);
  188.       }
  189.       break;
  190.     }
  191.  
  192. /*. . . . . . We are in the cells now, so get the range to read . . . . . . */
  193.  
  194.     if(((type>=12&&type<=16)||type==51)&&!selected) {
  195.       selected=1;                /* We've already got the range  */
  196.       cprintf("\n\rThe valid ranges are:\n\r");
  197.       for(i=0;i<rnumb;i++) {
  198.     EnCode(nrange[i].left,code1);
  199.     EnCode(nrange[i].right,code2);
  200.     cprintf("%c: %-16.16s %s%d..%s%d\n\r",i+65,nrange[i].name,
  201.      code1,nrange[i].top+1,code2,nrange[i].bott+1);
  202.       }
  203.       do {
  204.     cprintf("\n\rEnter the range to read (%c-%c)",65,rnumb+64);
  205.     i=toupper(getch())-65;
  206.       } while(i<0||i>=rnumb);
  207.       rnumb=i;
  208.       if(rnumb==1) {
  209.     cprintf("\n\n\rEnter the range: ");
  210.     scanf("%s",code1);
  211.     DeCode(code1,&nrange[1].left,&nrange[1].top,&nrange[1].right,
  212.      &nrange[1].bott);
  213.       }
  214.       cprintf("\n\rReading the file ...");
  215.  
  216.       tmp=Text;
  217.       for(i=0;i<nrange[rnumb].left;i++)
  218.        tmp+=Width[i];
  219.       ColText=tmp;                /* Set the start of the range   */
  220.       for(i=nrange[rnumb].left;i<=nrange[rnumb].right;i++)
  221.        tmp+=Width[i];
  222.       ColEnd=tmp;                /* Set the end of the range        */
  223.     }
  224.     fread(&len,2,1,fin);            /* Read in the record length    */
  225.     RecRead(fin,type,len);            /* Read in the record        */
  226.   }
  227.  
  228.   fclose(fout);                    /* Close the output file        */
  229. }
  230. /*--------------------------------------------------------------------------*/
  231. /*        This routine reads in all records and prints out the cells        */
  232. /*--------------------------------------------------------------------------*/
  233. void RecRead(FILE *fin,int type,int len)
  234. {
  235.   int i,stat;
  236.   char temp[500];
  237.  
  238.   switch(type) {
  239.     case 7:                    /* Window                */
  240.       fread(&win,len,1,fin);
  241.       for(i=0;i<240;i++) Width[i]=win.GlobColWid;
  242.       break;
  243.     case 8:                    /* Column width            */
  244.       fread(&colwid,len,1,fin);
  245.       Width[colwid.col]=colwid.wid;
  246.       break;
  247.     case 71:                    /* SNRANGE                */
  248.     case 11:                    /* NRANGE                */
  249.       fread(&nrange[rnumb],len,1,fin);
  250.       nrange[rnumb].name[15]=0;
  251.       if(rnumb<25) rnumb++;
  252.       break;
  253.     case 12:                    /* Blank                */
  254.       fread(&label,len,1,fin);
  255.       label.label[0]='\'';
  256.       label.label[1]=0;
  257.       CheckRow(label.row);
  258.       CheckCol(label.col);
  259.       StringPrint(Width[label.col],label.label);
  260.       break;
  261.     case 13:                    /* Integer record            */
  262.       fread(&integer,len,1,fin);
  263.       if(integer.format==255)            /* If it is default            */
  264.        integer.format=0;            /* Make it fixed, zero places   */
  265.       CheckRow(integer.row);
  266.       CheckCol(integer.col);
  267.       ValPrint(integer.format,Width[integer.col],(double)integer.val);
  268.       break;
  269.     case 14:                    /* double record            */
  270.       fread(&real,len,1,fin);
  271.       CheckRow(real.row);
  272.       CheckCol(real.col);
  273.       ValPrint(real.format,Width[real.col],real.val);
  274.       break;
  275.     case 15:                    /* Label record            */
  276.       fread(&label,len,1,fin);
  277.       label.label[240]=0;
  278.       CheckRow(label.row);
  279.       CheckCol(label.col);
  280.       StringPrint(Width[label.col],label.label);
  281.       break;
  282.     case 51:                    /* String record            */
  283.       fread(&strng,len,1,fin);
  284.       strng.strng[240]=0;
  285.       CheckRow(strng.row);
  286.       CheckCol(strng.col);
  287.       StringPrint(Width[strng.col],strng.strng);
  288.       break;
  289.     case 16:                    /* Formula record            */
  290.       fread(&formula,len,1,fin);
  291.       formula.terms[formula.size]=0;
  292.       if(formula.val>1.e99) formula.val=0.;
  293.  
  294.       stat=_status87();                /* See if we got an error        */
  295.       if(stat&&stat!=SW_INEXACT) {
  296.     FltErrHnd(stat,formula.row,formula.col);
  297.     formula.val=0.;
  298.       }
  299.       else if(stat==SW_INEXACT) _clear87();
  300.  
  301.       CheckRow(formula.row);
  302.       CheckCol(formula.col);
  303.       ValPrint(formula.format,Width[formula.col],formula.val);
  304.       break;
  305.     case 0:                    /* Open the worksheet        */
  306.     case 1:                    /* Close the worksheet        */
  307.     case 36:                    /* Global protection        */
  308.     default:                    /* Assume 500 is large enough   */
  309.       fread(&temp,len,1,fin);
  310.       break;
  311.   }
  312. }
  313. /*--------------------------------------------------------------------------*/
  314. /*                    This routine prints numeric cells                     */
  315. /*--------------------------------------------------------------------------*/
  316. void ValPrint(unsigned char format,int width,double val)
  317. {
  318.   unsigned char dec,style,special;
  319.   char temp[241];
  320.   char *tmp;
  321.   int i;
  322.   double max;
  323.  
  324.   dec=(format&15);                /* Digits to right of dec. pt.  */
  325.   style=((format>>4)&7);            /* Get the style            */
  326.   switch(style) {
  327.     case 0:                    /* Fixed                */
  328.       sprintf(ptr,"%*.*lf ",width-1,dec,val);
  329.       break;
  330.     case 1:                    /* Scientific            */
  331.       sprintf(ptr,"%*.*le ",width-1,dec,val);
  332.       break;
  333.     case 2:                    /* Currency                */
  334.       if(val>=0.)
  335.        sprintf(ptr," %*.*lf ",width-2,dec,val);
  336.       else
  337.        sprintf(ptr,"  %*.*lf)",width-3,dec,-val);
  338.       tmp=ptr;                    /* Define a temporary pointer   */
  339.       while(*tmp==32) tmp+=1;            /* Move over to first digit        */
  340.       tmp-=1;                    /* Back up one character        */
  341.       *tmp='$';                    /* Insert the dollar sign        */
  342.       if(val<0.) {                /* Put in the ( if it is a        */
  343.         tmp-=1;                    /* negative number            */
  344.         *tmp='(';
  345.       }
  346.       break;
  347.     case 3:                    /* Percent                */
  348.       sprintf(ptr,"%*.*lf%",width-1,dec,val*100.);
  349.       break;
  350.     case 4:                    /* Comma - This is not correct  */
  351.       sprintf(ptr,"%*.*lf ",width-1,dec,val);
  352.       break;
  353.     case 7:                    /* Special                */
  354.       special=dec;
  355.       switch(special) {                /* First three are not correct  */
  356.     case 0:                    /* Plus-Minus            */
  357.     case 5:                    /* Text                */
  358.     case 6:                    /* Hidden                */
  359.     case 1:                    /* General                */
  360.     case 15:                /* Default                */
  361.       max=1.;
  362.       for(i=0;i<width-1;i++) max*=10.;
  363.       if(val<max) {
  364.         sprintf(temp,"%*lf ",width-1,val);
  365.         temp[width]=0;            /* Make sure val isn't too long */
  366.         strcpy(ptr,temp);            /* Store it                */
  367.         DumpZeros(ptr);            /* Remove extra zeros        */
  368.       }
  369.       else
  370.        sprintf(ptr,"%*.*G ",width,width-7,val);
  371.       break;
  372.     default:                /* Must be a date format        */
  373.       DatePrint(format,width,val);
  374.       break;
  375.       }
  376.   }
  377. }
  378. /*--------------------------------------------------------------------------*/
  379. /*                     This routine prints string cells                     */
  380. /*--------------------------------------------------------------------------*/
  381. void StringPrint(int width,char *strng)
  382. {
  383.   char fmt,*tmpptr;
  384.   char temp[2]={" "};
  385.   int pad,pad1,i;
  386.  
  387.   tmpptr=ptr;                    /* Set a temporary pointer        */
  388.  
  389.   fmt=*strng;                    /* Get the format character        */
  390.   strng++;                    /* Move to start of string        */
  391.  
  392.   pad=width-strlen(strng)-1;            /* Assume right justified        */
  393.   if(pad<0) pad=0;                /* Is string longer than col    */
  394.  
  395.   if(fmt=='\'') pad=0;                /* Left justified            */
  396.   else if(fmt=='^') pad=(pad+1)/2;        /* Centered                */
  397.   else if(fmt=='\\') pad=0;            /* Repetitive character        */
  398.  
  399.   pad1=width-strlen(strng)-pad;            /* Get right side spaces        */
  400.   if(pad1<0) pad1=0;
  401.   if(fmt=='\\') pad1=0;                /* Don't pad if repetitive        */
  402.  
  403.   if(pad>0)                    /* Print the left pad        */
  404.    sprintf(tmpptr,"%-*.*s",pad,pad,temp);
  405.   tmpptr+=pad;
  406.  
  407.   if(fmt!='\\') {                /* Print the string            */
  408.     sprintf(tmpptr,"%s",strng);
  409.     tmpptr+=strlen(strng);
  410.   }
  411.   else
  412.    for(i=0;i<width;i++) {
  413.      sprintf(tmpptr,"%c",*strng);
  414.      tmpptr++;
  415.    }
  416.  
  417.   if(pad1>0)                    /* Print the right pad        */
  418.    sprintf(tmpptr,"%-*.*s",pad1,pad1,temp);
  419. }
  420. /*--------------------------------------------------------------------------*/
  421. /*                This routine does the formatted date print                */
  422. /*--------------------------------------------------------------------------*/
  423. void DatePrint(unsigned char format,int width,double val)
  424. {
  425.   int i,j,special;
  426.   int hr,min,sec;
  427.   int yr,mon,day;
  428.   unsigned int date;
  429.   double time;
  430.   static char months[12][4]={
  431.    "Jan","Feb","Mar","Apr","May","Jun",
  432.    "Jul","Aug","Sep","Oct","Nov","Dec"};
  433.   static int mlen[12]={0,31,28,31,30,31,30,31,31,30,31,30};
  434.   char *tmp;
  435.  
  436.   tmp=ptr;
  437.  
  438. /*............................ Decode the date .............................*/
  439.  
  440.   date=(int)val;                /* The date is the integer part */
  441.   yr=(date-(date/365/4+1)-1)/365;        /* This is the year 0=1900        */
  442.   day=date-yr*365-yr/4-1;            /* Find day of year            */
  443.   if(day<59&&yr==0) day+=1;            /* Haven't hit first leap year  */
  444.   for(i=0;i<12;i++) {
  445.     j=mlen[i];
  446.     if(i==2&&yr/4*4==yr) j++;            /* Add leap day            */
  447.     if(day-j>0) {
  448.       day-=mlen[i];
  449.       mon=i;                    /* This is the month        */
  450.     }
  451.     else break;
  452.   }
  453.   if(yr>99) yr+=1900;                /* Put year in the 2000's        */
  454.  
  455. /*............................ Decode the time .............................*/
  456.  
  457.   time=val-(int)val;                /* Time is the fractional part  */
  458.   hr=time*24.;                    /* Get the hour            */
  459.   min=(int)((time*24-(float)hr)*60.);        /* Get the minute            */
  460.   sec=(int)((time*24-(float)hr-(float)min/60.)*3600.);
  461.  
  462. /*..................... Print with the correct format ......................*/
  463.  
  464.   special=(format&15);
  465.   sprintf(ptr,"%-*.*s",width,width," ");        /* Blank the field            */
  466.   switch(special) {
  467.     case 2:                    /* Day-Month-Year            */
  468.       tmp+=width-10;
  469.       sprintf(tmp,"%02d-%-3.3s-%02d ",day,months[mon],yr);
  470.       break;
  471.     case 3:                    /* Day-Month            */
  472.       tmp+=width-7;
  473.       sprintf(tmp,"%02d-%-3.3s ",day,months[mon]);
  474.       break;
  475.     case 4:                    /* Month-Year            */
  476.       tmp+=width-7;
  477.       sprintf(tmp,"%-3.3s-%02d ",months[mon],yr);
  478.       break;
  479.     case 7:                    /* Hr-min-sec AM/PM            */
  480.       i=hr;
  481.       tmp+=width-12;
  482.       if(i>11) {
  483.     i-=11;
  484.     if(i==0) i=12;
  485.     sprintf(tmp,"%02d:%02d:%02d PM ",i,min,sec);
  486.       }
  487.       else {
  488.     if(i==0) i=12;
  489.     sprintf(tmp,"%02d:%02d:%02d AM ",i,min,sec);
  490.       }
  491.       break;
  492.     case 8:                    /* Hr-min AM/PM            */
  493.       i=hr;
  494.       tmp+=width-9;
  495.       if(i>11) {
  496.     i-=11;
  497.     if(i==0) i=12;
  498.     sprintf(tmp,"%02d:%02d PM ",i,min);
  499.       }
  500.       else {
  501.     if(i==0) i=12;
  502.     sprintf(tmp,"%02d:%02d AM ",i,min);
  503.       }
  504.       break;
  505.     case 9:                    /* Date-International 1        */
  506.       tmp+=width-9;
  507.       sprintf(tmp,"%02d/%02d/%02d ",mon+1,day,yr);
  508.       break;
  509.     case 10:                    /* Date-International 2        */
  510.       tmp+=width-6;
  511.       sprintf(tmp,"%02d/%02d ",mon+1,day);
  512.       break;
  513.     case 11:                    /* Time-International 1        */
  514.       tmp+=width-9;
  515.       sprintf(tmp,"%02d:%02d:%02d ",hr,min,sec);
  516.       break;
  517.     case 12:                    /* Time-International 2        */
  518.       tmp+=width-6;
  519.       sprintf(tmp,"%02d:%02d ",hr,min);
  520.       break;
  521.   }
  522. }
  523. /*--------------------------------------------------------------------------*/
  524. /*             This routine decides if a row should be printed              */
  525. /*   row is the new row, before we start it we have to print the old row    */
  526. /*--------------------------------------------------------------------------*/
  527. void CheckRow(int row)
  528. {
  529.   register int i;
  530.  
  531.   if(row>currow) {                /* Are we on a new row?        */
  532.     if(currow>=0) {                /* And it isn't the first row?  */
  533.       while(currow<row) {
  534.     Trim(Text);                /* Strip trailing blanks        */
  535.     *ColEnd=0;                /* End the line at range end    */
  536.     if(currow>=nrange[rnumb].top&&
  537.        currow<=nrange[rnumb].bott)        /* If the line is in valid range*/
  538.      fprintf(fout,"%s\n",ColText);        /* Print the text            */
  539.     *ColText=0;                /* Only print text on first line*/
  540.     currow++;                /* Increment the current row    */
  541.       }
  542.       for(i=0;i<1000;i++)
  543.        Text[i]=32;
  544.       ptr=Text;                    /* Reset the column pointer        */
  545.       curcol=0;
  546.     }
  547.     else currow=row;
  548.   }
  549. }
  550. /*--------------------------------------------------------------------------*/
  551. /*        This routine decides if blank columns should be filled in         */
  552. /*--------------------------------------------------------------------------*/
  553. void CheckCol(int col)
  554. {
  555.   register int i,j;
  556.  
  557.   for(i=curcol;i<col-1;i++) {            /* Move over amount of each col */
  558.     ptr+=Width[i];                /* Update the pointer        */
  559.     for(j=0;j<Width[i+1];j++)            /* Blank out skipped columns    */
  560.      if(*(ptr+j)==0) *(ptr+j)=32;
  561.   }
  562.  
  563.   if(col>0&&col!=curcol)
  564.    ptr+=Width[col-1];                /* Update the pointer        */
  565.  
  566.   curcol=col;                    /* Save the column            */
  567. }
  568. /*--------------------------------------------------------------------------*/
  569. /*  This routine converts the zero based column number to 123 alpha style   */
  570. /*--------------------------------------------------------------------------*/
  571. void EnCode(int col,char *code)
  572. {
  573.   code[1]=code[2]=0;
  574.  
  575.   if(col<26) code[0]=col+65;
  576.   else {
  577.     code[0]=(int)(col/26)+64;
  578.     code[1]=col-(code[0]-64)*26+65;
  579.   }
  580. }
  581. /*--------------------------------------------------------------------------*/
  582. /*            This routine splits a range string up into numbers            */
  583. /*--------------------------------------------------------------------------*/
  584. void DeCode(char *code,int *left,int *top,int *right,int *bott)
  585. {
  586.   char *ptr;
  587.   int i;
  588.  
  589.   for(i=0;i<strlen(code);i++)
  590.    code[i]=toupper(code[i]);
  591.  
  592.   ptr=code+strlen(code)-1;
  593.  
  594.   while(*ptr>='0'&&*ptr<='9'&&ptr!=code)    /* Get the bottom row        */
  595.    ptr-=1;
  596.   ptr+=1;
  597.   *bott=atoi(ptr)-1;
  598.   if(ptr==code) return;                /* Error check            */
  599.  
  600.   *ptr=0;
  601.   ptr-=1;
  602.   *right=*ptr-65;                /* Get part of the right side   */
  603.   ptr-=1;
  604.   if(*ptr>='A'&&*ptr<='I')            /* Get the rest of right side   */
  605.    *right=*right+(*ptr-64)*26;
  606.   if(ptr==code) return;                /* Error check            */
  607.  
  608.   while((*ptr>'9'||*ptr<'0')&&ptr!=code)    /* Trash the ..'s            */
  609.    ptr-=1;
  610.   *(ptr+1)=0;
  611.   if(ptr==code) return;                /* Error check            */
  612.  
  613.   while(*ptr>='0'&&*ptr<='9'&&ptr!=code)    /* Get the top row            */
  614.    ptr-=1;
  615.   ptr+=1;
  616.   *top=atoi(ptr)-1;
  617.   if(ptr==code) return;                /* Error check            */
  618.  
  619.   *ptr=0;
  620.   ptr-=1;
  621.   *left=*ptr-65;                /* Get part of the left side    */
  622.   if(ptr==code) return;                /* Error check            */
  623.   ptr-=1;
  624.   if(*ptr>='A'&&*ptr<='I')            /* Get the rest of left side    */
  625.    *left=*left+(*ptr-64)*26;
  626. }
  627. /*--------------------------------------------------------------------------*/
  628. /*                  Strip the trailing zeros from the line                  */
  629. /*--------------------------------------------------------------------------*/
  630. void Trim(char *strng)
  631. {
  632.   char *tmpptr;
  633.  
  634.   tmpptr=strng;
  635.   tmpptr+=(strlen(strng)-1);
  636.   while(*tmpptr==32&&tmpptr!=strng) {
  637.     *tmpptr=0;
  638.     tmpptr-=1;
  639.   }
  640. }
  641. /*--------------------------------------------------------------------------*/
  642. /*     Remove the extraneous zeros from the end of an unformatted cell      */
  643. /*--------------------------------------------------------------------------*/
  644. void DumpZeros(char *strng)
  645. {
  646.   char *tmpptr;
  647.   int kntr,len,i;
  648.  
  649.   tmpptr=strng;
  650.   while(*tmpptr!='.'&&*tmpptr) tmpptr+=1;   /* First find the decimal point */
  651.   if(*tmpptr==0) return;            /* No decimal point            */
  652.  
  653.   tmpptr=strng;
  654.   len=strlen(strng);
  655.   tmpptr+=(len-1);
  656.   if(*tmpptr!=32) {                /* Should be a space        */
  657.     *tmpptr=32;                    /* Just truncate the digit        */
  658.   }
  659.   while((*tmpptr==32||*tmpptr=='0')&&tmpptr!=strng) {
  660.     *tmpptr=32;
  661.     tmpptr-=1;
  662.   }
  663.  
  664.   if(*tmpptr=='.') *tmpptr=32;            /* Take out the lone dec. pt.   */
  665.   else tmpptr+=1;                /* Move to first blank        */
  666.  
  667.   kntr=0;
  668.   while(*tmpptr) {
  669.     tmpptr+=1;
  670.     kntr+=1;
  671.   }
  672.   if(kntr>1) {
  673.     kntr--;
  674.     for(i=len-2;i>=kntr;i--)
  675.      strng[i]=strng[i-kntr];
  676.     for(i=0;i<kntr;i++)
  677.      strng[i]=32;
  678.   }
  679. }
  680. /*--------------------------------------------------------------------------*/
  681. /*       This routine prints the floating point error if one is found       */
  682. /*--------------------------------------------------------------------------*/
  683. void FltErrHnd(unsigned int stat,int row,int col)
  684. {
  685.   char code[3];
  686.  
  687.   EnCode(col,code);
  688.  
  689.   if((stat&SW_INVALID)) cprintf("");
  690. /*   cprintf("Invalid: Cell %s%d\n\r",code,row+1);*/
  691.   else  if((stat&SW_DENORMAL))
  692.    cprintf("Denormal: Cell %s%d\n\r",code,row+1);
  693.   else if((stat&SW_ZERODIVIDE))
  694.    cprintf("Zero divide: Cell %s%d\n\r",code,row+1);
  695.   else if((stat&SW_OVERFLOW))
  696.    cprintf("Overflow\n\r: Cell %s%d",code,row+1);
  697.   else if((stat&SW_UNDERFLOW))
  698.    cprintf("Underflow: Cell %s%d\n\r",code,row+1);
  699.   else if((stat&SW_INEXACT))
  700.    cprintf("Inexact: Cell %s%d\n\r",code,row+1);
  701.   else
  702.    cprintf("Unknown %d: Cell %s%d\n\r",stat,code,row+1);
  703.  
  704.   _clear87();
  705. }
  706.