| 83 | } |
| 84 | |
| 85 | long strtol(const char* str, char** endptr, int base) { |
| 86 | if (!str) { |
| 87 | if (endptr) { |
| 88 | *endptr = const_cast<char*>(str); |
| 89 | } |
| 90 | return 0; |
| 91 | } |
| 92 | |
| 93 | const char* p = str; |
| 94 | long result = 0; |
| 95 | bool negative = false; |
| 96 | |
| 97 | // Skip leading whitespace |
| 98 | while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r' || *p == '\f' || *p == '\v') { |
| 99 | p++; |
| 100 | } |
| 101 | |
| 102 | // Handle sign |
| 103 | if (*p == '-') { |
| 104 | negative = true; |
| 105 | p++; |
| 106 | } else if (*p == '+') { |
| 107 | p++; |
| 108 | } |
| 109 | |
| 110 | // Auto-detect base if base is 0 |
| 111 | if (base == 0) { |
| 112 | if (*p == '0') { |
| 113 | if (*(p + 1) == 'x' || *(p + 1) == 'X') { |
| 114 | base = 16; |
| 115 | p += 2; |
| 116 | } else { |
| 117 | base = 8; |
| 118 | p++; |
| 119 | } |
| 120 | } else { |
| 121 | base = 10; |
| 122 | } |
| 123 | } else if (base == 16) { |
| 124 | // Skip optional 0x/0X prefix for base 16 |
| 125 | if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X')) { |
| 126 | p += 2; |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | // Validate base |
| 131 | if (base < 2 || base > 36) { |
| 132 | if (endptr) { |
| 133 | *endptr = const_cast<char*>(str); |
| 134 | } |
| 135 | return 0; |
| 136 | } |
| 137 | |
| 138 | // Parse digits |
| 139 | const char* start = p; |
| 140 | while (*p && isDigitInBase(*p, base)) { |
| 141 | result = result * base + charToDigit(*p); |
| 142 | p++; |
no test coverage detected