#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <sixel.h>
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_ERRNO_H
# include <errno.h>
#endif
#ifdef HAVE_LIBCURL
# include <curl/curl.h>
#endif
#include "status.h"
#define SIXEL_MESSAGE_OK ("succeeded")
#define SIXEL_MESSAGE_FALSE ("unexpected error (SIXEL_FALSE)");
#define SIXEL_MESSAGE_UNEXPECTED ("unexpected error")
#define SIXEL_MESSAGE_INTERRUPTED ("interrupted by a signal")
#define SIXEL_MESSAGE_BAD_ALLOCATION ("runtime error: bad allocation error")
#define SIXEL_MESSAGE_BAD_ARGUMENT ("runtime error: bad argument detected")
#define SIXEL_MESSAGE_BAD_INPUT ("runtime error: bad input detected")
#define SIXEL_MESSAGE_RUNTIME_ERROR ("runtime error")
#define SIXEL_MESSAGE_LOGIC_ERROR ("logic error")
#define SIXEL_MESSAGE_NOT_IMPLEMENTED ("feature error: not implemented")
#define SIXEL_MESSAGE_FEATURE_ERROR ("feature error")
#define SIXEL_MESSAGE_STBI_ERROR ("stb_image error")
#define SIXEL_MESSAGE_STBIW_ERROR ("stb_image_write error")
#define SIXEL_MESSAGE_JPEG_ERROR ("libjpeg error")
#define SIXEL_MESSAGE_PNG_ERROR ("libpng error")
#define SIXEL_MESSAGE_GDK_ERROR ("GDK error")
#define SIXEL_MESSAGE_GD_ERROR ("GD error")
static char g_buffer[1024] = { 0x0 };
SIXELAPI void
sixel_helper_set_additional_message(
const char *message
)
{
size_t len;
len = strlen(message);
memcpy(g_buffer, message, len < sizeof(g_buffer) ? len: sizeof(g_buffer) - 1);
g_buffer[sizeof(g_buffer) - 1] = 0;
}
SIXELAPI char const *
sixel_helper_get_additional_message(void)
{
return g_buffer;
}
SIXELAPI char const *
sixel_helper_format_error(
SIXELSTATUS status
)
{
static char buffer[1024];
char const *error_string;
char *p;
size_t len;
switch (status & 0x1000) {
case SIXEL_OK:
switch (status) {
case SIXEL_INTERRUPTED:
error_string = SIXEL_MESSAGE_INTERRUPTED;
break;
case SIXEL_OK:
default:
error_string = SIXEL_MESSAGE_OK;
break;
}
break;
case SIXEL_FALSE:
switch (status & 0x1f00) {
case SIXEL_RUNTIME_ERROR:
switch (status) {
case SIXEL_BAD_ALLOCATION:
error_string = SIXEL_MESSAGE_BAD_ALLOCATION;
break;
case SIXEL_BAD_ARGUMENT:
error_string = SIXEL_MESSAGE_BAD_ARGUMENT;
break;
case SIXEL_BAD_INPUT:
error_string = SIXEL_MESSAGE_BAD_INPUT;
break;
default:
error_string = SIXEL_MESSAGE_RUNTIME_ERROR;
break;
}
break;
case SIXEL_LOGIC_ERROR:
error_string = SIXEL_MESSAGE_LOGIC_ERROR;
break;
case SIXEL_FEATURE_ERROR:
switch (status) {
case SIXEL_NOT_IMPLEMENTED:
error_string = SIXEL_MESSAGE_NOT_IMPLEMENTED;
break;
default:
error_string = SIXEL_MESSAGE_FEATURE_ERROR;
break;
}
break;
case SIXEL_LIBC_ERROR:
p = strerror(errno);
len = strlen(p) + 1;
memcpy(buffer, p, len < sizeof(buffer) ? len: sizeof(buffer) - 1);
buffer[sizeof(buffer) - 1] = 0;
error_string = buffer;
break;
#ifdef HAVE_LIBCURL
case SIXEL_CURL_ERROR:
error_string = curl_easy_strerror(status & 0xff);
break;
#endif
#ifdef HAVE_JPEG
case SIXEL_JPEG_ERROR:
error_string = SIXEL_MESSAGE_JPEG_ERROR;
break;
#endif
#ifdef HAVE_LIBPNG
case SIXEL_PNG_ERROR:
error_string = SIXEL_MESSAGE_PNG_ERROR;
break;
#endif
#ifdef HAVE_GDK_PIXBUF2
case SIXEL_GDK_ERROR:
error_string = SIXEL_MESSAGE_GDK_ERROR;
break;
#endif
#ifdef HAVE_GD
case SIXEL_GD_ERROR:
error_string = SIXEL_MESSAGE_GD_ERROR;
break;
#endif
case SIXEL_STBI_ERROR:
error_string = SIXEL_MESSAGE_STBI_ERROR;
break;
case SIXEL_STBIW_ERROR:
error_string = SIXEL_MESSAGE_STBIW_ERROR;
break;
case SIXEL_FALSE:
error_string = SIXEL_MESSAGE_FALSE;
break;
default:
error_string = SIXEL_MESSAGE_UNEXPECTED;
break;
}
break;
default:
error_string = SIXEL_MESSAGE_UNEXPECTED;
break;
}
return error_string;
}
#if HAVE_TESTS
static int
test1(void)
{
int nret = EXIT_FAILURE;
char const *message;
message = sixel_helper_format_error(SIXEL_OK);
if (strcmp(message, SIXEL_MESSAGE_OK) != 0) {
goto error;
}
message = sixel_helper_format_error(SIXEL_INTERRUPTED);
if (strcmp(message, SIXEL_MESSAGE_INTERRUPTED) != 0) {
goto error;
}
return EXIT_SUCCESS;
error:
perror("test1");
return nret;
}
static int
test2(void)
{
int nret = EXIT_FAILURE;
char const *message;
message = sixel_helper_format_error(SIXEL_BAD_ALLOCATION);
if (strcmp(message, SIXEL_MESSAGE_BAD_ALLOCATION) != 0) {
goto error;
}
message = sixel_helper_format_error(SIXEL_BAD_ARGUMENT);
if (strcmp(message, SIXEL_MESSAGE_BAD_ARGUMENT) != 0) {
goto error;
}
message = sixel_helper_format_error(SIXEL_BAD_INPUT);
if (strcmp(message, SIXEL_MESSAGE_BAD_INPUT) != 0) {
goto error;
}
message = sixel_helper_format_error(SIXEL_RUNTIME_ERROR);
if (strcmp(message, SIXEL_MESSAGE_RUNTIME_ERROR) != 0) {
goto error;
}
message = sixel_helper_format_error(SIXEL_LOGIC_ERROR);
if (strcmp(message, SIXEL_MESSAGE_LOGIC_ERROR) != 0) {
goto error;
}
message = sixel_helper_format_error(SIXEL_NOT_IMPLEMENTED);
if (strcmp(message, SIXEL_MESSAGE_NOT_IMPLEMENTED) != 0) {
goto error;
}
message = sixel_helper_format_error(SIXEL_FEATURE_ERROR);
if (strcmp(message, SIXEL_MESSAGE_FEATURE_ERROR) != 0) {
goto error;
}
message = sixel_helper_format_error(SIXEL_LIBC_ERROR);
if (strcmp(message, SIXEL_MESSAGE_UNEXPECTED) == 0) {
goto error;
}
#ifdef HAVE_LIBCURL
message = sixel_helper_format_error(SIXEL_CURL_ERROR);
if (strcmp(message, SIXEL_MESSAGE_UNEXPECTED) == 0) {
goto error;
}
#endif
#if HAVE_JPEG
message = sixel_helper_format_error(SIXEL_JPEG_ERROR);
if (strcmp(message, SIXEL_MESSAGE_JPEG_ERROR) != 0) {
goto error;
}
#endif
#if HAVE_LIBPNG
message = sixel_helper_format_error(SIXEL_PNG_ERROR);
if (strcmp(message, SIXEL_MESSAGE_PNG_ERROR) != 0) {
goto error;
}
#endif
#if HAVE_GD
message = sixel_helper_format_error(SIXEL_GD_ERROR);
if (strcmp(message, SIXEL_MESSAGE_GD_ERROR) != 0) {
goto error;
}
#endif
#if HAVE_GDK_PIXBUF2
message = sixel_helper_format_error(SIXEL_GDK_ERROR);
if (strcmp(message, SIXEL_MESSAGE_GDK_ERROR) != 0) {
goto error;
}
#endif
message = sixel_helper_format_error(SIXEL_STBI_ERROR);
if (strcmp(message, SIXEL_MESSAGE_STBI_ERROR) != 0) {
goto error;
}
message = sixel_helper_format_error(SIXEL_STBIW_ERROR);
if (strcmp(message, SIXEL_MESSAGE_STBIW_ERROR) != 0) {
goto error;
}
return EXIT_SUCCESS;
error:
perror("test2");
return nret;
}
int
sixel_status_tests_main(void)
{
int nret = EXIT_FAILURE;
size_t i;
typedef int (* testcase)(void);
static testcase const testcases[] = {
test1,
test2,
};
for (i = 0; i < sizeof(testcases) / sizeof(testcase); ++i) {
nret = testcases[i]();
if (nret != EXIT_SUCCESS) {
goto error;
}
}
nret = EXIT_SUCCESS;
error:
return nret;
}
#endif