mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Use C++ iterator for fragment/union "pieces" of RGBLINK sections
This commit is contained in:
@@ -49,6 +49,39 @@ struct Section {
|
|||||||
std::vector<Symbol> *fileSymbols;
|
std::vector<Symbol> *fileSymbols;
|
||||||
std::vector<Symbol *> symbols;
|
std::vector<Symbol *> symbols;
|
||||||
std::unique_ptr<Section> nextPiece; // The next fragment or union "piece" of this section
|
std::unique_ptr<Section> nextPiece; // The next fragment or union "piece" of this section
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Template class for both const and non-const iterators over the "pieces" of this section
|
||||||
|
template<typename T>
|
||||||
|
class PiecesIterable {
|
||||||
|
T *_firstPiece;
|
||||||
|
|
||||||
|
class Iterator {
|
||||||
|
T *_piece;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit Iterator(T *piece) : _piece(piece) {}
|
||||||
|
|
||||||
|
Iterator &operator++() {
|
||||||
|
_piece = _piece->nextPiece.get();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
T &operator*() const { return *_piece; }
|
||||||
|
|
||||||
|
bool operator==(Iterator const &rhs) const { return _piece == rhs._piece; }
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit PiecesIterable(T *firstPiece) : _firstPiece(firstPiece) {}
|
||||||
|
|
||||||
|
Iterator begin() { return Iterator(_firstPiece); }
|
||||||
|
Iterator end() { return Iterator(nullptr); }
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
PiecesIterable<Section> pieces() { return PiecesIterable(this); }
|
||||||
|
PiecesIterable<Section const> pieces() const { return PiecesIterable(this); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Execute a callback for each section currently registered.
|
// Execute a callback for each section currently registered.
|
||||||
|
|||||||
@@ -223,12 +223,10 @@ void out_WriteObject() {
|
|||||||
|
|
||||||
putLong(fileStackNodes.size(), file);
|
putLong(fileStackNodes.size(), file);
|
||||||
for (auto it = fileStackNodes.begin(); it != fileStackNodes.end(); ++it) {
|
for (auto it = fileStackNodes.begin(); it != fileStackNodes.end(); ++it) {
|
||||||
FileStackNode const &node = **it;
|
writeFileStackNode(**it, file);
|
||||||
|
|
||||||
writeFileStackNode(node, file);
|
|
||||||
|
|
||||||
// The list is supposed to have decrementing IDs
|
// The list is supposed to have decrementing IDs
|
||||||
assume(it + 1 == fileStackNodes.end() || it[1]->ID == node.ID - 1);
|
assume(it + 1 == fileStackNodes.end() || it[1]->ID == it[0]->ID - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Symbol const *sym : objectSymbols) {
|
for (Symbol const *sym : objectSymbols) {
|
||||||
|
|||||||
@@ -53,9 +53,9 @@ static void initFreeSpace() {
|
|||||||
static void assignSection(Section §ion, MemoryLocation const &location) {
|
static void assignSection(Section §ion, MemoryLocation const &location) {
|
||||||
// Propagate the assigned location to all UNIONs/FRAGMENTs
|
// Propagate the assigned location to all UNIONs/FRAGMENTs
|
||||||
// so `jr` patches in them will have the correct offset
|
// so `jr` patches in them will have the correct offset
|
||||||
for (Section *piece = §ion; piece != nullptr; piece = piece->nextPiece.get()) {
|
for (Section &piece : section.pieces()) {
|
||||||
piece->org = location.address;
|
piece.org = location.address;
|
||||||
piece->bank = location.bank;
|
piece.bank = location.bank;
|
||||||
}
|
}
|
||||||
out_AddSection(section);
|
out_AddSection(section);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -251,8 +251,8 @@ void layout_PlaceSection(std::string const &name, bool isOptional) {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// SDCC areas don't have a type assigned yet, so the linker script gives them one.
|
// SDCC areas don't have a type assigned yet, so the linker script gives them one.
|
||||||
for (Section *piece = section; piece != nullptr; piece = piece->nextPiece.get()) {
|
for (Section &piece : section->pieces()) {
|
||||||
piece->type = activeType;
|
piece.type = activeType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (section->type != activeType) {
|
} else if (section->type != activeType) {
|
||||||
|
|||||||
@@ -317,13 +317,13 @@ static bool compareSymbols(SortedSymbol const &sym1, SortedSymbol const &sym2) {
|
|||||||
template<typename F>
|
template<typename F>
|
||||||
static void forEachSortedSection(SortedSections const &bankSections, F callback) {
|
static void forEachSortedSection(SortedSections const &bankSections, F callback) {
|
||||||
for (Section const *sect : bankSections.zeroLenSections) {
|
for (Section const *sect : bankSections.zeroLenSections) {
|
||||||
for (; sect != nullptr; sect = sect->nextPiece.get()) {
|
for (Section const &piece : sect->pieces()) {
|
||||||
callback(*sect);
|
callback(piece);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (Section const *sect : bankSections.sections) {
|
for (Section const *sect : bankSections.sections) {
|
||||||
for (; sect != nullptr; sect = sect->nextPiece.get()) {
|
for (Section const &piece : sect->pieces()) {
|
||||||
callback(*sect);
|
callback(piece);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -433,31 +433,32 @@ uint16_t forEachSection(SortedSections const §List, F callback) {
|
|||||||
return used;
|
return used;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void writeMapSymbols(Section const *sect) {
|
static void writeMapSymbols(Section const §) {
|
||||||
uint16_t org = sect->org;
|
bool announced = true;
|
||||||
|
for (Section const &piece : sect.pieces()) {
|
||||||
for (bool announced = true; sect != nullptr; sect = sect->nextPiece.get(), announced = false) {
|
for (Symbol *sym : piece.symbols) {
|
||||||
for (Symbol *sym : sect->symbols) {
|
|
||||||
// Don't output symbols that begin with an illegal character
|
// Don't output symbols that begin with an illegal character
|
||||||
if (sym->name.empty() || !startsIdentifier(sym->name[0])) {
|
if (sym->name.empty() || !startsIdentifier(sym->name[0])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Announce this "piece" before its contents
|
// Announce this "piece" before its contents
|
||||||
if (!announced) {
|
if (!announced) {
|
||||||
if (sect->modifier == SECTION_UNION) {
|
assume(sect.modifier == piece.modifier);
|
||||||
|
if (sect.modifier == SECTION_UNION) {
|
||||||
fputs("\t ; Next union\n", mapFile);
|
fputs("\t ; Next union\n", mapFile);
|
||||||
} else if (sect->modifier == SECTION_FRAGMENT) {
|
} else if (sect.modifier == SECTION_FRAGMENT) {
|
||||||
fputs("\t ; Next fragment\n", mapFile);
|
fputs("\t ; Next fragment\n", mapFile);
|
||||||
}
|
}
|
||||||
announced = true;
|
announced = true;
|
||||||
}
|
}
|
||||||
assume(std::holds_alternative<Label>(sym->data));
|
assume(std::holds_alternative<Label>(sym->data));
|
||||||
uint32_t address = std::get<Label>(sym->data).offset + org;
|
uint32_t address = std::get<Label>(sym->data).offset + sect.org;
|
||||||
// Space matches "\tSECTION: $xxxx ..."
|
// Space matches "\tSECTION: $xxxx ..."
|
||||||
fprintf(mapFile, "\t $%04" PRIx32 " = ", address);
|
fprintf(mapFile, "\t $%04" PRIx32 " = ", address);
|
||||||
writeSymName(sym->name, mapFile);
|
writeSymName(sym->name, mapFile);
|
||||||
putc('\n', mapFile);
|
putc('\n', mapFile);
|
||||||
}
|
}
|
||||||
|
announced = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -487,7 +488,7 @@ static void writeMapBank(SortedSections const §List, SectionType type, uint3
|
|||||||
|
|
||||||
if (!options.noSymInMap) {
|
if (!options.noSymInMap) {
|
||||||
// Also print symbols in the following "pieces"
|
// Also print symbols in the following "pieces"
|
||||||
writeMapSymbols(§);
|
writeMapSymbols(sect);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -586,8 +586,8 @@ static void applyPatches(Section §ion) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Section *piece = §ion; piece != nullptr; piece = piece->nextPiece.get()) {
|
for (Section &piece : section.pieces()) {
|
||||||
applyFilePatches(*piece, section);
|
applyFilePatches(piece, section);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user