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