Use format strings that contain %1, %2 etc. instead of %d, %s etc. - Linux, C++

Posted by rursw1 on Stack Overflow See other posts from Stack Overflow or by rursw1
Published on 2010-12-26T10:45:51Z Indexed on 2010/12/26 10:53 UTC
Read the original article Hit count: 235

Filed under:
|
|
|

Hello,

As a follow-up of this question (Message compiler replacement in Linux gcc), I have the following problem:

When using MC.exe on Windows for compiling and generating messages, within the C++ code I call FormatMessage, which retrieves the message and uses the va_list *Arguments parameter to send the varied message arguments. For example:
messages.mc file:

MessageId=1
Severity=Error
SymbolicName=MULTIPLE_MESSAGE_OCCURED
Language=English
message %1 occured %2 times.
.

C++ code:

void GetMsg(unsigned int errCode, wstring& message,unsigned int paramNumber, ...)
{   
    HLOCAL msg;
    DWORD ret;
    LANGID lang = GetUserDefaultLangID();
    try
    {
        va_list argList;
        va_start( argList, paramNumber );
        const TCHAR* dll = L"MyDll.dll";
        _hModule = GetModuleHandle(dll);
        ret =::FormatMessage(
            FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE|FORMAT_MESSAGE_IGNORE_INSERTS,
            _hModule,
            errCode,
            lang,
            (LPTSTR) &msg,
            0,
            &argList );
        if ( 0 != ret )
        {
            unsigned int count = 0 ;
            message = msg;
            if (paramNumber>0)
            {
                wstring::const_iterator iter;
                for (iter = message.begin();iter!=message.end();iter++)
                {
                    wchar_t xx = *iter;
                    if (xx ==L'%')
                        count++;
                }
            }
            if ((count == paramNumber) && (count >0))
            {

                ::LocalFree( msg );
                ret =::FormatMessage(
                    FORMAT_MESSAGE_ALLOCATE_BUFFER |
                    FORMAT_MESSAGE_FROM_HMODULE,
                    _hModule,
                    errCode,
                    GetUserDefaultLangID(),
                    (LPTSTR) &msg,
                    0,
                    &argList );
            }
            else if (count != paramNumber)
            {
                wstringstream tmp;
                wstring messNumber;
                tmp << (errCode & 0xFFFF);
                tmp >> messNumber;
                message = message +L"("+ messNumber + L"). Bad Format String. ";
            }
        }
        ::LocalFree( msg );
    }
    catch (...)
    {
        message << L"last error: " << GetLastError();
    }
    va_end( argList );
}

Caller code:

wstring message;
GetMsg(MULTIPLE_MESSAGE_OCCURED, message,2, "Error message", 5);

Now, I wrote a simple script to generate a .msg file from the .mc file, and then I use gencat to generate a catalog from it.

But is there a way to use the formatted strings as they contain %1, %2, etc. and NOT the general (%d, %s...) format?

Please note, that the solution has to be generic enough for each possible message with each posible types\ arguments order...

Is it possible at all?

Thank you.

© Stack Overflow or respective owner

Related posts about c++

Related posts about gcc