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

ascii-boxes / boxes / 27499449924

14 Jun 2026 12:33PM UTC coverage: 83.929% (+1.1%) from 82.852%
27499449924

push

github

tsjensen
Fix coverage measurement on macos-26

2624 of 3395 branches covered (77.29%)

Branch coverage included in aggregate %.

9 of 9 new or added lines in 2 files covered. (100.0%)

99 existing lines in 6 files now uncovered.

4066 of 4576 relevant lines covered (88.85%)

196072.68 hits per line

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

87.41
/src/boxes.c
1
/*
2
 * boxes - Command line filter to draw/remove ASCII boxes around text
3
 * SPDX-FileCopyrightText: Copyright (c) 1999-2026 Thomas Jensen and the boxes contributors
4
 * SPDX-License-Identifier: GPL-3.0-only
5
 *
6
 * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
7
 * License, version 3, as published by the Free Software Foundation.
8
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
9
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
10
 * details.
11
 * You should have received a copy of the GNU General Public License along with this program.
12
 * If not, see <https://www.gnu.org/licenses/>.
13
 *
14
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
15
 */
16

17
#include "config.h"
18

19
#ifndef __MINGW32__
20
#include <ncurses.h>
21
#endif
22
#include <errno.h>
23
#include <locale.h>
24
#include <stdio.h>
25
#include <stdlib.h>
26
#include <string.h>
27
#include <uniconv.h>
28
#include <unistd.h>
29
#ifdef _WIN32
30
#include <windows.h>
31
#include <shellapi.h>
32
#endif
33

34
#include "boxes.h"
35
#include "bxstring.h"
36
#include "cmdline.h"
37
#include "discovery.h"
38
#include "generate.h"
39
#include "input.h"
40
#include "list.h"
41
#include "logging.h"
42
#include "parsing.h"
43
#include "query.h"
44
#include "remove.h"
45
#include "shape.h"
46
#include "tools.h"
47
#include "unicode.h"
48

49

50

51
/*       _\|/_
52
         (o o)
53
 +----oOO-{_}-OOo------------------------------------------------------------+
54
 |                    G l o b a l   V a r i a b l e s                        |
55
 +--------------------------------------------------------------------------*/
56

57
design_t *designs = NULL;            /* available box designs */
58
int num_designs = 0;                 /* number of designs after parsing */
59

60
opt_t opt;                           /* command line options */
61

62
input_t input;                       /* input lines */
63

64
int color_output_enabled;            /* Flag indicating if ANSI color codes should be printed (1) or not (0) */
65

66

67

68
/*       _\|/_
69
         (o o)
70
 +----oOO-{_}-OOo------------------------------------------------------------+
71
 |                           F u n c t i o n s                               |
72
 +--------------------------------------------------------------------------*/
73

74

75
static int build_design(design_t **adesigns, const char *cld)
8✔
76
/*
77
 *  Build a box design.
78
 *
79
 *      adesigns    Pointer to global designs list
80
 *      cld         the W shape as specified on the command line
81
 *
82
 *  Builds the global design list containing only one design which was
83
 *  built from the -c command line definition.
84
 *
85
 *  RETURNS:  != 0   on error (out of memory)
86
 *            == 0   on success
87
 *
88
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
89
 */
90
{
91
    design_t *dp;                        /* pointer to design to be created */
92
    sentry_t *c;                         /* pointer to current shape */
93
    int i;
94
    int rc;
95

96
    *adesigns = (design_t *) calloc(1, sizeof(design_t));
8✔
97
    if (*adesigns == NULL) {
8!
UNCOV
98
        perror(PROJECT);
×
UNCOV
99
        return 1;
×
100
    }
101
    dp = *adesigns;                      /* for readability */
8✔
102

103
    dp->name = "<Command Line Definition>";
8✔
104
    dp->aliases = (char **) calloc(1, sizeof(char *));
8✔
105
    dp->sample = bxs_from_ascii("n/a");
8✔
106
    dp->indentmode = DEF_INDENTMODE;
8✔
107
    dp->padding[BLEF] = 1;
8✔
108
    dp->defined_in = bxs_from_ascii("(command line)");
8✔
109

110
    dp->tags = (char **) calloc(2, sizeof(char *));
8✔
111
    dp->tags[0] = "transient";
8✔
112

113
    /* We always use UTF-8, which is correct for Linux and MacOS, and for modern Windows configured for UTF-8. */
114
    uint32_t *cld_u32 = u32_strconv_from_arg(cld, "UTF-8");
8✔
115
    bxstr_t *cldW = bxs_from_unicode(cld_u32);
8✔
116
    BFREE(cld_u32);
8!
117

118
    dp->shape[W].name = W;
8✔
119
    dp->shape[W].height = 1;
8✔
120
    dp->shape[W].width = cldW->num_columns;
8✔
121
    dp->shape[W].elastic = 1;
8✔
122
    rc = genshape(dp->shape[W].width, dp->shape[W].height, &(dp->shape[W].chars), &(dp->shape[W].mbcs));
8✔
123
    if (rc) {
8!
UNCOV
124
        return rc;
×
125
    }
126
    bxs_free(dp->shape[W].mbcs[0]);
8✔
127
    dp->shape[W].mbcs[0] = cldW;
8✔
128
    strcpy(dp->shape[W].chars[0], cld);
8✔
129

130
    for (i = 0; i < NUM_SHAPES; ++i) {
136✔
131
        c = dp->shape + i;
128✔
132

133
        if (i == NNW || i == NNE || i == WNW || i == ENE || i == W
128✔
134
                || i == WSW || i == ESE || i == SSW || i == SSE) {
88✔
135
                    continue;
72✔
136
        }
137

138
        switch (i) {
56!
139
            case NW:
16✔
140
            case SW:
141
                c->width = dp->shape[W].width;
16✔
142
                c->height = 1;
16✔
143
                c->elastic = 0;
16✔
144
                break;
16✔
145

146
            case NE:
16✔
147
            case SE:
148
                c->width = 1;
16✔
149
                c->height = 1;
16✔
150
                c->elastic = 0;
16✔
151
                break;
16✔
152

153
            case N:
24✔
154
            case S:
155
            case E:
156
                c->width = 1;
24✔
157
                c->height = 1;
24✔
158
                c->elastic = 1;
24✔
159
                break;
24✔
160

161
            default:
×
UNCOV
162
                fprintf(stderr, "%s: internal error\n", PROJECT);
×
UNCOV
163
                return 1;
×
164
        }
165
        c->name = i;
56✔
166

167
        rc = genshape(c->width, c->height, &(c->chars), &(c->mbcs));
56✔
168
        if (rc) {
56!
UNCOV
169
            return rc;
×
170
        }
171
    }
172

173
    dp->maxshapeheight = 1;
8✔
174
    dp->minwidth = dp->shape[W].width + 2;
8✔
175
    dp->minheight = 3;
8✔
176

177
    return 0;
8✔
178
}
179

180

181

182
/**
183
 * Process command line options and store the result in the global `opt` struct. May exit the program.
184
 */
185
static void handle_command_line(int argc, char *argv[])
806✔
186
{
187
    log_debug(__FILE__, MAIN, "Processing Command Line ...\n");
806✔
188

189
    opt_t *parsed_opts = process_commandline(argc, argv);
806✔
190
    if (parsed_opts == NULL) {
806✔
191
        exit(EXIT_FAILURE);
20✔
192
    }
193
    if (parsed_opts->help) {
786✔
194
        usage_long(stdout);
2✔
195
        exit(EXIT_SUCCESS);
2✔
196
    }
197
    if (parsed_opts->version_requested) {
784!
UNCOV
198
        printf("%s version %s\n", PROJECT, VERSION);
×
UNCOV
199
        exit(EXIT_SUCCESS);
×
200
    }
201
    memcpy(&opt, parsed_opts, sizeof(opt_t));
784✔
202
    BFREE(parsed_opts);
784!
203
}
784✔
204

205

206

207
/**
208
 * Parse config file(s), then reset design pointer. May exit the program.
209
 */
210
static void handle_config_parsing()
784✔
211
{
212
    bxstr_t *config_file = discover_config_file(0);
784✔
213
    if (config_file == NULL) {
784✔
214
        exit(EXIT_FAILURE);
6✔
215
    }
216
    if (opt.cld == NULL) {
778✔
217
        size_t r_num_designs = 0;
770✔
218
        designs = parse_config_files(config_file, &r_num_designs);
770✔
219
        if (designs == NULL) {
770✔
220
            exit(EXIT_FAILURE);
6✔
221
        }
222
        num_designs = (int) r_num_designs;
764✔
223
    }
224
    else {
225
        int rc = build_design(&designs, opt.cld);
8✔
226
        if (rc) {
8!
UNCOV
227
            exit(EXIT_FAILURE);
×
228
        }
229
        num_designs = 1;
8✔
230
    }
231
    BFREE (opt.design);
772✔
232
    opt.design = designs;
772✔
233
}
772✔
234

235

236

237
/**
238
 * Adjust box size to command line specification.
239
 * Increase box width/height by width/height of empty sides in order to match appearance of box with the user's
240
 * expectations (if -s).
241
 */
242
static void apply_expected_size()
706✔
243
{
244
    if (opt.reqheight > (long) opt.design->minheight) {
706✔
245
        opt.design->minheight = opt.reqheight;
120✔
246
    }
247
    if (opt.reqwidth > (long) opt.design->minwidth) {
706✔
248
        opt.design->minwidth = opt.reqwidth;
120✔
249
    }
250
    if (opt.reqwidth) {
706✔
251
        if (empty_side(opt.design->shape, BRIG)) {
130✔
252
            opt.design->minwidth += opt.design->shape[SE].width;
4✔
253
        }
254
        if (empty_side(opt.design->shape, BLEF)) {
130✔
255
            opt.design->minwidth += opt.design->shape[NW].width;
4✔
256
        }
257
    }
258
    if (opt.reqheight) {
706✔
259
        if (empty_side(opt.design->shape, BTOP)) {
130✔
260
            opt.design->minheight += opt.design->shape[NW].height;
2✔
261
        }
262
        if (empty_side(opt.design->shape, BBOT)) {
130✔
263
            opt.design->minheight += opt.design->shape[SE].height;
2✔
264
        }
265
    }
266
}
706✔
267

268

269

270
/**
271
 * Read all input lines and store the result in the global `input` structure. May exit the program.
272
 */
273
static void handle_input()
852✔
274
{
275
    log_debug(__FILE__, MAIN, "Reading all input ...\n");
852✔
276

277
    input_t *raw_input = NULL;
852✔
278
    if (opt.mend != 0) {
852✔
279
        raw_input = read_all_input();
706✔
280
        if (raw_input == NULL) {
706!
UNCOV
281
            exit(EXIT_FAILURE);
×
282
        }
283
    }
284
    if (analyze_input(raw_input ? raw_input : &input)) {
852!
UNCOV
285
        exit(EXIT_FAILURE);
×
286
    }
287
    if (raw_input) {
852✔
288
        memcpy(&input, raw_input, sizeof(input_t));
706✔
289
        BFREE(raw_input);
706!
290
    }
291

292
    if (is_debug_logging(MAIN)) {
852✔
293
        log_debug(__FILE__, MAIN, "Effective encoding: %s\n", encoding);
6✔
294
        print_input_lines(NULL);
6✔
295
    }
296
    if (input.num_lines == 0) {
852!
UNCOV
297
        exit(EXIT_SUCCESS);
×
298
    }
299
}
852✔
300

301

302

303
/**
304
 * Adjust box size to fit requested padding value.
305
 * Command line-specified box size takes precedence over padding.
306
 */
307
static void adjust_size_and_padding()
852✔
308
{
309
    for (int i = 0; i < NUM_SIDES; ++i) {
4,260✔
310
        if (opt.padding[i] > -1) {
3,408✔
311
            opt.design->padding[i] = opt.padding[i];
54✔
312
        }
313
    }
314

315
    size_t pad = opt.design->padding[BTOP] + opt.design->padding[BBOT];
852✔
316
    if (pad > 0) {
852✔
317
        pad += input.num_lines;
176✔
318
        pad += opt.design->shape[NW].height + opt.design->shape[SW].height;
176✔
319
        if (pad > opt.design->minheight) {
176✔
320
            if (opt.reqheight) {
168✔
321
                for (int i = 0; i < (int) (pad - opt.design->minheight); ++i) {
14✔
322
                    if (opt.design->padding[i % 2 ? BBOT : BTOP]) {
12✔
323
                        opt.design->padding[i % 2 ? BBOT : BTOP] -= 1;
10✔
324
                    } else if (opt.design->padding[i % 2 ? BTOP : BBOT]) {
2!
UNCOV
325
                        opt.design->padding[i % 2 ? BTOP : BBOT] -= 1;
×
326
                    } else {
327
                        break;
2✔
328
                    }
329
                }
330
            }
331
            else {
332
                opt.design->minheight = pad;
164✔
333
            }
334
        }
335
    }
336

337
    pad = opt.design->padding[BLEF] + opt.design->padding[BRIG];
852✔
338
    if (pad > 0) {
852✔
339
        pad += input.maxline;
738✔
340
        pad += opt.design->shape[NW].width + opt.design->shape[NE].width;
738✔
341
        if (pad > opt.design->minwidth) {
738✔
342
            if (opt.reqwidth) {
624✔
343
                for (int i = 0; i < (int) (pad - opt.design->minwidth); ++i) {
38✔
344
                    if (opt.design->padding[i % 2 ? BRIG : BLEF]) {
32✔
345
                        opt.design->padding[i % 2 ? BRIG : BLEF] -= 1;
26✔
346
                    } else if (opt.design->padding[i % 2 ? BLEF : BRIG]) {
6✔
347
                        opt.design->padding[i % 2 ? BLEF : BRIG] -= 1;
2!
348
                    } else {
349
                        break;
4✔
350
                    }
351
                }
352
            }
353
            else {
354
                opt.design->minwidth = pad;
614✔
355
            }
356
        }
357
    }
358
}
852✔
359

360

361

362
/**
363
 * Generate box. May exit the program.
364
 */
365
static void handle_generate_box()
530✔
366
{
367
    log_debug(__FILE__, MAIN, "Generating Box ...\n");
530✔
368

369
    sentry_t *thebox = (sentry_t *) calloc(NUM_SIDES, sizeof(sentry_t));
530✔
370
    if (thebox == NULL) {
530!
UNCOV
371
        perror(PROJECT);
×
UNCOV
372
        exit(EXIT_FAILURE);
×
373
    }
374
    int rc = generate_box(thebox);
530✔
375
    if (rc) {
530!
UNCOV
376
        exit(EXIT_FAILURE);
×
377
    }
378
    output_box(thebox);
530✔
379
}
530✔
380

381

382

383
/**
384
 * Remove box. May exit the program.
385
 */
386
static void handle_remove_box()
322✔
387
{
388
    log_debug(__FILE__, MAIN, "Removing Box ...\n");
322✔
389

390
    if (opt.killblank == -1) {
322✔
391
        if (empty_side(opt.design->shape, BTOP) && empty_side(opt.design->shape, BBOT)) {
174✔
392
            opt.killblank = 0;
22✔
393
        } else {
394
            opt.killblank = 1;
152✔
395
        }
396
    }
397
    int rc = remove_box();
322✔
398
    if (rc) {
320!
UNCOV
399
        exit(EXIT_FAILURE);
×
400
    }
401
    rc = apply_substitutions(&input, 1);
320✔
402
    if (rc) {
320!
UNCOV
403
        exit(EXIT_FAILURE);
×
404
    }
405
    output_input(opt.mend > 0);
320✔
406
}
320✔
407

408

409

410
#ifndef __MINGW32__
411
    /* These two functions are actually declared in term.h, but for some reason, that can't be included. */
412
    extern NCURSES_EXPORT(int) setupterm(NCURSES_CONST char *, int, int *);
413
    extern NCURSES_EXPORT(int) tigetnum(NCURSES_CONST char *);
414
#endif
415

416
static int terminal_has_colors()
782✔
417
{
418
    int result = 0;
782✔
419
    char *termtype = getenv("TERM");
782✔
420
    #ifdef __MINGW32__
421
        result = 1; /* On Windows, we always assume color capability. */
422
        UNUSED(termtype);
423
    #else
424
        if (termtype != NULL && setupterm(termtype, STDOUT_FILENO, NULL) == OK && tigetnum("colors") >= 8) {
782!
425
            result = 1;
782✔
426
        }
427
    #endif
428

429
    if (is_debug_logging(MAIN)) {
782✔
430
        #ifdef __MINGW32__
431
            int num_colors = 1;
432
        #else
433
            int num_colors = result ? tigetnum("colors") : 0;
6!
434
        #endif
435
        log_debug(__FILE__, MAIN, "Terminal \"%s\" %s colors (number of colors = %d).\n",
6!
436
                termtype != NULL ? termtype : "(null)", result ? "has" : "does NOT have", num_colors);
437
    }
438
    return result;
782✔
439
}
440

441

442

443
static int check_color_support(int opt_color)
784✔
444
{
445
    int result = 0;
784✔
446
    if (opt_color == force_ansi_color) {
784✔
447
        result = 1;
2✔
448
    }
449
    else if (opt_color == color_from_terminal) {
782!
450
        result = terminal_has_colors();
782✔
451
    }
452

453
    log_debug(__FILE__, MAIN, "Color support %sabled\n", result ? "\x1b[92mEN\x1b[0m" : "DIS");
784!
454
    return result;
784✔
455
}
456

457

458

459
#ifdef _WIN32
460
static char *wide_to_utf8(const wchar_t *src)
461
{
462
    if (src == NULL) {
463
        errno = EINVAL;
464
        return NULL;
465
    }
466

467
    int len = WideCharToMultiByte(CP_UTF8, 0, src, -1, NULL, 0, NULL, NULL);
468
    if (len == 0) {
469
        errno = EILSEQ;
470
        return NULL;
471
    }
472

473
    char *result = (char *) malloc((size_t) len);
474
    if (result == NULL) {
475
        return NULL;
476
    }
477
    if (WideCharToMultiByte(CP_UTF8, 0, src, -1, result, len, NULL, NULL) == 0) {
478
        BFREE(result);
479
        errno = EILSEQ;
480
        return NULL;
481
    }
482
    return result;
483
}
484

485

486
static char **get_utf8_argv(int *argc)
487
{
488
    if (argc == NULL) {
489
        errno = EINVAL;
490
        return NULL;
491
    }
492

493
    int wide_argc = 0;
494
    wchar_t **wide_argv = CommandLineToArgvW(GetCommandLineW(), &wide_argc);
495
    if (wide_argv == NULL || wide_argc <= 0) {
496
        return NULL;
497
    }
498

499
    char **utf8_argv = (char **) calloc((size_t) wide_argc + 1, sizeof(char *));
500
    if (utf8_argv == NULL) {
501
        LocalFree(wide_argv);
502
        return NULL;
503
    }
504

505
    for (int i = 0; i < wide_argc; i++) {
506
        utf8_argv[i] = wide_to_utf8(wide_argv[i]);
507
        if (utf8_argv[i] == NULL) {
508
            for (int j = 0; j < i; j++) {
509
                BFREE(utf8_argv[j]);
510
            }
511
            BFREE(utf8_argv);
512
            LocalFree(wide_argv);
513
            return NULL;
514
        }
515
    }
516

517
    LocalFree(wide_argv);
518
    *argc = wide_argc;
519
    return utf8_argv;
520
}
521

522

523
static void free_utf8_argv(char **argv)
524
{
525
    if (argv == NULL) {
526
        return;
527
    }
528
    for (int i = 0; argv[i] != NULL; i++) {
529
        BFREE(argv[i]);
530
    }
531
    BFREE(argv);
532
}
533

534

535
static const char *get_locale_from_environment()
536
{
537
    const char *locale = getenv("LC_ALL");
538
    if (locale == NULL || locale[0] == '\0') {
539
        locale = getenv("LC_CTYPE");
540
    }
541
    if (locale == NULL || locale[0] == '\0') {
542
        locale = getenv("LANG");
543
    }
544
    return locale != NULL && locale[0] != '\0' ? locale : NULL;
545
}
546

547

548
static UINT get_console_codepage(const char *charset)
549
{
550
    if (charset == NULL || charset[0] == '\0') {
551
        return CP_ACP;
552
    }
553
    if (strcmp(charset, "UTF-8") == 0) {
554
        return CP_UTF8;
555
    }
556
    if (strncmp(charset, "CP", 2) == 0) {
557
        char *end = NULL;
558
        unsigned long codepage = strtoul(charset + 2, &end, 10);
559
        if (end != NULL && *end == '\0' && codepage > 0) {
560
            return (UINT) codepage;
561
        }
562
    }
563
    return CP_ACP;
564
}
565
#endif
566

567

568
/**
569
 * Switch from default "C" encoding to system encoding.
570
 */
571
static void activateSystemEncoding()
806✔
572
{
573
    #ifdef _WIN32
574
        const char *locale = get_locale_from_environment();
575
        if (locale == NULL || setlocale(LC_ALL, locale) == NULL) {
576
            setlocale(LC_ALL, "");
577
        }
578
        UINT codepage = get_console_codepage(get_default_encoding());
579
        SetConsoleOutputCP(codepage);
580
        SetConsoleCP(codepage);
581
    #else
582
        setlocale(LC_ALL, "");
806✔
583
    #endif
584
}
806✔
585

586

587

588
/**
589
 * On some (presumably older) Windows (like Windows 10), we must enable ANSI code support in the terminal.
590
 */
591
void enable_ansi_mode() {
784✔
592
    #if defined(_WIN32) || defined(__MINGW32__)
593
        HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
594
        if (hOut == INVALID_HANDLE_VALUE) {
595
            return;
596
        }
597

598
        DWORD dwMode = 0;
599
        if (!GetConsoleMode(hOut, &dwMode)) {
600
            return;
601
        }
602

603
        #ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
604
            #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
605
        #endif
606
        dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING | ENABLE_PROCESSED_OUTPUT;
607
        SetConsoleMode(hOut, dwMode);
608
    #endif
609
}
784✔
610

611

612

613
/*       _\|/_
614
         (o o)
615
 +----oOO-{_}-OOo------------------------------------------------------------+
616
 |                       P r o g r a m   S t a r t                           |
617
 +--------------------------------------------------------------------------*/
618

619
int main(int argc, char *argv[])
806✔
620
{
621
    int rc;                           /* general return code */
622
    int saved_designwidth;            /* opt.design->minwith backup, used for mending */
623
    int saved_designheight;           /* opt.design->minheight backup, used for mending */
624
    int effective_argc = argc;
806✔
625
    char **effective_argv = argv;
806✔
626

627
    #ifdef _WIN32
628
        char **utf8_argv = get_utf8_argv(&effective_argc);
629
        if (utf8_argv != NULL) {
630
            effective_argv = utf8_argv;
631
        }
632
    #endif
633

634
    /* Temporarily set the system encoding, for proper output of --help text etc. */
635
    activateSystemEncoding();
806✔
636
    const char *system_encoding = get_default_encoding();
806✔
637
    encoding = system_encoding;
806✔
638

639
    handle_command_line(effective_argc, effective_argv);
806✔
640

641
    #ifdef _WIN32
642
        free_utf8_argv(utf8_argv);
643
    #endif
644

645
    /* Store system character encoding */
646
    encoding = check_encoding(opt.encoding, system_encoding);
784✔
647
    log_debug(__FILE__, MAIN, "Character Encoding = %s\n", encoding);
784✔
648

649
    color_output_enabled = check_color_support(opt.color);
784✔
650
    enable_ansi_mode();
784✔
651

652
    handle_config_parsing();
784✔
653

654
    /* If "-l" option was given, list designs and exit. */
655
    if (opt.l) {
772✔
656
        rc = list_designs();
48✔
657
        exit(rc);
48✔
658
    }
659

660
    /* If "-q" option was given, print results of tag query and exit. */
661
    if (opt.query != NULL && opt.query[0] != NULL) {
724!
662
        rc = query_by_tag();
18✔
663
        exit(rc);
18✔
664
    }
665

666
    apply_expected_size();
706✔
667
    if (opt.indentmode) {
706✔
668
        opt.design->indentmode = opt.indentmode;
4✔
669
    }
670
    saved_designwidth = opt.design->minwidth;
706✔
671
    saved_designheight = opt.design->minheight;
706✔
672

673
    do {
674
        if (opt.mend == 1) {  /* Mending a box works in two phases: */
852✔
675
            opt.r = 0;        /* opt.mend == 2: remove box          */
146✔
676
        }
677
        --opt.mend;           /* opt.mend == 1: add it back         */
852✔
678
        opt.design->minwidth = saved_designwidth;
852✔
679
        opt.design->minheight = saved_designheight;
852✔
680

681
        handle_input();
852✔
682

683
        adjust_size_and_padding();
852✔
684

685
        if (opt.r) {
852✔
686
            handle_remove_box();
322✔
687
        }
688
        else {
689
            handle_generate_box();
530✔
690
        }
691
    } while (opt.mend > 0);
850✔
692

693
    return EXIT_SUCCESS;
704✔
694
}
695

696
/* vim: set sw=4: */
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