Make INCBIN's length argument optional

INCBIN can now be used with just a start position to include everything
from the start position until the end of the file.
This commit is contained in:
Matt Currie
2020-08-15 17:20:13 +12:00
parent cb4fbdfcd5
commit f863a927c1
5 changed files with 33 additions and 8 deletions

View File

@@ -1346,6 +1346,9 @@ INCBIN "sprites/hero.bin"
INCBIN "data.bin",78,256 INCBIN "data.bin",78,256
</pre> </pre>
</div> </div>
<p class="Pp">The length arugment is optional. If only the start position is
specified, the bytes from the start position until the end of the file will
be included.</p>
</section> </section>
<section class="Ss"> <section class="Ss">
<h2 class="Ss" id="Unions"><a class="permalink" href="#Unions">Unions</a></h2> <h2 class="Ss" id="Unions"><a class="permalink" href="#Unions">Unions</a></h2>

View File

@@ -57,7 +57,7 @@ void out_RelBytes(struct Expression *expr, uint32_t n);
void out_RelWord(struct Expression *expr); void out_RelWord(struct Expression *expr);
void out_RelLong(struct Expression *expr); void out_RelLong(struct Expression *expr);
void out_PCRelByte(struct Expression *expr); void out_PCRelByte(struct Expression *expr);
void out_BinaryFile(char const *s); void out_BinaryFile(char const *s, int32_t startPos);
void out_BinaryFileSlice(char const *s, int32_t start_pos, int32_t length); void out_BinaryFileSlice(char const *s, int32_t start_pos, int32_t length);
void out_PushSection(void); void out_PushSection(void);

View File

@@ -1073,7 +1073,12 @@ include : T_POP_INCLUDE string {
; ;
incbin : T_POP_INCBIN string { incbin : T_POP_INCBIN string {
out_BinaryFile($2); out_BinaryFile($2, 0);
if (oFailedOnMissingInclude)
YYACCEPT;
}
| T_POP_INCBIN string ',' const {
out_BinaryFile($2, $4);
if (oFailedOnMissingInclude) if (oFailedOnMissingInclude)
YYACCEPT; YYACCEPT;
} }

View File

@@ -1080,6 +1080,8 @@ The example below includes 256 bytes from data.bin, starting from byte 78.
.Bd -literal -offset indent .Bd -literal -offset indent
INCBIN "data.bin",78,256 INCBIN "data.bin",78,256
.Ed .Ed
.Pp
The length arugment is optional. If only the start position is specified, the bytes from the start position until the end of the file will be included.
.Ss Unions .Ss Unions
.Pp .Pp
Unions allow multiple memory allocations to overlap, like unions in C. Unions allow multiple memory allocations to overlap, like unions in C.

View File

@@ -583,8 +583,14 @@ void out_PCRelByte(struct Expression *expr)
/* /*
* Output a binary file * Output a binary file
*/ */
void out_BinaryFile(char const *s) void out_BinaryFile(char const *s, int32_t startPos)
{ {
if (startPos < 0) {
yyerror("Start position cannot be negative (%" PRId32 ")",
startPos);
startPos = 0;
}
FILE *f = fstk_FindFile(s, NULL); FILE *f = fstk_FindFile(s, NULL);
if (!f) { if (!f) {
@@ -602,12 +608,21 @@ void out_BinaryFile(char const *s)
checkcodesection(); checkcodesection();
if (fseek(f, 0, SEEK_END) != -1) { if (fseek(f, 0, SEEK_END) != -1) {
fsize = ftell(f); fsize = ftell(f);
rewind(f);
reserveSpace(fsize); if (startPos >= fsize) {
} else if (errno != ESPIPE) { yyerror("Specified start position is greater than length of file");
yyerror("Error determining size of INCBIN file '%s': %s", s, return;
strerror(errno)); }
fseek(f, startPos, SEEK_SET);
reserveSpace(fsize - startPos);
} else {
if (errno != ESPIPE)
yyerror("Error determining size of INCBIN file '%s': %s",
s, strerror(errno));
/* The file isn't seekable, so we'll just skip bytes */
while (startPos--)
(void)fgetc(f);
} }
while ((byte = fgetc(f)) != EOF) { while ((byte = fgetc(f)) != EOF) {