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

Last change on this file since 3577fe1 was 6dbed52, checked in by Thomas Lopatic <thomas@…>, 7 years ago

Explicitly mark fall-throughs.

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