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