LINUX.ORG.RU

Строковое значение константы

 


1

2

messages.hpp

// Message codes
#define MC_WINDOW  0x00000001
...

// Message params
// Generic
#define MP_NOTHING 0x00000000
// MC_WINDOW
#define MP_SHOW    0x00000001
#define MP_HIDE    0x00000002
...
logger.cpp
const char * Logger::MessageCode(uint code)
{
    switch(code)
    {
    case MC_WINDOW : return "MC_WINDOW";
    ...
    }

    return "";
}

const char * Logger::MessageParam(uint code)
{
    switch(code)
    {
    case MP_NOTHING : return "MC_NOTHING";
    case MP_SHOW    : return "MC_SHOW";
    case MP_HIDE    : return "MC_HIDE";
    ...
    }

    return "";
}

Как сделать лучше? Любой метод.


Ответ на: комментарий от arturpub

Так не сработает:

void Logger::message(uint messageCode, uint param1, uint param2)
{
    qDebug("LOG MESSAGE: %s, %s, %s",
           MessageCode(messageCode),
           MessageParam(param1),
           MessageParam(param2));
}
Будет «messageCode», если вызывать STRINGIFY(messageCode)

inn
() автор топика
Ответ на: комментарий от inn

А я это и не предлагал. Будет тот же код, только не два раза писать слово можно, а один, завернув строку кеймса в макрос.

arturpub ★★
()
Ответ на: комментарий от inn

Можно на перле сваять парсер дефайнов по конкретным префиксам например, и чтобы он выплевывал похожий код.

arturpub ★★
()

Немного препроцессорной магии

codes.def:

/* message codes */
DEFINE_CONSTANT(MC_WINDOW, 0x00000001)
/* other codes */

params.def:

/* Message params */
DEFINE_CONSTANT(MP_NOTHING, 0x00000000)
DEFINE_CONSTANT(MP_SHOW, 0x00000001)
DEFINE_CONSTANT(MP_HIDE, 0x00000002)
/* Other params */

messages.h:

/* INCLUDE GUARD BEGINS */

#define DEFINE_CONSTANT(IDENT, VALUE)           \
    IDENT = VALUE,

enum MESSAGE_CODE {
#include "codes.def"
};

enum MESSAGE_PARAM {
#include "params.def"
};

#undef DEFINE_CONSTANT

const char *message_code(unsigned int code);

const char *message_param(unsigned int param);

/* INCLUDE GUARD ENDS */

logger.c:

#include "messages.h"

#define DEFINE_CONSTANT(IDENT, VALUE)           \
    case IDENT : return #IDENT;

const char *message_code(unsigned int code)
{
    switch(code)
    {
#include "codes.def"

    default:
        return 0; /* indicates error */
    }
}

const char *message_param(unsigned int param)
{
    switch(param)
    {
#include "params.def"

    default:
        return 0; /* indicates error */
    }
}

#undef DEFINE_CONSTANT

Таким образом, определения констант сосредоточены в одном месте — в файлах *.def (расширением может быть любым, естественно), и из этих определений с помощью макросов генерируется различный код.

Сама техника не нова, называется X Macro.

theNamelessOne ★★★★★
()
#define DEFINE_TO_STRING_HELPER(x) #x
#define DEFINE_TO_STRING(x) DEFINE_TO_STRING_HELPER(x)

#include <stdio.h>

#define VALUE 123

int main(int argc, char *argv[])
{
    printf("value = %s\n", DEFINE_TO_STRING(VALUE));
    return 0;
}
oh-la-la
()
Ответ на: комментарий от oh-la-la

Как вариант из с++11, хотя и не совсем уж оптимально. :)

// Message codes
#define MC_WINDOW  0x00000001
....
const char* messageCode(uint code)
{
    static QMap<uint, const char*> codes = {
        {MC_WINDOW, "MC_WINDOW"},
        ....
    };
    return codes.value(code, "unknown");
}

qDebug() << messageCode(MC_WINDOW);

zJes ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.