xref: /netbsd-src/external/bsd/ntp/dist/libntp/hextolfp.c (revision 5bbd2a12505d72a8177929a37b5cee489d0a1cfd)
1 /*	$NetBSD: hextolfp.c,v 1.2 2009/12/14 00:38:48 christos Exp $	*/
2 
3 /*
4  * hextolfp - convert an ascii hex string to an l_fp number
5  */
6 #include <stdio.h>
7 #include <ctype.h>
8 
9 #include "ntp_fp.h"
10 #include "ntp_string.h"
11 #include "ntp_stdlib.h"
12 
13 int
14 hextolfp(
15 	const char *str,
16 	l_fp *lfp
17 	)
18 {
19 	register const char *cp;
20 	register const char *cpstart;
21 	register u_long dec_i;
22 	register u_long dec_f;
23 	char *ind = NULL;
24 	static const char *digits = "0123456789abcdefABCDEF";
25 
26 	dec_i = dec_f = 0;
27 	cp = str;
28 
29 	/*
30 	 * We understand numbers of the form:
31 	 *
32 	 * [spaces]8_hex_digits[.]8_hex_digits[spaces|\n|\0]
33 	 */
34 	while (isspace((unsigned char)*cp))
35 	    cp++;
36 
37 	cpstart = cp;
38 	while (*cp != '\0' && (cp - cpstart) < 8 &&
39 	       (ind = strchr(digits, *cp)) != NULL) {
40 		dec_i = dec_i << 4;	/* multiply by 16 */
41 		dec_i += ((ind - digits) > 15) ? (ind - digits) - 6
42 			: (ind - digits);
43 		cp++;
44 	}
45 
46 	if ((cp - cpstart) < 8 || ind == NULL)
47 	    return 0;
48 	if (*cp == '.')
49 	    cp++;
50 
51 	cpstart = cp;
52 	while (*cp != '\0' && (cp - cpstart) < 8 &&
53 	       (ind = strchr(digits, *cp)) != NULL) {
54 		dec_f = dec_f << 4;	/* multiply by 16 */
55 		dec_f += ((ind - digits) > 15) ? (ind - digits) - 6
56 			: (ind - digits);
57 		cp++;
58 	}
59 
60 	if ((cp - cpstart) < 8 || ind == NULL)
61 	    return 0;
62 
63 	if (*cp != '\0' && !isspace((unsigned char)*cp))
64 	    return 0;
65 
66 	lfp->l_ui = dec_i;
67 	lfp->l_uf = dec_f;
68 	return 1;
69 }
70