strtol.c (4bd71a3c895438d9e85930dc29d6000d8ecb59b4) | strtol.c (f34b139cda7501c64f60f699c87a263197d3dd90) |
---|---|
1/*- 2 * Copyright (c) 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 43 unchanged lines hidden (view full) --- 52long 53strtol(nptr, endptr, base) 54 const char *nptr; 55 char **endptr; 56 int base; 57{ 58 const char *s; 59 unsigned long acc; | 1/*- 2 * Copyright (c) 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 43 unchanged lines hidden (view full) --- 52long 53strtol(nptr, endptr, base) 54 const char *nptr; 55 char **endptr; 56 int base; 57{ 58 const char *s; 59 unsigned long acc; |
60 unsigned char c; | 60 char c; |
61 unsigned long cutoff; | 61 unsigned long cutoff; |
62 int neg, any, cutlim, n; | 62 int neg, any, cutlim; |
63 64 /* 65 * Skip white space and pick up leading +/- sign if any. 66 * If base is 0, allow 0x for hex and 0 for octal, else 67 * assume decimal; if base is already 16, allow 0x. 68 */ 69 s = nptr; 70 do { 71 c = *s++; | 63 64 /* 65 * Skip white space and pick up leading +/- sign if any. 66 * If base is 0, allow 0x for hex and 0 for octal, else 67 * assume decimal; if base is already 16, allow 0x. 68 */ 69 s = nptr; 70 do { 71 c = *s++; |
72 } while (isspace(c)); | 72 } while (isspace((unsigned char)c)); |
73 if (c == '-') { 74 neg = 1; 75 c = *s++; 76 } else { 77 neg = 0; 78 if (c == '+') 79 c = *s++; 80 } --- 26 unchanged lines hidden (view full) --- 107 * Set 'any' if any `digits' consumed; make it negative to indicate 108 * overflow. 109 */ 110 cutoff = neg ? (unsigned long)-(LONG_MIN + LONG_MAX) + LONG_MAX 111 : LONG_MAX; 112 cutlim = cutoff % base; 113 cutoff /= base; 114 for ( ; ; c = *s++) { | 73 if (c == '-') { 74 neg = 1; 75 c = *s++; 76 } else { 77 neg = 0; 78 if (c == '+') 79 c = *s++; 80 } --- 26 unchanged lines hidden (view full) --- 107 * Set 'any' if any `digits' consumed; make it negative to indicate 108 * overflow. 109 */ 110 cutoff = neg ? (unsigned long)-(LONG_MIN + LONG_MAX) + LONG_MAX 111 : LONG_MAX; 112 cutlim = cutoff % base; 113 cutoff /= base; 114 for ( ; ; c = *s++) { |
115 if (isxdigit(c)) 116 n = digittoint(c); 117 else if (isalpha(c)) 118 n = (char)c - (isupper(c) ? 'A' - 10 : 'a' - 10); | 115 if (c >= '0' && c <= '9') 116 c -= '0'; 117 else if (c >= 'A' && c <= 'Z') 118 c -= 'A' - 10; 119 else if (c >= 'a' && c <= 'z') 120 c -= 'a' - 10; |
119 else 120 break; | 121 else 122 break; |
121 if (n < 0 || n >= base) | 123 if (c >= base) |
122 break; | 124 break; |
123 if (any < 0 || acc > cutoff || (acc == cutoff && n > cutlim)) | 125 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) |
124 any = -1; 125 else { 126 any = 1; 127 acc *= base; | 126 any = -1; 127 else { 128 any = 1; 129 acc *= base; |
128 acc += n; | 130 acc += c; |
129 } 130 } 131 if (any < 0) { 132 acc = neg ? LONG_MIN : LONG_MAX; 133 errno = ERANGE; 134 } else if (!any) { 135noconv: 136 errno = EINVAL; 137 } else if (neg) 138 acc = -acc; 139 if (endptr != NULL) 140 *endptr = (char *)(any ? s - 1 : nptr); 141 return (acc); 142} | 131 } 132 } 133 if (any < 0) { 134 acc = neg ? LONG_MIN : LONG_MAX; 135 errno = ERANGE; 136 } else if (!any) { 137noconv: 138 errno = EINVAL; 139 } else if (neg) 140 acc = -acc; 141 if (endptr != NULL) 142 *endptr = (char *)(any ? s - 1 : nptr); 143 return (acc); 144} |