1
0
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:
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 */
{
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",

View File

@ -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,

View File

@ -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);
}