]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/libbsd/lib/contrib/src/dehumanize_number.c
update
[l4.git] / l4 / pkg / libbsd / lib / contrib / src / dehumanize_number.c
1 /*
2  * Copyright © 2012-2013 Guillem Jover <guillem@hadrons.org>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  * 3. The name of the author may not be used to endorse or promote products
13  *    derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
16  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
18  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include <sys/cdefs.h>
28
29 #include <errno.h>
30 #include <ctype.h>
31 #include <libutil.h>
32 #include <stdint.h>
33 #include <stdlib.h>
34
35 int
36 dehumanize_number(const char *buf, int64_t *num)
37 {
38         uint64_t rval, rmax;
39         int sign = +1;
40         int rc;
41
42         /* The current expand_number() implementation uses bit shifts, so
43          * we cannot pass negative numbers, preserve the sign and apply it
44          * later. */
45         while (isspace(*buf))
46                 buf++;
47         if (*buf == '-') {
48                 sign = -1;
49                 buf++;
50         }
51
52         rc = expand_number(buf, &rval);
53         if (rc < 0)
54                 return rc;
55
56         /* The sign has been stripped, so rval has the absolute value.
57          * Error out, regardless of the sign, if rval is greater than
58          * abs(INT64_MIN) (== INT64_MAX + 1), or if the sign is positive
59          * and the value has overflown by one (INT64_MAX + 1). */
60         rmax = INT64_MAX + 1ULL;
61         if (rval > rmax || (rval == rmax && sign == +1)) {
62                 errno = ERANGE;
63                 return -1;
64         }
65         *num = rval * sign;
66
67         return 0;
68 }