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

Last change on this file since dade7a0 was dade7a0, checked in by Thomas Lopatic <thomas@…>, 5 years ago

No more warnings in libsm.

  • 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 "ram.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
50 /*
51 for any base > 10, the digits incrementally following
52 9 are assumed to be "abc...z" or "ABC...Z"
53 */
54
55 if (!isalnum(c) || (xx = DIGIT(c)) >= base)
56 return (0); /* no number formed */
57
58 if (base == 16 && c == '0' && isxdigit(str[2]) &&
59 (str[1] == 'x' || str[1] == 'X'))
60 c = *(str += 2); /* skip over leading "0x" or "0X" */
61
62 for (val = -DIGIT(c); isalnum(c = *++str) && (xx = DIGIT(c)) < base; )
63 /* accumulate neg avoids surprises near MAXLONG */
64 val = base * val - xx;
65
66 if (ptr != (int8_t **)0)
67 *ptr = str;
68
69 return (neg ? val : -val);
70}
71
Note: See TracBrowser for help on using the repository browser.