tests: add fold(1) test for --bytes option
[coreutils.git] / gl / lib / xdectoint.c
blob05534701c65361b9ab1d497cb9ead043a7f3a662
1 /* Convert decimal strings with bounds checking and exit on error.
3 Copyright (C) 2014-2024 Free Software Foundation, Inc.
5 This program 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.
10 This program 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.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
18 #include <config.h>
20 #include "xdectoint.h"
22 #include <errno.h>
23 #include <inttypes.h>
24 #include <stdlib.h>
26 #include <error.h>
27 #include <quote.h>
28 #include <xstrtol.h>
30 /* Parse numeric string N_STR of base BASE, and return the value.
31 The value is between MIN and MAX.
32 Strings can have multiplicative SUFFIXES if specified.
33 On a parse error or out-of-range number, diagnose with N_STR and ERR, and
34 exit with status ERR_EXIT if nonzero, EXIT_FAILURE otherwise.
35 However, if FLAGS & XTOINT_MIN_QUIET, do not diagnose or exit
36 for too-low numbers; return MIN and set errno instead.
37 Similarly for XTOINT_MAX_QUIET and too-high numbers and MAX.
38 The errno value and diagnostic for out-of-range values depend on
39 whether FLAGS & XTOINT_MIN_RANGE and FLAGS & XTOINT_MAX_RANGE are set. */
41 __xdectoint_t
42 __xnumtoint (char const *n_str, int base, __xdectoint_t min, __xdectoint_t max,
43 char const *suffixes, char const *err, int err_exit,
44 int flags)
46 __xdectoint_t tnum, r;
47 strtol_error s_err = __xstrtol (n_str, nullptr, base, &tnum, suffixes);
49 /* Errno value to report if there is an overflow. */
50 int overflow_errno;
52 if (s_err != LONGINT_INVALID)
54 if (tnum < min)
56 r = min;
57 overflow_errno = flags & XTOINT_MIN_RANGE ? ERANGE : EOVERFLOW;
58 if (s_err == LONGINT_OK)
59 s_err = LONGINT_OVERFLOW;
61 else if (max < tnum)
63 r = max;
64 overflow_errno = flags & XTOINT_MAX_RANGE ? ERANGE : EOVERFLOW;
65 if (s_err == LONGINT_OK)
66 s_err = LONGINT_OVERFLOW;
68 else
70 r = tnum;
71 overflow_errno = EOVERFLOW;
75 int e = s_err == LONGINT_OVERFLOW ? overflow_errno : 0;
77 if (! (s_err == LONGINT_OK
78 || (s_err == LONGINT_OVERFLOW
79 && flags & (tnum < 0 ? XTOINT_MIN_QUIET : XTOINT_MAX_QUIET))))
80 error (err_exit ? err_exit : EXIT_FAILURE, e, "%s: %s", err, quote (n_str));
82 errno = e;
83 return r;
86 /* Parse decimal string N_STR, and return the value.
87 Exit on parse error or if MIN or MAX are exceeded.
88 Strings can have multiplicative SUFFIXES if specified.
89 ERR is printed along with N_STR on error. */
91 __xdectoint_t
92 __xdectoint (char const *n_str, __xdectoint_t min, __xdectoint_t max,
93 char const *suffixes, char const *err, int err_exit)
95 return __xnumtoint (n_str, 10, min, max, suffixes, err, err_exit, 0);