mirror of
https://github.com/cc65/cc65.git
synced 2025-01-10 19:29:45 +00:00
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:
parent
697abf3ed7
commit
27a55ba085
@ -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",
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
} 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);
|
||||
}
|
||||
/* Skip the name */
|
||||
NextTok ();
|
||||
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 {
|
||||
/* 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);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user