source: buchla-68k/libsm/strtol.c@ e225e77

Last change on this file since e225e77 was 7258c6a, checked in by Thomas Lopatic <thomas@…>, 7 years ago

Use standard integer types.

  • Property mode set to 100644
File size: 1.5 KB
Line 
1/*
2 =============================================================================
3 strtol.c -- convert a string of ASCII digits to a long
4 Version 1 -- 1987-06-12
5 =============================================================================
6*/
7
8#include "ctype.h"
9
10#define DIGIT(x) (isdigit(x) ? (x)-'0' : islower(x) ? (x)+10-'a' : (x)+10-'A')
11
12#define MBASE ('z' - 'a' + 1 + 10)
13
14int32_t strtol(int8_t *str, int8_t **ptr, int16_t base)
15{
16 register int32_t val;
17 register int16_t c;
18 int16_t xx, neg = 0;
19
20 if (ptr != (int8_t **)0)
21 *ptr = str; /* in case no number is formed */
22
23 if (base < 0 || base > MBASE)
24 return (0); /* base is invalid -- should be a fatal error */
25
26 if (!isalnum(c = *str)) {
27
28 while (isspace(c))
29 c = *++str;
30
31 switch (c) {
32
33 case '-':
34 neg++;
35
36 case '+': /* fall-through */
37 c = *++str;
38 }
39 }
40
41 if (base == 0)
42 if (c != '0')
43 base = 10;
44 else if (str[1] == 'x' || str[1] == 'X')
45 base = 16;
46 else
47 base = 8;
48 /*
49 for any base > 10, the digits incrementally following
50 9 are assumed to be "abc...z" or "ABC...Z"
51 */
52
53 if (!isalnum(c) || (xx = DIGIT(c)) >= base)
54 return (0); /* no number formed */
55
56 if (base == 16 && c == '0' && isxdigit(str[2]) &&
57 (str[1] == 'x' || str[1] == 'X'))
58 c = *(str += 2); /* skip over leading "0x" or "0X" */
59
60 for (val = -DIGIT(c); isalnum(c = *++str) && (xx = DIGIT(c)) < base; )
61 /* accumulate neg avoids surprises near MAXLONG */
62 val = base * val - xx;
63
64 if (ptr != (int8_t **)0)
65 *ptr = str;
66
67 return (neg ? val : -val);
68}
Note: See TracBrowser for help on using the repository browser.