/***********************************************************************
*
* bd - BCD Dump of file.
*
* Changes:
*   01/20/05   DGP   Original.
*	
***********************************************************************/

#include <stdio.h>
#include <string.h>

#include "nativebcd.h"

#define MAXRECSIZE 196610 /* The size of a tape record */

static int recmode;
static int recnum;
static int filenum;
static int altchars;

/***********************************************************************
* octdump - Octal dump routine.
***********************************************************************/

static void
octdump(FILE *file, void *ptr, int size,int offset)
{
   int jjj;
   int iii;
   int dmpmax;
   unsigned char *tp;
   unsigned char *cp;

   tp = (unsigned char *)ptr;
   cp = (unsigned char *)ptr;

   if (recmode) dmpmax = 9;
   else dmpmax = 4;
   for (iii = 0; iii < (size);)
   {
      fprintf (file, "%08o  ", iii+offset);

      for (jjj = 0; jjj < dmpmax; jjj++)
      {
	 if (recmode)
	 {
	    if (cp < ((unsigned char *)ptr+size))
	    {
	       fprintf (file, "%02o", *cp++ & 077);
	       iii ++;
	       if (cp < ((unsigned char *)ptr+size))
	       {
		  fprintf (file, "%02o", *cp++ & 077);
		  iii ++;
	       }
	       else 
		  fprintf (file, "  ");
	    }
	    else 
	       fprintf (file, "    ");
	 }
	 else
	 {
	    fprintf (file, "%03.3o ", *cp++);
	    fprintf (file, "%03.3o ", *cp++);
	    fprintf (file, " ");
	    iii += 2;
	 }
      }
      fprintf ((file), "   ");
      for (jjj = 0; jjj < dmpmax; jjj++)
      {
	 if (recmode)
	 {
	    if (tp < ((unsigned char *)ptr+size))
	    {
	       if (altchars)
		  fprintf (file, "%c", toaltnative[*tp++ & 077]);
	       else
		  fprintf (file, "%c", tonative[*tp++ & 077]);
	       if (tp < ((unsigned char *)ptr+size))
	       {
		  if (altchars)
		     fprintf (file, "%c", toaltnative[*tp++ & 077]);
		  else
		     fprintf (file, "%c", tonative[*tp++ & 077]);
	       }
	       else 
		  fprintf (file, " ");
	    }
	    else 
	       fprintf (file, "  ");
	 }
	 else
	 {
	    if (altchars)
	    {
	       fprintf (file, "%c", toaltnative[*tp++ & 077]);
	       fprintf (file, "%c", toaltnative[*tp++ & 077]);
	    }
	    else
	    {
	       fprintf (file, "%c ", tonative[*tp++ & 077]);
	       fprintf (file, "%c ", tonative[*tp++ & 077]);
	    }
	    fprintf (file, " ");
	 }
      }
      fprintf ((file), "\n");
   }
}


/***********************************************************************
* main - Main procedure.
***********************************************************************/

int
main (int argc, char **argv)
{
   FILE *fd;
   char *bp;
   char *file;
   int i;
   int size;
   int org;
   int ch;
   char tape[MAXRECSIZE];

   /*
   ** Process arguments and file.
   */

   file = NULL;
   recmode = 0;
   altchars = 0;
   recnum = 0;
   filenum = 0;

   for (i = 1; i < argc; i++)
   {
      bp = argv[i];
      if (*bp == '-')
      {
	 bp++;
         switch (*bp)
	 {
	 case 'a':
	    altchars = 1;
	    break;
	 case 'r':
	    recmode = 1;
	    break;
	 default:
      usage:
	    fprintf (stderr, "usage: bd [options] file\n");
	    fprintf (stderr, " options:\n");
	    fprintf (stderr, "    -r           - Process Records\n");
	    exit (1);
	 }
      }
      else
      {
	 if (file) goto usage;
	 file = bp;
      }
   }

   if (!file) goto usage;

   /*
   ** Open input file.
   */

   if ((fd = fopen (file, "r")) == NULL)
   {
      perror ("Can't open");
      exit (1);
   }

   /*
   ** Dump the file.
   */

   size = 0;
   org = 0;
   printf ("Dump of %s:\n", file);
   memset (tape, '\0', sizeof(tape));
   while ((ch = fgetc (fd)) != EOF)
   {
      if (recmode)
      {
         if (ch & 0200 || ch == 072)
	 {
	    if (size)
	    {
	       printf ("File %d record %d:\n", filenum, ++recnum);
	       octdump (stdout, tape, size, org);
	       memset (tape, '\0', sizeof(tape));
	       org = 0;
	       size = 0;
	       if (ch == 0217)
	       {
		  printf ("File %d EOF\n", filenum++);
		  recnum = 0;
	       }
	       else
		  tape[size++] = ch & 0xFF;
	    }
	    else 
	       tape[size++] = ch & 0xFF;
	 }
	 else
	    tape[size++] = ch & 0xFF;
      }

      else
      {
	 tape[size++] = ch & 0xFF;
	 if (size == MAXRECSIZE)
	 {
	    octdump (stdout, tape, size, org);
	    memset (tape, '\0', sizeof(tape));
	    org += MAXRECSIZE;
	    size = 0;
	 }
      }
   }
   if (size)
   {
      if (recmode)
	    printf ("File %d record %d:\n", filenum, recnum++);
      octdump (stdout, tape, size, org);
   }


   fclose (fd);
   return (0);
   
}
