xref: /openbsd-src/lib/libc/stdlib/a64l.c (revision c2c925dec2134a12f472359f2a189e9a312dd721)
1*c2c925deSespie /*	$OpenBSD: a64l.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
2df930be7Sderaadt /*
3df930be7Sderaadt  * Written by J.T. Conklin <jtc@netbsd.org>.
4df930be7Sderaadt  * Public domain.
5df930be7Sderaadt  */
6df930be7Sderaadt 
7a8eb249eSmillert #include <errno.h>
8a8eb249eSmillert #include <stdlib.h>
9a8eb249eSmillert 
10df930be7Sderaadt long
a64l(const char * s)11d8bc04e4Spat a64l(const char *s)
12df930be7Sderaadt {
13df930be7Sderaadt 	long value, digit, shift;
14df930be7Sderaadt 	int i;
15df930be7Sderaadt 
16a8eb249eSmillert 	if (s == NULL) {
17a8eb249eSmillert 		errno = EINVAL;
18a8eb249eSmillert 		return(-1L);
19a8eb249eSmillert 	}
20a8eb249eSmillert 
21df930be7Sderaadt 	value = 0;
22df930be7Sderaadt 	shift = 0;
23df930be7Sderaadt 	for (i = 0; *s && i < 6; i++, s++) {
24a8eb249eSmillert 		if (*s >= '.' && *s <= '/')
25df930be7Sderaadt 			digit = *s - '.';
26a8eb249eSmillert 		else if (*s >= '0' && *s <= '9')
27df930be7Sderaadt 			digit = *s - '0' + 2;
28a8eb249eSmillert 		else if (*s >= 'A' && *s <= 'Z')
29df930be7Sderaadt 			digit = *s - 'A' + 12;
30a8eb249eSmillert 		else if (*s >= 'a' && *s <= 'z')
31df930be7Sderaadt 			digit = *s - 'a' + 38;
32a8eb249eSmillert 		else {
33a8eb249eSmillert 			errno = EINVAL;
34a8eb249eSmillert 			return(-1L);
35a8eb249eSmillert 		}
36df930be7Sderaadt 
37df930be7Sderaadt 		value |= digit << shift;
38df930be7Sderaadt 		shift += 6;
39df930be7Sderaadt 	}
40df930be7Sderaadt 
41a8eb249eSmillert 	return(value);
42df930be7Sderaadt }
43