The Battle for Wesnoth  1.15.2+dev
lbitlib.cpp
Go to the documentation of this file.
1 /*
2 ** $Id: lbitlib.c,v 1.30.1.1 2017/04/19 17:20:42 roberto Exp $
3 ** Standard library for bitwise operations
4 ** See Copyright Notice in lua.h
5 */
6 
7 #define lbitlib_c
8 #define LUA_LIB
9 
10 #include "lprefix.h"
11 
12 
13 #include "lua.h"
14 
15 #include "lauxlib.h"
16 #include "lualib.h"
17 
18 
19 #if defined(LUA_COMPAT_BITLIB) /* { */
20 
21 
22 #define pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n))
23 #define checkunsigned(L,i) ((lua_Unsigned)luaL_checkinteger(L,i))
24 
25 
26 /* number of bits to consider in a number */
27 #if !defined(LUA_NBITS)
28 #define LUA_NBITS 32
29 #endif
30 
31 
32 /*
33 ** a lua_Unsigned with its first LUA_NBITS bits equal to 1. (Shift must
34 ** be made in two parts to avoid problems when LUA_NBITS is equal to the
35 ** number of bits in a lua_Unsigned.)
36 */
37 #define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1))
38 
39 
40 /* macro to trim extra bits */
41 #define trim(x) ((x) & ALLONES)
42 
43 
44 /* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */
45 #define mask(n) (~((ALLONES << 1) << ((n) - 1)))
46 
47 
48 
49 static lua_Unsigned andaux (lua_State *L) {
50  int i, n = lua_gettop(L);
51  lua_Unsigned r = ~(lua_Unsigned)0;
52  for (i = 1; i <= n; i++)
53  r &= checkunsigned(L, i);
54  return trim(r);
55 }
56 
57 
58 static int b_and (lua_State *L) {
59  lua_Unsigned r = andaux(L);
60  pushunsigned(L, r);
61  return 1;
62 }
63 
64 
65 static int b_test (lua_State *L) {
66  lua_Unsigned r = andaux(L);
67  lua_pushboolean(L, r != 0);
68  return 1;
69 }
70 
71 
72 static int b_or (lua_State *L) {
73  int i, n = lua_gettop(L);
74  lua_Unsigned r = 0;
75  for (i = 1; i <= n; i++)
76  r |= checkunsigned(L, i);
77  pushunsigned(L, trim(r));
78  return 1;
79 }
80 
81 
82 static int b_xor (lua_State *L) {
83  int i, n = lua_gettop(L);
84  lua_Unsigned r = 0;
85  for (i = 1; i <= n; i++)
86  r ^= checkunsigned(L, i);
87  pushunsigned(L, trim(r));
88  return 1;
89 }
90 
91 
92 static int b_not (lua_State *L) {
93  lua_Unsigned r = ~checkunsigned(L, 1);
94  pushunsigned(L, trim(r));
95  return 1;
96 }
97 
98 
99 static int b_shift (lua_State *L, lua_Unsigned r, lua_Integer i) {
100  if (i < 0) { /* shift right? */
101  i = -i;
102  r = trim(r);
103  if (i >= LUA_NBITS) r = 0;
104  else r >>= i;
105  }
106  else { /* shift left */
107  if (i >= LUA_NBITS) r = 0;
108  else r <<= i;
109  r = trim(r);
110  }
111  pushunsigned(L, r);
112  return 1;
113 }
114 
115 
116 static int b_lshift (lua_State *L) {
117  return b_shift(L, checkunsigned(L, 1), luaL_checkinteger(L, 2));
118 }
119 
120 
121 static int b_rshift (lua_State *L) {
122  return b_shift(L, checkunsigned(L, 1), -luaL_checkinteger(L, 2));
123 }
124 
125 
126 static int b_arshift (lua_State *L) {
127  lua_Unsigned r = checkunsigned(L, 1);
129  if (i < 0 || !(r & ((lua_Unsigned)1 << (LUA_NBITS - 1))))
130  return b_shift(L, r, -i);
131  else { /* arithmetic shift for 'negative' number */
132  if (i >= LUA_NBITS) r = ALLONES;
133  else
134  r = trim((r >> i) | ~(trim(~(lua_Unsigned)0) >> i)); /* add signal bit */
135  pushunsigned(L, r);
136  return 1;
137  }
138 }
139 
140 
141 static int b_rot (lua_State *L, lua_Integer d) {
142  lua_Unsigned r = checkunsigned(L, 1);
143  int i = d & (LUA_NBITS - 1); /* i = d % NBITS */
144  r = trim(r);
145  if (i != 0) /* avoid undefined shift of LUA_NBITS when i == 0 */
146  r = (r << i) | (r >> (LUA_NBITS - i));
147  pushunsigned(L, trim(r));
148  return 1;
149 }
150 
151 
152 static int b_lrot (lua_State *L) {
153  return b_rot(L, luaL_checkinteger(L, 2));
154 }
155 
156 
157 static int b_rrot (lua_State *L) {
158  return b_rot(L, -luaL_checkinteger(L, 2));
159 }
160 
161 
162 /*
163 ** get field and width arguments for field-manipulation functions,
164 ** checking whether they are valid.
165 ** ('luaL_error' called without 'return' to avoid later warnings about
166 ** 'width' being used uninitialized.)
167 */
168 static int fieldargs (lua_State *L, int farg, int *width) {
169  lua_Integer f = luaL_checkinteger(L, farg);
170  lua_Integer w = luaL_optinteger(L, farg + 1, 1);
171  luaL_argcheck(L, 0 <= f, farg, "field cannot be negative");
172  luaL_argcheck(L, 0 < w, farg + 1, "width must be positive");
173  if (f + w > LUA_NBITS)
174  luaL_error(L, "trying to access non-existent bits");
175  *width = (int)w;
176  return (int)f;
177 }
178 
179 
180 static int b_extract (lua_State *L) {
181  int w;
182  lua_Unsigned r = trim(checkunsigned(L, 1));
183  int f = fieldargs(L, 2, &w);
184  r = (r >> f) & mask(w);
185  pushunsigned(L, r);
186  return 1;
187 }
188 
189 
190 static int b_replace (lua_State *L) {
191  int w;
192  lua_Unsigned r = trim(checkunsigned(L, 1));
193  lua_Unsigned v = trim(checkunsigned(L, 2));
194  int f = fieldargs(L, 3, &w);
195  lua_Unsigned m = mask(w);
196  r = (r & ~(m << f)) | ((v & m) << f);
197  pushunsigned(L, r);
198  return 1;
199 }
200 
201 
202 static const luaL_Reg bitlib[] = {
203  {"arshift", b_arshift},
204  {"band", b_and},
205  {"bnot", b_not},
206  {"bor", b_or},
207  {"bxor", b_xor},
208  {"btest", b_test},
209  {"extract", b_extract},
210  {"lrotate", b_lrot},
211  {"lshift", b_lshift},
212  {"replace", b_replace},
213  {"rrotate", b_rrot},
214  {"rshift", b_rshift},
215  {NULL, NULL}
216 };
217 
218 
219 
221  luaL_newlib(L, bitlib);
222  return 1;
223 }
224 
225 
226 #else /* }{ */
227 
228 
230  return luaL_error(L, "library 'bit32' has been deprecated");
231 }
232 
233 #endif /* } */
LUA_API void lua_pushboolean(lua_State *L, int b)
Definition: lapi.cpp:557
LUA_API int lua_gettop(lua_State *L)
Definition: lapi.cpp:167
LUALIB_API lua_Integer luaL_optinteger(lua_State *L, int arg, lua_Integer def)
Definition: lauxlib.cpp:440
#define d
LUA_INTEGER lua_Integer
Definition: lua.h:93
std::size_t i
Definition: function.cpp:933
LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int arg)
Definition: lauxlib.cpp:430
#define LUAMOD_API
Definition: luaconf.h:261
int w
#define luaL_newlib(L, l)
Definition: lauxlib.h:119
LUA_UNSIGNED lua_Unsigned
Definition: lua.h:96
LUALIB_API int luaL_error(lua_State *L, const char *fmt,...)
Definition: lauxlib.cpp:223
#define luaL_argcheck(L, cond, arg, extramsg)
Definition: lauxlib.h:122
#define f
LUAMOD_API int luaopen_bit32(lua_State *L)
Definition: lbitlib.cpp:229
static map_location::DIRECTION n