Merge nixio 0.2
[project/luci.git] / libs / nixio / src / bit.c
1 /*
2  * nixio - Linux I/O library for lua
3  *
4  *   Copyright (C) 2009 Steven Barth <steven@midlink.org>
5  *
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License.
17  */
18
19 #include "nixio.h"
20 #include <stdint.h>
21 #include <stdlib.h>
22
23 /* 52 bit maximum precision */
24 #define NIXIO_BIT_BMAX 52
25 #define NIXIO_BIT_NMAX 0xfffffffffffff
26
27 #define NIXIO_BIT_XOP(BIT_XOP)                                          \
28         uint64_t oper = luaL_checknumber(L, 1);                 \
29         const int args = lua_gettop(L);                                 \
30                                                                                                         \
31         for (int i = 2; i <= args; i++) {                               \
32                 uint64_t oper2 = luaL_checknumber(L, i);        \
33                 oper BIT_XOP oper2;                                                     \
34         }                                                                                               \
35                                                                                                         \
36         lua_pushnumber(L, oper);                                                \
37         return 1;                                                                               \
38
39
40 static int nixio_bit_or(lua_State *L) {
41         NIXIO_BIT_XOP(|=);
42 }
43
44 static int nixio_bit_and(lua_State *L) {
45         NIXIO_BIT_XOP(&=);
46 }
47
48 static int nixio_bit_xor(lua_State *L) {
49         NIXIO_BIT_XOP(^=);
50 }
51
52 static int nixio_bit_unset(lua_State *L) {
53         NIXIO_BIT_XOP(&= ~);
54 }
55
56 static int nixio_bit_not(lua_State *L) {
57         lua_pushnumber(L, (~((uint64_t)luaL_checknumber(L, 1))) & NIXIO_BIT_NMAX);
58         return 1;
59 }
60
61 static int nixio_bit_shl(lua_State *L) {
62         uint64_t oper = luaL_checknumber(L, 1);
63         oper <<= luaL_checkinteger(L, 2);
64         if (oper > NIXIO_BIT_NMAX) {
65                 return luaL_error(L, "arithmetic overflow");
66         } else {
67                 lua_pushnumber(L, oper);
68                 return 1;
69         }
70 }
71
72 static int nixio_bit_ashr(lua_State *L) {
73         int64_t oper = luaL_checknumber(L, 1);
74         lua_pushnumber(L, oper >> luaL_checkinteger(L, 2));
75         return 1;
76 }
77
78 static int nixio_bit_shr(lua_State *L) {
79         uint64_t oper = luaL_checknumber(L, 1);
80         lua_pushnumber(L, oper >> luaL_checkinteger(L, 2));
81         return 1;
82 }
83
84 static int nixio_bit_div(lua_State *L) {
85         NIXIO_BIT_XOP(/=);
86 }
87
88 static int nixio_bit_check(lua_State *L) {
89         uint64_t oper  = luaL_checknumber(L, 1);
90         uint64_t oper2 = luaL_checknumber(L, 2);
91         lua_pushboolean(L, (oper & oper2) == oper2);
92         return 1;
93 }
94
95 static int nixio_bit_cast(lua_State *L) {
96         lua_pushnumber(L, ((uint64_t)luaL_checknumber(L, 1)) & NIXIO_BIT_NMAX);
97         return 1;
98 }
99
100 /* module table */
101 static const luaL_reg R[] = {
102         {"bor",                 nixio_bit_or},
103         {"set",                 nixio_bit_or},
104         {"band",                nixio_bit_and},
105         {"bxor",                nixio_bit_xor},
106         {"unset",               nixio_bit_unset},
107         {"bnot",                nixio_bit_not},
108         {"rshift",              nixio_bit_shr},
109         {"arshift",             nixio_bit_ashr},
110         {"lshift",              nixio_bit_shl},
111         {"div",                 nixio_bit_div},
112         {"check",               nixio_bit_check},
113         {"cast",                nixio_bit_cast},
114         {NULL,                  NULL}
115 };
116
117 void nixio_open_bit(lua_State *L) {
118         lua_newtable(L);
119         luaL_register(L, NULL, R);
120         lua_pushnumber(L, NIXIO_BIT_BMAX);
121         lua_setfield(L, -2, "bits");
122         lua_pushnumber(L, NIXIO_BIT_NMAX);
123         lua_setfield(L, -2, "max");
124         lua_setfield(L, -2, "bit");
125 }