/*
 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

/*
 * NOTE: this file was auto generated by the mkerr.pl script: any changes
 * made to it will be overwritten when the script next updates this file,
 * only reason strings will be preserved.
 */

#include <stdio.h>
#include <openssl/err.h>
#include "e_dasync_err.h"

/* BEGIN ERROR CODES */
#ifndef OPENSSL_NO_ERR

# define ERR_FUNC(func) ERR_PACK(0,func,0)
# define ERR_REASON(reason) ERR_PACK(0,0,reason)

static ERR_STRING_DATA DASYNC_str_functs[] = {
    {ERR_FUNC(DASYNC_F_BIND_DASYNC), "bind_dasync"},
    {ERR_FUNC(DASYNC_F_CIPHER_AES_128_CBC_CODE), "CIPHER_AES_128_CBC_CODE"},
    {ERR_FUNC(DASYNC_F_DASYNC_AES128_CBC_HMAC_SHA1_INIT_KEY),
     "dasync_aes128_cbc_hmac_sha1_init_key"},
    {ERR_FUNC(DASYNC_F_DASYNC_AES128_INIT_KEY), "dasync_aes128_init_key"},
    {ERR_FUNC(DASYNC_F_DASYNC_BN_MOD_EXP), "DASYNC_BN_MOD_EXP"},
    {ERR_FUNC(DASYNC_F_DASYNC_CIPHER_INIT_KEY_HELPER),
     "dasync_cipher_init_key_helper"},
    {ERR_FUNC(DASYNC_F_DASYNC_MOD_EXP), "DASYNC_MOD_EXP"},
    {ERR_FUNC(DASYNC_F_DASYNC_PRIVATE_DECRYPT), "DASYNC_PRIVATE_DECRYPT"},
    {ERR_FUNC(DASYNC_F_DASYNC_PRIVATE_ENCRYPT), "DASYNC_PRIVATE_ENCRYPT"},
    {ERR_FUNC(DASYNC_F_DASYNC_PUBLIC_DECRYPT), "DASYNC_PUBLIC_DECRYPT"},
    {ERR_FUNC(DASYNC_F_DASYNC_PUBLIC_ENCRYPT), "DASYNC_PUBLIC_ENCRYPT"},
    {0, NULL}
};

static ERR_STRING_DATA DASYNC_str_reasons[] = {
    {ERR_REASON(DASYNC_R_INIT_FAILED), "init failed"},
    {ERR_REASON(DASYNC_R_LENGTH_NOT_BLOCK_ALIGNED),
     "length not block aligned"},
    {ERR_REASON(DASYNC_R_UNKNOWN_FAULT), "unknown fault"},
    {0, NULL}
};

#endif

#ifdef DASYNC_LIB_NAME
static ERR_STRING_DATA DASYNC_lib_name[] = {
    {0, DASYNC_LIB_NAME},
    {0, NULL}
};
#endif

static int DASYNC_lib_error_code = 0;
static int DASYNC_error_init = 1;

static void ERR_load_DASYNC_strings(void)
{
    if (DASYNC_lib_error_code == 0)
        DASYNC_lib_error_code = ERR_get_next_error_library();

    if (DASYNC_error_init) {
        DASYNC_error_init = 0;
#ifndef OPENSSL_NO_ERR
        ERR_load_strings(DASYNC_lib_error_code, DASYNC_str_functs);
        ERR_load_strings(DASYNC_lib_error_code, DASYNC_str_reasons);
#endif

#ifdef DASYNC_LIB_NAME
        DASYNC_lib_name->error = ERR_PACK(DASYNC_lib_error_code, 0, 0);
        ERR_load_strings(0, DASYNC_lib_name);
#endif
    }
}

static void ERR_unload_DASYNC_strings(void)
{
    if (DASYNC_error_init == 0) {
#ifndef OPENSSL_NO_ERR
        ERR_unload_strings(DASYNC_lib_error_code, DASYNC_str_functs);
        ERR_unload_strings(DASYNC_lib_error_code, DASYNC_str_reasons);
#endif

#ifdef DASYNC_LIB_NAME
        ERR_unload_strings(0, DASYNC_lib_name);
#endif
        DASYNC_error_init = 1;
    }
}

static void ERR_DASYNC_error(int function, int reason, char *file, int line)
{
    if (DASYNC_lib_error_code == 0)
        DASYNC_lib_error_code = ERR_get_next_error_library();
    ERR_PUT_error(DASYNC_lib_error_code, function, reason, file, line);
}
