DESC: A C version of the ASC-> decoder.  Works on any machine with C.
Article 1430 of comp.sys.handhelds:
Path: csn!ncar!elroy.jpl.nasa.gov!sdd.hp.com!hp-pcd!hpcvra.cv.hp.com!rnews!hpcvbbs!akcs.wilsonpm
From: akcs.wilsonpm@hpcvbbs.UUCP (Pete M. Wilson)
Newsgroups: comp.sys.handhelds
Subject: Re: ASC-> for UNIX
Message-ID: <2798e77c:1547.1comp.sys.handhelds;1@hpcvbbs.UUCP>
Date: 20 Jan 91 01:40:06 GMT
References: <1990Dec31.080317.12174@csn.org>
Lines: 267

This is my C version of ASC->.  It was written on a PC & compiled with
Microsoft C & Turbo C++.  I used ANSI C functions (mostly). I hope it
will help you.
                       Pete
P.S. If I can get it uploaded!
# additional notes.  May have to edit section on strerror as some machines
# don't understand.  I changed to stderr.. Crude but it works.
------------------------------CUT HERE--------------------------------
 
    This programs reads an up to 127K ASCII (RPL) file consisting of a
string
    intended for ASC-> and converts it into a binary object file.
 
    This program was compiled with Microsoft C 5.1 and Turbo C. ANSI C
    conventions are mostly followed.
 
 
    The original algorithm for CRC computation was extracted from
    Li Sheng's posting to comp.sys.handhelds.
 
    01/19/91 PMW  created
*/
 
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
 
#define MAX_READ_SIZE 127
 
 
 
#if !defined(FILENAME_MAX)
#define FILENAME_MAX 65
#endif
 
#if !defined(EXIT_FAILURE)
#define EXIT_FAILURE 1
#endif
 
#if !defined(EXIT_SUCCESS)
#define EXIT_SUCCESS 0
#endif
 
#define HEX2INT(hc) ((unsigned int) (isdigit(hc) ? (hc)-'0' :
(hc)-'A'+10))
 
int FileExists(char *f)
{
    FILE *tf;
 
    if ((tf = fopen(f, "rb")) != NULL) {
        fclose(tf);
        return 1;
    }
    else
        return 0;
}
 
long FileSize(FILE *f)
{
    long origPos = ftell(f), fileSize = 0;
 
    fseek(f, 0L, SEEK_END);
    fileSize = ftell(f);
    fseek(f, origPos, SEEK_SET);
 
    return fileSize;
}
 
 
typedef unsigned char BYTE;
typedef unsigned int WORD;
 
#define CALC_CRC(c, i) (((((c)^(i)) & 0xF) * 0x1081) ^ ((c) >> 4))
 
WORD crcBlock(BYTE *mb, size_t len)
{
    WORD crc = 0, bObjSize = len/2;
 
    while (bObjSize--) {
        crc = CALC_CRC(crc, (WORD) (*mb) & 0xF);
        crc = CALC_CRC(crc, (WORD) ((*mb) >> 4));
        ++mb;
    }
    if (len & 1)
        crc = CALC_CRC(crc, (WORD) (*mb) & 0xF);
 
    return crc;
}
 
 
void CopyLine(BYTE **mb, char **s, WORD *objSize)
{
    char *ts = *s;
    BYTE *tmb = *mb;
    WORD ls = 0;
 
    while (isxdigit(ts[0]) && isxdigit(ts[1])) {
        *tmb++ = (BYTE) (HEX2INT(ts[0]) + (HEX2INT(ts[1]) << 4));
        ls += 2;
        ts += 2;
    }
 
    if (isxdigit(ts[0]) && ts[1] == '"') {
        /* we ended on a nibble boundary!! */
        BYTE crc1, crc2;
 
        /* correct crc by nibble shifting end */
        crc2 = (BYTE) ((tmb[-1] >> 4) + (HEX2INT(ts[0]) << 4));
        crc1 = (BYTE) ((tmb[-2] >> 4) + ((tmb[-1] & 0xF) << 4));
 
        /* fix memory buffer */
        tmb[-2] &= 0xf;
        tmb[-1] = crc1;
        *tmb++ = crc2;
        ++ls;
        ++ts;
    }
 
    *s = ts;
    *mb = tmb;
    *objSize += ls;
}
 
 
#define READLN(s, f) fgets((s), sizeof(s), (f))
 
void ReadFile(char *filepath, BYTE **mb, WORD *objSize)
{
    FILE *infile;
    char lineBuf[250], *p;
    WORD bufSize;
    long fileSize;
    BYTE *wmb;
 
    if (!strchr(filepath, '.'))
        strcat(filepath, ".rpl");
 
    if (!(infile = fopen(filepath, "r"))) {
        fprintf(stderr, "asc2bin:  can't open %s\n", filepath);
        exit(EXIT_FAILURE);
    }
 
    fileSize = FileSize(infile);
    if (fileSize > MAX_READ_SIZE*1024L) {
        fprintf(stderr, "asc2bin: File %s is too long\n", filepath);
        exit(EXIT_FAILURE);
    }
    bufSize = 4+(WORD) (fileSize / 2);  /* approximate byte size of
object */
    if (!(*mb = (BYTE *) malloc(bufSize))) {
        fprintf(stderr, "asc2bin:  Unable to allocate %u bytes\n",
bufSize);
        exit(EXIT_FAILURE);
    }
    wmb = *mb;
 
    /* find string */
    while (!feof(infile)) {
        if (!READLN(lineBuf, infile)) {
            if (feof(infile))
                fputs("asc2bin:  Unable to locate string\n", stderr);
            else
                fprintf(stderr, "asc2bin:  Read error: %s\n",
                    strerror(errno));
 
            fclose(infile);
            exit(EXIT_FAILURE);
        }
 
        if (*lineBuf == '"')
            break;
    }
 
    *objSize = 0;
 
    /* put string into buffer */
    p = &lineBuf[1];  /* skip opening quote */
    CopyLine(&wmb, &p, objSize);
 
    /* copy remainder into buffer */
    while (*p != '"' && !feof(infile)) {
        if (!READLN(lineBuf, infile)) {
            if (feof(infile))
                fputs("asc2bin:  Unable to locate closing quote\n",
stderr);
            else
                fprintf(stderr, "asc2bin:  Read error: %s\n",
                    strerror(errno));
 
            fclose(infile);
            exit(EXIT_FAILURE);
        }
 
        p = lineBuf;
        CopyLine(&wmb, &p, objSize);
    }
 
    fclose(infile);
}
 
void WriteFile(char *filepath, BYTE *mb, WORD objSize)
{
    FILE *outfile;
    char *extpos = strchr(filepath, '.');
 
    strcpy(extpos+1, "bin");
 
    if (FileExists(filepath)) {
        fprintf(stderr, "asc2bin:  file already exists: %s\n", filepath);
        exit(EXIT_FAILURE);
    }
 
    if (!(outfile = fopen(filepath, "wb"))) {
        fprintf(stderr, "asc2bin:  unable to create %s\n", filepath);
        exit(EXIT_FAILURE);
    }
 
    fputs("HPHP48-B", outfile);  /* my own version */
    while (objSize--)
        fputc(*mb++, outfile);
 
    fclose(outfile);
}
 
 
main(int argc,  char *argv[])
{
    char filepath[FILENAME_MAX];
    BYTE *mb;
    WORD objSize, rcrc, crc,bObjSize;  /*  NOTE: objSize is in nibbles!
*/
 
    if (argc < 2) {
        fputs("usage:  asc2bin infile[.ext]\n", stderr);
        fputs("\treads infile.ext and creates infile.bin\n", stderr);
        fputs("\tif omitted, .ext is assumed to be .rpl\n", stderr);
        exit(EXIT_FAILURE);
    }
 
    strcpy(filepath, argv[1]);
 
    ReadFile(filepath, &mb, &objSize);
    if (objSize < 2) {
        fputs("asc2bin: String too short to include crc\n", stderr);
        exit(EXIT_FAILURE);
    }
 
    objSize -= 4;  /* nibbles */
    bObjSize = objSize / 2 + (objSize & 1);
    rcrc = (WORD) mb[bObjSize] + ((WORD) mb[bObjSize+1] << 8);
 
    crc = crcBlock(mb, objSize);
    if (crc != rcrc) {
        fprintf(stderr,
            "asc2bin: Calculated CRC # %Xh does not match read CRC #
%Xh\n",
            crc, rcrc);
        exit(EXIT_FAILURE);
    }
 
    WriteFile(filepath, mb, bObjSize);
 
    return EXIT_SUCCESS;
}
------------------------------CUT HERE--------------------------------
NOTE:  I forgot that some of my lines would wrap because of the line
number - The code will need to be cleaned up.  I'll upload the source & a
self-unzipping PC archive (with executable) in user.programs.


