master ohmu/fastfetch-openbsd / src / 3rdparty / sixel / status.c
ohmu  ·  2026-10-15
  1/*
  2 * Copyright (c) 2014-2018 Hayaki Saito
  3 *
  4 * Permission is hereby granted, free of charge, to any person obtaining a copy of
  5 * this software and associated documentation files (the "Software"), to deal in
  6 * the Software without restriction, including without limitation the rights to
  7 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  8 * the Software, and to permit persons to whom the Software is furnished to do so,
  9 * subject to the following conditions:
 10 *
 11 * The above copyright notice and this permission notice shall be included in all
 12 * copies or substantial portions of the Software.
 13 *
 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 16 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 17 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 18 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 20 */
 21
 22#include "config.h"
 23
 24/* STDC_HEADERS */
 25#include <stdio.h>
 26#include <stdlib.h>
 27
 28#if HAVE_MEMORY_H
 29# include <memory.h>
 30#endif  /* HAVE_MEMORY_H */
 31#ifdef HAVE_STRING_H
 32# include <string.h>
 33#endif  /* HAVE_STRING_H */
 34#ifdef HAVE_ERRNO_H
 35# include <errno.h>
 36#endif  /* HAVE_ERRNO_H */
 37#ifdef HAVE_LIBCURL
 38# include <curl/curl.h>
 39#endif  /* HAVE_LIBCURL */
 40
 41#include <sixel.h>
 42#include "status.h"
 43
 44#define SIXEL_MESSAGE_OK                    ("succeeded")
 45#define SIXEL_MESSAGE_FALSE                 ("unexpected error (SIXEL_FALSE)");
 46#define SIXEL_MESSAGE_UNEXPECTED            ("unexpected error")
 47#define SIXEL_MESSAGE_INTERRUPTED           ("interrupted by a signal")
 48#define SIXEL_MESSAGE_BAD_ALLOCATION        ("runtime error: bad allocation error")
 49#define SIXEL_MESSAGE_BAD_ARGUMENT          ("runtime error: bad argument detected")
 50#define SIXEL_MESSAGE_BAD_INPUT             ("runtime error: bad input detected")
 51#define SIXEL_MESSAGE_BAD_INTEGER_OVERFLOW  ("runtime error: integer overflow")
 52#define SIXEL_MESSAGE_RUNTIME_ERROR         ("runtime error")
 53#define SIXEL_MESSAGE_LOGIC_ERROR           ("logic error")
 54#define SIXEL_MESSAGE_NOT_IMPLEMENTED       ("feature error: not implemented")
 55#define SIXEL_MESSAGE_FEATURE_ERROR         ("feature error")
 56#define SIXEL_MESSAGE_STBI_ERROR            ("stb_image error")
 57#define SIXEL_MESSAGE_STBIW_ERROR           ("stb_image_write error")
 58#define SIXEL_MESSAGE_JPEG_ERROR            ("libjpeg error")
 59#define SIXEL_MESSAGE_PNG_ERROR             ("libpng error")
 60#define SIXEL_MESSAGE_GDK_ERROR             ("GDK error")
 61#define SIXEL_MESSAGE_GD_ERROR              ("GD error")
 62
 63
 64static char g_buffer[1024] = { 0x0 };
 65
 66/* set detailed error message (thread-unsafe) */
 67SIXELAPI void
 68sixel_helper_set_additional_message(
 69    const char      /* in */  *message         /* error message */
 70)
 71{
 72    size_t len;
 73
 74    if (message == 0)
 75        return;
 76    len = strlen(message);
 77    memcpy(g_buffer, message, len < sizeof(g_buffer) ? len: sizeof(g_buffer) - 1);
 78    g_buffer[sizeof(g_buffer) - 1] = 0;
 79}
 80
 81
 82/* get detailed error message (thread-unsafe) */
 83SIXELAPI char const *
 84sixel_helper_get_additional_message(void)
 85{
 86    return g_buffer;
 87}
 88
 89
 90/* convert error status code int formatted string */
 91SIXELAPI char const *
 92sixel_helper_format_error(
 93    SIXELSTATUS     /* in */  status           /* status code */
 94)
 95{
 96    static char buffer[1024];
 97    char const *error_string;
 98    char *p;
 99    size_t len;
100
101    switch (status & 0x1000) {
102    case SIXEL_OK:
103        switch (status) {
104        case SIXEL_INTERRUPTED:
105            error_string = SIXEL_MESSAGE_INTERRUPTED;
106            break;
107        case SIXEL_OK:
108        default:
109            error_string = SIXEL_MESSAGE_OK;
110            break;
111        }
112        break;
113    case SIXEL_FALSE:
114        switch (status & 0x1f00) {
115        case SIXEL_RUNTIME_ERROR:
116            switch (status) {
117            case SIXEL_BAD_ALLOCATION:
118                error_string = SIXEL_MESSAGE_BAD_ALLOCATION;
119                break;
120            case SIXEL_BAD_ARGUMENT:
121                error_string = SIXEL_MESSAGE_BAD_ARGUMENT;
122                break;
123            case SIXEL_BAD_INPUT:
124                error_string = SIXEL_MESSAGE_BAD_INPUT;
125                break;
126            case SIXEL_BAD_INTEGER_OVERFLOW:
127                error_string = SIXEL_MESSAGE_BAD_INTEGER_OVERFLOW;
128                break;
129            default:
130                error_string = SIXEL_MESSAGE_RUNTIME_ERROR;
131                break;
132            }
133            break;
134        case SIXEL_LOGIC_ERROR:
135            error_string = SIXEL_MESSAGE_LOGIC_ERROR;
136            break;
137        case SIXEL_FEATURE_ERROR:
138            switch (status) {
139            case SIXEL_NOT_IMPLEMENTED:
140                error_string = SIXEL_MESSAGE_NOT_IMPLEMENTED;
141                break;
142            default:
143                error_string = SIXEL_MESSAGE_FEATURE_ERROR;
144                break;
145            }
146            break;
147        case SIXEL_LIBC_ERROR:
148            p = strerror(errno);
149            len = strlen(p) + 1;
150            memcpy(buffer, p, len < sizeof(buffer) ? len: sizeof(buffer) - 1);
151            buffer[sizeof(buffer) - 1] = 0;
152            error_string = buffer;
153            break;
154#ifdef HAVE_LIBCURL
155        case SIXEL_CURL_ERROR:
156            error_string = curl_easy_strerror(status & 0xff);
157            break;
158#endif
159#ifdef HAVE_JPEG
160        case SIXEL_JPEG_ERROR:
161            error_string = SIXEL_MESSAGE_JPEG_ERROR;
162            break;
163#endif
164#ifdef HAVE_LIBPNG
165        case SIXEL_PNG_ERROR:
166            error_string = SIXEL_MESSAGE_PNG_ERROR;
167            break;
168#endif
169#ifdef HAVE_GDK_PIXBUF2
170        case SIXEL_GDK_ERROR:
171            error_string = SIXEL_MESSAGE_GDK_ERROR;
172            break;
173#endif
174#ifdef HAVE_GD
175        case SIXEL_GD_ERROR:
176            error_string = SIXEL_MESSAGE_GD_ERROR;
177            break;
178#endif
179        case SIXEL_STBI_ERROR:
180            error_string = SIXEL_MESSAGE_STBI_ERROR;
181            break;
182        case SIXEL_STBIW_ERROR:
183            error_string = SIXEL_MESSAGE_STBIW_ERROR;
184            break;
185        case SIXEL_FALSE:
186            error_string = SIXEL_MESSAGE_FALSE;
187            break;
188        default:
189            error_string = SIXEL_MESSAGE_UNEXPECTED;
190            break;
191        }
192        break;
193    default:
194        error_string = SIXEL_MESSAGE_UNEXPECTED;
195        break;
196    }
197    return error_string;
198}
199
200
201#if HAVE_TESTS
202static int
203test1(void)
204{
205    int nret = EXIT_FAILURE;
206    char const *message;
207
208    message = sixel_helper_format_error(SIXEL_OK);
209    if (strcmp(message, SIXEL_MESSAGE_OK) != 0) {
210        goto error;
211    }
212
213    message = sixel_helper_format_error(SIXEL_INTERRUPTED);
214    if (strcmp(message, SIXEL_MESSAGE_INTERRUPTED) != 0) {
215        goto error;
216    }
217    return EXIT_SUCCESS;
218error:
219    perror("test1");
220    return nret;
221}
222
223
224static int
225test2(void)
226{
227    int nret = EXIT_FAILURE;
228    char const *message;
229
230    message = sixel_helper_format_error(SIXEL_BAD_ALLOCATION);
231    if (strcmp(message, SIXEL_MESSAGE_BAD_ALLOCATION) != 0) {
232        goto error;
233    }
234
235    message = sixel_helper_format_error(SIXEL_BAD_ARGUMENT);
236    if (strcmp(message, SIXEL_MESSAGE_BAD_ARGUMENT) != 0) {
237        goto error;
238    }
239
240    message = sixel_helper_format_error(SIXEL_BAD_INPUT);
241    if (strcmp(message, SIXEL_MESSAGE_BAD_INPUT) != 0) {
242        goto error;
243    }
244
245    message = sixel_helper_format_error(SIXEL_RUNTIME_ERROR);
246    if (strcmp(message, SIXEL_MESSAGE_RUNTIME_ERROR) != 0) {
247        goto error;
248    }
249
250    message = sixel_helper_format_error(SIXEL_LOGIC_ERROR);
251    if (strcmp(message, SIXEL_MESSAGE_LOGIC_ERROR) != 0) {
252        goto error;
253    }
254
255    message = sixel_helper_format_error(SIXEL_NOT_IMPLEMENTED);
256    if (strcmp(message, SIXEL_MESSAGE_NOT_IMPLEMENTED) != 0) {
257        goto error;
258    }
259
260    message = sixel_helper_format_error(SIXEL_FEATURE_ERROR);
261    if (strcmp(message, SIXEL_MESSAGE_FEATURE_ERROR) != 0) {
262        goto error;
263    }
264
265    message = sixel_helper_format_error(SIXEL_LIBC_ERROR);
266    if (strcmp(message, SIXEL_MESSAGE_UNEXPECTED) == 0) {
267        goto error;
268    }
269
270#ifdef HAVE_LIBCURL
271    message = sixel_helper_format_error(SIXEL_CURL_ERROR);
272    if (strcmp(message, SIXEL_MESSAGE_UNEXPECTED) == 0) {
273        goto error;
274    }
275#endif
276
277#if HAVE_JPEG
278    message = sixel_helper_format_error(SIXEL_JPEG_ERROR);
279    if (strcmp(message, SIXEL_MESSAGE_JPEG_ERROR) != 0) {
280        goto error;
281    }
282#endif
283
284#if HAVE_LIBPNG
285    message = sixel_helper_format_error(SIXEL_PNG_ERROR);
286    if (strcmp(message, SIXEL_MESSAGE_PNG_ERROR) != 0) {
287        goto error;
288    }
289#endif
290
291#if HAVE_GD
292    message = sixel_helper_format_error(SIXEL_GD_ERROR);
293    if (strcmp(message, SIXEL_MESSAGE_GD_ERROR) != 0) {
294        goto error;
295    }
296#endif
297
298#if HAVE_GDK_PIXBUF2
299    message = sixel_helper_format_error(SIXEL_GDK_ERROR);
300    if (strcmp(message, SIXEL_MESSAGE_GDK_ERROR) != 0) {
301        goto error;
302    }
303#endif
304
305    message = sixel_helper_format_error(SIXEL_STBI_ERROR);
306    if (strcmp(message, SIXEL_MESSAGE_STBI_ERROR) != 0) {
307        goto error;
308    }
309
310    message = sixel_helper_format_error(SIXEL_STBIW_ERROR);
311    if (strcmp(message, SIXEL_MESSAGE_STBIW_ERROR) != 0) {
312        goto error;
313    }
314
315    return EXIT_SUCCESS;
316error:
317    perror("test2");
318    return nret;
319}
320
321
322SIXELAPI int
323sixel_status_tests_main(void)
324{
325    int nret = EXIT_FAILURE;
326    size_t i;
327    typedef int (* testcase)(void);
328
329    static testcase const testcases[] = {
330        test1,
331        test2,
332    };
333
334    for (i = 0; i < sizeof(testcases) / sizeof(testcase); ++i) {
335        nret = testcases[i]();
336        if (nret != EXIT_SUCCESS) {
337            goto error;
338        }
339    }
340
341    nret = EXIT_SUCCESS;
342
343error:
344    return nret;
345}
346#endif  /* HAVE_TESTS */
347
348/* emacs Local Variables:      */
349/* emacs mode: c               */
350/* emacs tab-width: 4          */
351/* emacs indent-tabs-mode: nil */
352/* emacs c-basic-offset: 4     */
353/* emacs End:                  */
354/* vim: set expandtab ts=4 sts=4 sw=4 : */
355/* EOF */