attempt to regularize atoi mess.
[oweals/busybox.git] / libbb / safe_strtol.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * Utility routines.
4  *
5  * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
6  *
7  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
8  */
9
10 #include <assert.h>
11 #include "libbb.h"
12
13 int safe_strtod(const char *arg, double* value)
14 {
15         char *endptr;
16         int errno_save = errno;
17
18         assert(arg!=NULL);
19         errno = 0;
20         *value = strtod(arg, &endptr);
21         if (errno != 0 || *endptr != '\0' || endptr == arg) {
22                 return 1;
23         }
24         errno = errno_save;
25         return 0;
26 }
27
28 int safe_strtoull(const char *arg, unsigned long long* value)
29 {
30         char *endptr;
31         int errno_save = errno;
32
33         assert(arg!=NULL);
34         if (!isdigit(arg[0])) /* strtouXX takes minus signs w/o error! :( */
35                 return 1;
36         errno = 0;
37         *value = strtoull(arg, &endptr, 0);
38         if (errno != 0 || *endptr != '\0' || endptr == arg) {
39                 return 1;
40         }
41         errno = errno_save;
42         return 0;
43 }
44
45 int safe_strtoll(const char *arg, long long* value)
46 {
47         char *endptr;
48         int errno_save = errno;
49
50         assert(arg!=NULL);
51         errno = 0;
52         *value = strtoll(arg, &endptr, 0);
53         if (errno != 0 || *endptr != '\0' || endptr == arg) {
54                 return 1;
55         }
56         errno = errno_save;
57         return 0;
58 }
59
60 int safe_strtoul(const char *arg, unsigned long* value)
61 {
62         char *endptr;
63         int errno_save = errno;
64
65         assert(arg!=NULL);
66         if (!isdigit(arg[0])) /* strtouXX takes minus signs w/o error! :( */
67                 return 1;
68         errno = 0;
69         *value = strtoul(arg, &endptr, 0);
70         if (errno != 0 || *endptr != '\0' || endptr == arg) {
71                 return 1;
72         }
73         errno = errno_save;
74         return 0;
75 }
76
77 int safe_strtol(const char *arg, long* value)
78 {
79         char *endptr;
80         int errno_save = errno;
81
82         assert(arg!=NULL);
83         errno = 0;
84         *value = strtol(arg, &endptr, 0);
85         if (errno != 0 || *endptr != '\0' || endptr == arg) {
86                 return 1;
87         }
88         errno = errno_save;
89         return 0;
90 }
91
92 /* TODO: This is what uclibc is doing. Try to do the same? */
93
94 #if 0
95 #if defined __HAVE_ELF__
96
97 # define strong_alias(name, aliasname) _strong_alias(name, aliasname)
98 # define _strong_alias(name, aliasname) \
99   extern __typeof (name) aliasname __attribute__ ((alias (#name)));
100
101 #else /* !defined __HAVE_ELF__ */
102
103 #  define strong_alias(name, aliasname) _strong_alias (name, aliasname)
104 #  define _strong_alias(name, aliasname) \
105         __asm__(".global " __C_SYMBOL_PREFIX__ #aliasname "\n" \
106                 ".set " __C_SYMBOL_PREFIX__ #aliasname "," __C_SYMBOL_PREFIX__ #name);
107
108 #endif
109 #endif
110
111 int safe_strtoi(const char *arg, int* value)
112 {
113         if (sizeof(long) == sizeof(int)) {
114                 return safe_strtol(arg, (long*)value);
115         } else {
116                 int error;
117                 long lvalue = *value;
118                 error = safe_strtol(arg, &lvalue);
119                 if (lvalue < INT_MIN || lvalue > INT_MAX)
120                         return 1;
121                 *value = (int) lvalue;
122                 return error;
123         }
124 }
125
126 int safe_strtou(const char *arg, unsigned* value)
127 {
128         if (sizeof(unsigned long) == sizeof(unsigned)) {
129                 return safe_strtoul(arg, (unsigned long*)value);
130         } else {
131                 int error;
132                 unsigned long lvalue = *value;
133                 error = safe_strtoul(arg, &lvalue);
134                 if (lvalue > UINT_MAX)
135                         return 1;
136                 *value = (unsigned) lvalue;
137                 return error;
138         }
139 }
140
141 int BUG_safe_strtou32_unimplemented(void);
142 int safe_strtou32(const char *arg, uint32_t* value)
143 {
144         if (sizeof(uint32_t) == sizeof(unsigned))
145                 return safe_strtou(arg, (unsigned*)value);
146         if (sizeof(uint32_t) == sizeof(unsigned long))
147                 return safe_strtoul(arg, (unsigned long*)value);
148         return BUG_safe_strtou32_unimplemented();
149 }