#include "kim_private.h"
#include <com_err.h>
#include <Kerberos/KerberosDebug.h>
struct kim_error_opaque {
kim_error_code_t code;
kim_string_t string;
};
struct kim_error_opaque kim_no_memory_error_struct = { KIM_OUT_OF_MEMORY_ECODE, NULL };
kim_error_t kim_no_memory_error = &kim_no_memory_error_struct;
struct kim_error_opaque kim_error_initializer = { KIM_NO_ERROR_ECODE, NULL };
static inline kim_error_t kim_error_allocate (void)
{
kim_error_t error = malloc (sizeof (*error));
if (error != NULL) {
*error = kim_error_initializer;
}
return error;
}
#pragma mark -- Helper Functions --
kim_error_t _kim_error_create_for_param (kim_string_t in_function,
kim_count_t in_argument_position,
kim_string_t in_argument_name,
kim_string_t in_invalid_value)
{
return kim_error_create_from_code (KIM_PARAMETER_ECODE,
in_function,
in_argument_position,
in_argument_name,
in_invalid_value);
}
#pragma mark -- Generic Functions --
kim_error_t kim_error_create_from_code (kim_error_code_t in_code,
...)
{
kim_error_t err = KIM_NO_ERROR;
va_list args;
va_start (args, in_code);
err = kim_error_create_from_code_va (in_code, args);
va_end (args);
return check_error (err);
}
kim_error_t kim_error_create_from_code_va (kim_error_code_t in_code,
va_list args)
{
kim_error_t err = NULL;
kim_error_code_t code = KIM_NO_ERROR_ECODE;
kim_string_t string = NULL;
switch (in_code) {
case KIM_OUT_OF_MEMORY_ECODE:
case ENOMEM:
code = KIM_OUT_OF_MEMORY_ECODE;
break;
}
if (!code) {
code = kim_string_create_from_format_va_retcode (&string, error_message (in_code), args);
}
if (!code) {
err = kim_error_allocate ();
if (err == NULL) { code = KIM_OUT_OF_MEMORY_ECODE; }
}
if (!code) {
err->code = in_code;
err->string = string;
string = NULL;
}
kim_string_free (&string);
return code ? kim_no_memory_error : err;
}
kim_error_t kim_error_copy (kim_error_t *out_error,
kim_error_t in_error)
{
kim_error_t err = KIM_NO_ERROR;
kim_error_t error = KIM_NO_ERROR;
if (in_error != NULL) { err = param_error (2, "in_error", "NULL"); }
if (!err) {
if (in_error == kim_no_memory_error) {
error = kim_no_memory_error;
} else {
err = kim_error_allocate ();
if (err == NULL) { err = os_error (KIM_OUT_OF_MEMORY_ECODE); }
if (!err) {
error->code = in_error->code;
in_error->string = NULL;
if (in_error->string != NULL) {
err = kim_string_copy (&error->string, in_error->string);
}
}
}
}
if (!err) {
*out_error = error;
error = KIM_NO_ERROR;
}
kim_error_free (&error);
return check_error (err);
}
kim_error_code_t kim_error_get_code (kim_error_t in_error)
{
if (in_error == KIM_NO_ERROR) {
return KIM_NO_ERROR_ECODE;
} else {
return in_error->code;
}
}
kim_string_t kim_error_get_display_string (kim_error_t in_error)
{
if (in_error == KIM_NO_ERROR) {
return error_message (KIM_NO_ERROR_ECODE);
} else if (in_error->string != NULL) {
return in_error->string;
} else {
return error_message (in_error->code);
}
}
void kim_error_free (kim_error_t *io_error)
{
if (io_error && *io_error) {
if (*io_error != kim_no_memory_error) {
kim_string_free (&(*io_error)->string);
free (*io_error);
io_error = NULL;
}
}
}
#pragma mark -- Debugging Functions --
kim_error_t _check_error (kim_error_t in_err,
kim_string_t in_function,
kim_string_t in_file,
int in_line)
{
if (in_err != KIM_NO_ERROR) {
kim_error_code_t code = kim_error_get_code (in_err);
kim_string_t message = kim_error_get_display_string (in_err);
kim_debug_printf ("%s() got %d ('%s') at %s: %d",
in_function, code, message, in_file, in_line);
}
return in_err;
}