1 | /* |
---|
2 | * COPYRIGHT (c) 2009. |
---|
3 | * On-Line Applications Research Corporation (OAR). |
---|
4 | * |
---|
5 | * The license and distribution terms for this file may be |
---|
6 | * found in the file LICENSE in this distribution or at |
---|
7 | * http://www.rtems.com/license/LICENSE. |
---|
8 | * |
---|
9 | * $Id$ |
---|
10 | */ |
---|
11 | |
---|
12 | #include <rtems/stringto.h> |
---|
13 | |
---|
14 | #include <errno.h> |
---|
15 | #include <stdlib.h> |
---|
16 | #include <limits.h> |
---|
17 | #include <stdbool.h> |
---|
18 | |
---|
19 | /* |
---|
20 | * If we are doing floating point conversion, then we need math.h |
---|
21 | */ |
---|
22 | #if defined(STRING_TO_FLOAT) |
---|
23 | #include <math.h> |
---|
24 | #endif |
---|
25 | |
---|
26 | #include <rtems.h> |
---|
27 | |
---|
28 | /* |
---|
29 | * This file is designed to be included multiple times to instantiate |
---|
30 | * it and should NOT be protected against multiple inclusions. |
---|
31 | */ |
---|
32 | |
---|
33 | #if defined(STRING_TO_POINTER) |
---|
34 | #define STRING_TO_INTEGER |
---|
35 | #endif |
---|
36 | |
---|
37 | #if !defined(STRING_TO_FLOAT) && !defined(STRING_TO_INTEGER) |
---|
38 | #error "Neither STRING_TO_FLOAT nor STRING_TO_INTEGER defined" |
---|
39 | #endif |
---|
40 | |
---|
41 | #if defined(STRING_TO_FLOAT) && defined(STRING_TO_INTEGER) |
---|
42 | #error "Both STRING_TO_FLOAT nor STRING_TO_INTEGER defined" |
---|
43 | #endif |
---|
44 | |
---|
45 | #ifndef STRING_TO_TYPE |
---|
46 | #error "STRING_TO_TYPE not defined" |
---|
47 | #endif |
---|
48 | |
---|
49 | #ifndef STRING_TO_NAME |
---|
50 | #error "STRING_TO_NAME not defined" |
---|
51 | #endif |
---|
52 | |
---|
53 | #ifndef STRING_TO_METHOD |
---|
54 | #error "STRING_TO_METHOD not defined" |
---|
55 | #endif |
---|
56 | |
---|
57 | #ifndef STRING_TO_MAX |
---|
58 | #error "STRING_TO_MAX not defined" |
---|
59 | #endif |
---|
60 | |
---|
61 | #undef ZERO |
---|
62 | #ifdef STRING_TO_FLOAT |
---|
63 | #define ZERO 0.0 |
---|
64 | #elif defined(STRING_TO_INTEGER) |
---|
65 | #define ZERO 0 |
---|
66 | #endif |
---|
67 | |
---|
68 | #if !defined(STRING_TO_INPUT_TYPE) |
---|
69 | #define STRING_TO_INPUT_TYPE STRING_TO_TYPE |
---|
70 | #endif |
---|
71 | |
---|
72 | rtems_status_code STRING_TO_NAME ( |
---|
73 | const char *s, |
---|
74 | STRING_TO_TYPE *n, |
---|
75 | char **endptr |
---|
76 | #if defined(STRING_TO_INTEGER) && !defined(STRING_TO_POINTER) |
---|
77 | , |
---|
78 | int base |
---|
79 | #endif |
---|
80 | ) |
---|
81 | { |
---|
82 | STRING_TO_INPUT_TYPE result; |
---|
83 | char *end; |
---|
84 | |
---|
85 | if ( !n ) |
---|
86 | return RTEMS_INVALID_ADDRESS; |
---|
87 | |
---|
88 | errno = 0; |
---|
89 | *n = 0; |
---|
90 | |
---|
91 | #ifdef STRING_TO_FLOAT |
---|
92 | result = STRING_TO_METHOD( s, &end ); |
---|
93 | #elif defined(STRING_TO_POINTER) |
---|
94 | result = STRING_TO_METHOD( s, &end, 16 ); |
---|
95 | #elif defined(STRING_TO_INTEGER) |
---|
96 | result = STRING_TO_METHOD( s, &end, base ); |
---|
97 | #endif |
---|
98 | |
---|
99 | /* If the user wants the end pointer back, then return it. */ |
---|
100 | if ( endptr ) |
---|
101 | *endptr = end; |
---|
102 | |
---|
103 | /* nothing was converted */ |
---|
104 | if ( end == s ) |
---|
105 | return RTEMS_NOT_DEFINED; |
---|
106 | |
---|
107 | /* |
---|
108 | * In theory, we should check this but newlib never returns anything |
---|
109 | * but range errors. So this is unreachable code based upon the newlib |
---|
110 | * implementation of strXXX methods as of 1 December 2009. --joel |
---|
111 | */ |
---|
112 | #if 0 |
---|
113 | /* there was a conversion error */ |
---|
114 | if ( (result == ZERO) && errno ) |
---|
115 | return RTEMS_INVALID_NUMBER; |
---|
116 | #endif |
---|
117 | |
---|
118 | #ifdef STRING_TO_MAX |
---|
119 | /* there was an overflow */ |
---|
120 | if ( (result == STRING_TO_MAX) && (errno == ERANGE)) |
---|
121 | return RTEMS_INVALID_NUMBER; |
---|
122 | #endif |
---|
123 | |
---|
124 | #ifdef STRING_TO_MIN |
---|
125 | /* there was an underflow */ |
---|
126 | if ( (result == STRING_TO_MIN) && (errno == ERANGE)) |
---|
127 | return RTEMS_INVALID_NUMBER; |
---|
128 | #endif |
---|
129 | |
---|
130 | *n = (STRING_TO_TYPE) result; |
---|
131 | return RTEMS_SUCCESSFUL; |
---|
132 | } |
---|
133 | |
---|