shithub: rgbds

Download patch

ref: f863a927c19f0a70f7a22cb1eb2d2817f334f778
parent: cb4fbdfcd534e43a5f8504b405acd7b8b29f5001
author: Matt Currie <me@mattcurrie.com>
date: Sat Aug 15 13:20:13 EDT 2020

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.

--- a/docs/rgbasm.5.html
+++ b/docs/rgbasm.5.html
@@ -1346,6 +1346,9 @@
 INCBIN &quot;data.bin&quot;,78,256
 </pre>
 </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 class="Ss">
 <h2 class="Ss" id="Unions"><a class="permalink" href="#Unions">Unions</a></h2>
--- a/include/asm/section.h
+++ b/include/asm/section.h
@@ -57,7 +57,7 @@
 void out_RelWord(struct Expression *expr);
 void out_RelLong(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_PushSection(void);
--- a/src/asm/asmy.y
+++ b/src/asm/asmy.y
@@ -1073,7 +1073,12 @@
 ;
 
 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)
 				YYACCEPT;
 		}
--- a/src/asm/rgbasm.5
+++ b/src/asm/rgbasm.5
@@ -1080,6 +1080,8 @@
 .Bd -literal -offset indent
 INCBIN "data.bin",78,256
 .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
 .Pp
 Unions allow multiple memory allocations to overlap, like unions in C.
--- a/src/asm/section.c
+++ b/src/asm/section.c
@@ -583,8 +583,14 @@
 /*
  * 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);
 
 	if (!f) {
@@ -602,12 +608,21 @@
 	checkcodesection();
 	if (fseek(f, 0, SEEK_END) != -1) {
 		fsize = ftell(f);
-		rewind(f);
 
-		reserveSpace(fsize);
-	} else if (errno != ESPIPE) {
-		yyerror("Error determining size of INCBIN file '%s': %s", s,
-			strerror(errno));
+		if (startPos >= fsize) {
+			yyerror("Specified start position is greater than length of file");
+			return;
+		}
+
+		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) {