/*****************************************************************************
******************************************************************************
******************************************************************************
*****                                                                    *****
*****                       PROGRAM READTEXT v1.1                        *****
***** A program for  reading restriction site or fragment data from text *****
*****                       form into binary form.                       *****
*****    Copyright (c) 1990 by Joyce C. Miller.  All Rights Reserved.    *****
*****                                                                    *****
***** This  program  takes a  textfile name,  a  datafile name,  and  an *****
***** optional N, A, or O  (New, Append, or Overwrite)  command from the *****
***** command-line argument.  Each line from the textfile is read into a *****
***** record, which is written to the datafile.                          *****
*****                                                                    *****
*****                                                                    *****
***** List of C functions used in this program:                          *****
*****                                                                    *****
*****     FUNCTION         LIBRARY          FUNCTION         LIBRARY     *****
*****     fclose           stdio.h          feof             stdio.h     *****
*****     fgets            stdio.h          free             stdlib.h    *****
*****     fwrite           stdio.h          malloc           stdlib.h    *****
*****     printf           stdio.h          sscanf           stdio.h     *****
*****     strcat           string.h         strcpy           string.h    *****
*****     strlen           string.h         strtok           string.h    *****
*****     toupper          ctype.h                                       *****
*****                                                                    *****
******************************************************************************
******************************************************************************
*****************************************************************************/

/*****************************************************************************
**                              INCLUDE FILES                               **
*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <rstypes.h>       /* header file with type definitions & constants */
#include <rserrors.h>                           /* file with error messages */
#include <rsfuncs.h>          /* file with some functions (NEEDS RSTYPES.H) */
/*****************************************************************************
**                            SYMBOLIC CONSTANTS                            **
*****************************************************************************/
#define VNUM 1.1                          /* version number of this program */
#define YEAR 1990                                  /* current calendar year */
/*****************************************************************************
**                             TYPE DEFINITIONS                             **
*****************************************************************************/
typedef char item[MAXSTRLEN];
/*****************************************************************************
**                            FUNCTION PROTOTYPES                           **
*****************************************************************************/
void rddat(char rdfl[], char wtfl[], char ao[]);
char *createbakname(char flname1[]);
FILE *opnwtfl(FILE *fpw, char wtfl[], char bakfl[], char c);
/*****************************************************************************
******************************************************************************
******************************************************************************
******                                                                  ******
******                           MAIN PROGRAM                           ******
******                                                                  ******
****** This  function prints out the  program name, the version number, ******
****** and a copyright message.  It  error-checks the command line, and ******
****** passes  control to  FUNCTION RDDAT,  which reads  the ASCII text ******
****** file and writes the data to a binary data file.                  ******
******                                                                  ******
****** Functions called:                                                ******
****** rddat          --  reads the ASCII text file and prints the data ******
******                    in it to a binary data file.                  ******
****** rserror101     --  error message if no input text file or output ******
******                    data file specified.                          ******
******************************************************************************
******************************************************************************
*****************************************************************************/
void main(int argc, char *argv[])
{
  char rdfl[FILELEN];
  char wtfl[FILELEN];
  int i;

  printf("\r\n\nPROGRAM READTEXT v%3.1f\r\nCopyright",VNUM);
  printf(" (c) %4.0d by Joyce C. Miller.  All Rights Reserved.\r\n",YEAR);

  if (argc < 3) rserror101();                /* error if no files specified */
  if (argc == 3) argv[3] = "X";    /* supply temp A/O command if none given */

  for (i=0; i<strlen(argv[1]); ++i)            /* convert rdfl to uppercase */
    if (i<FILELEN) rdfl[i] = toupper(argv[1][i]);
    else break;
  rdfl[i] = '\0';
  for (i=0; i<strlen(argv[2]); ++i)            /* convert wtfl to uppercase */
    if (i<FILELEN) wtfl[i] = toupper(argv[2][i]);
    else break;
  wtfl[i] = '\0';

  rddat(rdfl, wtfl, argv[3]);                      /* read the data in RDFL */
}                                                   /* END OF FUNCTION MAIN */
/*****************************************************************************
******************************************************************************
*****                                                                    *****
*****                             FUNCTIONS                              *****
*****                                                                    *****
******************************************************************************
*****************************************************************************/

/*****************************************************************************
**                                                                          **
**                              FUNCTION RDDAT                              **
**                                                                          **
** This  function  opens the textfile  (RDFL) and the datafile  (WTFL).  It **
** then reads each text line from  RDFL, turns it into a record, and writes **
** it to WTFL.                                                              **
**                                                                          **
** Functions called:                                                        **
** opntrdfl       --  opens text file for reading, returns file pointer.    **
** createbakname  --  takes WTFL name, returns same name with a ".BAK" ext. **
** opnwtfl        --  opens WTFL for writing/appending, returns file        **
**                    pointer fpw.                                          **
** rserror201     --  error message if not enough words on text line.       **
** rserror202     --  error message if too many words on line.              **
** rserror203     --  error message if ID number too long.                  **
** rserror204     --  error message if KEY1 too long.                       **
** rserror205     --  error message if KEY2 too long.                       **
** rserror206     --  error message if KEY3 too long.                       **
** rserror207     --  error message if KEY4 too long.                       **
** rserror208     --  error message if probe too long.                      **
** rserror209     --  error message if enzyme too long.                     **
** rserror322     --  error message if error writing to WTFL.               **
** rserror312     --  error message if error writing, BAK made.             **
** rserror400     --  error message if not enough memory.                   **
*****************************************************************************/
void rddat(char rdfl[], char wtfl[], char ao[])
{
  char tempstr[MAXSTRLEN];                              /* temporary string */
  char TEMPSTR[MAXSTRLEN];                              /* temporary string */
  register int i,j;                                             /* loop var */
  item *itemarray;                   /* array of words taken from text line */
  FILE *fpr, *fpw;                                /* RDFL and WTFL pointers */
  char bakfl[FILELEN];                                 /* name of .BAK file */
  char *b;                                   /* pointer to name of BAK file */
  long ln = 1;                                                    /* line # */
  char *word;                                  /* word taken from text line */
  fragdat t;                                                 /* temp record */

  if ((itemarray=(item *)malloc((PREWORDS+NUMFS)*sizeof(item)))==NULL)
    rserror400();

  b = createbakname(wtfl);                      /* make .BAK name from WTFL */
  strcpy(bakfl,b);
  fpr   = opntrdfl(fpr,rdfl);                 /* open text file for reading */
  fpw   = opnwtfl(fpw,wtfl,bakfl,ao[0]);     /* opens data file for writing */

  printf("\r\n\nReading file %s...\r\n",rdfl);   /* status messages to user */
  printf("Writing to file %s...\r\n\nReading data...\r\n\n\n",wtfl);

  while ((fgets(tempstr,MAXSTRLEN,fpr)) != NULL) {    /* GET LINE FROM FILE */
    strcpy(TEMPSTR,tempstr);
    printf("\r%d",ln++);                               /* print line number */

    t.id[0]   = '\0';                                 /* initialize record: */
    t.key1[0] = '\0';                              /* strings get '\0', and */
    t.key2[0] = '\0';
    t.key3[0] = '\0';
    t.key4[0] = '\0';
    t.prb[0]  = '\0';                  /* numbers get arbitrary value of -5 */
    t.enz[0]  = '\0';
    t.rv      =  -5;
    for (i=0; i<NUMFS; ++i) t.f[i] = -5;

    i = 0;                                  /* divide text line into tokens */
    word = strtok(tempstr," ");
    while ((word != NULL) && (i < PREWORDS+NUMFS)) {
      strcpy(itemarray[i++],word);             /* put tokens into itemarray */
      word = strtok(NULL," ");
    }

                  /* error-check line: */
    if (i < PREWORDS+1) {                      /* error if not enough words */
      fclose(fpr);
      fclose(fpw);
      rserror201(wtfl,bakfl,TEMPSTR,ln-1);
    }

    if (i >= PREWORDS+NUMFS) {                   /* error if too many words */
      fclose(fpr);
      fclose(fpw);
      rserror202(wtfl,bakfl,TEMPSTR,ln-1);
    }

    if (strlen(itemarray[0]) >= IDLEN) {         /* error if IDNUM too long */
      fclose(fpr);
      fclose(fpw);
      rserror203(wtfl,bakfl,TEMPSTR,ln-1);
    }
    else strcpy(t.id,itemarray[0]);

    if (strlen(itemarray[1]) >= KEYLEN) {         /* error if KEY1 too long */
      fclose(fpr);
      fclose(fpw);
      rserror204(wtfl,bakfl,TEMPSTR,ln-1);
    }
    else strcpy(t.key1,itemarray[1]);

    if (strlen(itemarray[2]) >= KEYLEN) {         /* error if KEY2 too long */
      fclose(fpr);
      fclose(fpw);
      rserror205(wtfl,bakfl,TEMPSTR,ln-1);
    }
    else strcpy(t.key2,itemarray[2]);

    if (strlen(itemarray[3]) >= KEYLEN) {         /* error if KEY3 too long */
      fclose(fpr);
      fclose(fpw);
      rserror206(wtfl,bakfl,TEMPSTR,ln-1);
    }
    else strcpy(t.key3,itemarray[3]);
    if (strlen(itemarray[4]) >= KEYLEN) {         /* error if KEY4 too long */
      fclose(fpr);
      fclose(fpw);
      rserror207(wtfl,bakfl,TEMPSTR,ln-1);
    }
    else strcpy(t.key4,itemarray[4]);

    if (strlen(itemarray[5]) >= PRBLEN) {        /* error if probe too long */
      fclose(fpr);
      fclose(fpw);
      rserror208(wtfl,bakfl,TEMPSTR,ln-1);
    }
    else strcpy(t.prb,itemarray[5]);

    if (strlen(itemarray[6]) >= ENZLEN) {       /* error if enzyme too long */
      fclose(fpr);
      fclose(fpw);
      rserror209(wtfl,bakfl,TEMPSTR,ln-1);
    }
    else strcpy(t.enz,itemarray[6]);

    sscanf(itemarray[7],"%f",&t.rv);

    for (j=PREWORDS; j<i; ++j) sscanf(itemarray[j],"%f",&t.f[j-PREWORDS]);

    if (fwrite(&t,sizeof(fragdat),1,fpw) == NULL)   /* write record to file */
      rserror322(wtfl,bakfl);
  }                                                         /* end of while */

  if (feof(fpr)) {                                     /* if normal stop... */
    printf("\r\nEnd of file %s.\r\n",rdfl);
    printf("Data read and converted to database %s.\r\n",wtfl);
  }
  else rserror312(rdfl,wtfl,bakfl);              /* if stop due to error... */

  fclose(fpr);                                             /* close up shop */
  fclose(fpw);
  free(itemarray);                                 /* free allocated memory */
}                                                  /* END OF FUNCTION RDDAT */
/*****************************************************************************
**                                                                          **
**                          FUNCTION CREATEBAKNAME                          **
**                                                                          **
** This  function  receives the  name  of a file,  and creates a name for a **
** backup file by replacing the extension with ".BAK".                      **
**                                                                          **
** Functions called:  none                                                  **
*****************************************************************************/
char *createbakname(char flname1[])
{
  char wf[FILELEN];
  char vf[FILELEN];
  char *v;                                         /* pointer to bakfl name */
  int i;

  strcpy(wf,flname1);                        /* copy : WTFL.EXT -> WTFL.EXT */
  for (i=0; i<strlen(wf); ++i)
    if (wf[i] != '.') vf[i] = wf[i];
    else vf[i] = '\0';
  v = strcat(vf,".BAK");
  return(v);
}                                          /* END OF FUNCTION CREATEBAKNAME */
/*****************************************************************************
**                                                                          **
**                             FUNCTION OPNWTFL                             **
**                                                                          **
** This  function  takes  the  N/A/O  command, and  opens  an  output  file **
** accordingly.  If 'N' or 'O', the output file is opened whether or not it **
** already  exists.  If 'A', the existing file is opened for appending.     **
**                                                                          **
** Functions called:                                                        **
** opnbwtfl       --  opens a binary  file  for writing, destroys contents, **
**                    if any.                                               **
** opnbapfl       --  if asked to append pre-existing WTFL: opens WTFL for  **
**                    appending.                                            **
*****************************************************************************/
FILE *opnwtfl(FILE *fpw, char wtfl[], char bakfl[], char c)
{
  c = toupper(c);
  if (c == 'A') fpw = opnbapfl(fpw,wtfl,bakfl);  /* open file for appending */
  else fpw = opnbwtfl(fpw,wtfl);               /* open new file for writing */

  return(fpw);                               /* return writing file pointer */
}                                                /* END OF FUNCTION OPNWTFL */
/****************************************************************************/
