Voilà comme promis quelques exemples de macros utilisés comme des templates tirés de
ld-tigcc:
#define CheckItems(Type,Item) \
({ \
const Type *Item = Find##Item##AtPos (Section, Start, FALSE) ? : GetFirst (Section->Item##s); \
while (Item && (Item->Location < End)) \
{ \
if ((Item != Exception) && (RangesOverlap (Start, End, Item->Location, Item->Location + Item->Size))) \
return FALSE; \
Item = GetNext (Item); \
} \
})
CheckItems (RELOC, Reloc);
CheckItems (ROM_CALL, ROMCall);
CheckItems (RAM_CALL, RAMCall);
CheckItems (LIB_CALL, LibCall);
#undef CheckItems
(Ici, c'est de l'inline. Remarquez l'utilisation de
##.)
// Find the item preceding or following the given location. May return NULL.
#define DefineFindItemAtPos(Type,Item,LocationSuffix) \
Type *Find##Item##AtPos (const SECTION *Section, OFFSET Location, BOOLEAN Following) \
{ \
/* Find the place so that Item->Location is always less than Location */ \
/* and Next##Item->Location is always greater or equal. */ \
Type *Item = NULL, *Next##Item = NULL; \
if (Location > Section->Size / 2) \
{ \
Item = GetLast (Section->Item##s); \
while (Item && (Item->Location LocationSuffix >= Location)) \
{ \
Next##Item = Item; \
Item = GetPrev (Item); \
} \
} \
else \
{ \
Next##Item = GetFirst (Section->Item##s); \
while (Next##Item && (Next##Item->Location LocationSuffix < Location)) \
{ \
Item = Next##Item; \
Next##Item = GetNext (Next##Item); \
} \
} \
/* If we are looking for something that follows, the case is clear. */ \
/* Otherwise, we need to check whether the next item is also OK. */ \
if (Following || (Next##Item && (Next##Item->Location LocationSuffix <= Location))) \
return Next##Item; \
else \
return Item; \
}
DefineFindItemAtPos (SYMBOL, Symbol, );
DefineFindItemAtPos (RELOC, Reloc, );
DefineFindItemAtPos (ROM_CALL, ROMCall, );
DefineFindItemAtPos (RAM_CALL, RAMCall, );
DefineFindItemAtPos (LIB_CALL, LibCall, );
DefineFindItemAtPos (SEGMENT, Segment, .Start->Location);
#undef DefineFindItemAtPos
(Et ici ce sont des fonctions.
## est encore très utile.)