Replace current verbose GPL stuff in libbb/*.c with one-line GPL boilerplate.
[oweals/busybox.git] / libbb / parse_number.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * bb_xparse_number implementation for busybox
4  *
5  * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
6  *
7  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
8  */
9
10 #include <stdlib.h>
11 #include <string.h>
12 #include <limits.h>
13 #include <errno.h>
14 #include <assert.h>
15 #include "libbb.h"
16
17 unsigned long bb_xparse_number(const char *numstr,
18                                                            const struct suffix_mult *suffixes)
19 {
20         unsigned long int r;
21         char *e;
22         int old_errno;
23
24         /* Since this is a lib function, we're not allowed to reset errno to 0.
25          * Doing so could break an app that is deferring checking of errno.
26          * So, save the old value so that we can restore it if successful. */
27         old_errno = errno;
28         errno = 0;
29         r = strtoul(numstr, &e, 10);
30
31         if ((numstr != e) && !errno) {
32                 errno = old_errno;      /* Ok.  So restore errno. */
33                 if (!*e) {
34                         return r;
35                 }
36                 if (suffixes) {
37                         assert(suffixes->suffix);       /* No nul suffixes. */
38                         do {
39                                 if (strcmp(suffixes->suffix, e) == 0) {
40                                         if (ULONG_MAX / suffixes->mult < r) {   /* Overflow! */
41                                                 break;
42                                         }
43                                         return r * suffixes->mult;
44                                 }
45                                 ++suffixes;
46                         } while (suffixes->suffix);
47                 }
48         }
49         bb_error_msg_and_die("invalid number `%s'", numstr);
50 }