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

Last change on this file since 050d522 was f40a309, checked in by Thomas Lopatic <thomas@…>, 7 years ago

Unix line breaks.

  • Property mode set to 100644
File size: 1.5 KB
RevLine 
[f40a309]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
14long
15strtol(str, ptr, base)
16register char *str;
17char **ptr;
18register int base;
19{
20 register long val;
21 register int c;
22 int xx, neg = 0;
23
24 if (ptr != (char **)0)
25 *ptr = str; /* in case no number is formed */
26
27 if (base < 0 || base > MBASE)
28 return (0); /* base is invalid -- should be a fatal error */
29
30 if (!isalnum(c = *str)) {
31
32 while (isspace(c))
33 c = *++str;
34
35 switch (c) {
36
37 case '-':
38 neg++;
39
40 case '+': /* fall-through */
41 c = *++str;
42 }
43 }
44
45 if (base == 0)
46 if (c != '0')
47 base = 10;
48 else if (str[1] == 'x' || str[1] == 'X')
49 base = 16;
50 else
51 base = 8;
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 != (char **)0)
69 *ptr = str;
70
71 return (neg ? val : -val);
72}
Note: See TracBrowser for help on using the repository browser.