Merge pull request #2654 from Antiklesys/master
[RRG-proxmark3.git] / client / src / lua_bitlib.c
blobbd92d2d593a64b058e48817927a1866f9661abc9
1 /*
2 ** $Id: lbitlib.c,v 1.18 2013/03/19 13:19:12 roberto Exp $
3 ** Standard library for bitwise operations
4 ** See Copyright Notice in lua.h
5 **
6 ** Patched to provide a compatibility layer with Lua5.3+ where
7 ** bit32 library was removed.
8 */
10 #include "lua_bitlib.h"
12 #include "lauxlib.h"
14 /* number of bits to consider in a number */
15 #define LUA_BITLIB_NBITS 32
18 #define ALLONES (~(((~(lua_Unsigned)0) << (LUA_BITLIB_NBITS - 1)) << 1))
20 /* macro to trim extra bits */
21 #define trim(x) ((x) & ALLONES)
24 /* builds a number with 'n' ones (1 <= n <= LUA_BITLIB_NBITS) */
25 #define mask(n) (~((ALLONES << 1) << ((n) - 1)))
28 typedef lua_Unsigned b_uint;
31 static b_uint andaux(lua_State *L) {
32 int i, n = lua_gettop(L);
33 b_uint r = ~(b_uint)0;
34 for (i = 1; i <= n; i++)
35 r &= (b_uint)luaL_checkinteger(L, i);
36 return trim(r);
40 static int b_and(lua_State *L) {
41 b_uint r = andaux(L);
42 lua_pushinteger(L, r);
43 return 1;
47 static int b_test(lua_State *L) {
48 b_uint r = andaux(L);
49 lua_pushboolean(L, r != 0);
50 return 1;
54 static int b_or(lua_State *L) {
55 int i, n = lua_gettop(L);
56 b_uint r = 0;
57 for (i = 1; i <= n; i++)
58 r |= (b_uint) luaL_checkinteger(L, i);
59 lua_pushinteger(L, trim(r));
60 return 1;
64 static int b_xor(lua_State *L) {
65 int i, n = lua_gettop(L);
66 b_uint r = 0;
67 for (i = 1; i <= n; i++)
68 r ^= (b_uint) luaL_checkinteger(L, i);
69 lua_pushinteger(L, trim(r));
70 return 1;
74 static int b_not(lua_State *L) {
75 b_uint r = ~((b_uint)luaL_checkinteger(L, 1));
76 lua_pushinteger(L, trim(r));
77 return 1;
81 static int b_shift(lua_State *L, b_uint r, int i) {
82 if (i < 0) { /* shift right? */
83 i = -i;
84 r = trim(r);
85 if (i >= LUA_BITLIB_NBITS) r = 0;
86 else r >>= i;
87 } else { /* shift left */
88 if (i >= LUA_BITLIB_NBITS) r = 0;
89 else r <<= i;
90 r = trim(r);
92 lua_pushinteger(L, r);
93 return 1;
97 static int b_lshift(lua_State *L) {
98 return b_shift(L, (b_uint)luaL_checkinteger(L, 1), luaL_checkinteger(L, 2));
102 static int b_rshift(lua_State *L) {
103 return b_shift(L, (b_uint)luaL_checkinteger(L, 1), -luaL_checkinteger(L, 2));
107 static int b_arshift(lua_State *L) {
108 b_uint r = (b_uint)luaL_checkinteger(L, 1);
109 int i = luaL_checkinteger(L, 2);
110 if (i < 0 || !(r & ((b_uint)1 << (LUA_BITLIB_NBITS - 1))))
111 return b_shift(L, r, -i);
112 else { /* arithmetic shift for 'negative' number */
113 if (i >= LUA_BITLIB_NBITS) r = ALLONES;
114 else
115 r = trim((r >> i) | ~(~(b_uint)0 >> i)); /* add signal bit */
116 lua_pushinteger(L, r);
117 return 1;
122 static int b_rot(lua_State *L, int i) {
123 b_uint r = (b_uint)luaL_checkinteger(L, 1);
124 i &= (LUA_BITLIB_NBITS - 1); /* i = i % NBITS */
125 r = trim(r);
126 if (i != 0) /* avoid undefined shift of LUA_BITLIB_NBITS when i == 0 */
127 r = (r << i) | (r >> (LUA_BITLIB_NBITS - i));
129 lua_pushinteger(L, trim(r));
130 return 1;
134 static int b_lrot(lua_State *L) {
135 return b_rot(L, luaL_checkinteger(L, 2));
139 static int b_rrot(lua_State *L) {
140 return b_rot(L, -luaL_checkinteger(L, 2));
145 ** get field and width arguments for field-manipulation functions,
146 ** checking whether they are valid.
147 ** ('luaL_error' called without 'return' to avoid later warnings about
148 ** 'width' being used uninitialized.)
150 static int fieldargs(lua_State *L, int farg, int *width) {
151 int f = luaL_checkinteger(L, farg);
152 int w = luaL_optinteger(L, farg + 1, 1);
153 luaL_argcheck(L, 0 <= f, farg, "field cannot be negative");
154 luaL_argcheck(L, 0 < w, farg + 1, "width must be positive");
155 if (f + w > LUA_BITLIB_NBITS)
156 luaL_error(L, "trying to access non-existent bits");
157 *width = w;
158 return f;
162 static int b_extract(lua_State *L) {
163 int w;
164 b_uint r = (b_uint)luaL_checkinteger(L, 1);
165 int f = fieldargs(L, 2, &w);
166 r = (r >> f) & mask(w);
167 lua_pushinteger(L, r);
168 return 1;
172 static int b_replace(lua_State *L) {
173 int w;
174 b_uint r = (b_uint)luaL_checkinteger(L, 1);
175 b_uint v = (b_uint)luaL_checkinteger(L, 2);
176 int f = fieldargs(L, 3, &w);
177 int m = mask(w);
178 v &= m; /* erase bits outside given width */
179 r = (r & ~(m << f)) | (v << f);
180 lua_pushinteger(L, r);
181 return 1;
185 void register_bit32_lib(lua_State *L) {
186 static const luaL_Reg bitlib[] = {
187 {"arshift", b_arshift},
188 {"band", b_and},
189 {"bnot", b_not},
190 {"bor", b_or},
191 {"bxor", b_xor},
192 {"btest", b_test},
193 {"extract", b_extract},
194 {"lrotate", b_lrot},
195 {"lshift", b_lshift},
196 {"replace", b_replace},
197 {"rrotate", b_rrot},
198 {"rshift", b_rshift},
199 {NULL, NULL}
202 luaL_newlib(L, bitlib);
203 lua_setfield(L, -2, "bit32");