Added optional start and count arguments to .INCBIN

git-svn-id: svn://svn.cc65.org/cc65/trunk@617 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz
2001-03-09 23:12:34 +00:00
parent 697abf3ed7
commit 27a55ba085
3 changed files with 87 additions and 23 deletions

View File

@@ -122,9 +122,10 @@ void ErrorMsg (const FilePos* Pos, unsigned ErrNum, va_list ap)
/* Print an error message */ /* Print an error message */
{ {
static const char* Msgs [ERR_COUNT-1] = { static const char* Msgs [ERR_COUNT-1] = {
"Command/operation not implemented", "Command/operation not implemented",
"Cannot open include file `%s': %s", "Cannot open include file `%s': %s",
"Include nesting too deep", "Cannot read from include file `%s': %s",
"Include nesting too deep",
"Invalid input character: %02X", "Invalid input character: %02X",
"Hex digit expected", "Hex digit expected",
"Digit expected", "Digit expected",
@@ -158,7 +159,7 @@ void ErrorMsg (const FilePos* Pos, unsigned ErrNum, va_list ap)
"Illegal use of local symbol", "Illegal use of local symbol",
"Illegal segment name: `%s'", "Illegal segment name: `%s'",
"Illegal segment attribute", "Illegal segment attribute",
"Illegal macro package name", "Illegal macro package name",
"Illegal emulation feature", "Illegal emulation feature",
"Syntax error", "Syntax error",
"Symbol `%s' is already defined", "Symbol `%s' is already defined",
@@ -179,7 +180,7 @@ void ErrorMsg (const FilePos* Pos, unsigned ErrNum, va_list ap)
"Circular reference in symbol definition", "Circular reference in symbol definition",
"Symbol redeclaration mismatch", "Symbol redeclaration mismatch",
"Alignment value must be a power of 2", "Alignment value must be a power of 2",
"Duplicate `.ELSE'", "Duplicate `.ELSE'",
"Conditional assembly branch was never closed", "Conditional assembly branch was never closed",
"Lexical level was not terminated correctly", "Lexical level was not terminated correctly",
"Segment attribute mismatch", "Segment attribute mismatch",

View File

@@ -65,6 +65,7 @@ enum Errors {
ERR_NONE, /* No error */ ERR_NONE, /* No error */
ERR_NOT_IMPLEMENTED, /* Command/operation not implemented */ ERR_NOT_IMPLEMENTED, /* Command/operation not implemented */
ERR_CANNOT_OPEN_INCLUDE, ERR_CANNOT_OPEN_INCLUDE,
ERR_CANNOT_READ_INCLUDE,
ERR_INCLUDE_NESTING, ERR_INCLUDE_NESTING,
ERR_INVALID_CHAR, ERR_INVALID_CHAR,
ERR_HEX_DIGIT_EXPECTED, ERR_HEX_DIGIT_EXPECTED,

View File

@@ -816,27 +816,89 @@ static void DoImportZP (void)
static void DoIncBin (void) static void DoIncBin (void)
/* Include a binary file */ /* Include a binary file */
{ {
char Name [sizeof (SVal)];
long Start = 0L;
long Count = -1L;
long Size;
FILE* F;
/* Name must follow */ /* Name must follow */
if (Tok != TOK_STRCON) { if (Tok != TOK_STRCON) {
ErrorSkip (ERR_STRCON_EXPECTED); ErrorSkip (ERR_STRCON_EXPECTED);
} else { return;
/* 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);
}
/* Skip the name */
NextTok ();
} }
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 {
/* Count was given, check if it is valid */
if (Start + Count > Size) {
ErrorSkip (ERR_RANGE);
goto Done;
}
}
/* 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);
} }