+
+ if (*tok != EOL)
+ {
+ // Parse size and position parameters
+ uint64_t requested_size = -1; // -1 means "not set" for these two
+
+ if (*tok++ != ',')
+ {
+ close(fd);
+ return error("expected comma after incbin filename");
+ }
+
+ if (*tok != EOL)
+ {
+ if (*tok != ',')
+ {
+ if (abs_expr(&requested_size) != OK)
+ {
+ close(fd);
+ return ERROR;
+ }
+
+ if ((int64_t)requested_size <= 0 || requested_size > size)
+ {
+ close(fd);
+ return error("invalid incbin size requested");
+ }
+ }
+
+ if (*tok != EOL)
+ {
+ if (*tok++ != ',')
+ {
+ close(fd);
+ return error("expected comma after size parameter");
+ }
+
+ if (*tok != EOL)
+ {
+ if (abs_expr(&pos) != OK)
+ {
+ close(fd);
+ return ERROR;
+ }
+
+ if ((int64_t)pos <= 0 || pos > size)
+ {
+ close(fd);
+ return error("invalid incbin position requested");
+ }
+ }
+ }
+
+ if (*tok != EOL)
+ {
+ close(fd);
+ return error("extra characters following incbin");
+ }
+ }
+
+ // Adjust size if the user didn't specify it via the parameter
+ if (requested_size == -1)
+ {
+ requested_size = size - pos;
+ }
+
+ // Are we going to read past the end of the file?
+ if (pos + requested_size > size)
+ {
+ close(fd);
+ return error("invalid combination of incbin position and size");
+ }
+ size = requested_size;
+
+ // All checks passed, let's seek to where the user requested, otherwise at file start
+ lseek(fd, pos, SEEK_SET);
+ }
+