home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 142_01 / startim.c < prev    next >
Text File  |  1985-03-10  |  7KB  |  278 lines

  1. #include bdscio.h
  2. /* Modified 8 April 1984 by Alan Coates from Starpri, written by Julian Hyde
  3.  */
  4. char ibuf[BUFSIZ],obuf[BUFSIZ],date1[10],date2[10];
  5. int ok;
  6. main(argc,argv)
  7. int argc;
  8. char **argv;
  9. {
  10.     char *d1,*d2;
  11.     int fct;
  12.     int surv;
  13.     if(argc!=3)
  14.     {
  15.     printf("\nStartim was modified by Alan Coates\n");
  16.     printf("from Starpri,written by Julian Hyde in 1983,\n");
  17.     printf("augmented to calculate interval durations.\n");
  18.     printf("It accepts a file in datastar format\n");
  19.     printf("from which are selected by field number two fields\n");
  20.     printf("which are copied to the output file in the order input\n");
  21.     printf("plus two dates in ddmmyy format.\n");
  22.     printf("  The 2 dates are processed to give \n");
  23.     printf("the interval from the first to the second\n");
  24.     printf("and this is output in days as the fifth field.\n");
  25.     printf("The actual dates are also output to assist debugging data.\n");
  26.     printf("\nEach output field will be padded with leading or\n");
  27.     printf("trailing blanks to a nominated fixed length.\n");
  28.     printf("Cases in which any requested variable is missing \n");
  29.     printf("will be excluded, and the number of such cases reported.\n");
  30.         printf("The program will handle records up to 250 chars.\n\n");
  31.     printf("Type 'startim inputfile outputfile'.\n");
  32.     return;
  33.     }    
  34.        
  35.     /*OPEN INPUT FILE*/
  36.     if(fopen(*(argv+1),ibuf)==ERROR)
  37.     {    printf("File %s is not available!",*argv);
  38.         return;
  39.     }
  40.     /*CREATE OUTPUT FILE*/
  41.     if(fcreat(*(argv+2),obuf)==ERROR)
  42.     {    printf("Cannot create %s!",*(argv+1));
  43.         return;
  44.     }
  45.     /*RECORD AREAS*/
  46.     char iline[MAXLINE],*i;
  47.     char oline[MAXLINE],*o;
  48.     char store[MAXLINE],*s;
  49.     char diff[MAXLINE],*d3;
  50.     int qno,cno;
  51.     unsigned recs,badrecs;
  52.         badrecs=recs=0;
  53.     /*READ SPECIFICATION LINE*/
  54.     printf("\nEnter the field numbers wanted, each followed by the \n");
  55.     printf("length to which it is to be padded out or truncated\n");
  56.     printf("in the output record, in sequence separated\n");
  57.     printf("by non-numerics.  Then type return.\n");
  58.     printf("\nIf output fields are to be right justified, use a\n");
  59.     printf("specifier of the form lRp where l is the length to which\n");
  60.     printf("the field will be right truncated then right justified,\n");
  61.     printf("and p specifies a fixed number of trailing blanks.\n\n");
  62.     gets(store);
  63.     /*PROCESS REST OF INPUT FILE*/
  64.     while(fgets(iline,ibuf))
  65.     {    /*IGNORE LEADING NON NUMERICS IN SPEC*/
  66.         s=store;
  67.         fct = 0;    /* reset counter for new line    */
  68.         ok = TRUE;    /* reset test for new case    */
  69.         while(!isdigit(*s)&&*s)s++;
  70.         for(i=iline,o=oline;*s;)
  71.         {    /*GET FIELD NO */
  72.             int fieldno;fieldno=0;
  73.             while(isdigit(*s))
  74.                 fieldno=fieldno*10+*(s++)-48;
  75.             /*IGNORE NON NUMERIC IN SPEC*/
  76.             while(!isdigit(*s)&&*s)s++;
  77.             /*GET LENGTH NO*/
  78.             int ll; ll=0;
  79.             while (isdigit(*s))
  80.                 ll=ll*10+*(s++)-48;
  81.             if(fieldno)
  82.             {    fieldno--;
  83.                 /*FIND FIELD*/
  84.              
  85.                 qno=cno=0;
  86.                 for(i=iline;*i&&cno<fieldno;i++)
  87.                     if(*i=='"')qno++;
  88.                     else if(*i==','&&!(qno%2))cno++;
  89.                 if(!*i)
  90.                 {    printf("\nNo field %d exists!",
  91.                     fieldno+1); return;
  92.                 }
  93.                 /*COPY FIELD*/
  94.                      int l;l=0;
  95.                 ++fct;
  96.                 char *oo;oo=o;
  97.                 while(*i&&*i!='\n'&&(*i!=','||qno%2))
  98.                 {       char c;                 
  99.                     c=*(i++);
  100.                     if(c=='"')cno++;
  101.                     if(((c!='"')||(cno%2&&cno>1))&&l<ll)
  102.                     {    *(o++)=c;
  103.                         l++;
  104.                     }
  105.                 }
  106.                 /* TEST FOR BLANK FIELD MAY BE ADDED LATER
  107.                 if (c = ' ')
  108.                     remark("blank in field",fieldno+1);*/
  109.                 /* TEST THIRD AND FOURTH FIELDS FOR length=6
  110.                  */
  111.                 if(fct == 3 || fct == 4)
  112.                 {    
  113.                     
  114.                     if(l != 6)
  115.         remark("Wrong length date field - case no",recs+1); 
  116.  
  117.                 /* COPY LAST 6 CHARACTERS TO DATE */
  118.                 char *ooo; 
  119.                 if (fct == 3)
  120.                  {
  121.                  for(d1=date1,ooo=o-6; ooo < o; ooo++)
  122.                    *(d1++) = *ooo;
  123.                  *(d1++) = '\0';
  124.                  }
  125.                 if (fct == 4)
  126.                  { 
  127.                  for(d2=date2,ooo=o-6; ooo < o; ooo++)
  128.                    *(d2++) = *ooo;
  129.                  *(d2++) = '\0';
  130.                    surv = days(date2) - days(date1);
  131.                 if (ok == FALSE || surv <= 0)
  132.                     {
  133.                     badrecs += 1;
  134.                     d3 = diff;
  135.                     *(d3++) = '1';
  136.                     *(d3++) = '-';
  137.                     for(d3=diff+2;d3<diff+8;++d3)
  138.                         *d3 = ' ';
  139.                     *(d3++) = '\0';
  140.         printf("Unable to calculate survival for case %d\n\n",recs+1); 
  141.                     }
  142.                 else
  143. /*    make string diff backwards from surv    */
  144.                   for (d3=diff;d3 < diff + 8;++d3)
  145.                     {
  146.                     *d3 = (surv%10) + 48;
  147.                     surv = surv/10;
  148.                     }
  149.                   *d3='\0';
  150.                  }
  151.                 }
  152.                 if(*s=='R'||*s=='r')
  153.                 {    /*RIGHT JUSTIFY*/
  154.                     char *ora,*orb;
  155.                     while(l<ll)
  156.                     {
  157.             for(orb=o++,ora=orb-1;orb>oo;ora--,orb--)
  158.                         *orb=*ora;
  159.                     *orb=' ';
  160.                     l++;
  161.                     }
  162.                     /*GET PADDING SIZE*/
  163.                     ll=l=0;
  164.                     s++;
  165.                     while (isdigit(*s))
  166.                         ll=ll*10+*(s++)-48;
  167.                 }
  168.                 /*PAD FIELD WITH BLANKS*/
  169.                 while (l<ll)
  170.                 {    *(o++)=' ';
  171.                     l++;
  172.                 }
  173.                  
  174.             }
  175.             /*IGNORE NON NUMERIC IN SPEC*/
  176.                    while(!isdigit(*s)&&*s)s++;
  177.             /*TERMINATE FIELD OR LINE*/
  178.             if(*s);
  179.             else
  180.             {    /* WRITE diff to oline, reversed */
  181.                 for(d3=diff+5; d3>=diff; --d3)
  182.                     *(o++) = *d3;
  183.  
  184.                 *(o++)='\n';
  185.                 *o=0;
  186.             }
  187.         }
  188.         /*WRITE OUTPUT FILE*/
  189.             if(fputs(oline,obuf)==ERROR)
  190.              {    printf("Write error!\n");
  191.             return;
  192.              }
  193.         if(!(++recs%100))
  194.          printf("\nReformatted %d records - %d bad\n",recs,badrecs);
  195.     }
  196.     printf("\nFinal cases processed : %d\n",recs);
  197.     printf("Cases set to -1 : %d\n",badrecs);
  198.     /*CLOSE INPUT FILE*/
  199.     fclose(ibuf);
  200.     /*CLOSE OUTPUT FILE*/
  201.     putc(CPMEOF,obuf);
  202.     fflush(obuf);
  203. }
  204. /*
  205. function days(date)
  206. ASSUMES 6 DIGIT ASCII ARGUMENT DDMMYY, RETURNS DAYS FROM 1.1.1900
  207. If date > about mid 1989, this will exceed MAXINT and appear negative.
  208. For the purpose of calculating a difference between two dates, the
  209. overflow doesn't matter so long as difference is not > MAXINT.
  210.  */
  211. int days(date)
  212. char date[];
  213. {
  214. int dd,mm,yy;
  215. unsigned daytot;
  216. char *s;
  217.     dd = mm = yy = 0;
  218.     for(s = date;s < date+2 && isdigit(*s); )
  219.         dd = dd*10 + *(s++) -48;
  220.     for(s = date + 2;s < date+4 && isdigit(*s); )
  221.         mm = mm*10 + *(s++) -48;
  222.     for(s = date + 4 ;s < date+ 6 && isdigit(*s); )
  223.         yy = yy*10 + *(s++) -48;
  224.     if(dd > 31)
  225.         {
  226.         remark("Bad day",dd);
  227.         }
  228.     daytot = dd;
  229.     /*    add months, correct for time of year    */
  230.     daytot += 30*(mm - 1);
  231.     switch (mm)
  232.             {
  233.         case 1:
  234.         case 4:
  235.         case 5:
  236.             daytot += 0; /*    no correction    */
  237.             break;
  238.         case 3:
  239.             daytot -= 1;
  240.             break;
  241.         case 2:
  242.         case 6:
  243.         case 7:
  244.             daytot += 1;
  245.             break;
  246.         case 8:
  247.             daytot += 2;
  248.             break;
  249.         case 9:
  250.         case 10:
  251.             daytot += 3;
  252.             break;
  253.         case 11:
  254.         case 12:
  255.             daytot += 4;
  256.             break;
  257.         default:
  258.             remark("Bad month",mm);
  259.             break;
  260.             }
  261.     /*    add for completed years    */
  262.         daytot += 365*yy;
  263.     /*    correct within a leap year iff after Feb 29    */
  264.         if(mm > 2 && yy%4 == 0 && yy > 0)
  265.             daytot += 1;
  266.     /*    correct for elapsed leap years    */
  267.         daytot += (yy-1)/4;
  268.     return(daytot);
  269. }
  270. remark(s1,x)
  271.     char s1[] ;
  272.     int x;
  273.     {
  274.     printf("%s   %d\n",s1,x);
  275.     ok = FALSE;
  276.     return;
  277.     }
  278.