/*
 *  Error message information
 *
 *  Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
 *
 *  This file is part of mbed TLS (https://www.polarssl.org)
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#if !defined(POLARSSL_CONFIG_FILE)
#include "polarssl/config.h"
#else
#include POLARSSL_CONFIG_FILE
#endif

#if defined(POLARSSL_ERROR_C) || defined(POLARSSL_ERROR_STRERROR_DUMMY)
#include "polarssl/error.h"
#endif

#if defined(POLARSSL_ERROR_C)

HEADER_INCLUDED

#include <string.h>

#if defined(_MSC_VER) && !defined  snprintf && !defined(EFIX64) && \
    !defined(EFI32)
#define  snprintf  _snprintf
#endif

void polarssl_strerror( int ret, char *buf, size_t buflen )
{
    size_t len;
    int use_ret;

    if( buflen == 0 )
        return;

    memset( buf, 0x00, buflen );
    /* Reduce buflen to make sure MSVC _snprintf() ends with \0 as well */
    buflen -= 1;

    if( ret < 0 )
        ret = -ret;

    if( ret & 0xFF80 )
    {
        use_ret = ret & 0xFF80;

        // High level error codes
        //
        // BEGIN generated code
HIGH_LEVEL_CODE_CHECKS
        // END generated code

        if( strlen( buf ) == 0 )
            snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
    }

    use_ret = ret & ~0xFF80;

    if( use_ret == 0 )
        return;

    // If high level code is present, make a concatenation between both
    // error strings.
    //
    len = strlen( buf );

    if( len > 0 )
    {
        if( buflen - len < 5 )
            return;

        snprintf( buf + len, buflen - len, " : " );

        buf += len + 3;
        buflen -= len + 3;
    }

    // Low level error codes
    //
    // BEGIN generated code
LOW_LEVEL_CODE_CHECKS
    // END generated code

    if( strlen( buf ) != 0 )
        return;

    snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
}

#if defined(POLARSSL_ERROR_STRERROR_BC)
void error_strerror( int ret, char *buf, size_t buflen )
{
    polarssl_strerror( ret, buf, buflen );
}
#endif /* POLARSSL_ERROR_STRERROR_BC */

#else /* POLARSSL_ERROR_C */

#if defined(POLARSSL_ERROR_STRERROR_DUMMY)

#include <string.h>

/*
 * Provide an non-function in case POLARSSL_ERROR_C is not defined
 */
void polarssl_strerror( int ret, char *buf, size_t buflen )
{
    ((void) ret);

    if( buflen > 0 )
        buf[0] = '\0';
}

#if defined(POLARSSL_ERROR_STRERROR_BC)
void error_strerror( int ret, char *buf, size_t buflen )
{
    polarssl_strerror( ret, buf, buflen );
}
#endif /* POLARSSL_ERROR_STRERROR_BC */
#endif /* POLARSSL_ERROR_STRERROR_DUMMY */

#endif /* POLARSSL_ERROR_C */
