[e8d59ca] | 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 | |
---|
[48751ab] | 12 | #include <rtems/stringto.h> |
---|
| 13 | |
---|
[e8d59ca] | 14 | #include <errno.h> |
---|
| 15 | #include <stdlib.h> |
---|
| 16 | #include <limits.h> |
---|
| 17 | #include <stdbool.h> |
---|
| 18 | |
---|
[48751ab] | 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> |
---|
[e8d59ca] | 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 | |
---|
[48751ab] | 33 | #if defined(STRING_TO_POINTER) |
---|
| 34 | #define STRING_TO_INTEGER |
---|
| 35 | #endif |
---|
| 36 | |
---|
[e8d59ca] | 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 | |
---|
[48751ab] | 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 ( |
---|
[e8d59ca] | 73 | const char *s, |
---|
| 74 | STRING_TO_TYPE *n, |
---|
| 75 | char **endptr |
---|
[48751ab] | 76 | #if defined(STRING_TO_INTEGER) && !defined(STRING_TO_POINTER) |
---|
[e8d59ca] | 77 | , |
---|
| 78 | int base |
---|
| 79 | #endif |
---|
| 80 | ) |
---|
| 81 | { |
---|
[48751ab] | 82 | STRING_TO_INPUT_TYPE result; |
---|
| 83 | char *end; |
---|
[e8d59ca] | 84 | |
---|
| 85 | if ( !n ) |
---|
[48751ab] | 86 | return RTEMS_INVALID_ADDRESS; |
---|
[e8d59ca] | 87 | |
---|
| 88 | errno = 0; |
---|
| 89 | *n = 0; |
---|
| 90 | |
---|
| 91 | #ifdef STRING_TO_FLOAT |
---|
| 92 | result = STRING_TO_METHOD( s, &end ); |
---|
[48751ab] | 93 | #elif defined(STRING_TO_POINTER) |
---|
| 94 | result = STRING_TO_METHOD( s, &end, 16 ); |
---|
[e8d59ca] | 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 ) |
---|
[48751ab] | 105 | return RTEMS_NOT_DEFINED; |
---|
[e8d59ca] | 106 | |
---|
| 107 | /* there was a conversion error */ |
---|
| 108 | if ( (result == ZERO) && errno ) |
---|
[48751ab] | 109 | return RTEMS_INVALID_NUMBER; |
---|
[e8d59ca] | 110 | |
---|
| 111 | #ifdef STRING_TO_MAX |
---|
| 112 | /* there was an overflow */ |
---|
| 113 | if ( (result == STRING_TO_MAX) && (errno == ERANGE)) |
---|
[48751ab] | 114 | return RTEMS_INVALID_NUMBER; |
---|
[e8d59ca] | 115 | #endif |
---|
| 116 | |
---|
| 117 | #ifdef STRING_TO_MIN |
---|
| 118 | /* there was an underflow */ |
---|
| 119 | if ( (result == STRING_TO_MIN) && (errno == ERANGE)) |
---|
[48751ab] | 120 | return RTEMS_INVALID_NUMBER; |
---|
[e8d59ca] | 121 | #endif |
---|
| 122 | |
---|
[35d09ba] | 123 | *n = (STRING_TO_TYPE) result; |
---|
[48751ab] | 124 | return RTEMS_SUCCESSFUL; |
---|
[e8d59ca] | 125 | } |
---|
| 126 | |
---|