Metropoli BBS
VIEWER: copydesc.c MODE: TEXT (ASCII)
/*  COPYDESC version 1.02        Copyright (C) 1992 by Jim Robeson
 *                                                     11/11/92
 *  Function:
 *    Read a PCBoard DIR LIST file (arg-1),
 *      and copy it to a file (arg-2),
 *      changing all multi-line descriptions to "long lines".
 *      with the output position of the '|' set in arg-3,
 *      and the starting position of the text set in arg-4.
 *    note: requirment:   1 < arg-3 < arg-4 <= 34
 *
 *  Other uses:
 *    None.
 *
 *  Execution:
 *    Run from command line or .BAT:
 *      COPYDESC drv:\path\in-file-name drv:\path\out-file-name |pos txtpos
 *    If run without arguments, a bit of help appears.
 *
 *  Compiled with:
 *    Borland's Turbo C 2.0.
 *    tcc copydesc
 *
 *  Disclaimer:
 *    This program is contributed to the Public Domain.  It can be
 *    freely used, modified and/or distributed by anyone. The only
 *    thing I ask is that you remember that I am not responsible
 *    for anything that might go wrong through the use of this
 *    program.  I have tested the program enough for my own use.
 *    I also realize that bugs can appear in most every program.
 *    Therefore, YOU USE THIS PROGRAM AT YOUR OWN RISK.
 *
 *  To-do:
 *    > See if the blank in split-line hyphenated words can be eliminated.
 *
 *  Enjoy,
 *  Jim Robeson
 *  The Cricket BBS, Pacific Grove CA,  408-373-3773
 */

#include "stdio.h"                        /* Standard I/O definitions */
#include "string.h"

#define TRUE 1
#define FALSE 0

/* test to see if 'ch' is an acceptable DOS filename character */
#define vld_dos(ch)  ( (( (ch) >= 'A' && (ch) <= 'Z' ) || \
                        ( (ch) >= '0' && (ch) <= '9' ) || \
                        (ch) == '!' || \
                        (ch) == '$' || \
                        (ch) == '#' || \
                        (ch) == '@' || \
                        (ch) == '_' || \
                        (ch) == '-' || \
                        (ch) == '{' || \
                        (ch) == '}' || \
                        (ch) == '~' || \
                        (ch) == '%' || \
                        (ch) == '^' || \
                        (ch) == '(' || \
                        (ch) == ')')   \
                       ? 1             \
                       : 0 )
/* test to see if 'ch' is numeric..... <compare   to isdigit(c)> */
#define is_digit(ch)   ( ( (ch) < '0' || (ch) > '9' ) \
                         ? 0                          \
                         : ch )

void write_desc ( );             /* prototype */
void save_desc ( );              /* prototype */
void showhelp ( );               /* prototype */

  FILE *infile;                  /* the IN file */
  FILE *outfile;                 /* the OUT file */
  char inbuf[BUFSIZ];            /* line buffer for reading from file */
                                 /* BUFSIZ = 512 in stdio.h */

  char outbuf[3300];             /* Description Lines save area */
        /* Lets start by assuming 40 max lines coming in. */
        /* Therefore, we need on the output side:         */
        /* a maximum of 80*40 = 3200.                     */
        /* Make it 3300 for safety's sake!                */
        /* Watch this over run itself now!                */

  int in_a_desc;         /* working on a description indicator */
  int ipt,opt,linept;    /* index pointers                     */
  int pos_mark;          /* line position of the '|' character */
  int pos_text;          /* starting position of output text   */

/* ========================================= */
/* ===  MAIN                             === */
/* ========================================= */
main(int argc, char *argv[])                /* main reads command args  */
{
  char *progname;
  char *filein;
  char *fileout;
  char *adr_mark;
  char *adr_text;

/*  Display a little how-to "help" if arguments are null or improper  */

  if (argc != 5)           /*  should be 4 args + prognam */
     { if (argc != 1)
         printf("\nERROR: needs 4 arguments\n");
       showhelp();
       exit (1); }               /* exit with errorlevel=1 */

  progname = argv[0];
  filein   = argv[1];
  fileout  = argv[2];

  adr_mark = argv[3];   /* get arg-3: the position of the output '|' */
  sscanf(&adr_mark[0],"%2d",&pos_mark);

  adr_text = argv[4];   /* get arg-4: the 1st position of output text */
  sscanf(&adr_text[0],"%2d",&pos_text);

  if (pos_text >= 35)        /* 1st text position must be 34 or less */
     { printf("\nERROR: text position must be less than 35. (arg-4)\n");
       showhelp();
       exit (1); }               /* exit with errorlevel=1 */

  if (pos_mark >= pos_text)  /* the '|' must be on the left of the text */
     { printf("\nERROR: '|' position must be less than text position. (arg-3 or arg-4)\n");
       showhelp();
       exit (1); }               /* exit with errorlevel=1 */

  if (pos_mark <= 1)         /* the '|' must be 2 or higher */
     { printf("\nERROR: '|' position is 1 or less. (arg-3)\n");
       showhelp();
       exit (1); }               /* exit with errorlevel=1 */


  printf("\nCOPYDESC IS RUNNING:\n");
  printf("           input = %s, output = %s,\n",filein,fileout);
  printf("           mark = %2d, text = %2d.\n",pos_mark,pos_text);

  infile = fopen(filein,"r");          /* open the input file */
  if (infile == NULL)
    {
    fprintf(stderr,"\n\007%s can't open the INPUT file: %s.\n",progname,filein);
    exit (1);
    }

  outfile = fopen(fileout,"w");          /* open the output file */
  if (outfile == NULL)
    {
    fprintf(stderr,"\n\007%s can't open the OUTPUT file: %s.\n",progname,fileout);
    exit (1);
    }

  in_a_desc = FALSE;      /* say we're not inside a description yet */

 /* ========================  copy the file ========================= */
  while ( fgets(inbuf,BUFSIZ,infile) != NULL )  /* TOP-OF-LOOP */
    {
    /* test for line 1 of a file description:     */
    if (vld_dos(inbuf[0]) &&        /* pos 1 valid DOS chars & */
        is_digit(inbuf[20]) &&      /* pos 21 is numeric       */
        inbuf[25] == '-' &&         /* pos 26 = '-'            */
        inbuf[28] == '-')           /* pos 29 = '-'            */

      { /* ==== FILE DESCRIPTION LINE # 1 FOUND ======== */

        /* if we're already in a description, write the old one */
        if (in_a_desc) write_desc();
        in_a_desc = TRUE;            /* say we are 'inside' */
                                     /* save the 1st line   */
        ipt = 0;
        opt = 0;
        while (inbuf[ipt] != '\0')
          { outbuf[opt] = inbuf[ipt];
            ipt++;
            opt++;
          }
  /* ++++ add a blank to the end for wrap problem */
        opt--;
        while (outbuf[opt] == ' ' || outbuf[opt] == '\n')
            opt--;
        opt++;
        outbuf[opt] = ' ';
        opt++;
        outbuf[opt] = '\n';
        opt++;
 /* ++++ */
        outbuf[opt] = '\0';
        linept = opt;       /* card pointer (1-80), pointing */
        opt--;              /* at the '\n' right now.        */

      }   /* ====== end  FILE #1 LINE HERE =============== */

    else

      {   /* =========== OTHER LINES HERE ================ */

        /* if we're already in a description, continue saving data */
        if (in_a_desc) save_desc();
        else                       /* if not, write junk straight out */
          fprintf(outfile,"%s",inbuf);

      }   /* ====== end  OTHER LINES HERE ================ */


    } /* end of while at TOP-OF-LOOP */

  /* === Since we dropped through,  ============== */
  /* === implies end of file found. ============== */

  if (in_a_desc) write_desc();  /* if we're in a description, write it */

  fclose(infile);
  fclose(outfile);

  printf("COPYDESC IS FINISHED.\n");
  exit (0);      /* job done, get out, errorvalue = 0 */

}  /* ------------- end of main ------------------------------- */

/* ========================================= */
/* ===  SHOWHELP                         === */
/* ========================================= */
void showhelp ()
{
  printf("\nCOPYDESC v1.02:\n");
  printf("    Copy PCBoard DIR files (descriptions) converting them to long-liners.\n");
  printf("    by Jim Robeson, 11-15-92\n\n");
  printf("USAGE:\n");
  printf("    COPYDESC drv:\path\in-file-name drv:\path\out-file-name |pos txtpos \n");
  printf("    where  1 < |pos < txtpos <= 34 \n\n");
  return;
}  /* ------------- end of showhelp --------------------------- */

/* ========================================= */
/* ===  WRITE_DESC                       === */
/* ========================================= */
void write_desc ()
{
  fprintf(outfile,"%s",outbuf);
  in_a_desc = FALSE;
  return;
}  /* ------------- end of write_desc ------------------------- */

/* ========================================= */
/* ===  SAVE_DESC                        === */
/* ========================================= */
/* this is to save all but the first card into the output buffer */
/* the first card is saved in MAIN */
/*                 ipt goes 0-n thru input line, not flexible */
/*                 opt goes 0-x thru output line, set/resets  */
/*                     according to needs                     */
/*                 linept is RELEATIVE to each OUTPUT LINE,   */
/*                     ranging from 1-78 (PCBoard max);       */
/*                     it gets reset as we fill lines.        */
/*                     When coming from line 1, linept points */
/*                     at the '\n' while opt = '\0'           */
void save_desc ()
{
  int skipping;
  int tmpipt;
  int i;
  skipping = TRUE;

  ipt = 0;
  while (inbuf[ipt] != '\0')
    {
    if (inbuf[ipt] == '\n')
       { ipt++;               /* skip over any '\n' */
         continue; }
    if (inbuf[ipt] == '|')
       { ipt++;               /* skip over any '|' */
         continue; }
    if (inbuf[ipt] == ' ' && skipping)
       { ipt++;               /* skip over leading blanks */
         continue; }
    skipping = FALSE;

    tmpipt = ipt;             /* see if there is room for a word */
    for (i=0; !(inbuf[tmpipt]==' ' || inbuf[tmpipt]=='\n' || inbuf[tmpipt]=='\0' ); tmpipt++) i++;
    if (i+linept > 79)
       { /* do newline wrap first */
       if (outbuf[opt] != '\n') outbuf[opt] = '\n';
       opt++;
       /* run out the '|' character & leading blanks */
       for (linept=1; linept<pos_mark; linept++)
         { outbuf[opt] = ' ';
           opt++;
         }
       outbuf[opt] = '|';
       opt++;
       linept++;
       for (; linept<pos_text; linept++)
         { outbuf[opt] = ' ';
           opt++;
         }
       }
       /* now stuff the word */
       for (; i >= 1; i--)               /* ++++ was >=0 */
          { outbuf[opt] = inbuf[ipt];
            ipt++;
            opt++;
            linept++;
           }
       /* now pop a blank IFF not '\n' nor '\0' */
       if (inbuf[ipt]=='\n') continue;
       if (inbuf[ipt]=='\0') continue;
       for (; inbuf[ipt]==' '; ipt++);
         outbuf[opt] = ' ';
         opt++;
         linept++;
    }
  outbuf[opt] = ' ';
  opt++;
  linept++;
  outbuf[opt] = '\n';
  opt++;
  outbuf[opt] = '\0';
  opt--;

  return;
}  /* ------------- end of save_desc -------------------------- */

/*------------- End of COPYDESC.C ------------------------------------*/
[ RETURN TO DIRECTORY ]