| 90 | |
| 91 | template <typename Type> |
| 92 | static int ParseSigned(const char* str, const ScanSpecification& spec, Type* value) |
| 93 | { |
| 94 | int base = 0; |
| 95 | switch (spec.specifier) { |
| 96 | case 'v': |
| 97 | case 'i': |
| 98 | break; |
| 99 | case 'd': |
| 100 | base = 10; |
| 101 | break; |
| 102 | case 'x': |
| 103 | case 'X': |
| 104 | base = 16; |
| 105 | break; |
| 106 | case 'o': |
| 107 | base = 8; |
| 108 | break; |
| 109 | default: |
| 110 | LOG(DFATAL) << "Invalid scan specifier '" << spec.specifier |
| 111 | << "' for signed integral type"; |
| 112 | return 0; |
| 113 | } |
| 114 | |
| 115 | char* endptr; |
| 116 | int saved_errno = errno; |
| 117 | Type v; |
| 118 | errno = 0; |
| 119 | if (sizeof(Type) > sizeof(long)) { |
| 120 | long long n = strtoll(str, &endptr, base); |
| 121 | if (errno != 0) |
| 122 | return 0; |
| 123 | v = n; |
| 124 | } else { |
| 125 | long n = strtol(str, &endptr, base); |
| 126 | if (errno != 0) |
| 127 | return 0; |
| 128 | v = n; |
| 129 | if (v != n) { |
| 130 | errno = ERANGE; |
| 131 | return false; |
| 132 | } |
| 133 | } |
| 134 | |
| 135 | *value = v; |
| 136 | errno = saved_errno; |
| 137 | return endptr - str; |
| 138 | } |
| 139 | |
| 140 | template <typename Type> |
| 141 | static int ParseUnsigned(const char* str, const ScanSpecification& spec, Type* value) |
nothing calls this directly
no outgoing calls
no test coverage detected