diff options
| author | Keith Packard <keithp@keithp.com> | 2009-08-18 12:40:24 -0700 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2009-08-18 12:40:24 -0700 | 
| commit | 9789ca5e8caa9a013e804f307b9da380e147bd75 (patch) | |
| tree | 0bba9fdba9d761d0ead763ab593bc51d1658a693 /cctools/lib/ccdbg-hex.c | |
| parent | a5782398d968e7cb11f7203afada7c216f233b3b (diff) | |
Rename tools to ao-<foo>
Use a consistent prefix to make it easier to remember which programs
belong to this package
Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'cctools/lib/ccdbg-hex.c')
| -rw-r--r-- | cctools/lib/ccdbg-hex.c | 330 | 
1 files changed, 0 insertions, 330 deletions
| diff --git a/cctools/lib/ccdbg-hex.c b/cctools/lib/ccdbg-hex.c deleted file mode 100644 index dfea9156..00000000 --- a/cctools/lib/ccdbg-hex.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright © 2008 Keith Packard <keithp@keithp.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#include "ccdbg.h" -#include <stdarg.h> -#include <ctype.h> - -struct hex_input { -	FILE	*file; -	int	line; -	char	*name; -}; - -enum hex_read_state { -	read_marker, -	read_length, -	read_address, -	read_type, -	read_data, -	read_checksum, -	read_newline, -	read_white, -	read_done, -}; - - -static void -ccdbg_hex_error(struct hex_input *input, char *format, ...) -{ -	va_list ap; - -	va_start(ap, format); -	fprintf(stderr, "Hex error %s:%d: ", input->name, input->line); -	vfprintf(stderr, format, ap); -	fprintf(stderr, "\n"); -	va_end(ap); -} - -static void -ccdbg_hex_free(struct hex_record *record) -{ -	if (!record) return; -	free(record); -} - -static struct hex_record * -ccdbg_hex_alloc(uint8_t length) -{ -	struct hex_record *record; - -	record = calloc(1, sizeof(struct hex_record) + length); -	record->length = length; -	return record; -} - -static int -ishex(char c) -{ -	return isdigit(c) || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F'); -} - -static int -fromhex(char c) -{ -	if (isdigit(c)) -		return c - '0'; -	if ('a' <= c && c <= 'f') -		return c - 'a' + 10; -	if ('A' <= c && c <= 'F') -		return c - 'A' + 10; -	abort(); -	return 0; -} - -static uint8_t -ccdbg_hex_checksum(struct hex_record *record) -{ -	uint8_t	checksum = 0; -	int i; - -	checksum += record->length; -	checksum += record->address >> 8; -	checksum += record->address & 0xff; -	checksum += record->type; -	for (i = 0; i < record->length; i++) -		checksum += record->data[i]; -	return -checksum; -} - -static struct hex_record * -ccdbg_hex_read_record(struct hex_input *input) -{ -	struct hex_record *record = NULL; -	enum hex_read_state state = read_marker; -	char c; -	int nhexbytes; -	uint32_t hex; -	uint32_t ndata; -	uint8_t checksum; - -	while (state != read_done) { -		c = getc(input->file); -		if (c == EOF && state != read_white) { -			ccdbg_hex_error(input, "Unexpected EOF"); -			goto bail; -		} -		if (c == ' ') -			continue; -		if (c == '\n') -			input->line++; -		switch (state) { -		case read_marker: -			if (c != ':') { -				ccdbg_hex_error(input, "Missing ':'"); -				goto bail; -			} -			state = read_length; -			nhexbytes = 2; -			hex = 0; -			break; -		case read_length: -		case read_address: -		case read_type: -		case read_data: -		case read_checksum: -			if (!ishex(c)) { -				ccdbg_hex_error(input, "Non-hex char '%c'", -						c); -				goto bail; -			} -			hex = hex << 4 | fromhex(c); -			--nhexbytes; -			if (nhexbytes != 0) -				break; - -			switch (state) { -			case read_length: -				record = ccdbg_hex_alloc(hex); -				if (!record) { -					ccdbg_hex_error(input, "Out of memory"); -					goto bail; -				} -				state = read_address; -				nhexbytes = 4; -				break; -			case read_address: -				record->address = hex; -				state = read_type; -				nhexbytes = 2; -				break; -			case read_type: -				record->type = hex; -				state = read_data; -				nhexbytes = 2; -				ndata = 0; -				break; -			case read_data: -				record->data[ndata] = hex; -				ndata++; -				nhexbytes = 2; -				break; -			case read_checksum: -				record->checksum = hex; -				state = read_newline; -				break; -			default: -				break; -			} -			if (state == read_data) -				if (ndata == record->length) { -					nhexbytes = 2; -					state = read_checksum; -				} -			hex = 0; -			break; -		case read_newline: -			if (c != '\n' && c != '\r') { -				ccdbg_hex_error(input, "Missing newline"); -				goto bail; -			} -			state = read_white; -			break; -		case read_white: -			if (!isspace(c)) { -				if (c == '\n') -					input->line--; -				if (c != EOF) -					ungetc(c, input->file); -				state = read_done; -			} -			break; -		case read_done: -			break; -		} -	} -	checksum = ccdbg_hex_checksum(record); -	if (checksum != record->checksum) { -		ccdbg_hex_error(input, "Invalid checksum (read 0x%02x computed 0x%02x)\n", -				record->checksum, checksum); -		goto bail; -	} -	return record; - -bail: -	ccdbg_hex_free(record); -	return NULL; -} - -void -ccdbg_hex_file_free(struct hex_file *hex) -{ -	int	i; - -	if (!hex) -		return; -	for (i = 0; i < hex->nrecord; i++) -		ccdbg_hex_free(hex->records[i]); -	free(hex); -} - -static int -ccdbg_hex_record_compar(const void *av, const void *bv) -{ -	const struct hex_record *a = *(struct hex_record **) av; -	const struct hex_record *b = *(struct hex_record **) bv; - -	return (int) a->address - (int) b->address; -} - -struct hex_file * -ccdbg_hex_file_read(FILE *file, char *name) -{ -	struct hex_input input; -	struct hex_file	*hex = NULL, *newhex; -	struct hex_record *record; -	int srecord = 1; -	int done = 0; - -	hex = calloc(sizeof (struct hex_file) + sizeof (struct hex_record *), 1); -	input.name = name; -	input.line = 1; -	input.file = file; -	while (!done) { -		record = ccdbg_hex_read_record(&input); -		if (!record) -			goto bail; -		if (hex->nrecord == srecord) { -			srecord *= 2; -			newhex = realloc(hex, -					 sizeof (struct hex_file) + -					 srecord * sizeof (struct hex_record *)); -			if (!newhex) -				goto bail; -			hex = newhex; -		} -		hex->records[hex->nrecord++] = record; -		if (record->type == HEX_RECORD_EOF) -			done = 1; -	} -	/* -	 * Sort them into increasing addresses, except for EOF -	 */ -	qsort(hex->records, hex->nrecord - 1, sizeof (struct hex_record *), -	      ccdbg_hex_record_compar); -	return hex; - -bail: -	ccdbg_hex_file_free(hex); -	return NULL; -} - -struct hex_image * -ccdbg_hex_image_create(struct hex_file *hex) -{ -	struct hex_image *image; -	struct hex_record *first, *last, *record; -	int i; -	uint32_t base, bound; -	uint32_t offset; -	int length; - -	first = hex->records[0]; -	last = hex->records[hex->nrecord - 2];	/* skip EOF */ -	base = (uint32_t) first->address; -	bound = (uint32_t) last->address + (uint32_t) last->length; -	length = bound - base; -	image = calloc(sizeof(struct hex_image) + length, 1); -	if (!image) -		return NULL; -	image->address = base; -	image->length = length; -	memset(image->data, 0xff, length); -	for (i = 0; i < hex->nrecord - 1; i++) { -		record = hex->records[i]; -		offset = record->address - base; -		memcpy(image->data + offset, record->data, record->length); -	} -	return image; -} - -void -ccdbg_hex_image_free(struct hex_image *image) -{ -	free(image); -} - -int -ccdbg_hex_image_equal(struct hex_image *a, struct hex_image *b) -{ -	if (a->length != b->length) -		return 0; -	if (memcmp(a->data, b->data, a->length) != 0) -		return 0; -	return 1; -} | 
