382Fermer384
Kevin KoflerLe 01/09/2003 à 16:39
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.)