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