xref: /freebsd-src/contrib/ntp/libntp/atoint.c (revision 416ba5c74546f32a993436a99516d35008e9f384)
1c0b746e5SOllivier Robert /*
2c0b746e5SOllivier Robert  * atoint - convert an ascii string to a signed long, with error checking
3c0b746e5SOllivier Robert  */
4*2b15cb3dSCy Schubert #include <config.h>
5c0b746e5SOllivier Robert #include <sys/types.h>
6c0b746e5SOllivier Robert #include <ctype.h>
7c0b746e5SOllivier Robert 
8c0b746e5SOllivier Robert #include "ntp_types.h"
9c0b746e5SOllivier Robert #include "ntp_stdlib.h"
10c0b746e5SOllivier Robert 
11c0b746e5SOllivier Robert int
atoint(const char * str,long * ival)12c0b746e5SOllivier Robert atoint(
13c0b746e5SOllivier Robert 	const char *str,
14c0b746e5SOllivier Robert 	long *ival
15c0b746e5SOllivier Robert 	)
16c0b746e5SOllivier Robert {
17c0b746e5SOllivier Robert 	register long u;
18c0b746e5SOllivier Robert 	register const char *cp;
19c0b746e5SOllivier Robert 	register int isneg;
20c0b746e5SOllivier Robert 	register int oflow_digit;
21c0b746e5SOllivier Robert 
22c0b746e5SOllivier Robert 	cp = str;
23c0b746e5SOllivier Robert 
24c0b746e5SOllivier Robert 	if (*cp == '-') {
25c0b746e5SOllivier Robert 		cp++;
26c0b746e5SOllivier Robert 		isneg = 1;
27c0b746e5SOllivier Robert 		oflow_digit = '8';
28c0b746e5SOllivier Robert 	} else {
29c0b746e5SOllivier Robert 		isneg = 0;
30c0b746e5SOllivier Robert 		oflow_digit = '7';
31c0b746e5SOllivier Robert 	}
32c0b746e5SOllivier Robert 
33c0b746e5SOllivier Robert 	if (*cp == '\0')
34c0b746e5SOllivier Robert 	    return 0;
35c0b746e5SOllivier Robert 
36c0b746e5SOllivier Robert 	u = 0;
37c0b746e5SOllivier Robert 	while (*cp != '\0') {
38*2b15cb3dSCy Schubert 		if (!isdigit((unsigned char)*cp))
39c0b746e5SOllivier Robert 		    return 0;
40c0b746e5SOllivier Robert 		if (u > 214748364 || (u == 214748364 && *cp > oflow_digit))
41c0b746e5SOllivier Robert 		    return 0;	/* overflow */
42c0b746e5SOllivier Robert 		u = (u << 3) + (u << 1);
43c0b746e5SOllivier Robert 		u += *cp++ - '0';	/* ascii dependent */
44c0b746e5SOllivier Robert 	}
45c0b746e5SOllivier Robert 
46c0b746e5SOllivier Robert 	if (isneg)
47c0b746e5SOllivier Robert 	    *ival = -u;
48c0b746e5SOllivier Robert 	else
49c0b746e5SOllivier Robert 	    *ival = u;
50c0b746e5SOllivier Robert 	return 1;
51c0b746e5SOllivier Robert }
52