mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Use std::vector for SDCC object section data
This commit is contained in:
@@ -220,12 +220,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
|
|||||||
uint16_t writeIndex;
|
uint16_t writeIndex;
|
||||||
};
|
};
|
||||||
std::vector<struct FileSection> fileSections;
|
std::vector<struct FileSection> fileSections;
|
||||||
size_t nbBytes = 0; // How many bytes are in `data`, including the ADDR_SIZE "header" bytes
|
std::vector<uint8_t> data;
|
||||||
size_t dataCapacity = 16 + ADDR_SIZE; // SDCC object files usually contain 16 bytes per T line
|
|
||||||
uint8_t *data = (uint8_t *)malloc(sizeof(*data) * dataCapacity);
|
|
||||||
|
|
||||||
if (!data)
|
|
||||||
fatal(where, lineNo, "Failed to alloc data buffer: %s", strerror(errno));
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
lineType = nextLine(line, lineNo, where, file);
|
lineType = nextLine(line, lineNo, where, file);
|
||||||
@@ -395,30 +390,21 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
|
|||||||
|
|
||||||
case 'T':
|
case 'T':
|
||||||
// Now, time to parse the data!
|
// Now, time to parse the data!
|
||||||
if (nbBytes != 0)
|
if (!data.empty())
|
||||||
warning(where, lineNo, "Previous 'T' line had no 'R' line (ignored)");
|
warning(where, lineNo, "Previous 'T' line had no 'R' line (ignored)");
|
||||||
|
|
||||||
nbBytes = 0;
|
data.clear();
|
||||||
for (token = strtok(line.data(), delim); token; token = strtok(NULL, delim)) {
|
for (token = strtok(line.data(), delim); token; token = strtok(NULL, delim))
|
||||||
if (dataCapacity == nbBytes) {
|
data.push_back(parseByte(where, lineNo, token, numberType));
|
||||||
dataCapacity *= 2;
|
|
||||||
data = (uint8_t *)realloc(data, sizeof(*data) * dataCapacity);
|
|
||||||
if (!data)
|
|
||||||
fatal(where, lineNo, "Failed to realloc data buffer: %s",
|
|
||||||
strerror(errno));
|
|
||||||
}
|
|
||||||
data[nbBytes] = parseByte(where, lineNo, token, numberType);
|
|
||||||
++nbBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nbBytes < ADDR_SIZE)
|
if (data.size() < ADDR_SIZE)
|
||||||
fatal(where, lineNo, "'T' line is too short");
|
fatal(where, lineNo, "'T' line is too short");
|
||||||
// Importantly, now we know that `nbBytes != 0`, which means "pending data"
|
// Importantly, now we know that there is "pending data" in `data`
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'R': {
|
case 'R': {
|
||||||
// Supposed to directly follow `T`
|
// Supposed to directly follow `T`
|
||||||
if (nbBytes == 0) {
|
if (data.empty()) {
|
||||||
warning(where, lineNo, "'R' line with no 'T' line, ignoring");
|
warning(where, lineNo, "'R' line with no 'T' line, ignoring");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -449,7 +435,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
|
|||||||
}
|
}
|
||||||
// Lines are emitted that violate this check but contain no "payload";
|
// Lines are emitted that violate this check but contain no "payload";
|
||||||
// ignore those. "Empty" lines shouldn't trigger allocation, either.
|
// ignore those. "Empty" lines shouldn't trigger allocation, either.
|
||||||
if (nbBytes != ADDR_SIZE) {
|
if (data.size() != ADDR_SIZE) {
|
||||||
if (addr != *writeIndex)
|
if (addr != *writeIndex)
|
||||||
fatal(where, lineNo, "'T' lines which don't append to their section are not supported (%" PRIu16 " != %" PRIu16 ")",
|
fatal(where, lineNo, "'T' lines which don't append to their section are not supported (%" PRIu16 " != %" PRIu16 ")",
|
||||||
addr, *writeIndex);
|
addr, *writeIndex);
|
||||||
@@ -486,9 +472,9 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
|
|||||||
if (offset < ADDR_SIZE)
|
if (offset < ADDR_SIZE)
|
||||||
fatal(where, lineNo, "Relocation index cannot point to header (%" PRIu16 " < %u)",
|
fatal(where, lineNo, "Relocation index cannot point to header (%" PRIu16 " < %u)",
|
||||||
offset, ADDR_SIZE);
|
offset, ADDR_SIZE);
|
||||||
if (offset >= nbBytes)
|
if (offset >= data.size())
|
||||||
fatal(where, lineNo, "Relocation index is out of bounds (%" PRIu16 " >= %zu)",
|
fatal(where, lineNo, "Relocation index is out of bounds (%" PRIu16 " >= %zu)",
|
||||||
offset, nbBytes);
|
offset, data.size());
|
||||||
|
|
||||||
getToken(NULL, "Incomplete relocation");
|
getToken(NULL, "Incomplete relocation");
|
||||||
uint16_t idx = parseByte(where, lineNo, token, numberType);
|
uint16_t idx = parseByte(where, lineNo, token, numberType);
|
||||||
@@ -521,10 +507,10 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
|
|||||||
uint8_t nbBaseBytes = patch.type == PATCHTYPE_BYTE ? ADDR_SIZE : 2;
|
uint8_t nbBaseBytes = patch.type == PATCHTYPE_BYTE ? ADDR_SIZE : 2;
|
||||||
uint32_t baseValue = 0;
|
uint32_t baseValue = 0;
|
||||||
|
|
||||||
assert(offset < nbBytes);
|
assert(offset < data.size());
|
||||||
if (nbBytes - offset < nbBaseBytes)
|
if (data.size() - offset < nbBaseBytes)
|
||||||
fatal(where, lineNo, "Reloc would patch out of bounds (%" PRIu8 " > %zu)",
|
fatal(where, lineNo, "Reloc would patch out of bounds (%" PRIu8 " > %zu)",
|
||||||
nbBaseBytes, nbBytes - offset);
|
nbBaseBytes, data.size() - offset);
|
||||||
for (uint8_t i = 0; i < nbBaseBytes; ++i)
|
for (uint8_t i = 0; i < nbBaseBytes; ++i)
|
||||||
baseValue = baseValue | data[offset + i] << (8 * i);
|
baseValue = baseValue | data[offset + i] << (8 * i);
|
||||||
|
|
||||||
@@ -661,16 +647,16 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If there is some data left to append, do so
|
// If there is some data left to append, do so
|
||||||
if (writtenOfs != nbBytes) {
|
if (writtenOfs != data.size()) {
|
||||||
assert(nbBytes > writtenOfs);
|
assert(data.size() > writtenOfs);
|
||||||
if (*writeIndex + (nbBytes - writtenOfs) > section->size)
|
if (*writeIndex + (data.size() - writtenOfs) > section->size)
|
||||||
fatal(where, lineNo, "'T' line writes past \"%s\"'s end (%zu > %" PRIu16 ")",
|
fatal(where, lineNo, "'T' line writes past \"%s\"'s end (%zu > %" PRIu16 ")",
|
||||||
section->name.c_str(), *writeIndex + (nbBytes - writtenOfs), section->size);
|
section->name.c_str(), *writeIndex + (data.size() - writtenOfs), section->size);
|
||||||
memcpy(§ion->data[*writeIndex], &data[writtenOfs], nbBytes - writtenOfs);
|
memcpy(§ion->data[*writeIndex], &data[writtenOfs], data.size() - writtenOfs);
|
||||||
*writeIndex += nbBytes - writtenOfs;
|
*writeIndex += data.size() - writtenOfs;
|
||||||
}
|
}
|
||||||
|
|
||||||
nbBytes = 0; // Do not allow two R lines to refer to the same T line
|
data.clear(); // Do not allow two R lines to refer to the same T line
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -681,7 +667,7 @@ void sdobj_ReadFile(struct FileStackNode const *where, FILE *file, std::vector<s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nbBytes != 0)
|
if (!data.empty())
|
||||||
warning(where, lineNo, "Last 'T' line had no 'R' line (ignored)");
|
warning(where, lineNo, "Last 'T' line had no 'R' line (ignored)");
|
||||||
if (fileSections.size() < expectedNbAreas)
|
if (fileSections.size() < expectedNbAreas)
|
||||||
warning(where, lineNo, "Expected %" PRIu32 " 'A' lines, got only %zu", expectedNbAreas,
|
warning(where, lineNo, "Expected %" PRIu32 " 'A' lines, got only %zu", expectedNbAreas,
|
||||||
|
|||||||
Reference in New Issue
Block a user