src/consolelogger.c
void consolelogger_log_with_GetLastError(const char* file, const char* func, int line, const char* format, ...)
{
    DWORD lastError;

    char message[LOG_SIZE_REGULAR];

    int size = 0; /*size tracks number of character from "message" that are used so far, not counting the last null character. Uses int as data type because snprintf functions return int*/

    int snprintf_result;

    /*this function builds a string in message variable from 3 sources
    1) the system state (time, file, function, line)
    2) the user (format,...)
    3) whatever GetLastError can provide
    */
    va_list args;
    va_start(args, format);

    lastError = GetLastError();

    message[0] = '\0';

    {/*scope for 1) the system state (time, file, function, line)*/
        time_t t;
        t = time(NULL);
        snprintf_result = snprintf(message + size, sizeof(message) - size, "Error: Time:%.24s File:%s Func:%s Line:%d ", ctime(&t), file, func, line);
        if (snprintf_result < 0)
        {
            (void)puts("error in snprintf trying to output the system message");
        }
        else
        {
            if (snprintf_result >= (int)sizeof(message) - size)
            {
                (void)puts("not enough caracters in message to hold the system message");
            }
            else
            {
                size += snprintf_result;
            }
        }
    }

    {/*scope for 2) the user (format,...)*/
        snprintf_result = vsnprintf(message + size, sizeof(message) - size, format, args);
        if (snprintf_result < 0)
        {
            (void)puts("error in vsnprintf trying to output the user message");
        }
        else
        {
            if (snprintf_result >= (int)sizeof(message) - size)
            {
                (void)puts("not enough characters in message to hold the user message");
            }
            else
            {
                size += snprintf_result;
            }
        }
    }

    {/*scope for 3) whatever GetLastError can provide*/

        /*add the getlastError for good measure anyway*/
        snprintf_result = snprintf(message + size, sizeof(message) - size, " GetLastError()=%#lx ", lastError);
        if (snprintf_result < 0)
        {
            (void)puts("error in snprintf trying to output GetLastError's value");
        }
        else
        {
            if (snprintf_result >= (int)sizeof(message) - size)
            {
                (void)puts("not enough characters in message to hold  GetLastError's value");
            }
            else
            {
                size += snprintf_result;

                if (FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, lastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), message + size, sizeof(message) - size, NULL) == 0)
                {
                    (void)puts("error in snprintf trying to output GetLastError's value as string");
                }
                else
                {
                    /*remove extraneous newlines from FormatMessageA's output*/
                    char* whereAreThey;
                    if ((whereAreThey = strchr(message + size, '\r')) != NULL)
                    {
                        *whereAreThey = '\0';
                    }
                    if ((whereAreThey = strchr(message + size, '\n')) != NULL)
                    {
                        *whereAreThey = '\0';
                    }

                    /*everything has been compiled in message...*/
                }
            }
        }
    }

    /*in any case, print the string as is*/
    (void)puts(message);

    va_end(args);
}
/*this function will use 1x puts (in the happy case) .*/
/*more than 1x printf / function call can mean intermingled LogErrors in a multithreaded env*/
/*the function will also attempt to produce some human readable strings for GetLastError*/
this function will use 1x puts (in the happy case) .
more than 1x printf / function call can mean intermingled LogErrors in a multithreaded env
the function will also attempt to produce some human readable strings for GetLastError
this function will use 1x puts ( in the happy case ) . more than 1x printf / function call can mean intermingled LogErrors in a multithreaded env the function will also attempt to produce some human readable strings for GetLastError
void consolelogger_log_with_GetLastError(const char* file, const char* func, int line, const char* format, ...)
{
    DWORD lastError;
    char message[LOG_SIZE_REGULAR];
    int size = 0; 
    int snprintf_result;
    va_list args;
    va_start(args, format);
    lastError = GetLastError();
    message[0] = '\0';
    {
        time_t t;
        t = time(NULL);
        snprintf_result = snprintf(message + size, sizeof(message) - size, "Error: Time:%.24s File:%s Func:%s Line:%d ", ctime(&t), file, func, line);
        if (snprintf_result < 0)
        {
            (void)puts("error in snprintf trying to output the system message");
        }
        else
        {
            if (snprintf_result >= (int)sizeof(message) - size)
            {
                (void)puts("not enough caracters in message to hold the system message");
            }
            else
            {
                size += snprintf_result;
            }
        }
    }
    {
        snprintf_result = vsnprintf(message + size, sizeof(message) - size, format, args);
        if (snprintf_result < 0)
        {
            (void)puts("error in vsnprintf trying to output the user message");
        }
        else
        {
            if (snprintf_result >= (int)sizeof(message) - size)
            {
                (void)puts("not enough characters in message to hold the user message");
            }
            else
            {
                size += snprintf_result;
            }
        }
    }
    {
        snprintf_result = snprintf(message + size, sizeof(message) - size, " GetLastError()=%#lx ", lastError);
        if (snprintf_result < 0)
        {
            (void)puts("error in snprintf trying to output GetLastError's value");
        }
        else
        {
            if (snprintf_result >= (int)sizeof(message) - size)
            {
                (void)puts("not enough characters in message to hold  GetLastError's value");
            }
            else
            {
                size += snprintf_result;
                if (FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, lastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), message + size, sizeof(message) - size, NULL) == 0)
                {
                    (void)puts("error in snprintf trying to output GetLastError's value as string");
                }
                else
                {
                    char* whereAreThey;
                    if ((whereAreThey = strchr(message + size, '\r')) != NULL)
                    {
                        *whereAreThey = '\0';
                    }
                    if ((whereAreThey = strchr(message + size, '\n')) != NULL)
                    {
                        *whereAreThey = '\0';
                    }
                }
            }
        }
    }
    (void)puts(message);
    va_end(args);
}
void consolelogger_log_with_GetLastError ( const char * file , const char * func , int line , const char * format , ... ) { DWORD lastError ; char message [ LOG_SIZE_REGULAR ] ; int size = 0 ; int snprintf_result ; va_list args ; va_start ( args , format ) ; lastError = GetLastError ( ) ; message [ 0 ] = ' \0 ' ; { time_t t ; t = time ( NULL ) ; snprintf_result = snprintf ( message + size , sizeof ( message ) - size , " " , ctime ( & t ) , file , func , line ) ; if ( snprintf_result < 0 ) { ( void ) puts ( " " ) ; } else { if ( snprintf_result >= ( int ) sizeof ( message ) - size ) { ( void ) puts ( " " ) ; } else { size += snprintf_result ; } } } { snprintf_result = vsnprintf ( message + size , sizeof ( message ) - size , format , args ) ; if ( snprintf_result < 0 ) { ( void ) puts ( " " ) ; } else { if ( snprintf_result >= ( int ) sizeof ( message ) - size ) { ( void ) puts ( " " ) ; } else { size += snprintf_result ; } } } { snprintf_result = snprintf ( message + size , sizeof ( message ) - size , " " , lastError ) ; if ( snprintf_result < 0 ) { ( void ) puts ( " " ) ; } else { if ( snprintf_result >= ( int ) sizeof ( message ) - size ) { ( void ) puts ( " " ) ; } else { size += snprintf_result ; if ( FormatMessageA ( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS , NULL , lastError , MAKELANGID ( LANG_NEUTRAL , SUBLANG_DEFAULT ) , message + size , sizeof ( message ) - size , NULL ) == 0 ) { ( void ) puts ( " " ) ; } else { char * whereAreThey ; if ( ( whereAreThey = strchr ( message + size , ' \r ' ) ) != NULL ) { * whereAreThey = ' \0 ' ; } if ( ( whereAreThey = strchr ( message + size , ' \n ' ) ) != NULL ) { * whereAreThey = ' \0 ' ; } } } } } ( void ) puts ( message ) ; va_end ( args ) ; }
this function will use 1x puts (in the happy case) .
this function will use 1x puts ( in the happy case ) .
/*size tracks number of character from "message" that are used so far, not counting the last null character. Uses int as data type because snprintf functions return int*/ /*this function builds a string in message variable from 3 sources
    1) the system state (time, file, function, line)
    2) the user (format,...)
    3) whatever GetLastError can provide
    */ /*scope for 1) the system state (time, file, function, line)*/ /*scope for 2) the user (format,...)*/ /*scope for 3) whatever GetLastError can provide*/ /*add the getlastError for good measure anyway*/ /*remove extraneous newlines from FormatMessageA's output*/ /*everything has been compiled in message...*/ /*in any case, print the string as is*/