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