Rework LuCI build system
[project/luci.git] / libs / luci-lib-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 #ifdef NIXIO_DOUBLE
25 #define NIXIO_BIT_BMAX 52
26 #define NIXIO_BIT_NMAX 0xfffffffffffff
27 #else
28 #define NIXIO_BIT_BMAX 32
29 #define NIXIO_BIT_NMAX 0xffffffff
30 #endif
31
32 #define NIXIO_BIT_XOP(BIT_XOP)                                          \
33         uint64_t oper = nixio__checknumber(L, 1);               \
34         const int args = lua_gettop(L);                                 \
35                                                                                                         \
36         for (int i = 2; i <= args; i++) {                               \
37                 uint64_t oper2 = nixio__checknumber(L, i);      \
38                 oper BIT_XOP oper2;                                                     \
39         }                                                                                               \
40                                                                                                         \
41         nixio__pushnumber(L, oper);                                             \
42         return 1;                                                                               \
43
44
45 static int nixio_bit_or(lua_State *L) {
46         NIXIO_BIT_XOP(|=);
47 }
48
49 static int nixio_bit_and(lua_State *L) {
50         NIXIO_BIT_XOP(&=);
51 }
52
53 static int nixio_bit_xor(lua_State *L) {
54         NIXIO_BIT_XOP(^=);
55 }
56
57 static int nixio_bit_unset(lua_State *L) {
58         NIXIO_BIT_XOP(&= ~);
59 }
60
61 static int nixio_bit_not(lua_State *L) {
62         nixio__pushnumber(L,
63                         (~((uint64_t)nixio__checknumber(L, 1))) & NIXIO_BIT_NMAX);
64         return 1;
65 }
66
67 static int nixio_bit_shl(lua_State *L) {
68         uint64_t oper = nixio__checknumber(L, 1);
69         oper <<= luaL_checkinteger(L, 2);
70         if (oper > NIXIO_BIT_NMAX) {
71                 return luaL_error(L, "arithmetic overflow");
72         } else {
73                 nixio__pushnumber(L, oper);
74                 return 1;
75         }
76 }
77
78 static int nixio_bit_ashr(lua_State *L) {
79         int64_t oper = nixio__checknumber(L, 1);
80         nixio__pushnumber(L, oper >> luaL_checkinteger(L, 2));
81         return 1;
82 }
83
84 static int nixio_bit_shr(lua_State *L) {
85         uint64_t oper = nixio__checknumber(L, 1);
86         nixio__pushnumber(L, oper >> luaL_checkinteger(L, 2));
87         return 1;
88 }
89
90 static int nixio_bit_div(lua_State *L) {
91         uint64_t oper = luaL_checknumber(L, 1);
92         const int args = lua_gettop(L);
93
94         for (int i = 2; i <= args; i++) {
95                 uint64_t oper2 = nixio__checknumber(L, i);
96                 oper /= oper2;
97         }
98
99         nixio__pushnumber(L, oper);
100         return 1;
101 }
102
103 static int nixio_bit_check(lua_State *L) {
104         uint64_t oper  = nixio__checknumber(L, 1);
105         uint64_t oper2 = nixio__checknumber(L, 2);
106         lua_pushboolean(L, (oper & oper2) == oper2);
107         return 1;
108 }
109
110 static int nixio_bit_cast(lua_State *L) {
111         nixio__pushnumber(L, ((uint64_t)nixio__checknumber(L, 1)) & NIXIO_BIT_NMAX);
112         return 1;
113 }
114
115 static int nixio_bit_swap(lua_State *L) {
116         uint64_t op = nixio__checknumber(L, 1);
117         op = (op >> 24) | ((op >> 8) & 0xff00) | ((op & 0xff00) << 8) | (op << 24);
118         nixio__pushnumber(L, op);
119         return 1;
120 }
121
122 /* module table */
123 static const luaL_reg R[] = {
124         {"bor",                 nixio_bit_or},
125         {"set",                 nixio_bit_or},
126         {"band",                nixio_bit_and},
127         {"bxor",                nixio_bit_xor},
128         {"unset",               nixio_bit_unset},
129         {"bnot",                nixio_bit_not},
130         {"rshift",              nixio_bit_shr},
131         {"arshift",             nixio_bit_ashr},
132         {"lshift",              nixio_bit_shl},
133         {"div",                 nixio_bit_div},
134         {"check",               nixio_bit_check},
135         {"cast",                nixio_bit_cast},
136         {"tobit",               nixio_bit_cast},
137         {"bswap",               nixio_bit_swap},
138         {NULL,                  NULL}
139 };
140
141 void nixio_open_bit(lua_State *L) {
142         lua_newtable(L);
143         luaL_register(L, NULL, R);
144         nixio__pushnumber(L, NIXIO_BIT_BMAX);
145         lua_setfield(L, -2, "bits");
146         nixio__pushnumber(L, NIXIO_BIT_NMAX);
147         lua_setfield(L, -2, "max");
148         lua_setfield(L, -2, "bit");
149 }