LCOV - code coverage report
Current view: top level - src - lbitlib.c Coverage Total Hit
Test: Lua 5.2.4 Lines: 100.0 % 95 95
Test Date: 2024-04-28 10:23:12
Legend: Lines: hit not hit

            Line data    Source code
       1              : /*
       2              : ** $Id: lbitlib.c,v 1.18.1.2 2013/07/09 18:01:41 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 "lua.h"
      11              : 
      12              : #include "lauxlib.h"
      13              : #include "lualib.h"
      14              : 
      15              : 
      16              : /* number of bits to consider in a number */
      17              : #if !defined(LUA_NBITS)
      18              : #define LUA_NBITS       32
      19              : #endif
      20              : 
      21              : 
      22              : #define ALLONES         (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1))
      23              : 
      24              : /* macro to trim extra bits */
      25              : #define trim(x)         ((x) & ALLONES)
      26              : 
      27              : 
      28              : /* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */
      29              : #define mask(n)         (~((ALLONES << 1) << ((n) - 1)))
      30              : 
      31              : 
      32              : typedef lua_Unsigned b_uint;
      33              : 
      34              : 
      35              : 
      36            3 : static b_uint andaux (lua_State *L) {
      37            3 :   int i, n = lua_gettop(L);
      38            3 :   b_uint r = ~(b_uint)0;
      39            8 :   for (i = 1; i <= n; i++)
      40            5 :     r &= luaL_checkunsigned(L, i);
      41            3 :   return trim(r);
      42              : }
      43              : 
      44              : 
      45            1 : static int b_and (lua_State *L) {
      46            1 :   b_uint r = andaux(L);
      47            1 :   lua_pushunsigned(L, r);
      48            1 :   return 1;
      49              : }
      50              : 
      51              : 
      52            2 : static int b_test (lua_State *L) {
      53            2 :   b_uint r = andaux(L);
      54            2 :   lua_pushboolean(L, r != 0);
      55            2 :   return 1;
      56              : }
      57              : 
      58              : 
      59            1 : static int b_or (lua_State *L) {
      60            1 :   int i, n = lua_gettop(L);
      61            1 :   b_uint r = 0;
      62            4 :   for (i = 1; i <= n; i++)
      63            3 :     r |= luaL_checkunsigned(L, i);
      64            1 :   lua_pushunsigned(L, trim(r));
      65            1 :   return 1;
      66              : }
      67              : 
      68              : 
      69            1 : static int b_xor (lua_State *L) {
      70            1 :   int i, n = lua_gettop(L);
      71            1 :   b_uint r = 0;
      72            4 :   for (i = 1; i <= n; i++)
      73            3 :     r ^= luaL_checkunsigned(L, i);
      74            1 :   lua_pushunsigned(L, trim(r));
      75            1 :   return 1;
      76              : }
      77              : 
      78              : 
      79            1 : static int b_not (lua_State *L) {
      80            1 :   b_uint r = ~luaL_checkunsigned(L, 1);
      81            1 :   lua_pushunsigned(L, trim(r));
      82            1 :   return 1;
      83              : }
      84              : 
      85              : 
      86            3 : static int b_shift (lua_State *L, b_uint r, int i) {
      87            3 :   if (i < 0) {  /* shift right? */
      88            2 :     i = -i;
      89            2 :     r = trim(r);
      90            2 :     if (i >= LUA_NBITS) r = 0;
      91            2 :     else r >>= i;
      92              :   }
      93              :   else {  /* shift left */
      94            1 :     if (i >= LUA_NBITS) r = 0;
      95            1 :     else r <<= i;
      96            1 :     r = trim(r);
      97              :   }
      98            3 :   lua_pushunsigned(L, r);
      99            3 :   return 1;
     100              : }
     101              : 
     102              : 
     103            1 : static int b_lshift (lua_State *L) {
     104            1 :   return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkint(L, 2));
     105              : }
     106              : 
     107              : 
     108            1 : static int b_rshift (lua_State *L) {
     109            1 :   return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkint(L, 2));
     110              : }
     111              : 
     112              : 
     113            3 : static int b_arshift (lua_State *L) {
     114            3 :   b_uint r = luaL_checkunsigned(L, 1);
     115            3 :   int i = luaL_checkint(L, 2);
     116            3 :   if (i < 0 || !(r & ((b_uint)1 << (LUA_NBITS - 1))))
     117            1 :     return b_shift(L, r, -i);
     118              :   else {  /* arithmetic shift for 'negative' number */
     119            2 :     if (i >= LUA_NBITS) r = ALLONES;
     120              :     else
     121            2 :       r = trim((r >> i) | ~(~(b_uint)0 >> i));  /* add signal bit */
     122            2 :     lua_pushunsigned(L, r);
     123            2 :     return 1;
     124              :   }
     125              : }
     126              : 
     127              : 
     128            2 : static int b_rot (lua_State *L, int i) {
     129            2 :   b_uint r = luaL_checkunsigned(L, 1);
     130            2 :   i &= (LUA_NBITS - 1);  /* i = i % NBITS */
     131            2 :   r = trim(r);
     132            2 :   if (i != 0)  /* avoid undefined shift of LUA_NBITS when i == 0 */
     133            2 :     r = (r << i) | (r >> (LUA_NBITS - i));
     134            2 :   lua_pushunsigned(L, trim(r));
     135            2 :   return 1;
     136              : }
     137              : 
     138              : 
     139            1 : static int b_lrot (lua_State *L) {
     140            1 :   return b_rot(L, luaL_checkint(L, 2));
     141              : }
     142              : 
     143              : 
     144            1 : static int b_rrot (lua_State *L) {
     145            1 :   return b_rot(L, -luaL_checkint(L, 2));
     146              : }
     147              : 
     148              : 
     149              : /*
     150              : ** get field and width arguments for field-manipulation functions,
     151              : ** checking whether they are valid.
     152              : ** ('luaL_error' called without 'return' to avoid later warnings about
     153              : ** 'width' being used uninitialized.)
     154              : */
     155            8 : static int fieldargs (lua_State *L, int farg, int *width) {
     156            8 :   int f = luaL_checkint(L, farg);
     157            8 :   int w = luaL_optint(L, farg + 1, 1);
     158            8 :   luaL_argcheck(L, 0 <= f, farg, "field cannot be negative");
     159            6 :   luaL_argcheck(L, 0 < w, farg + 1, "width must be positive");
     160            4 :   if (f + w > LUA_NBITS)
     161            2 :     luaL_error(L, "trying to access non-existent bits");
     162            2 :   *width = w;
     163            2 :   return f;
     164              : }
     165              : 
     166              : 
     167            4 : static int b_extract (lua_State *L) {
     168              :   int w;
     169            4 :   b_uint r = luaL_checkunsigned(L, 1);
     170            4 :   int f = fieldargs(L, 2, &w);
     171            1 :   r = (r >> f) & mask(w);
     172            1 :   lua_pushunsigned(L, r);
     173            1 :   return 1;
     174              : }
     175              : 
     176              : 
     177            4 : static int b_replace (lua_State *L) {
     178              :   int w;
     179            4 :   b_uint r = luaL_checkunsigned(L, 1);
     180            4 :   b_uint v = luaL_checkunsigned(L, 2);
     181            4 :   int f = fieldargs(L, 3, &w);
     182            1 :   int m = mask(w);
     183            1 :   v &= m;  /* erase bits outside given width */
     184            1 :   r = (r & ~(m << f)) | (v << f);
     185            1 :   lua_pushunsigned(L, r);
     186            1 :   return 1;
     187              : }
     188              : 
     189              : 
     190              : static const luaL_Reg bitlib[] = {
     191              :   {"arshift", b_arshift},
     192              :   {"band", b_and},
     193              :   {"bnot", b_not},
     194              :   {"bor", b_or},
     195              :   {"bxor", b_xor},
     196              :   {"btest", b_test},
     197              :   {"extract", b_extract},
     198              :   {"lrotate", b_lrot},
     199              :   {"lshift", b_lshift},
     200              :   {"replace", b_replace},
     201              :   {"rrotate", b_rrot},
     202              :   {"rshift", b_rshift},
     203              :   {NULL, NULL}
     204              : };
     205              : 
     206              : 
     207              : 
     208           86 : LUAMOD_API int luaopen_bit32 (lua_State *L) {
     209           86 :   luaL_newlib(L, bitlib);
     210           86 :   return 1;
     211              : }
     212              : 
        

Generated by: LCOV version 2.0-1