blob: a7f012fbcad236ba93b3953ae8a0d852648f5400 [file] [log] [blame]
Eric Andersen24794452004-03-06 22:11:45 +00001/* vi: set sw=4 ts=4: */
2/*
3 * Utility routines.
4 *
5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
6 *
"Robert P. J. Day"5d8843e2006-07-10 11:41:19 +00007 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
Eric Andersen24794452004-03-06 22:11:45 +00008 */
9
Eric Andersen24794452004-03-06 22:11:45 +000010#include <assert.h>
11#include "libbb.h"
12
Denis Vlasenko13858992006-10-08 12:49:22 +000013int safe_strtod(const char *arg, double* value)
Eric Andersen24794452004-03-06 22:11:45 +000014{
15 char *endptr;
16 int errno_save = errno;
17
18 assert(arg!=NULL);
19 errno = 0;
20 *value = strtod(arg, &endptr);
Denis Vlasenko13858992006-10-08 12:49:22 +000021 if (errno != 0 || *endptr != '\0' || endptr == arg) {
Eric Andersen24794452004-03-06 22:11:45 +000022 return 1;
23 }
24 errno = errno_save;
25 return 0;
26}
Eric Andersen24794452004-03-06 22:11:45 +000027
Denis Vlasenko13858992006-10-08 12:49:22 +000028int safe_strtoull(const char *arg, unsigned long long* value)
Eric Andersen24794452004-03-06 22:11:45 +000029{
30 char *endptr;
31 int errno_save = errno;
32
33 assert(arg!=NULL);
Denis Vlasenko13858992006-10-08 12:49:22 +000034 if (!isdigit(arg[0])) /* strtouXX takes minus signs w/o error! :( */
35 return 1;
Eric Andersen24794452004-03-06 22:11:45 +000036 errno = 0;
Denis Vlasenko13858992006-10-08 12:49:22 +000037 *value = strtoull(arg, &endptr, 0);
38 if (errno != 0 || *endptr != '\0' || endptr == arg) {
Eric Andersen24794452004-03-06 22:11:45 +000039 return 1;
40 }
41 errno = errno_save;
42 return 0;
43}
Eric Andersen24794452004-03-06 22:11:45 +000044
Denis Vlasenko13858992006-10-08 12:49:22 +000045int safe_strtoll(const char *arg, long long* value)
Denis Vlasenkoa552eeb2006-09-26 09:22:12 +000046{
47 char *endptr;
48 int errno_save = errno;
49
50 assert(arg!=NULL);
51 errno = 0;
52 *value = strtoll(arg, &endptr, 0);
Denis Vlasenko13858992006-10-08 12:49:22 +000053 if (errno != 0 || *endptr != '\0' || endptr == arg) {
Denis Vlasenkoa552eeb2006-09-26 09:22:12 +000054 return 1;
55 }
56 errno = errno_save;
57 return 0;
58}
Denis Vlasenkoa552eeb2006-09-26 09:22:12 +000059
Denis Vlasenko13858992006-10-08 12:49:22 +000060int 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
77int safe_strtol(const char *arg, long* value)
Denis Vlasenkoa552eeb2006-09-26 09:22:12 +000078{
79 char *endptr;
80 int errno_save = errno;
81
82 assert(arg!=NULL);
83 errno = 0;
Denis Vlasenko13858992006-10-08 12:49:22 +000084 *value = strtol(arg, &endptr, 0);
85 if (errno != 0 || *endptr != '\0' || endptr == arg) {
Denis Vlasenkoa552eeb2006-09-26 09:22:12 +000086 return 1;
87 }
88 errno = errno_save;
89 return 0;
90}
Denis Vlasenko13858992006-10-08 12:49:22 +000091
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
111int 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
126int 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
141int BUG_safe_strtou32_unimplemented(void);
142int 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}