/*
 * The following macros are used to declare global sets of objects, which
 * are collected by the linker into a `struct linker_set' as defined below.
 *
 * NB: the constants defined below must match those defined in
 * ld/ld.h.  Since their calculation requires arithmetic, we
 * can't name them symbolically (e.g., 23 is N_SETT | N_EXT).
 */

#if 0
#define MAKE_SET(set, sym, type) \
        asm(".stabs \"_" #set "\", " #type ", 0, 0, _" #sym)
#else
#define MAKE_SET(set, sym, type) \
        asm(".stabs \"" #set "\", " #type ", 0, 0, " #sym)
#endif
#define TEXT_SET(set, sym) MAKE_SET(set, sym, 23)
#define DATA_SET(set, sym) MAKE_SET(set, sym, 25)
#define BSS_SET(set, sym)  MAKE_SET(set, sym, 27)
#define ABS_SET(set, sym)  MAKE_SET(set, sym, 21)


     /*---*/


#define selfprint(name) void name() { printf(#name "\n"); }

selfprint(foo)
selfprint(bar)
selfprint(toto)

extern struct
    {
     int entries;
     void (*func[1])();
    } functab;

TEXT_SET(functab, foo);
TEXT_SET(functab, toto);
TEXT_SET(functab, bar);



main()

{
 int n, i;

 for (n = functab.entries, i = 0;; ++i) {
    if (i == n) {
      printf("fin du compte\n");
      if (functab.func[i])
	printf("manque le NULL\n");
      exit(0);
    } else if (!functab.func[i]) {
      printf("fin prematuree\n");
      exit(0);
    }
    (*functab.func[i])();
  }
}
