/*************************************************************************
 ***                            TOA.C                    (JJB TEMPLAR) ***
 *** Date begun: 24/5/89.                                              ***
 *** Last modified: 24/5/89.                                           ***
 ***                3/8/89 - optimization pass.                        ***
 *************************************************************************/
/*** This is a newer verion of my old toascii program. Functionally    ***
 *** similar but structurally different.                               ***
 *************************************************************************/

#include <exec/types.h>
#include <proto/dos.h>
#include <string.h>
#include "tabort.h"

#define NULL        0L
#define charOK(x)   ((x > 31) && (x < 123))

BPTR    file;
char    *fname;
int     width = 76;

#define USAGESIZE   9
char    *usage[USAGESIZE] = {
"[32mToa1.1: ",__DATE__," - [42m[33m JJB TEMPLAR [40m - a binary to ascii converter.[0m\n",
"[32mUSAGE: [0m",NULL," [-w{num}] {file}\n",
"    where num = output line width (def:76).\n",
"          file = input filename.\n",
"[32mNOTE: [0m[] = optional, <> = 1 or more, {} = mandatory.\n"
};

void    printf(char *);
void    doopts(int,char **);
int     getint(char *);
void    cleanup(int,char *,int);
void    fbreak();

void    printf(cp) /*====================================================*/
register char *cp;
{
    Write(Output(),cp,strlen(cp));
}

void    doopts(argc,argv) /*=============================================*/
register int argc;
char    *argv[];
{
register int    j;
    if (argc < 2) XCEXIT(0);        /* Exit if from WB or no args */
    while (--argc) {
        switch (argv[argc][0]) {
            case ('?'): usage[4] = argv[0];
                        for (j = 0; j < USAGESIZE; j++) printf(usage[j]);
                        cleanup(0,NULL,0);
            case ('-'): if (argv[argc][1] == 'w') width = getint(&argv[argc][2]);
                        break;      /* other - options ignored */
            default:    fname = argv[argc];
        }
    }
}

int     getint(cp) /*====================================================*/
register char   *cp;
{
register char   *st = cp;
register int    ret,place;
  /** Don't use ctype, so don't pull in flag table **/
  /** Don't swallow whitespace -----------------------------
    while (*st == ' ') *st++;
    cp = st;
   --------------------------------------------------------- ***/
    while ((*cp >= '0') && (*cp <= '9')) *cp++;
    ret = 0;    place = 1;
    while (--cp >= st) {
        ret += (*cp - '0') * place;
        place *= 10;
    }
    return(ret);
}

void    main(argc,argv) /*===============================================*/
int     argc;
char    *argv[];
{
char    line[128];
register int    j,len;
register char   *cp;

    doopts(argc,argv);

    if (!fname) cleanup(0,"ERROR: no filename!\n",20);
    if (width > 127) width = 127;   /* So don't kill stack */
    else if (width < 5) width = 5;  /* Avoid infinite loop */

    if (!(file = Open(fname,MODE_OLDFILE)))
        cleanup(0,"ERROR: failed to open file!\n",20);

    while (len = Read(file,line,width)) {
        if (len == -1) cleanup(1,"ERROR: reading file!\n",20);
        line[len] = '\n';   line[len+1] = 0;
        cp = line;
        for (j = 0; j < len; j++,cp++) if (!charOK(*cp)) *cp = '.';
        printf(line);
        tabort((APTR)fbreak);
    }
    Close(file);
    XCEXIT(0);
}

void    cleanup(bra,cp,r) /*=============================================*/
register int    bra;
register char   *cp;
register int    r;
{
    if (bra) Close(file);
    if (cp) printf(cp);
    XCEXIT(r);
}

void    fbreak() /*======================================================*/
{
    cleanup(1,"[33mBREAK SIGNAL DETECTED[0m\n",0);
}
