Как создавать комментарии к сгенерированному коду

#c #c #doxygen #c-preprocessor

#c #c #doxygen #c-препроцессор

Вопрос:

Я использую препроцессор C для генерации элементов в перечислении. Есть ли способ написать комментарии doxygen для сгенерированных элементов? Я не могу просто запустить его через препроцессор перед doxygen, поскольку это приведет к удалению комментариев doxygen.

Пример:

 #define ATTRIBUTES 
X(TITLE,    "title") 
X(FILENAME, "filename") 
X(GENRE_ID, "genre_id")

enum ATTRIBUTES_ENUM {
  #define X(a, b) a##_ATTRIBUTE,
  ATTRIBUTES
  #undef X
  ATTRIBUTES_COUNT
};
 

И добавление чего-то вроде:

 /**
 * def TITLE_ATTRIBUTE
 * The media's title.
 */
 

не работает.

РЕДАКТИРОВАТЬ Благодаря Томасу Мэтьюзу, вот решение, которое я использовал:

 #define ATTRIBUTES 
X(TITLE,    "title")    /*!< title attribute */ 
X(FILENAME, "filename") /*!< filename attribute */ 
X(GENRE_ID, "genre_id") /*!< genre id attribute */

#define X(a, b) a##_ATTRIBUTE,

enum ATTRIBUTES_ENUM {
  ATTRIBUTES
  ATTRIBUTES_COUNT
};

#undef X
 

И скажите Doxygen развернуть макросы. Единственным недостатком является то, что комментарий к последнему элементу также используется в качестве комментария к ATTRIBUTES определению. Но в моем случае это незначительная проблема.

Комментарии:

1. Возможно, вы могли бы злоупотреблять оператором ## для генерации токена //, но вы оказались бы в области неопределенного поведения. Проблема в том, что комментарии удаляются на этапе перевода 3, перед расширением макросов.

Ответ №1:

Попробуйте следующее

  1. В файле конфигурации Doxygen укажите, чтобы он обрабатывал макросы.
  2. В определении макроса добавьте комментарии Doxygen после каждого элемента:
     #define ATTRIBUTES   
    X(TITLE, "title") /**!< title element */   
    X(FILENAME, "filename") /**!< file name element */   
    X(GENRE_ID, "genre_id") /**!< title element */  
     

Из-за проблем с форматированием кода комментарии к каждой строке должны быть комментариями C sytle.

Я понимаю, что Doxygen должен обработать макрос (сделать замены), а затем передать измененный текст в его механизм комментариев.

Хотя просто предположение.

Я настоятельно рекомендую другую схему для преобразования перечислений в текст. Используйте либо массив, вектор, либо карту. Например:

 enum Attributes_Enum
{
  TITLE, FILENAME, GENRE
};

struct Enum_Text_Entry
{
    enum Attributes_Enum value;
    const char * text;
};

Enum_Text_Entry  Enum_To_Text[] =
{
    {TITLE, "title"},
    {FILENAME, "filename"},
    {GENRE, "genre"},
};

const unsigned int NUMBER_OF_ENTRIES =
sizeof(Enum_To_Text) / sizeof(Enum_To_Text[0]);
 

Теперь просто найдите в таблице перечисление и прочитайте текст. Самое приятное в объединении значения enum и текста в структуре заключается в том, что это позволяет изменять значения enum, но остальная часть кода не должна меняться.

Комментарии:

1. Приятно, что сработало! Мне пришлось немного поиграть с этим и #define убрать enum определение. В нашем случае, я полагаю, мысль заключалась в том, что линейный поиск по списку атрибутов был бы нежелательным, поскольку он заканчивается в узком цикле. Однако это хороший момент — использование такого препроцессора довольно запутанно.