xref: /csrg-svn/lib/libc/stdlib/strtol.c (revision 35278)
1*35278Sbostic /*
2*35278Sbostic  * Copyright (c) 1988 Regents of the University of California.
3*35278Sbostic  * All rights reserved.
4*35278Sbostic  *
5*35278Sbostic  * Redistribution and use in source and binary forms are permitted
6*35278Sbostic  * provided that the above copyright notice and this paragraph are
7*35278Sbostic  * duplicated in all such forms and that any documentation,
8*35278Sbostic  * advertising materials, and other materials related to such
9*35278Sbostic  * distribution and use acknowledge that the software was developed
10*35278Sbostic  * by the University of California, Berkeley.  The name of the
11*35278Sbostic  * University may not be used to endorse or promote products derived
12*35278Sbostic  * from this software without specific prior written permission.
13*35278Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14*35278Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15*35278Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16*35278Sbostic  */
17*35278Sbostic 
18*35278Sbostic #if defined(LIBC_SCCS) && !defined(lint)
19*35278Sbostic static char sccsid[] = "@(#)strtol.c	5.1 (Berkeley) 07/23/88";
20*35278Sbostic #endif /* LIBC_SCCS and not lint */
21*35278Sbostic 
22*35278Sbostic #include <ctype.h>
23*35278Sbostic 
24*35278Sbostic long
25*35278Sbostic strtol(ascii, endp, base)
26*35278Sbostic 	register char *ascii;
27*35278Sbostic 	char **endp;
28*35278Sbostic 	register int base;
29*35278Sbostic {
30*35278Sbostic 	register long val;
31*35278Sbostic 	register int c;
32*35278Sbostic 	int negative;
33*35278Sbostic 
34*35278Sbostic 	for (; isascii(*ascii) && isspace(*ascii); ++ascii);
35*35278Sbostic 
36*35278Sbostic 	negative = 0;
37*35278Sbostic 	if (*ascii == '+')
38*35278Sbostic 		++ascii;
39*35278Sbostic 	else if (*ascii == '-') {
40*35278Sbostic 		negative = 1;
41*35278Sbostic 		++ascii;
42*35278Sbostic 	}
43*35278Sbostic 
44*35278Sbostic 	/*
45*35278Sbostic 	 * ``If base is positive, but not greater than 36, it is used as
46*35278Sbostic 	 * the base for the conversion.''
47*35278Sbostic 	 *	-- The UNIX System User's Manual, 1986
48*35278Sbostic 	 */
49*35278Sbostic 	if ((unsigned int)base > 36)
50*35278Sbostic 		base = 10;
51*35278Sbostic 	else if (base == 0)
52*35278Sbostic 		if (*ascii == '0') {
53*35278Sbostic 			++ascii;
54*35278Sbostic 			if (*ascii == 'X' || *ascii == 'x') {
55*35278Sbostic 				++ascii;
56*35278Sbostic 				base = 16;
57*35278Sbostic 			}
58*35278Sbostic 			else
59*35278Sbostic 				base = 8;
60*35278Sbostic 		}
61*35278Sbostic 		else
62*35278Sbostic 			base = 10;
63*35278Sbostic 	else if (base == 16 && *ascii == '0' &&
64*35278Sbostic 	    (*++ascii == 'X' || *ascii == 'x'))
65*35278Sbostic 			++ascii;
66*35278Sbostic 
67*35278Sbostic 	for (val = 0; isascii(c = *ascii) && isalnum(c); ++ascii) {
68*35278Sbostic 		if (isdigit(c))
69*35278Sbostic 			c -= '0';
70*35278Sbostic 		else {
71*35278Sbostic 			if (isupper(c))
72*35278Sbostic 				c = tolower(c);
73*35278Sbostic 			c = c - 'a' + 10;
74*35278Sbostic 		}
75*35278Sbostic 		if (c >= base)
76*35278Sbostic 			break;
77*35278Sbostic 		val = val * base + c;
78*35278Sbostic 	}
79*35278Sbostic 	if (endp)
80*35278Sbostic 		*endp = ascii;
81*35278Sbostic 	return(negative ? -val : val);
82*35278Sbostic }
83