1 /*
2  * This file has been modified for the cdrkit suite.
3  *
4  * The behaviour and appearence of the program code below can differ to a major
5  * extent from the version distributed by the original author(s).
6  *
7  * For details, see Changelog file distributed with the cdrkit package. If you
8  * received this file from another source then ask the distributing person for
9  * a log of modifications.
10  *
11  */
12 
13 /* @(#)astoi.c	1.8 03/06/15 Copyright 1985, 1995-2003 J. Schilling */
14 /*
15  *	astoi() converts a string to int
16  *	astol() converts a string to long
17  *
18  *	Leading tabs and spaces are ignored.
19  *	Both return pointer to the first char that has not been used.
20  *	Caller must check if this means a bad conversion.
21  *
22  *	leading "+" is ignored
23  *	leading "0"  makes conversion octal (base 8)
24  *	leading "0x" makes conversion hex   (base 16)
25  *
26  *	Copyright (c) 1985, 1995-2003 J. Schilling
27  */
28 /*
29  * This program is free software; you can redistribute it and/or modify
30  * it under the terms of the GNU General Public License version 2
31  * as published by the Free Software Foundation.
32  *
33  * This program is distributed in the hope that it will be useful,
34  * but WITHOUT ANY WARRANTY; without even the implied warranty of
35  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
36  * GNU General Public License for more details.
37  *
38  * You should have received a copy of the GNU General Public License along with
39  * this program; see the file COPYING.  If not, write to the Free Software
40  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
41  */
42 
43 #include <standard.h>
44 #include <schily.h>
45 
46 #define	is_space(c)	 ((c) == ' ' || (c) == '\t')
47 #define	is_digit(c)	 ((c) >= '0' && (c) <= '9')
48 #define	is_hex(c)	(\
49 			((c) >= 'a' && (c) <= 'f') || \
50 			((c) >= 'A' && (c) <= 'F'))
51 
52 #define	to_lower(c)	(((c) >= 'A' && (c) <= 'Z') ? (c) - 'A'+'a' : (c))
53 
54 #ifdef	notdef
55 EXPORT int
atoi(s)56 atoi(s)
57 	char	*s;
58 {
59 	long	l;
60 
61 	(void) astol(s, &l);
62 	return ((int) l);
63 }
64 
65 EXPORT long
atol(s)66 atol(s)
67 	char	*s;
68 {
69 	long	l;
70 
71 	(void) astol(s, &l);
72 	return (l);
73 }
74 #endif
75 
76 EXPORT char *
astoi(s,i)77 astoi(s, i)
78 	const char *s;
79 	int *i;
80 {
81 	long l;
82 	char *ret;
83 
84 	ret = astol(s, &l);
85 	*i = l;
86 	return (ret);
87 }
88 
89 EXPORT char *
astol(s,l)90 astol(s, l)
91 	register const char *s;
92 	long *l;
93 {
94 	return (astolb(s, l, 0));
95 }
96 
97 EXPORT char *
astolb(s,l,base)98 astolb(s, l, base)
99 	register const char *s;
100 	long *l;
101 	register int base;
102 {
103 	int neg = 0;
104 	register long ret = 0L;
105 	register int digit;
106 	register char c;
107 
108 	while (is_space(*s))
109 		s++;
110 
111 	if (*s == '+') {
112 		s++;
113 	} else if (*s == '-') {
114 		s++;
115 		neg++;
116 	}
117 
118 	if (base == 0) {
119 		if (*s == '0') {
120 			base = 8;
121 			s++;
122 			if (*s == 'x' || *s == 'X') {
123 				s++;
124 				base = 16;
125 			}
126 		} else {
127 			base = 10;
128 		}
129 	}
130 	for (; (c = *s) != 0; s++) {
131 
132 		if (is_digit(c)) {
133 			digit = c - '0';
134 		} else if (is_hex(c)) {
135 			digit = to_lower(c) - 'a' + 10;
136 		} else {
137 			break;
138 		}
139 
140 		if (digit < base) {
141 			ret *= base;
142 			ret += digit;
143 		} else {
144 			break;
145 		}
146 	}
147 	if (neg)
148 		ret = -ret;
149 	*l = ret;
150 	return ((char *)s);
151 }
152