LINUX.ORG.RU

История изменений

Исправление theNamelessOne, (текущая версия) :

Например, сгенерировать enum и функцию обхода по нему в одно действие.

В твоём случае сгодятся упомянутые выше xmacro. Положи в enum.def описание элементов enum’а

ENUM_ELEM(elem0, 9, "Element no. 0")
ENUM_ELEM(elem1, 8, "Element no. 1")
ENUM_ELEM(elem2, 7, "Element no. 2")
ENUM_ELEM(elem3, 6, "Element no. 3")
ENUM_ELEM(elem4, 5, "Element no. 4")
ENUM_ELEM(elem5, 4, "Element no. 5")
ENUM_ELEM(elem6, 3, "Element no. 6")
ENUM_ELEM(elem7, 2, "Element no. 7")
ENUM_ELEM(elem8, 1, "Element no. 8")
ENUM_ELEM(elem9, 0, "Element no. 9")

…и дальше генерируй из этого описания что угодно:

#include <stdio.h>
#include <stdbool.h>

/* generate enum */
#define ENUM_ELEM(name, value, desc) name = value,

enum E {
#include "enum.def"
};

/* stringify enum item names */
#undef ENUM_ELEM
#define ENUM_ELEM(name, value, desc) [value] = #name,

static const char *E_names[] = {
#include "enum.def"
};

const char *E_stringify(enum E item) {
  return E_names[item];
}

/* description for enum items */
#undef ENUM_ELEM
#define ENUM_ELEM(name, value, desc) [value] = desc,

static const char *E_desc[] = {
#include "enum.def"
};

const char *E_describe(enum E item) {
  return E_desc[item];
}


/* advance function */
#undef ENUM_ELEM
#define ENUM_ELEM(name, value, desc) value,

static const enum E E_values[] = {
#include "enum.def"
};

static const size_t E_size = sizeof E_values / sizeof *E_values;

bool advance_E(enum E *curr) {
  for (int i = 0; i < (int) E_size - 1; ++i) {
    if (*curr == E_values[i]) {
      *curr = E_values[i + 1];
      return true;
    }
  }
  return false;
}

int main(void) {
  /* iterate over E items */
  bool has_next = true;

  for (enum E item = elem0; has_next; has_next = advance_E(&item)) {
    printf("enum item `%s' has value `%d' and description `%s'\n",
           E_stringify(item), item, E_describe(item));
  }

  return 0;
}

Исходная версия theNamelessOne, :

Например, сгенерировать enum и функцию обхода по нему в одно действие.

В твоём случае сгодятся упомянутые выше xmacro. Положи в enum.def описание элементов enum’а

ENUM_ELEM(elem0, 9, "Element no. 0")
ENUM_ELEM(elem1, 8, "Element no. 1")
ENUM_ELEM(elem2, 7, "Element no. 2")
ENUM_ELEM(elem3, 6, "Element no. 3")
ENUM_ELEM(elem4, 5, "Element no. 4")
ENUM_ELEM(elem5, 4, "Element no. 5")
ENUM_ELEM(elem6, 3, "Element no. 6")
ENUM_ELEM(elem7, 2, "Element no. 7")
ENUM_ELEM(elem8, 1, "Element no. 8")
ENUM_ELEM(elem9, 0, "Element no. 9")

…и дальше генерируй из этого описания что угодно:

#include <stdio.h>
#include <stdbool.h>

/* generate enum */
#define ENUM_ELEM(name, value, desc) name = value,

enum E {
#include "enum.def"
};

/* stringify enum item names */
#undef ENUM_ELEM
#define ENUM_ELEM(name, value, desc) [value] = #name,

static const char *E_names[] = {
#include "enum.def"
};

const char *E_stringify(enum E item) {
  return E_names[item];
}

/* description for enum items */
#undef ENUM_ELEM
#define ENUM_ELEM(name, value, desc) [value] = desc,

static const char *E_desc[] = {
#include "enum.def"
};

const char *E_describe(enum E item) {
  return E_desc[item];
}


/* advance function */
#undef ENUM_ELEM
#define ENUM_ELEM(name, value, desc) value,

static const enum E E_values[] = {
#include "enum.def"
};

static const size_t E_size = sizeof E_values / sizeof *E_values;

bool advance_E(enum E *curr) {
  for (int i = 0; i < (int) E_size - 1; ++i) {
    if (*curr == E_values[i]) {
      *curr = E_values[i + 1];
      return true;
    }
  }
  return false;
}

int main(void) {
  /* iterate all E items */
  bool has_next = true;

  for (enum E item = elem0; has_next; has_next = advance_E(&item)) {
    printf("enum item `%s' has value `%d' and description `%s'\n",
           E_stringify(item), item, E_describe(item));
  }

  return 0;
}