From 27a55ba08593145ddea585903896dfe977ef9521 Mon Sep 17 00:00:00 2001 From: cuz Date: Fri, 9 Mar 2001 23:12:34 +0000 Subject: [PATCH] Added optional start and count arguments to .INCBIN git-svn-id: svn://svn.cc65.org/cc65/trunk@617 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/ca65/error.c | 11 +++--- src/ca65/error.h | 1 + src/ca65/pseudo.c | 94 +++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 85 insertions(+), 21 deletions(-) diff --git a/src/ca65/error.c b/src/ca65/error.c index 358be913f..750457638 100644 --- a/src/ca65/error.c +++ b/src/ca65/error.c @@ -122,9 +122,10 @@ void ErrorMsg (const FilePos* Pos, unsigned ErrNum, va_list ap) /* Print an error message */ { static const char* Msgs [ERR_COUNT-1] = { - "Command/operation not implemented", - "Cannot open include file `%s': %s", - "Include nesting too deep", + "Command/operation not implemented", + "Cannot open include file `%s': %s", + "Cannot read from include file `%s': %s", + "Include nesting too deep", "Invalid input character: %02X", "Hex digit expected", "Digit expected", @@ -158,7 +159,7 @@ void ErrorMsg (const FilePos* Pos, unsigned ErrNum, va_list ap) "Illegal use of local symbol", "Illegal segment name: `%s'", "Illegal segment attribute", - "Illegal macro package name", + "Illegal macro package name", "Illegal emulation feature", "Syntax error", "Symbol `%s' is already defined", @@ -179,7 +180,7 @@ void ErrorMsg (const FilePos* Pos, unsigned ErrNum, va_list ap) "Circular reference in symbol definition", "Symbol redeclaration mismatch", "Alignment value must be a power of 2", - "Duplicate `.ELSE'", + "Duplicate `.ELSE'", "Conditional assembly branch was never closed", "Lexical level was not terminated correctly", "Segment attribute mismatch", diff --git a/src/ca65/error.h b/src/ca65/error.h index 857d52f18..54e2ae198 100644 --- a/src/ca65/error.h +++ b/src/ca65/error.h @@ -65,6 +65,7 @@ enum Errors { ERR_NONE, /* No error */ ERR_NOT_IMPLEMENTED, /* Command/operation not implemented */ ERR_CANNOT_OPEN_INCLUDE, + ERR_CANNOT_READ_INCLUDE, ERR_INCLUDE_NESTING, ERR_INVALID_CHAR, ERR_HEX_DIGIT_EXPECTED, diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 14568ad22..f1953804e 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -816,27 +816,89 @@ static void DoImportZP (void) static void DoIncBin (void) /* Include a binary file */ { + char Name [sizeof (SVal)]; + long Start = 0L; + long Count = -1L; + long Size; + FILE* F; + /* Name must follow */ if (Tok != TOK_STRCON) { - ErrorSkip (ERR_STRCON_EXPECTED); + ErrorSkip (ERR_STRCON_EXPECTED); + return; + } + strcpy (Name, SVal); + NextTok (); + + /* A starting offset may follow */ + if (Tok == TOK_COMMA) { + NextTok (); + Start = ConstExpression (); + + /* And a length may follow */ + if (Tok == TOK_COMMA) { + NextTok (); + Count = ConstExpression (); + } + + } + + /* Try to open the file */ + F = fopen (Name, "rb"); + if (F == 0) { + ErrorSkip (ERR_CANNOT_OPEN_INCLUDE, Name, strerror (errno)); + return; + } + + /* Get the size of the file */ + fseek (F, 0, SEEK_END); + Size = ftell (F); + + /* If a count was not given, calculate it now */ + if (Count < 0) { + Count = Size - Start; + if (Count < 0) { + /* Nothing to read - flag this as a range error */ + ErrorSkip (ERR_RANGE); + goto Done; + } } else { - /* Try to open the file */ - FILE* F = fopen (SVal, "rb"); - if (F == 0) { - Error (ERR_CANNOT_OPEN_INCLUDE, SVal, strerror (errno)); - } else { - unsigned char Buf [1024]; - size_t Count; - /* Read chunks and insert them into the output */ - while ((Count = fread (Buf, 1, sizeof (Buf), F)) > 0) { - EmitData (Buf, Count); - } - /* Close the file, ignore errors since it's r/o */ - (void) fclose (F); + /* Count was given, check if it is valid */ + if (Start + Count > Size) { + ErrorSkip (ERR_RANGE); + goto Done; } - /* Skip the name */ - NextTok (); } + + /* Seek to the start position */ + fseek (F, Start, SEEK_SET); + + /* Read chunks and insert them into the output */ + while (Count > 0) { + + unsigned char Buf [1024]; + + /* Calculate the number of bytes to read */ + size_t BytesToRead = (Count > (long)sizeof(Buf))? sizeof(Buf) : (size_t) Count; + + /* Read chunk */ + size_t BytesRead = fread (Buf, 1, BytesToRead, F); + if (BytesToRead != BytesRead) { + /* Some sort of error */ + ErrorSkip (ERR_CANNOT_READ_INCLUDE, Name, strerror (errno)); + break; + } + + /* Insert it into the output */ + EmitData (Buf, Count); + + /* Keep the counters current */ + Count -= BytesRead; + } + +Done: + /* Close the file, ignore errors since it's r/o */ + (void) fclose (F); } -- 2.39.5