#include <stdio.h>
#include <ctype.h>
#include <midi.h>

FILE *sopen();

/*
** AXTOBB/BBTOAX -- Convert ascii hex to binary bytes or vice-versa
**	psl 6/87
*/
main(argc,argv)
char *argv[];
{
	char *cp, *np;
	int i;
	FILE *fp;

	for (cp = np = argv[0]; *cp; )
	    if (*cp++ == '/')
		np = cp;
	fp = (FILE *) 0;
	for (i = 1; i < argc; i++) {
	    if (fp = sopen(argv[i], "r")) {
		if (*np == 'a')
		    atob(fp, stdout);
		else
		    btoa(fp, stdout);
		sclose(fp);
	    } else {
		fprintf(stderr, "%s: ", argv[0]);
		perror(argv[i]);
		fp = (FILE *) -1;
	    }
	}
	if (fp == (FILE *) 0) {
	    if (*np == 'a')
		atob(stdin,stdout);
	    else
		btoa(stdin,stdout);
	}
}

#define	ISHEX(x) \
	(('0'<=(x)&&(x)<='9')||('A'<=(x)&&(x)<='F')||('a'<=(x)&&(x)<='f'))
#define	HEXOF(x)	((x)<='9'?(x)-'0':((x)<'G'?0xA+(x)-'A':0xa+(x)-'a'))

/*
** Read ascii hex numbers from ifp and write binary bytes to ofp.
** The ascii hex format DOES NOT include '0x'; it's simply 2-digit hex.
** Only the characters 0-9, a-b, A-B, <SP>, <TAB>, <LF>, and ';' are legal.
** All characters on a line following a ';' are ignored.
*/
atob(ifp, ofp)
FILE *ifp, *ofp;
{
	char *cp, buf[512];
	int digits, value;

	while (fgets(buf, sizeof buf, ifp)) {
	    digits = value = 0;
	    for (cp = buf; *cp; cp++) {
		if (ISHEX(*cp)) {
		    digits++;
		    value = value * 16 + HEXOF(*cp);
		} else {
		    if (*cp <= ' ' || *cp == ';') {
			if (digits) {
			    putc(value, ofp);
			    digits = value = 0;
			}
			if (*cp == ';')
			    break;
		    }
		}
	    }
	}
}

/*
** Read binary bytes from ifp and write ascii hex numbers to ofp.
** The ascii hex format DOES NOT include '0x'; it's simply 2-digit hex.
** Numbers are separated by a single space and 16 are put on each line.
*/
btoa(ifp, ofp)
FILE *ifp, *ofp;
{
	int c, i;

	for (i = 1; (c = getc(ifp)) != EOF; i++)
	    fprintf(ofp,"%02x%s", c & 0xff, (i & 0xF)? " " : "\n");
	if ((i & 0xF) != 1)
	    fprintf(ofp, "\n");
}
