xref: /freebsd/sys/contrib/openzfs/module/lua/lcompat.c (revision 02e9120893770924227138ba49df1edb3896112a)
1 /*
2  * Copyright (c) 2016 by Delphix. All rights reserved.
3  */
4 
5 #include <sys/lua/lua.h>
6 
7 
8 ssize_t
9 lcompat_sprintf(char *buf, size_t size, const char *fmt, ...)
10 {
11 	ssize_t res;
12 	va_list args;
13 
14 	va_start(args, fmt);
15 	res = vsnprintf(buf, size, fmt, args);
16 	va_end(args);
17 
18 	return (res);
19 }
20 
21 int64_t
22 lcompat_strtoll(const char *str, char **ptr)
23 {
24 	int base;
25 	const char *cp;
26 	int digits;
27 	int64_t value;
28 	boolean_t is_negative;
29 
30 	cp = str;
31 	while (*cp == ' ' || *cp == '\t' || *cp == '\n') {
32 		cp++;
33 	}
34 	is_negative = (*cp == '-');
35 	if (is_negative) {
36 		cp++;
37 	}
38 	base = 10;
39 
40 	if (*cp == '0') {
41 		base = 8;
42 		cp++;
43 		if (*cp == 'x' || *cp == 'X') {
44 			base = 16;
45 			cp++;
46 		}
47 	}
48 
49 	value = 0;
50 	for (; *cp != '\0'; cp++) {
51 		if (*cp >= '0' && *cp <= '9') {
52 			digits = *cp - '0';
53 		} else if (*cp >= 'a' && *cp <= 'f') {
54 			digits = *cp - 'a' + 10;
55 		} else if (*cp >= 'A' && *cp <= 'F') {
56 			digits = *cp - 'A' + 10;
57 		} else {
58 			break;
59 		}
60 		if (digits >= base) {
61 			break;
62 		}
63 		value = (value * base) + digits;
64 	}
65 
66 	if (ptr != NULL) {
67 		*ptr = (char *)cp;
68 	}
69 	if (is_negative) {
70 		value = -value;
71 	}
72 	return (value);
73 }
74 
75 int64_t
76 lcompat_pow(int64_t x, int64_t y)
77 {
78 	int64_t result = 1;
79 	if (y < 0)
80 		return (0);
81 
82 	while (y) {
83 		if (y & 1)
84 			result *= x;
85 		y >>= 1;
86 		x *= x;
87 	}
88 	return (result);
89 }
90 
91 int
92 lcompat_hashnum(int64_t x)
93 {
94 	x = (~x) + (x << 18);
95 	x = x ^ (x >> 31);
96 	x = x * 21;
97 	x = x ^ (x >> 11);
98 	x = x + (x << 6);
99 	x = x ^ (x >> 22);
100 	return ((int)x);
101 }
102