• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

saitoha / libsixel / 19918707358

04 Dec 2025 05:12AM UTC coverage: 38.402% (-4.0%) from 42.395%
19918707358

push

github

saitoha
tests: fix meson msys dll lookup

9738 of 38220 branches covered (25.48%)

12841 of 33438 relevant lines covered (38.4%)

782420.02 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

41.45
/src/status.c
1
/*
2
 * SPDX-License-Identifier: MIT
3
 *
4
 * Copyright (c) 2021-2025 libsixel developers. See `AUTHORS`.
5
 * Copyright (c) 2014-2018 Hayaki Saito
6
 *
7
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
8
 * this software and associated documentation files (the "Software"), to deal in
9
 * the Software without restriction, including without limitation the rights to
10
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11
 * the Software, and to permit persons to whom the Software is furnished to do so,
12
 * subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included in all
15
 * copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
 */
24

25
#include "config.h"
26

27
/* STDC_HEADERS */
28
#include <stdio.h>
29
#include <stdlib.h>
30

31
#if HAVE_MEMORY_H
32
# include <memory.h>
33
#endif  /* HAVE_MEMORY_H */
34
#ifdef HAVE_STRING_H
35
# include <string.h>
36
#endif  /* HAVE_STRING_H */
37
#ifdef HAVE_ERRNO_H
38
# include <errno.h>
39
#endif  /* HAVE_ERRNO_H */
40
#ifdef SIXEL_DISABLE_EXT_LIBS
41
# undef HAVE_LIBCURL
42
# undef HAVE_JPEG
43
# undef HAVE_LIBPNG
44
# undef HAVE_GDK_PIXBUF2
45
# undef HAVE_GD
46
#endif
47

48
#ifdef HAVE_LIBCURL
49
# include <curl/curl.h>
50
#endif  /* HAVE_LIBCURL */
51

52
#include <sixel.h>
53
#include "status.h"
54

55
#if !defined(SIXEL_STATUS_HAVE_TTY_HELPERS)
56
/*
57
 * Some auxiliary targets (for example the macOS Quick Look helpers)
58
 * build src/status.c without linking src/tty.c.  The flag lets those
59
 * targets drop the tty dependency while the main library keeps it.
60
 */
61
#define SIXEL_STATUS_HAVE_TTY_HELPERS 1
62
#endif
63

64
#if SIXEL_STATUS_HAVE_TTY_HELPERS
65
# include "tty.h"
66
#endif
67
#include "compat_stub.h"
68

69
#define SIXEL_MESSAGE_OK                    ("succeeded")
70
#define SIXEL_MESSAGE_FALSE                 ("unexpected error (SIXEL_FALSE)");
71
#define SIXEL_MESSAGE_UNEXPECTED            ("unexpected error")
72
#define SIXEL_MESSAGE_INTERRUPTED           ("interrupted by a signal")
73
#define SIXEL_MESSAGE_BAD_ALLOCATION        ("runtime error: bad allocation error")
74
#define SIXEL_MESSAGE_BAD_ARGUMENT          ("runtime error: bad argument detected")
75
#define SIXEL_MESSAGE_BAD_INPUT             ("runtime error: bad input detected")
76
#define SIXEL_MESSAGE_BAD_INTEGER_OVERFLOW  ("runtime error: integer overflow")
77
#define SIXEL_MESSAGE_BAD_CLIPBOARD         \
78
    ("runtime error: clipboard payload unavailable")
79
#define SIXEL_MESSAGE_LOADER_FAILED         \
80
    ("runtime error: unable to decode input with available loaders")
81
#define SIXEL_MESSAGE_RUNTIME_ERROR         ("runtime error")
82
#define SIXEL_MESSAGE_LOGIC_ERROR           ("logic error")
83
#define SIXEL_MESSAGE_NOT_IMPLEMENTED       ("feature error: not implemented")
84
#define SIXEL_MESSAGE_FEATURE_ERROR         ("feature error")
85
#define SIXEL_MESSAGE_STBI_ERROR            ("stb_image error")
86
#define SIXEL_MESSAGE_STBIW_ERROR           ("stb_image_write error")
87
#define SIXEL_MESSAGE_JPEG_ERROR            ("libjpeg error")
88
#define SIXEL_MESSAGE_PNG_ERROR             ("libpng error")
89
#define SIXEL_MESSAGE_GDK_ERROR             ("GDK error")
90
#define SIXEL_MESSAGE_GD_ERROR              ("GD error")
91

92
void
93
sixel_debugf(char const *fmt, ...)
684✔
94
{
95
#if HAVE_DEBUG
96
    enum { message_length = 256 };
684✔
97
    char message[message_length];
684✔
98
    va_list args;
684✔
99
    int nwrite;
684✔
100

101
    if (fmt == NULL) {
684!
102
        return;
×
103
    }
104

105
    va_start(args, fmt);
684✔
106
#if defined(__clang__)
107
#pragma clang diagnostic push
108
#pragma clang diagnostic ignored "-Wformat-nonliteral"
109
#elif defined(__GNUC__)
110
#pragma GCC diagnostic push
111
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
112
#endif
113
    nwrite = sixel_compat_vsnprintf(message,
684✔
114
                                    sizeof(message),
115
                                    fmt,
116
                                    args);
117
#if defined(__clang__)
118
#pragma clang diagnostic pop
119
#elif defined(__GNUC__)
120
#pragma GCC diagnostic pop
121
#endif
122
    va_end(args);
684✔
123

124
    if (nwrite > 0) {
684!
125
        sixel_helper_set_additional_message(message);
684✔
126
    }
127
#else
128
    (void)fmt;
129
#endif
130
}
1!
131

132
enum {
133
    SIXEL_STATUS_MESSAGE_LIMIT = 4096
134
};
135

136
static char status_markup_buffer[SIXEL_STATUS_MESSAGE_LIMIT] = { 0x0 };
137
static char status_render_buffer[SIXEL_STATUS_MESSAGE_LIMIT] = { 0x0 };
138

139
enum sixel_status_markup_attr {
140
    SIXEL_STATUS_ATTR_NONE = 0,
141
    SIXEL_STATUS_ATTR_BOLD,
142
    SIXEL_STATUS_ATTR_ERROR,
143
    SIXEL_STATUS_ATTR_WARNING
144
};
145

146
static size_t
147
sixel_status_utf8_expected_length(unsigned char byte);
148

149
static size_t
150
sixel_status_utf8_trim_length(const char *message, size_t length);
151

152
static size_t
153
sixel_status_append_literal(char *buffer,
154
                            size_t buffer_size,
155
                            size_t index,
156
                            char value);
157

158
static size_t
159
sixel_status_append_sequence(char *buffer,
160
                             size_t buffer_size,
161
                             size_t index,
162
                             const char *sequence);
163

164
static size_t
165
sixel_status_render_markup(const char *source,
166
                           char *destination,
167
                           size_t destination_size);
168

169
/*
170
 * Markup overview
171
 * +---------+------------------------------+-----------------------------+
172
 * | Token   | Meaning                      | Notes                       |
173
 * +---------+------------------------------+-----------------------------+
174
 * | \\fB ... | Bold text                   | Closed by \\fP              |
175
 * | \\fE ... | Error highlight (red)       | Closed by \\fP              |
176
 * | \\fW ... | Warning highlight (yellow)  | Closed by \\fP              |
177
 * | \\fP     | Reset attributes            | Applies to active token     |
178
 * | \\\\     | Literal backslash           |                             |
179
 * | \\f\\\\  | Literal form-feed marker    | Emits a single '\\f'        |
180
 * +---------+------------------------------+-----------------------------+
181
 */
182

183
/* set detailed error message (thread-unsafe) */
184
SIXELAPI void
185
sixel_helper_set_additional_message(
912✔
186
    const char      /* in */  *message         /* error message */
187
)
188
{
189
    size_t length;
912✔
190
    size_t copy_length;
912✔
191

192
    if (message == NULL) {
912!
193
        status_markup_buffer[0] = '\0';
×
194
        status_render_buffer[0] = '\0';
×
195
        return;
×
196
    }
197

198
    length = strlen(message);
912✔
199
    copy_length = length;
912✔
200

201
    if (copy_length >= SIXEL_STATUS_MESSAGE_LIMIT) {
912!
202
        copy_length = SIXEL_STATUS_MESSAGE_LIMIT - 1;
×
203
        copy_length = sixel_status_utf8_trim_length(message,
×
204
                                                    copy_length);
205
    }
206

207
    memcpy(status_markup_buffer, message, copy_length);
912✔
208
    status_markup_buffer[copy_length] = '\0';
912✔
209
    status_render_buffer[0] = '\0';
912✔
210
}
1!
211

212

213
/* get detailed error message (thread-unsafe) */
214
SIXELAPI char const *
215
sixel_helper_get_additional_message(void)
222✔
216
{
217
    (void)sixel_status_render_markup(status_markup_buffer,
222✔
218
                                     status_render_buffer,
219
                                     sizeof(status_render_buffer));
220
    return status_render_buffer;
222✔
221
}
222

223
void
224
sixel_status_render_markup_text(char const *source,
×
225
                                char *destination,
226
                                size_t destination_size)
227
{
228
    if (destination == NULL || destination_size == 0) {
×
229
        return;
230
    }
231

232
    if (source == NULL) {
×
233
        destination[0] = '\0';
×
234
        return;
×
235
    }
236

237
    (void)sixel_status_render_markup(source,
×
238
                                     destination,
239
                                     destination_size);
240
}
241

242
static size_t
243
sixel_status_utf8_expected_length(unsigned char byte)
×
244
{
245
    size_t length;
×
246

247
    length = 1;
×
248

249
    if ((byte & 0x80u) == 0) {
×
250
        length = 1;
251
    } else if ((byte & 0xE0u) == 0xC0u) {
×
252
        length = 2;
253
    } else if ((byte & 0xF0u) == 0xE0u) {
×
254
        length = 3;
255
    } else if ((byte & 0xF8u) == 0xF0u) {
×
256
        length = 4;
×
257
    }
258

259
    return length;
×
260
}
261

262
static size_t
263
sixel_status_utf8_trim_length(const char *message, size_t length)
×
264
{
265
    size_t index;
×
266
    size_t available;
×
267
    size_t required;
×
268
    unsigned char byte;
×
269

270
    index = length;
×
271

272
    while (index > 0) {
×
273
        byte = (unsigned char)message[index - 1];
×
274
        if ((byte & 0xC0u) != 0x80u) {
×
275
            required = sixel_status_utf8_expected_length(byte);
×
276
            available = length - (index - 1);
×
277
            if (available >= required) {
×
278
                return length;
279
            }
280
            length = index - 1;
×
281
            index = length;
×
282
            continue;
×
283
        }
284
        --index;
285
    }
286

287
    return length;
288
}
289

290
static size_t
291
sixel_status_append_literal(char *buffer,
76,410✔
292
                            size_t buffer_size,
293
                            size_t index,
294
                            char value)
295
{
296
    size_t remaining;
76,410✔
297

298
    if (buffer_size == 0) {
76,410!
299
        return 0;
300
    }
301

302
    if (index >= buffer_size) {
76,410!
303
        return buffer_size;
304
    }
305

306
    remaining = buffer_size - index;
76,410✔
307
    if (remaining <= 1) {
76,410!
308
        buffer[buffer_size - 1] = '\0';
×
309
        return buffer_size;
×
310
    }
311

312
    buffer[index] = value;
76,410✔
313
    ++index;
76,410✔
314
    buffer[index] = '\0';
76,410✔
315

316
    return index;
76,410✔
317
}
318

319
static size_t
320
sixel_status_append_sequence(char *buffer,
×
321
                             size_t buffer_size,
322
                             size_t index,
323
                             const char *sequence)
324
{
325
    size_t length;
×
326
    size_t remaining;
×
327

328
    if (buffer_size == 0) {
×
329
        return 0;
330
    }
331

332
    if (index >= buffer_size) {
×
333
        return buffer_size;
334
    }
335

336
    length = strlen(sequence);
×
337
    remaining = buffer_size - index;
×
338

339
    if (length + 1 > remaining) {
×
340
        buffer[buffer_size - 1] = '\0';
×
341
        return buffer_size;
×
342
    }
343

344
    memcpy(buffer + index, sequence, length);
×
345
    index += length;
×
346
    buffer[index] = '\0';
×
347

348
    return index;
×
349
}
350

351
static size_t
352
sixel_status_render_markup(const char *source,
222✔
353
                           char *destination,
354
                           size_t destination_size)
355
{
356
    size_t index;
222✔
357
    const char *cursor;
222✔
358
    enum sixel_status_markup_attr active_attr;
222✔
359
    int use_sequences;
222✔
360
    int have_bold;
222✔
361
    int have_color;
222✔
362
    int sequence_active;
222✔
363
    size_t appended;
222✔
364
    char token;
222✔
365
    const char *start_sequence;
222✔
366
    enum sixel_status_markup_attr target_attr;
222✔
367

368
    index = 0;
222✔
369

370
    if (destination_size == 0) {
222!
371
        return 0;
372
    }
373

374
    destination[0] = '\0';
222✔
375
    cursor = source;
222✔
376
    use_sequences = 0;
222✔
377
    have_bold = 0;
222✔
378
    have_color = 0;
222✔
379

380
#if SIXEL_STATUS_HAVE_TTY_HELPERS
381
    {
382
        const struct sixel_tty_output_state *tty;
222✔
383

384
        tty = sixel_tty_get_output_state();
222✔
385
        if (tty != NULL) {
222!
386
            if (tty->is_tty != 0 && tty->use_ansi_sequences != 0) {
222!
387
                use_sequences = 1;
222✔
388
            }
389
            if (tty->supports_bold != 0) {
222!
390
                have_bold = 1;
×
391
            }
392
            if (tty->supports_color != 0) {
222!
393
                have_color = 1;
×
394
            }
395
        }
396
    }
397
#endif  /* SIXEL_STATUS_HAVE_TTY_HELPERS */
398

399
    active_attr = SIXEL_STATUS_ATTR_NONE;
222✔
400
    sequence_active = 0;
222✔
401

402
    while (cursor != NULL && cursor[0] != '\0') {
77,256!
403
        if (cursor[0] == '\\') {
77,034✔
404
            if (cursor[1] == '\\') {
624!
405
                appended = sixel_status_append_literal(destination,
×
406
                                                       destination_size,
407
                                                       index,
408
                                                       '\\');
409
                index = appended;
×
410
                if (index >= destination_size) {
×
411
                    break;
412
                }
413
                cursor += 2;
×
414
                continue;
×
415
            }
416

417
            if (cursor[1] == 'f') {
624!
418
                if (cursor[2] == '\\' && cursor[3] == '\\') {
624!
419
                    appended = sixel_status_append_literal(destination,
×
420
                                                           destination_size,
421
                                                           index,
422
                                                           '\f');
423
                    index = appended;
×
424
                    if (index >= destination_size) {
×
425
                        break;
426
                    }
427
                    cursor += 4;
×
428
                    continue;
×
429
                }
430

431
                if (cursor[2] == 'P') {
624✔
432
                    if (sequence_active != 0 && use_sequences != 0) {
312!
433
                        appended = sixel_status_append_sequence(
×
434
                            destination,
435
                            destination_size,
436
                            index,
437
                            "\x1b[0m");
438
                        index = appended;
×
439
                        if (index >= destination_size) {
×
440
                            break;
441
                        }
442
                        sequence_active = 0;
443
                    }
444
                    active_attr = SIXEL_STATUS_ATTR_NONE;
312✔
445
                    cursor += 3;
312✔
446
                    continue;
312✔
447
                }
448

449
                if (cursor[2] == 'B' || cursor[2] == 'E' ||
312!
450
                    cursor[2] == 'W') {
451
                    token = cursor[2];
312✔
452
                    start_sequence = NULL;
312✔
453
                    target_attr = SIXEL_STATUS_ATTR_NONE;
312✔
454

455
                    if (token == 'B') {
312✔
456
                        target_attr = SIXEL_STATUS_ATTR_BOLD;
204✔
457
                        if (use_sequences != 0 && have_bold != 0) {
204!
458
                            start_sequence = "\x1b[1m";
×
459
                        }
460
                    } else if (token == 'E') {
108!
461
                        target_attr = SIXEL_STATUS_ATTR_ERROR;
×
462
                        if (use_sequences != 0 && have_color != 0) {
×
463
                            start_sequence = "\x1b[31m";
×
464
                        }
465
                    } else {
466
                        target_attr = SIXEL_STATUS_ATTR_WARNING;
108✔
467
                        if (use_sequences != 0 && have_color != 0) {
108!
468
                            start_sequence = "\x1b[33m";
×
469
                        }
470
                    }
471

472
                    if (target_attr != active_attr) {
312!
473
                        if (sequence_active != 0 && use_sequences != 0) {
312!
474
                            appended = sixel_status_append_sequence(
×
475
                                destination,
476
                                destination_size,
477
                                index,
478
                                "\x1b[0m");
479
                            index = appended;
×
480
                            if (index >= destination_size) {
×
481
                                break;
482
                            }
483
                            sequence_active = 0;
484
                        }
485

486
                        if (start_sequence != NULL) {
312!
487
                            appended = sixel_status_append_sequence(
×
488
                                destination,
489
                                destination_size,
490
                                index,
491
                                start_sequence);
492
                            index = appended;
×
493
                            if (index >= destination_size) {
×
494
                                break;
495
                            }
496
                            sequence_active = 1;
497
                        }
498

499
                        active_attr = target_attr;
500
                    }
501

502
                    cursor += 3;
312✔
503
                    continue;
312✔
504
                }
505

506
                appended = sixel_status_append_literal(destination,
×
507
                                                       destination_size,
508
                                                       index,
509
                                                       '\\');
510
                index = appended;
×
511
                if (index >= destination_size) {
×
512
                    break;
513
                }
514
                cursor += 1;
×
515
                continue;
×
516
            }
517
        }
518

519
        appended = sixel_status_append_literal(destination,
76,410✔
520
                                               destination_size,
521
                                               index,
522
                                               cursor[0]);
523
        index = appended;
76,410✔
524
        if (index >= destination_size) {
76,410!
525
            break;
526
        }
527
        cursor += 1;
76,410✔
528
    }
529

530
    if (sequence_active != 0 && use_sequences != 0) {
222!
531
        appended = sixel_status_append_sequence(destination,
×
532
                                                destination_size,
533
                                                index,
534
                                                "\x1b[0m");
535
        index = appended;
×
536
    }
537

538
    if (index >= destination_size) {
222!
539
        index = destination_size - 1;
×
540
        destination[index] = '\0';
×
541
    }
542

543
    return index;
544
}
545

546

547
/* convert error status code int formatted string */
548
SIXELAPI char const *
549
sixel_helper_format_error(
123✔
550
    SIXELSTATUS     /* in */  status           /* status code */
551
)
552
{
553
    static char buffer[1024];
123✔
554
    char const *error_string;
123✔
555

556
    switch (status & 0x1000) {
123!
557
    case SIXEL_OK:
×
558
        switch (status) {
×
559
        case SIXEL_INTERRUPTED:
560
            error_string = SIXEL_MESSAGE_INTERRUPTED;
561
            break;
562
        case SIXEL_OK:
×
563
        default:
564
            error_string = SIXEL_MESSAGE_OK;
×
565
            break;
×
566
        }
567
        break;
568
    case SIXEL_FALSE:
123✔
569
        switch (status & 0x1f00) {
123!
570
        case SIXEL_RUNTIME_ERROR:
123✔
571
            switch (status) {
123!
572
            case SIXEL_BAD_ALLOCATION:
573
                error_string = SIXEL_MESSAGE_BAD_ALLOCATION;
574
                break;
575
            case SIXEL_BAD_ARGUMENT:
114✔
576
                error_string = SIXEL_MESSAGE_BAD_ARGUMENT;
114✔
577
                break;
114✔
578
            case SIXEL_BAD_INPUT:
3✔
579
                error_string = SIXEL_MESSAGE_BAD_INPUT;
3✔
580
                break;
3✔
581
            case SIXEL_LOADER_FAILED:
3✔
582
                error_string = SIXEL_MESSAGE_LOADER_FAILED;
3✔
583
                break;
3✔
584
            case SIXEL_BAD_CLIPBOARD:
3✔
585
                error_string = SIXEL_MESSAGE_BAD_CLIPBOARD;
3✔
586
                break;
3✔
587
            case SIXEL_BAD_INTEGER_OVERFLOW:
×
588
                error_string = SIXEL_MESSAGE_BAD_INTEGER_OVERFLOW;
×
589
                break;
×
590
            default:
×
591
                error_string = SIXEL_MESSAGE_RUNTIME_ERROR;
×
592
                break;
×
593
            }
594
            break;
595
        case SIXEL_LOGIC_ERROR:
596
            error_string = SIXEL_MESSAGE_LOGIC_ERROR;
597
            break;
598
        case SIXEL_FEATURE_ERROR:
×
599
            switch (status) {
×
600
            case SIXEL_NOT_IMPLEMENTED:
601
                error_string = SIXEL_MESSAGE_NOT_IMPLEMENTED;
602
                break;
603
            default:
×
604
                error_string = SIXEL_MESSAGE_FEATURE_ERROR;
×
605
                break;
×
606
            }
607
            break;
608
        case SIXEL_LIBC_ERROR:
×
609
            if (sixel_compat_strerror(errno,
×
610
                                      buffer,
611
                                      sizeof(buffer)) == NULL) {
612
                buffer[0] = '\0';
×
613
            }
614
            error_string = buffer;
615
            break;
616
#ifdef HAVE_LIBCURL
617
        case SIXEL_CURL_ERROR:
618
            error_string = curl_easy_strerror(status & 0xff);
619
            break;
620
#endif
621
#ifdef HAVE_JPEG
622
        case SIXEL_JPEG_ERROR:
623
            error_string = SIXEL_MESSAGE_JPEG_ERROR;
624
            break;
625
#endif
626
#ifdef HAVE_LIBPNG
627
        case SIXEL_PNG_ERROR:
628
            error_string = SIXEL_MESSAGE_PNG_ERROR;
629
            break;
630
#endif
631
#ifdef HAVE_GDK_PIXBUF2
632
        case SIXEL_GDK_ERROR:
633
            error_string = SIXEL_MESSAGE_GDK_ERROR;
634
            break;
635
#endif
636
#ifdef HAVE_GD
637
        case SIXEL_GD_ERROR:
638
            error_string = SIXEL_MESSAGE_GD_ERROR;
639
            break;
640
#endif
641
        case SIXEL_STBI_ERROR:
×
642
            error_string = SIXEL_MESSAGE_STBI_ERROR;
×
643
            break;
×
644
        case SIXEL_STBIW_ERROR:
×
645
            error_string = SIXEL_MESSAGE_STBIW_ERROR;
×
646
            break;
×
647
        case SIXEL_FALSE:
×
648
            error_string = SIXEL_MESSAGE_FALSE;
×
649
            break;
×
650
        default:
651
            error_string = SIXEL_MESSAGE_UNEXPECTED;
×
652
            break;
653
        }
654
        break;
655
    default:
656
        error_string = SIXEL_MESSAGE_UNEXPECTED;
657
        break;
658
    }
659
    return error_string;
123✔
660
}
661

662

663
#if HAVE_TESTS
664
static int
665
test1(void)
×
666
{
667
    int nret = EXIT_FAILURE;
×
668
    char const *message;
×
669

670
    message = sixel_helper_format_error(SIXEL_OK);
×
671
    if (strcmp(message, SIXEL_MESSAGE_OK) != 0) {
×
672
        goto error;
673
    }
674

675
    message = sixel_helper_format_error(SIXEL_INTERRUPTED);
×
676
    if (strcmp(message, SIXEL_MESSAGE_INTERRUPTED) != 0) {
×
677
        goto error;
678
    }
679
    return EXIT_SUCCESS;
×
680
error:
681
    perror("test1");
682
    return nret;
683
}
684

685

686
static int
687
test2(void)
×
688
{
689
    int nret = EXIT_FAILURE;
×
690
    char const *message;
×
691

692
    message = sixel_helper_format_error(SIXEL_BAD_ALLOCATION);
×
693
    if (strcmp(message, SIXEL_MESSAGE_BAD_ALLOCATION) != 0) {
×
694
        goto error;
695
    }
696

697
    message = sixel_helper_format_error(SIXEL_BAD_ARGUMENT);
×
698
    if (strcmp(message, SIXEL_MESSAGE_BAD_ARGUMENT) != 0) {
×
699
        goto error;
700
    }
701

702
    message = sixel_helper_format_error(SIXEL_BAD_INPUT);
×
703
    if (strcmp(message, SIXEL_MESSAGE_BAD_INPUT) != 0) {
×
704
        goto error;
705
    }
706

707
    message = sixel_helper_format_error(SIXEL_LOADER_FAILED);
×
708
    if (strcmp(message, SIXEL_MESSAGE_LOADER_FAILED) != 0) {
×
709
        goto error;
710
    }
711

712
    message = sixel_helper_format_error(SIXEL_RUNTIME_ERROR);
×
713
    if (strcmp(message, SIXEL_MESSAGE_RUNTIME_ERROR) != 0) {
×
714
        goto error;
715
    }
716

717
    message = sixel_helper_format_error(SIXEL_LOGIC_ERROR);
×
718
    if (strcmp(message, SIXEL_MESSAGE_LOGIC_ERROR) != 0) {
×
719
        goto error;
720
    }
721

722
    message = sixel_helper_format_error(SIXEL_NOT_IMPLEMENTED);
×
723
    if (strcmp(message, SIXEL_MESSAGE_NOT_IMPLEMENTED) != 0) {
×
724
        goto error;
725
    }
726

727
    message = sixel_helper_format_error(SIXEL_FEATURE_ERROR);
×
728
    if (strcmp(message, SIXEL_MESSAGE_FEATURE_ERROR) != 0) {
×
729
        goto error;
730
    }
731

732
    message = sixel_helper_format_error(SIXEL_LIBC_ERROR);
×
733
    if (strcmp(message, SIXEL_MESSAGE_UNEXPECTED) == 0) {
×
734
        goto error;
×
735
    }
736

737
#ifdef HAVE_LIBCURL
738
    message = sixel_helper_format_error(SIXEL_CURL_ERROR);
739
    if (strcmp(message, SIXEL_MESSAGE_UNEXPECTED) == 0) {
×
740
        goto error;
741
    }
742
#endif
743

744
#if HAVE_JPEG
745
    message = sixel_helper_format_error(SIXEL_JPEG_ERROR);
746
    if (strcmp(message, SIXEL_MESSAGE_JPEG_ERROR) != 0) {
×
747
        goto error;
748
    }
749
#endif
750

751
#if HAVE_LIBPNG
752
    message = sixel_helper_format_error(SIXEL_PNG_ERROR);
753
    if (strcmp(message, SIXEL_MESSAGE_PNG_ERROR) != 0) {
×
754
        goto error;
755
    }
756
#endif
757

758
#if HAVE_GD
759
    message = sixel_helper_format_error(SIXEL_GD_ERROR);
760
    if (strcmp(message, SIXEL_MESSAGE_GD_ERROR) != 0) {
761
        goto error;
762
    }
763
#endif
764

765
#if HAVE_GDK_PIXBUF2
766
    message = sixel_helper_format_error(SIXEL_GDK_ERROR);
767
    if (strcmp(message, SIXEL_MESSAGE_GDK_ERROR) != 0) {
768
        goto error;
769
    }
770
#endif
771

772
    message = sixel_helper_format_error(SIXEL_STBI_ERROR);
773
    if (strcmp(message, SIXEL_MESSAGE_STBI_ERROR) != 0) {
×
774
        goto error;
775
    }
776

777
    message = sixel_helper_format_error(SIXEL_STBIW_ERROR);
×
778
    if (strcmp(message, SIXEL_MESSAGE_STBIW_ERROR) != 0) {
×
779
        goto error;
780
    }
781

782
    return EXIT_SUCCESS;
783
error:
×
784
    perror("test2");
×
785
    return nret;
×
786
}
787

788

789
SIXELAPI int
790
sixel_status_tests_main(void)
×
791
{
792
    int nret = EXIT_FAILURE;
×
793
    size_t i;
×
794
    typedef int (* testcase)(void);
×
795

796
    static testcase const testcases[] = {
×
797
        test1,
798
        test2,
799
    };
800

801
    for (i = 0; i < sizeof(testcases) / sizeof(testcase); ++i) {
×
802
        nret = testcases[i]();
×
803
        if (nret != EXIT_SUCCESS) {
×
804
            goto error;
×
805
        }
806
    }
807

808
    nret = EXIT_SUCCESS;
809

810
error:
×
811
    return nret;
×
812
}
813
#endif  /* HAVE_TESTS */
814

815
/* emacs Local Variables:      */
816
/* emacs mode: c               */
817
/* emacs tab-width: 4          */
818
/* emacs indent-tabs-mode: nil */
819
/* emacs c-basic-offset: 4     */
820
/* emacs End:                  */
821
/* vim: set expandtab ts=4 sts=4 sw=4 : */
822
/* EOF */
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc