/*====================================================================* * * size_t hexload (void * memory, size_t extent, FILE * fp); * * memory.h * * read a file and convert hexadecimal octets to binary bytes then * store them in consecutive memory locations up to a given length; * return the actual number of bytes stored; * * digits may be consecutive or separated by white space or comment * text; a colon terminates a frame, to allow multiple frames in a * on one file; * * Motley Tools by Charles Maier <cmaier@cmassoc.net>; * Copyright (c) 2001-2006 by Charles Maier Associates; * Licensed under the Internet Software Consortium License; * *--------------------------------------------------------------------*/ #ifndef HEXLOAD_SOURCE #define HEXLOAD_SOURCE #include <stdio.h> #include <ctype.h> #include <stdint.h> #include <errno.h> #include "../tools/memory.h" #include "../tools/error.h" #include "../tools/chars.h" /*====================================================================* * private variables; *--------------------------------------------------------------------*/ static unsigned row = 1; static unsigned col = 1; /*====================================================================* * * signed fpgetc (FILE * fp) * * return the next input character after updating the file cursor * position; * * Motley Tools by Charles Maier <cmaier@cmassoc.net>; * Copyright (c) 2001-2006 by Charles Maier Associates; * Licensed under the Internet Software Consortium License; * *--------------------------------------------------------------------*/ static signed fpgetc (FILE * fp) { extern unsigned row; extern unsigned col; signed c = getc (fp); if (c == '\n') { row++; col = 0; } else { col++; } return (c); } /*====================================================================* * * size_t hexload (void * memory, size_t extent, FILE * fp); * * memory.h * * read a file and convert hexadecimal octets to binary bytes then * store them in consecutive memory locations up to a given length; * return the actual number of bytes stored; * * digits may be consecutive or separated by white space or comment * text; a colon terminates a frame, to allow multiple frames in a * on one file; * * Motley Tools by Charles Maier <cmaier@cmassoc.net>; * Copyright (c) 2001-2006 by Charles Maier Associates; * Licensed under the Internet Software Consortium License; * *--------------------------------------------------------------------*/ size_t hexload (void * memory, size_t extent, FILE * fp) { extern unsigned row; extern unsigned col; byte * origin = (uint8_t *)(memory); byte * offset = (uint8_t *)(memory); unsigned digits = sizeof (* offset) << 1; unsigned digit = 0; signed c = EOF; while ((extent) && ((c = fpgetc (fp)) != EOF) && (c != ';')) { if (isspace (c)) { continue; } if (c == '#') { do { c = fpgetc (fp); } while (nobreak (c)); continue; } if (c == '/') { c = fpgetc (fp); if (c == '/') { do { c = fpgetc (fp); } while (nobreak (c)); continue; } if (c == '*') { while ((c != '/') && (c != EOF)) { while ((c != '*') && (c != EOF)) { c = fpgetc (fp); } c = fpgetc (fp); } continue; } continue; } if ((c >= '0') && (c <= '9')) { *offset *= 16; *offset += c - '0'; if (!(++digit % digits)) { offset++; extent--; } continue; } if ((c >= 'A') && (c <= 'F')) { *offset *= 16; *offset += 10; *offset += c - 'A'; if (!(++digit % digits)) { offset++; extent--; } continue; } if ((c >= 'a') && (c <= 'f')) { *offset *= 16; *offset += 10; *offset += c - 'a'; if (!(++digit % digits)) { offset++; extent--; } continue; } #if 1 error (1, ENOTSUP, "Unexpected character '%c': row %d: col %d", c, row, col); #else return ((size_t)(-1)); #endif } if (digit & 1) { #if 1 error (1, ENOTSUP, "Odd digit count (%d) in source", digit); #else return ((size_t)(-1)); #endif } return (offset - origin); } #endif