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

SRI-CSL / yices2 / 16032530443

02 Jul 2025 06:08PM UTC coverage: 60.349% (-5.0%) from 65.357%
16032530443

Pull #582

github

web-flow
Merge b7e09d316 into b3af64ab1
Pull Request #582: Update ci

63716 of 105580 relevant lines covered (60.35%)

1127640.75 hits per line

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

23.46
/src/utils/command_line.c
1
/*
2
 * This file is part of the Yices SMT Solver.
3
 * Copyright (C) 2017 SRI International.
4
 *
5
 * Yices is free software: you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation, either version 3 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * Yices is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with Yices.  If not, see <http://www.gnu.org/licenses/>.
17
 */
18

19
/*
20
 * SUPPORT FOR PARSING COMMAND-LINE ARGUMENTS
21
 */
22

23
#include <float.h>
24
#include <inttypes.h>
25
#include <stdbool.h>
26
#include <stdint.h>
27
#include <stdlib.h>
28
#include <stdio.h>
29
#include <string.h>
30
#include <ctype.h>
31
#include <assert.h>
32

33
#include "utils/command_line.h"
34
#include "utils/string_utils.h"
35

36

37
/*
38
 * Extract name out of a path as in /usr/bin/name
39
 * - same as basename
40
 */
41

42
// TODO check whether this works on mingw
43
#ifdef MINGW
44
#define PCHAR '\\'
45
#else
46
#define PCHAR '/'
47
#endif
48

49
static char *get_basename(char *path) {
1,011✔
50
  char *s;
51

52
  s = strrchr(path, PCHAR);
1,011✔
53
  if (s != NULL) {
1,011✔
54
    return s + 1;
1,011✔
55
  } else {
56
    return path;
×
57
  }
58
}
59

60

61
/*
62
 * Initialize parser
63
 */
64
void init_cmdline_parser(cmdline_parser_t *p,
1,011✔
65
                         option_desc_t *options, uint32_t noptions,
66
                         char **argv, uint32_t argc) {
67
  p->options = options;
1,011✔
68
  p->noptions = noptions;
1,011✔
69
  p->argv = argv;
1,011✔
70
  p->argc = argc;
1,011✔
71

72
  if (argc > 0) {
1,011✔
73
    p->scan_index = 1;
1,011✔
74
    p->command_name = get_basename(argv[0]);
1,011✔
75
  } else {
76
    p->scan_index = 0;
×
77
    p->command_name = NULL;
×
78
  }
79
}
1,011✔
80

81

82
/*
83
 * Check whether s1 is a prefix of s2
84
 * If so return a pointer to what follows s1 into s2.
85
 * If not return NULL.
86
 */
87
static char *check_prefix(const char *s1, char *s2) {
394✔
88
  char c1, c2;
89

90
  for (;;) {
91
    c1 = *s1;
999✔
92
    c2 = *s2;
999✔
93
    if (c1 == '\0') return s2;
999✔
94
    if (c1 != c2) return NULL;
930✔
95
    s1 ++;
605✔
96
    s2 ++;
605✔
97
  }
98
}
99

100

101
/*
102
 * Search for an option descriptor with abbrev == a
103
 * - return NULL if not found, a pointer to it otherwise
104
 * - if a is '\0' just return NULL
105
 */
106
static option_desc_t *find_by_abbrev(option_desc_t *options, uint32_t n, char a) {
×
107
  uint32_t i;
108
  option_desc_t *p;
109

110
  if (a == '\0') return NULL;
×
111

112
  p = options;
×
113
  for (i=0; i<n; i++) {
×
114
    if (p->abbrev == a) return p;
×
115
    p ++;
×
116
  }
117
  return NULL;
×
118
}
119

120

121
/*
122
 * Search for an option descriptor whose name matches s
123
 * - matches mean that either s is "name" or s is "name=<value>"
124
 * - if a match is found, return the corresponding descriptor
125
 *   and set *value to NULL or to "<value>"
126
 * - if no match is found, return NULL
127
 */
128
static option_desc_t *find_by_name(option_desc_t *options, uint32_t n, char *s, char **value) {
69✔
129
  uint32_t i;
130
  option_desc_t *p;
131
  char *q;
132

133
  p = options;
69✔
134
  for (i=0; i<n; i++) {
394✔
135
    q = check_prefix(p->name, s);
394✔
136
    if (q != NULL) {
394✔
137
      if (*q == '\0') {
69✔
138
        *value = NULL;
42✔
139
        return p;
42✔
140
      } else if (*q == '=') {
27✔
141
        *value = q + 1;
27✔
142
        return p;
27✔
143
      }
144
    }
145
    p ++;
325✔
146
  }
147
  return NULL;
×
148
}
149

150

151

152
/*
153
 * Parse e->s_value as an integer argument
154
 * - convert the value to a 32bit integer and store it in e->i_value
155
 * - if that fails, set e->status and e->e_code to an error
156
 * - if that succeeds, set e->status to cmdline_option (i.e., correct option)
157
 */
158
static void check_integer_value(cmdline_elem_t *e) {
2✔
159
  int32_t aux;
160

161
  assert(e->s_value != NULL);
162
  switch (parse_as_integer(e->s_value, &aux)) {
2✔
163
  case valid_integer:
2✔
164
    e->status = cmdline_option;
2✔
165
    e->i_value = aux;
2✔
166
    break;
2✔
167

168
  case integer_overflow:
×
169
    e->status = cmdline_error;
×
170
    e->i_value = -1;
×
171
    e->e_code = cmdline_int_overflow;
×
172
    break;
×
173

174
  case invalid_integer:
×
175
    e->status = cmdline_error;
×
176
    e->i_value = -1;
×
177
    e->e_code = cmdline_int_format;
×
178
    break;
×
179
  }
180
}
2✔
181

182

183
/*
184
 * Check whether the next component of the command line can
185
 * be parsed as an integer. If so store it as current value for e.
186
 */
187
static void parse_optional_integer(cmdline_parser_t *p, cmdline_elem_t *e) {
×
188
  uint32_t i;
189
  int32_t aux;
190
  char *s;
191

192
  assert(e->s_value == NULL);
193
  i = p->scan_index;
×
194
  if (i < p->argc) {
×
195
    s = p->argv[i];
×
196
    switch (parse_as_integer(s, &aux)) {
×
197
    case valid_integer:
×
198
      p->scan_index = i+1;
×
199
      e->status = cmdline_option;
×
200
      e->s_value = s;
×
201
      e->i_value = aux;
×
202
      return;
×
203

204
    case integer_overflow:
×
205
      p->scan_index = i+1;
×
206
      e->status = cmdline_error;
×
207
      e->s_value = s;
×
208
      e->i_value = -1;
×
209
      e->e_code = cmdline_int_overflow;
×
210
      return;
×
211

212
    default:
×
213
      break;
×
214
    }
215
  }
216

217
  // no integer given
218
  e->i_value = -1;
×
219
  e->status = cmdline_option;
×
220
}
221

222

223
/*
224
 * Parse e->s_value as a floating-point argument
225
 * - convert the value to double and store if in e->d_value
226
 * - if that fails, set e->status and e->e_code to an error
227
 * - if that succeeds, set e->status to cmdline_option (i.e., correct option)
228
 */
229
static void check_double_value(cmdline_elem_t *e) {
×
230
  double aux;
231

232
  assert(e->s_value != NULL);
233
  switch (parse_as_double(e->s_value, &aux)) {
×
234
  case valid_double:
×
235
    e->status = cmdline_option;
×
236
    e->d_value = aux;
×
237
    break;
×
238

239
  case double_overflow:
×
240
    e->status = cmdline_error;
×
241
    e->d_value = -1.0;
×
242
    e->e_code = cmdline_float_overflow;
×
243
    break;
×
244

245
  case invalid_double:
×
246
    e->status = cmdline_error;
×
247
    e->d_value = -1.0;
×
248
    e->e_code = cmdline_float_format;
×
249
    break;
×
250
  }
251
}
×
252

253

254
/*
255
 * Check whether the next component of the command line can be parsed
256
 * as a floating-point number. If so store it as the current value for e.
257
 */
258
static void parse_optional_double(cmdline_parser_t *p, cmdline_elem_t *e) {
×
259
  uint32_t i;
260
  double aux;
261
  char *s;
262

263
  assert(e->s_value == NULL);
264
  i = p->scan_index;
×
265
  if (i < p->argc) {
×
266
    s = p->argv[i];
×
267
    switch (parse_as_double(s, &aux)) {
×
268
    case valid_double:
×
269
      p->scan_index = i+1;
×
270
      e->status = cmdline_option;
×
271
      e->s_value = s;
×
272
      e->d_value = aux;
×
273
      return;
×
274

275
    case double_overflow:
×
276
      p->scan_index = i+1;
×
277
      e->status = cmdline_error;
×
278
      e->s_value = s;
×
279
      e->d_value = -1.0;
×
280
      e->e_code = cmdline_float_overflow;
×
281
      return;
×
282

283
    default:
×
284
      break;
×
285
    }
286
  }
287

288
  // no number given
289
  e->d_value = -1.0;
×
290
  e->status = cmdline_option;
×
291
}
292

293

294
/*
295
 * Check whether s is a blank string
296
 */
297
static bool blank_string(char *s) {
27✔
298
  while (isspace((int) *s)) s++;
27✔
299
  return *s == '\0';
27✔
300
}
301

302

303
/*
304
 * Check whether e->s_value is a valid string parameter:
305
 * - whether it's not empty
306
 */
307
static void check_string(cmdline_elem_t *e) {
×
308
  assert(e->s_value != NULL);
309

310
  e->i_value = -1;
×
311
  e->status = cmdline_option;
×
312
  if (e->s_value[0] == '\0') {
×
313
    e->status = cmdline_error;
×
314
    e->e_code = cmdline_format;
×
315
  }
316
}
×
317

318

319
/*
320
 * Check whether the next component of the command line is
321
 * a valid string parameter (not empty and does not start with '-')
322
 * If so, store it as the s_value for e.
323
 */
324
static void parse_optional_string(cmdline_parser_t *p, cmdline_elem_t *e) {
×
325
  uint32_t i;
326
  char *s;
327

328
  assert(e->s_value == NULL);
329
  i = p->scan_index;
×
330
  if (i < p->argc) {
×
331
    s = p->argv[i];
×
332
    if (s[0] != '\0' && s[0] != '-') {
×
333
      p->scan_index = i + 1;
×
334
      e->s_value = s;
×
335
    }
336
  }
337
  e->status = cmdline_option;
×
338
  e->i_value = -1;
×
339
}
×
340

341

342
/*
343
 * Check whether option with descriptor d has a mandatory or optional parameter
344
 * and parse the parameter if present.
345
 * - e->s_value points to the string <value> if the option was given as --option=<value>
346
 * - e->s_value is NULL if the option was given as -o or --option
347
 */
348
static void check_option_parameter(cmdline_parser_t *p, cmdline_elem_t *e,
69✔
349
                                   option_desc_t *d) {
350
  uint32_t i;
351

352
  switch (d->type) {
69✔
353
  case FLAG_OPTION:
42✔
354
    if (e->s_value != NULL) {
42✔
355
      e->status = cmdline_error;
×
356
      e->e_code = cmdline_noval_expected;
×
357
    } else {
358
      e->status = cmdline_option;
42✔
359
      e->i_value = -1;
42✔
360
    }
361
    break;
42✔
362

363
  case OPTIONAL_INT:
×
364
    if (e->s_value != NULL) {
×
365
      check_integer_value(e);
×
366
    } else {
367
      parse_optional_integer(p, e);
×
368
    }
369
    break;
×
370

371
  case MANDATORY_INT:
2✔
372
    if (e->s_value == NULL) {
2✔
373
      i = p->scan_index;
×
374
      if (i >= p->argc) {
×
375
        e->status = cmdline_error;
×
376
        e->e_code = cmdline_val_missing;
×
377
        return;
×
378
      } else {
379
        e->s_value = p->argv[i];
×
380
        p->scan_index = i+1;
×
381
      }
382
    }
383
    check_integer_value(e);
2✔
384
    break;
2✔
385

386
  case OPTIONAL_FLOAT:
×
387
    if (e->s_value != NULL) {
×
388
      check_double_value(e);
×
389
    } else {
390
      parse_optional_double(p, e);
×
391
    }
392
    break;
×
393

394
  case MANDATORY_FLOAT:
×
395
    if (e->s_value == NULL) {
×
396
      i = p->scan_index;
×
397
      if (i >= p->argc) {
×
398
        e->status = cmdline_error;
×
399
        e->e_code = cmdline_val_missing;
×
400
        return;
×
401
      } else {
402
        e->s_value = p->argv[i];
×
403
        p->scan_index = i+1;
×
404
      }
405
    }
406
    check_double_value(e);
×
407
    break;
×
408

409
  case OPTIONAL_STRING:
×
410
    // reject empty string here
411
    if (e->s_value != NULL) {
×
412
      check_string(e);
×
413
    } else {
414
      parse_optional_string(p, e);
×
415
    }
416
    break;
×
417

418
  case MANDATORY_STRING:
25✔
419
    // accept empty string here
420
    if (e->s_value == NULL) {
25✔
421
      i = p->scan_index;
×
422
      if (i >= p->argc) {
×
423
        e->status = cmdline_error;
×
424
        e->e_code = cmdline_val_missing;
×
425
        return;
×
426

427
      } else {
428
        e->s_value = p->argv[i];
×
429
        p->scan_index = i+1;
×
430
      }
431
    }
432
    e->status = cmdline_option;
25✔
433
    e->i_value = -1;
25✔
434
    break;
25✔
435

436

437
  default:
438
    assert(false);
439
  }
440
}
441

442

443
/*
444
 * Parse string a as a short option (leading '-' is not included)
445
 */
446
static void parse_short_option(cmdline_parser_t *p, cmdline_elem_t *e, char *a) {
×
447
  option_desc_t *d;
448

449
  if (isalpha((int) a[0]) && a[1] == '\0') {
×
450
    e->format = cmdline_short;
×
451

452
    d = find_by_abbrev(p->options, p->noptions, a[0]);
×
453
    if (d == NULL) {
×
454
      e->status = cmdline_error;
×
455
      e->e_code = cmdline_unknown_option;
×
456
    } else {
457
      e->key = d->key;
×
458
      e->s_value = NULL;
×
459
      check_option_parameter(p, e, d);
×
460
    }
461

462
  } else {
463
    e->status = cmdline_error;
×
464
    e->e_code = cmdline_format;
×
465
  }
466
}
×
467

468

469
/*
470
 * Parse string a as a long option (leading '--' have been removed)
471
 */
472
static void parse_long_option(cmdline_parser_t *p, cmdline_elem_t *e, char *a) {
69✔
473
  option_desc_t *d;
474
  char *suffix;
475
  uint32_t i;
476

477
  e->format = cmdline_long;
69✔
478
  if (a[0] == '\0') {
69✔
479
    // '--' option: interpret the next argument as a generic parameter
480
    i = p->scan_index;
×
481
    if (i < p->argc) {
×
482
      e->status = cmdline_argument;
×
483
      e->arg = p->argv[i];
×
484
      p->scan_index = i+1;
×
485
    } else {
486
      e->status = cmdline_error;
×
487
      e->e_code = cmdline_arg_missing;
×
488
    }
489

490
  } else if (isalpha((int) a[0])) {
69✔
491
    d = find_by_name(p->options, p->noptions, a, &suffix);
69✔
492

493
    if (d == NULL) {
69✔
494
      e->status = cmdline_error;
×
495
      e->e_code = cmdline_unknown_option;
×
496
    } else {
497
      e->key = d->key;
69✔
498
      e->s_value = suffix;
69✔
499

500
      if (suffix != NULL) {
69✔
501
        e->format = cmdline_long_val;
27✔
502
        if (blank_string(suffix)) {
27✔
503
          e->status = cmdline_error;
×
504
          e->e_code = cmdline_format;
×
505
          return;
×
506
        }
507
      }
508

509
      check_option_parameter(p, e, d);
69✔
510
    }
511

512
  } else {
513
    e->status = cmdline_error;
×
514
    e->e_code = cmdline_format;
×
515
  }
516
}
517

518

519
/*
520
 * Top-level parsing function: fill-in e
521
 */
522
void cmdline_parse_element(cmdline_parser_t *p, cmdline_elem_t *e) {
2,089✔
523
  uint32_t i;
524
  char *a;
525

526
  i = p->scan_index;
2,089✔
527
  if (i >= p->argc) {
2,089✔
528
    e->status = cmdline_done;
1,010✔
529
    return;
1,010✔
530
  }
531

532
  p->scan_index = i+1;
1,079✔
533
  a = p->argv[i];
1,079✔
534
  e->arg = a;
1,079✔
535

536
  if (*a == '-') {
1,079✔
537
    a ++;
69✔
538
    if (*a == '-') {
69✔
539
      a ++;
69✔
540
      parse_long_option(p, e, a);
69✔
541
    } else {
542
      parse_short_option(p, e, a);
×
543
    }
544
  } else {
545
    e->status = cmdline_argument;
1,010✔
546
  }
547
}
548

549

550

551

552
/*
553
 * Print long name or abbreviation of an option based on e->arg
554
 * - i.e., print e->arg until '=' or '\0' is found.
555
 */
556
static void print_option_name(FILE *f, cmdline_elem_t *e) {
×
557
  char *s, c;
558

559
  s = e->arg;
×
560
  c = *s ++;
×
561
  while (c != '=' && c != '\0') {
×
562
    fputc(c, f);
×
563
    c = *s ++;
×
564
  }
565
}
×
566

567

568
/*
569
 * Print an error message on stderr
570
 */
571
void cmdline_print_error(cmdline_parser_t *p, cmdline_elem_t *e) {
×
572
  assert(e->status == cmdline_error);
573

574
  if (p->command_name != NULL) {
×
575
    fprintf(stderr, "%s: ", p->command_name);
×
576
  }
577

578
  switch (e->e_code) {
×
579
  case cmdline_unknown_option:
×
580
    fprintf(stderr, "invalid option: %s\n", e->arg);
×
581
    break;
×
582

583
  case cmdline_noval_expected:
×
584
    fputs("option ", stderr);
×
585
    print_option_name(stderr, e);
×
586
    fputs(" takes no parameter\n", stderr);
×
587
    break;
×
588

589
  case cmdline_val_missing:
×
590
    fputs("option ", stderr);
×
591
    print_option_name(stderr, e);
×
592
    fputs(" requires an argument\n", stderr);
×
593
    break;
×
594

595
  case cmdline_format:
×
596
    fprintf(stderr, "invalid option: %s\n", e->arg);
×
597
    break;
×
598

599
  case cmdline_int_format:
×
600
    if (e->format == cmdline_long_val) {
×
601
      fprintf(stderr, "invalid option: %s (parameter must be an integer)\n", e->arg);
×
602
    } else {
603
      fprintf(stderr, "invalid parameter to %s (parameter must be an integer)\n", e->arg);
×
604
    }
605
    break;
×
606

607
  case cmdline_int_overflow:
×
608
    if (e->format == cmdline_long_val) {
×
609
      fprintf(stderr, "integer overflow: %s\n", e->arg);
×
610
    } else {
611
      fprintf(stderr, "integer overflow: %s %s\n", e->arg, e->s_value);
×
612
    }
613
    break;
×
614

615
  case cmdline_float_format:
×
616
    if (e->format == cmdline_long_val) {
×
617
      fprintf(stderr, "invalid option: %s (parameter must be a number)\n", e->arg);
×
618
    } else {
619
      fprintf(stderr, "invalid parameter to %s (parameter must be a number)\n", e->arg);
×
620
    }
621
    break;
×
622

623
  case cmdline_float_overflow:
×
624
    if (e->format == cmdline_long_val) {
×
625
      fprintf(stderr, "floating-point over/underflow: %s\n", e->arg);
×
626
    } else {
627
      fprintf(stderr, "floating-point over/underflow: %s %s\n", e->arg, e->s_value);
×
628
    }
629
    break;
×
630

631
  case cmdline_arg_missing:
×
632
    fputs("missing argument after '--'\n", stderr);
×
633
    break;
×
634

635
  default:
×
636
    assert(false);
637
  }
638
}
×
639

640

641
/*
642
 * Invalid option argument.
643
 */
644
void cmdline_invalid_argument(cmdline_parser_t *p, cmdline_elem_t *e, char *explanation) {
×
645
  if (e->format == cmdline_long_val) {
×
646
    fprintf(stderr, "invalid option: %s (%s)\n", e->arg, explanation);
×
647
  } else {
648
    fprintf(stderr, "invalid parameter to %s (%s)\n", e->arg, explanation);
×
649
  }
650
}
×
651

652

653
/*
654
 * Validate an integer option:
655
 * - e = command-line element being parsed
656
 * - min = minimal value
657
 * - max = maximal value
658
 *
659
 * This returns true if min <= option value <= max.
660
 * Otherwise, the function prrints an error message and returns false.
661
 */
662
bool validate_integer_option(cmdline_parser_t *p, cmdline_elem_t *e, int32_t min, int32_t max) {
×
663
  if (min <= e->i_value && e->i_value <= max) {
×
664
    return true;
×
665
  }
666

667
  if (p->command_name != NULL) {
×
668
    fprintf(stderr, "%s: ", p->command_name);
×
669
  }
670
  print_option_name(stderr, e);
×
671
  if (max == INT32_MAX) {
×
672
    if (min == 0) {
×
673
      fputs(" must not be negative\n", stderr);
×
674
    } else if (min == 1) {
×
675
      fputs(" must be positiver\n", stderr);
×
676
    } else {
677
      fprintf(stderr, " must be at least %"PRId32"\n", min);
×
678
    }
679
  } else if (min == INT32_MIN) {
×
680
    if (max == 0) {
×
681
      fputs(" must not be positive\n", stderr);
×
682
    } else if (max == -1) {
×
683
      fputs(" must be negative\n", stderr);
×
684
    } else {
685
      fprintf(stderr, " must be no more than %"PRId32"\n", max);
×
686
    }
687
  } else {
688
    fprintf(stderr, " must be between %"PRId32" and %"PRId32"\n", min, max);
×
689
  }
690

691
  return false;
×
692
}
693

694

695
/*
696
 * Validate a floating-point option
697
 * - e = command-line option being processed
698
 * - min = minimal value (DBL_MIN means no lower bound)
699
 * - max = maximal value (DBL_MAX means no upper bound)
700
 * - min_strict: true means  check min < e->d_value
701
 *               false means check min <= e->d_value
702
 * - max_strict: true  means check e->d_value < max
703
 *               false means check e->d_value <= max
704
 *
705
 * Return true the checks pass.
706
 * Otherwise, print an error message and return false.
707
 */
708
bool validate_double_option(cmdline_parser_t *p, cmdline_elem_t *e, double min, bool min_strict, double max, bool max_strict) {
×
709
  bool good_lb, good_ub;
710
  char left_bracket, right_bracket;
711

712
  good_lb = min_strict ? e->d_value > min : e->d_value >= min;
×
713
  good_ub = max_strict ? e->d_value < max : e->d_value <= max;
×
714
  if (good_lb && good_ub) {
×
715
    return true;
×
716
  }
717

718
  if (p->command_name != NULL) {
×
719
    fprintf(stderr, "%s: ", p->command_name);
×
720
  }
721
  print_option_name(stderr, e);
×
722
  if (max == DBL_MAX) {
×
723
    // no meaningfull upper bound
724
    if (min == 0) {
×
725
      if (min_strict) {
×
726
        fputs(" must be positive\n", stderr);
×
727
      } else {
728
        fputs(" must be positive or zero\n",  stderr);
×
729
      }
730
    } else {
731
      if (min_strict) {
×
732
        fprintf(stderr, " must be more than %.2f\n", min);
×
733
      } else {
734
        fprintf(stderr, " must be at least %.2f\n", min);
×
735
      }
736
    }
737
  } else if (min == DBL_MIN) {
×
738
    // no lower bound
739
    if (max == 0) {
×
740
      if (max_strict) {
×
741
        fputs(" must be negative\n", stderr);
×
742
      } else {
743
        fputs(" must be negative or zero\n", stderr);
×
744
      }
745
    } else {
746
      if (max_strict) {
×
747
        fprintf(stderr, " must be less than %.2f\n", max);
×
748
      } else {
749
        fprintf(stderr, " must be no more than %.2f\n", max);
×
750
      }
751
    }
752
  } else {
753
    left_bracket = min_strict ? '(' : '[';
×
754
    right_bracket = max_strict ? ')' : ']';
×
755
    fprintf(stderr, " must be in the interval %c%.2f, %.2f%c\n", left_bracket, min, max, right_bracket);
×
756
  }
757

758
  return false;
×
759
}
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