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