Removed dependency of Cygwin from hexameter.

This commit is contained in:
matsutsuka 2008-07-20 07:44:39 +00:00
parent f822ac9797
commit 6c9291f38b
23 changed files with 440 additions and 182 deletions

View file

@ -38,29 +38,24 @@
* A main file for hex2cas.
*/
#define MAX_PATH 1024
#if __CYGWIN32__
#include <windows.h>
#else
#include <stdlib.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifndef TRUE
#define TRUE 1
#endif
#include <ctype.h>
#include "ihx2bin.h"
#define MAXFILES 256
struct Configuration {
typedef struct {
char* output;
char* prefix;
char* suffix;
char* dir;
char archname[6];
char *files[MAXFILES];
unsigned int defsize;
struct ConvertDefinition defs[DEF_MAX];
unsigned char verbose;
// number of the ihx files
int length;
@ -68,9 +63,33 @@ struct Configuration {
int size;
// output file wriiten size
int written;
};
} Configuration;
static char *changeExt(const char *path, const char* ext) {
static
const char* IHXEXT = ".ihx";
static
const char *strcasestr(const char *haystack, const char *needle) {
int haypos;
int needlepos;
haypos = 0;
while (haystack[haypos]) {
if (tolower (haystack[haypos]) == tolower(needle[0])) {
needlepos = 1;
while ( (needle[needlepos]) &&
(tolower(haystack[haypos + needlepos])
== tolower(needle[needlepos])) )
++needlepos;
if (! needle[needlepos]) return (haystack + haypos);
}
++haypos;
}
return NULL;
}
static
char *changeExt(const char *path, const char* ext) {
char *p;
char *tail;
char *changed;
@ -79,7 +98,6 @@ static char *changeExt(const char *path, const char* ext) {
for (tail = (char*) path; *tail != 0; tail++);
for (p = tail; p > path; p--) {
if (*p == '.') {
len = p - path;
changed = (char*) malloc(len + extlen + 2);
@ -98,47 +116,50 @@ static char *changeExt(const char *path, const char* ext) {
return changed;
}
static unsigned char analyzeOption(int argc, char **argv, struct Configuration *config) {
static
unsigned char analyzeOption(int argc, char **argv, Configuration *config) {
int c;
char *defval;
opterr = 0;
while ((c = getopt(argc, argv, "hvo:p:s:n:b:")) != EOF) {
int i;
while ((c = getopt(argc, argv, "hvo:d:b:")) != EOF) {
switch (c) {
case 'v':
config->verbose = TRUE;
config->verbose = 1;
break;
case 'o':
config->output = optarg;
break;
case 'p':
config->prefix = optarg;
break;
case 's':
config->suffix = optarg;
break;
case 'b':
sscanf(optarg, "%x", &config->size);
break;
// case 'n':
// for (i = 0; i < 6; i++) {
// if (optarg[i] == 0) {
// break;
// }
// config->archname[i] = optarg[i];
// }
// break;
case 'd':
if (config->defsize >= DEF_MAX) {
printf("excess number of definitions\n");
return 1;
}
defval = strchr(optarg, '=');
if (defval) {
*defval = 0;
config->defs[config->defsize].name = optarg;
config->defs[config->defsize].value = defval + 1;
config->defsize++;
} else {
printf("definition value required:%s\n", optarg);
return 1;
}
break;
case 'h':
printf("%s : Convert Intel HEX file (ihx) to binary file, ver. 2.0.0\n", getprogname());
printf("Hexameter: Convert Intel HEX file (ihx) to binary file, ver. 2.1.0\n");
printf("Copyright (c) 2003-2008 Takahide Matsutsuka <markn@markn.org>\n");
printf("Usage: %s [options] <ihx> [<ihx>...]\n", argv[0]);
printf("Usage: hexameter [options] <ihx|bin> [<ihx|bin>...]\n");
printf("Options:\n");
printf(" -v verbose output\n");
printf(" -o <output file name>\n");
// printf(" -n <cassette file name> (for NEC PC series)\n");
printf(" -p <prefix file>\n");
printf(" -s <suffix file>\n");
printf(" -d <name>=<value> define property\n");
printf(" -b <output file size in hexadecimal bytes>\n");
printf(" -h print this help\n");
printf(" -h show this help\n");
return 1;
default:
@ -150,7 +171,9 @@ static unsigned char analyzeOption(int argc, char **argv, struct Configuration *
return 0;
}
static int isFileExists(const char *dir, const char *filename) {
#if 0
static
int isFileExists(const char *dir, const char *filename) {
char path[MAX_PATH];
FILE *f;
@ -171,19 +194,25 @@ static int isFileExists(const char *dir, const char *filename) {
return 0;
}
#endif
/**
* @return 1 if given filename has an extension of ".ihx"
*/
static
int isIhx(const char *filename) {
const char* pos = strcasestr(filename, IHXEXT);
if (pos && pos[strlen(IHXEXT)] == 0) {
return 1;
}
return 0;
}
static int checkExistence(struct Configuration *config) {
static
int checkExistence(Configuration *config) {
int i;
int r;
FILE *f;
fclose(f);
if (r = isFileExists(config->dir, config->prefix)) {
return r;
}
if (r = isFileExists(config->dir, config->suffix)) {
return r;
}
for (i = 0; i < config->length; i++) {
f = fopen(config->files[i], "r");
if (!f) {
@ -201,7 +230,7 @@ static int checkExistence(struct Configuration *config) {
static
int copy(FILE *out, const char* dir, const char* filename, unsigned char verbose) {
FILE *in;
char ch;
int ch;
char path[MAX_PATH];
int bytes = 0;
if (!filename) {
@ -213,31 +242,42 @@ int copy(FILE *out, const char* dir, const char* filename, unsigned char verbose
} else {
strcpy(path, filename);
}
if (verbose) {
printf("importing file: %s\n", path);
}
in = fopen(path, "rb");
while ((ch = getc(in)) != EOF) {
putc(ch, out);
bytes++;
}
fclose(in);
if (verbose) {
printf("imported file: %s, size=%d\n", path, bytes);
}
return bytes;
}
static int output(struct Configuration *config) {
static
int output(Configuration *config) {
FILE *out;
int i;
// TODO: ARCH FILE NAME
if (!(out = fopen(config->output, "wb"))) {
printf("cannot open output file:%s\n", config->output);
return 1;
}
config->written += copy(out, config->dir, config->prefix, config->verbose);
for (i = 0; i < config->length; i++) {
config->written += ihx2bin(out, config->files[i], config->verbose);
struct ConvertInfo info;
info.out = out;
info.filename = config->files[i];
info.verbose = config->verbose;
info.defsize = config->defsize;
info.defs = config->defs;
if (isIhx(config->files[i])) {
config->written += ihx2bin(&info);
} else {
config->written += copy(out, NULL, config->files[i], config->verbose);
}
}
config->written += copy(out, config->dir, config->suffix, config->verbose);
if (config->size) {
if (config->verbose) {
@ -254,27 +294,14 @@ static int output(struct Configuration *config) {
int main(int argc, char **argv) {
struct Configuration config;
Configuration config;
unsigned char r;
memset(&config, 0, sizeof(struct Configuration));
#if __CYGWIN32__
char path[MAX_PATH];
GetModuleFileName(NULL, path, MAX_PATH);
int len = strlen(path);
while (len > 0) {
if (path[len] == '\\') {
path[len + 1] = 0;
break;
}
len--;
}
config.dir = path;
#endif
memset(&config, 0, sizeof(Configuration));
while (optind < argc) {
if (r = analyzeOption(argc, argv, &config)) {
r = analyzeOption(argc, argv, &config);
if (r) {
return r;
}
if (optind == argc) {
@ -298,13 +325,15 @@ int main(int argc, char **argv) {
config.output = changeExt(config.files[0], "bin");
}
if (r = checkExistence(&config)) {
r = checkExistence(&config);
if (r) {
return r;
}
if (config.verbose) {
printf("Generating file: %s\n", config.output);
}
if (r = output(&config)) {
r = output(&config);
if (r) {
return r;
}

View file

@ -35,19 +35,41 @@
*/
/*
* Intel HEX format to PC-6001 CAS format conversion utility.
* Intel HEX format (extended) to binary format conversion utility.
*/
#include <stdio.h>
#include <string.h>
#include "ihx2bin.h"
#define TYPE_DATA 0
#define TYPE_END 1
#define TYPE_STRING 2
#define TYPE_BYTE 3
#define TYPE_WORD 4
#define MEMORY_SIZE 0x10000
typedef struct {
unsigned int start;
unsigned int end;
unsigned char buffer[MEMORY_SIZE];
// current line
int type;
unsigned int address;
unsigned int length;
} Memory;
static
const char NAME_CHARS[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_";
/**
* Convert a character to a value.
* @param ch a character to convert
* @return integer value represents the given character
*/
static int aton(const unsigned char ch) {
int n;
static
int aton(const unsigned char ch) {
if (ch >= '0' && ch <= '9') {
return ch - '0';
}
@ -66,19 +88,95 @@ static int aton(const unsigned char ch) {
* @param in file
* @return -1 if EOF
*/
static int getByte(FILE *in) {
static
int getByte(FILE *in) {
int ch1, ch2;
ch1 = getc(in);
if (ch1 == EOF) {
if (feof(in)) {
printf("eof");
return -1;
}
ch2 = getc(in);
if (ch2 == EOF) {
ch1 = fgetc(in);
if (feof(in)) {
printf("eof");
return -1;
}
ch2 = fgetc(in);
return 16 * aton(ch1) + aton(ch2);
}
/**
* @return non-zero if error
*/
static
void replace(FILE* in, struct ConvertInfo *info, Memory *memory) {
int i, j;
char name[DEF_NAMELEN];
int len = 0;
// read name
while (len < DEF_NAMELEN - 1) {
char ch = fgetc(in);
if (!strchr(NAME_CHARS, ch)) {
break;
}
name[len] = ch;
len++;
}
name[len] = 0;
for (i = 0; i < info->defsize; i++) {
if (!strcmp(name, info->defs[i].name)) {
int tmp;
char value[DEF_VALUELEN];
// replace!
switch (memory->type) {
case TYPE_STRING:
for (j = 0; j < memory->length; j++) {
memory->buffer[memory->address] = value[j] = info->defs[i].value[j];
memory->address++;
}
value[j] = 0;
if (info->verbose) {
printf("[%s]->[%s], ", name, value);
}
break;
case TYPE_BYTE:
tmp = 0;
for (j = 0; j < 2; j++) {
if (aton(info->defs[i].value[j])) {
tmp = tmp * 16 + aton(info->defs[i].value[j]);
}
}
memory->buffer[memory->address] = tmp;
if (info->verbose) {
printf("[%s]->[%02x], ", name, tmp);
}
break;
case TYPE_WORD:
tmp = 0;
for (j = 0; j < 2; j++) {
tmp = tmp * 16 + aton(info->defs[i].value[j]);
}
memory->buffer[memory->address + 1] = tmp;
tmp = 0;
for (j = 2; j < 4; j++) {
tmp = tmp * 16 + aton(info->defs[i].value[j]);
}
memory->buffer[memory->address] = tmp;
if (info->verbose) {
printf("[%s]->[%02x%02x], ", name,
memory->buffer[memory->address + 1],
memory->buffer[memory->address]);
}
break;
}
break;
}
}
}
/**
* Extract a 64kB memory map from given file.
* IHEX format is as follows:
@ -86,6 +184,7 @@ static int getByte(FILE *in) {
* A_ : size of this chunk
* B___: address (big endian)
* C_ : record type (00: notmal data, 01: end)
* extension: 02: char, 03: byte(hex), 04: word(hex, little-endian)
* D_....D_: data
* E_ : check sum
* :0DCCCF00673008D620D607D63013C937C904
@ -95,68 +194,71 @@ static int getByte(FILE *in) {
* @param end pointer to end address
* @return 0 if noerror, otherwise if error
*/
static int ihx2mem(const char *inFilename, unsigned char *buffer, unsigned int *start, unsigned int *end) {
static
int ihx2mem(struct ConvertInfo *info, Memory *memory) {
FILE *in;
*start = 0xffff;
*end = 0;
memory->start = MEMORY_SIZE - 1;
memory->end = 0;
in = fopen(inFilename, "rb");
in = fopen(info->filename, "rb");
if (in == NULL) {
printf("cannot open input file\n");
return 1;
}
while(1) {
int ch;
int length;
unsigned int address;
int tmp;
// skip checksum and cr/lf
while ((ch = getc(in)) != ':') {
if (ch == EOF) {
while (!feof(in)) {
if (fgetc(in) == ':') {
break;
}
}
if (ch == EOF) {
if (feof(in)) {
break;
}
// get length of this chunk
length = getByte(in);
if (length <= 0) {
// TODO: end of bytes, retrieve variables
if ((memory->length = getByte(in)) < 0) {
break;
}
// make an address
tmp = getByte(in);
if (tmp < 0) {
if ((tmp = getByte(in)) < 0) {
break;
}
address = tmp * 256;
tmp = getByte(in);
if (tmp < 0) {
memory->address = tmp * 256;
if ((tmp = getByte(in)) < 0) {
break;
}
address += tmp;
if (*start > address) {
*start = address;
}
memory->address += tmp;
if (*end < (address + length)) {
*end = address + length;
}
// ignore record type
if (getByte(in) < 0) {
// process record type
if ((memory->type = getByte(in)) < 0) {
break;
}
while (length > 0) {
buffer[address] = getByte(in);
address++;
length--;
if (memory->type != TYPE_END) {
// modify start and end
if (memory->start > memory->address) {
memory->start = memory->address;
}
if (memory->end < (memory->address + memory->length)) {
memory->end = memory->address + memory->length;
}
}
if (memory->type == TYPE_DATA) {
while (memory->length > 0) {
memory->buffer[memory->address] = getByte(in);
memory->address++;
memory->length--;
}
} else if (memory->type == TYPE_STRING
|| memory->type == TYPE_BYTE
|| memory->type == TYPE_WORD) {
replace(in, info, memory);
}
}
@ -167,24 +269,28 @@ static int ihx2mem(const char *inFilename, unsigned char *buffer, unsigned int *
/**
* @return written size
*/
int ihx2bin(FILE* dst, const char *src, unsigned char verbose) {
unsigned int start, end;
unsigned char buffer[65536];
int ihx2bin(struct ConvertInfo *info) {
Memory memory;
unsigned int i;
memset(buffer, 0, 65536);
memset(&memory, 0, sizeof(Memory));
if (ihx2mem(src, buffer, &start, &end)) {
printf("cannot open input file: %s\n", src);
if (info->verbose) {
printf("importing ihx: %s, ", info->filename);
}
if (ihx2mem(info, &memory)) {
printf("cannot open input file: %s\n", info->filename);
return 0;
}
if (verbose) {
printf("importing ihx : %s (%04x:%04x)\n", src, start, end);
}
for (i = start; i < end; i++) {
putc(buffer[i], dst);
if (info->verbose) {
printf("(%04x:%04x)\n", memory.start, memory.end);
}
return (end - start);
for (i = memory.start; i < memory.end; i++) {
putc(memory.buffer[i], info->out);
}
return (memory.end - memory.start);
}

View file

@ -27,7 +27,7 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: ihx2bin.h,v 1.1 2008/07/02 07:17:14 matsutsuka Exp $
* $Id: ihx2bin.h,v 1.2 2008/07/20 07:44:39 matsutsuka Exp $
*
*/
@ -39,9 +39,27 @@
#ifndef __IHX2BIN_H__
#define __IHX2BIN_H__
#define DEF_MAX 1024
#define DEF_NAMELEN 256
#define DEF_VALUELEN 256
struct ConvertDefinition {
char *name;
char *value;
};
struct ConvertInfo {
FILE* out;
char* filename;
unsigned char verbose;
unsigned int defsize;
struct ConvertDefinition *defs;
};
/* A default architecture-depend file name. */
#define DEFAULT_ARCH_FILENAME "noname"
int ihx2bin(FILE* dst, const char *src, unsigned char verbose);
// int ihx2bin(FILE* dst, const char *src, unsigned char verbose);
int ihx2bin(struct ConvertInfo* info);
#endif /* __IHX2BIN_H__ */