/*
**
** expand -- Expand tabs in a file to fixed tab stops of regular 
**           spacing.  The spacing, tab character, and fill character
**           are arguments with standard defaults.
**
**  Copyright (C) 1987 By Robert G. Arsenault
**
**  This software is provided "as-is" and carries with it no explicit or
**  implicit promise of support by the author. Nor will the author be 
**  held liable for any damages, real or imagined, which may result 
**  from the use or abuse of this software.
**
**  The author grants permission for the non-commercial distribution of 
**  this software provided that this and other identifying information 
**  remains intact.
**
** Useage:  expand [-s#] [-t#] [-f#] Input Output, where
**          -s# : Specifies a new tab size.  The default is 8 characters.
**                The new tab size must be greater than zero.
**          -t# : Specifies a new character to be expanded rather than
**                the horizontal tab character.
**          -f# : Specifies a new fill character which will be used
**                in replacing all tabs within the input file.
**           Input : File which may (or may not) contain tabs.
**           Output : File which must not already exist.  This file will
**                    be created and will contain a copy of the input
**                    with all occurances of tabs expanded using the fill 
**                    character.
*/

#include <stdio.h>
#include <exec/types.h>
#include <libraries/dosextens.h>

#define LSIZE 256
#define FSIZE 64

#define NL  '\n'
#define DEF_TAB '\t'
#define DEF_SIZE 8
#define DEF_FILL ' '

main(argc,argv)
int argc;
char *argv[];
{
   struct  FileHandle   *hand, *Open();
   struct  FileHandle   *tmp_hand, *Lock();

   FILE    *fpr, *fpw, *fopen();
   char    line[LSIZE], input[FSIZE+1], output[FSIZE+1];
   SHORT   temp = 0;

   register char   *c, tab_char = DEF_TAB, tab_fill = DEF_FILL;
   register SHORT   tab_size = DEF_SIZE, pos, i;

   /* process arguments */
   *input = *output = NULL;
   while (argc > 1) {
      --argc;
      if (argv[argc][0] == '-') {
         switch (argv[argc][1]) {
            case 's' : tab_size = atoi (argv[argc]+2);
                       break;
            case 'e' : tab_char = argv[argc][2];
                       break;
            case 'f' : tab_fill = argv[argc][2];
                       break;
            default:   temp = 1;
         }
      } else if (argv[argc][0] == '?') {
         temp = 1;
      } else if (!(*output)) {
         strncpy (output, argv[argc], FSIZE);
      } else if (!(*input)) {
         strncpy (input, argv[argc], FSIZE);
      } else
         temp = 1;
   }

   if (temp || !(*input) || !(*output)) {
      hand = Open ("*",MODE_OLDFILE);
      if (hand) {
       	Write (hand, "Useage: expand [-[3ms#[0m] [-[3me#[0m] [-[3mf#[0m] [3mInput Output[0m, where\n\n", 87);
       	Write (hand, "       -[3ms#[0m Tab size used for expansion will be #        (default is 8)\n", 80);
       	Write (hand, "       -[3me#[0m The tab character to be expanded will be #   (default is CNTRL-I)\n", 85);
       	Write (hand, "       -[3mf#[0m Fill character used in expansion will be #   (default is BLANK)\n\n", 84);
      	Write (hand, "       [3mInput[0m  - Unexpanded input file (with tabs)\n       [3mOutput[0m - Expanded file\n", 96);
         Close (hand);
      }
      exit(1);
   }

   if (tab_size <= 0) {
      hand = Open ("*",MODE_OLDFILE);
      if (hand) {
         Write (hand, "expand: Tab size must be greater than zero.\n        Input was zero, negative, or invalid.\n", 90);
         Close (hand);
      }
      exit(1);
   }

   if (tmp_hand = Lock (output, ACCESS_READ)) {
      UnLock (tmp_hand);
      hand = Open ("*",MODE_OLDFILE);
      if (hand) {
         Write (hand, "expand: Output file \"",21);
         Write (hand, output, strlen(output));
         Write (hand, "\" can not already exist.\n",25);
         Close (hand);
      }
      exit(1);
   }

   if (!(fpr = fopen(input, "r"))) {
      hand = Open ("*",MODE_OLDFILE);
      if (hand) {
         Write (hand, "expand: Input file \"",20);
         Write (hand, input, strlen(input));
         Write (hand, "\" can not be opened for reading.\n",33);
         Close (hand);
      }
      exit(1);
   }

   if (!(fpw = fopen(output, "w"))) {
      fclose (fpr);
      hand = Open ("*",MODE_OLDFILE);
      if (hand) {
         Write (hand, "expand: Output file \"",21);
         Write (hand, output, strlen(output));
         Write (hand, "\" can not be opened for writing.\n",33);
         Close (hand);
      }
      exit(1);
   }

   while (fgets (line, LSIZE, fpr)) {
      for (pos = 0, c = line; *c ; ++c)
         if (*c != tab_char) {
            fputc (*c, fpw);
            ++pos;
         } else {
            /* tab char */
            for (i = temp = tab_size - (pos % tab_size); i > 0 ; --i) {
               fputc (tab_fill, fpw);
            }
            pos += temp;
         }
   }

   fclose (fpr);
   fflush (fpw);
   fclose (fpw);
}
