rename a_version.alpha to a_version.alpha_
[liba.git] / lua / src / version.c
blob8fa6ed15b7cee8ec0fe2dd26df13fbca50588c17
1 /***
2 algorithm library version
3 @module liba.version
4 */
6 #include "version.h"
7 #include "a/version.h"
9 static int liba_version_tostring(lua_State *L)
11 a_version const *const ctx = (a_version const *)lua_touserdata(L, 1);
12 if (ctx)
14 char str[48];
15 a_version_tostr(ctx, str, sizeof(str));
16 lua_pushstring(L, str);
17 return 1;
19 return 0;
22 static int liba_version_init_(lua_State *L, a_version *ctx, int arg, int top)
24 ctx->alpha_[0] = '.';
25 ctx->alpha_[1] = 0;
26 ctx->alpha_[2] = 0;
27 ctx->alpha_[3] = 0;
28 switch (top)
30 default:
31 case 4:
32 ctx->extra = (unsigned int)luaL_checkinteger(L, arg + 4);
33 A_FALLTHROUGH;
34 case 3:
35 ctx->third = (unsigned int)luaL_checkinteger(L, arg + 3);
36 A_FALLTHROUGH;
37 case 2:
38 ctx->minor = (unsigned int)luaL_checkinteger(L, arg + 2);
39 A_FALLTHROUGH;
40 case 1:
41 if (lua_type(L, arg + 1) == LUA_TSTRING)
43 a_version_parse(ctx, lua_tostring(L, arg + 1));
44 break;
46 ctx->major = (unsigned int)luaL_checkinteger(L, arg + 1);
47 A_FALLTHROUGH;
48 case 0:;
50 return 1;
53 /***
54 constructor for algorithm library version
55 @tparam[opt] integer major version major number
56 @tparam[opt] integer minor version minor number
57 @tparam[opt] integer third version third number
58 @tparam[opt] integer extra version extra number
59 @treturn a.version algorithm library version userdata
60 @function new
62 int liba_version_new(lua_State *L)
64 int const top = lua_gettop(L);
65 a_version *const ctx = lua_newclass(L, a_version);
66 a_zero(ctx, sizeof(a_version));
67 lua_registry_get(L, liba_version_new);
68 lua_setmetatable(L, -2);
69 return liba_version_init_(L, ctx, 0, top);
72 /***
73 initialize for algorithm library version
74 @tparam a.version ctx algorithm library version userdata
75 @tparam[opt] integer major version major number
76 @tparam[opt] integer minor version minor number
77 @tparam[opt] integer third version third number
78 @tparam[opt] integer extra version extra number
79 @treturn a.version algorithm library version userdata
80 @function init
82 int liba_version_init(lua_State *L)
84 int const top = lua_gettop(L);
85 luaL_checktype(L, 1, LUA_TUSERDATA);
86 a_version *const ctx = (a_version *)lua_touserdata(L, 1);
87 lua_pushvalue(L, 1);
88 return liba_version_init_(L, ctx, 1, top - 1);
91 /***
92 parse version string to version
93 @tparam a.version ctx algorithm library version userdata
94 @tparam string version string to be parsed
95 @treturn a.version algorithm library version userdata
96 @function parse
98 int liba_version_parse(lua_State *L)
100 a_version *const ctx = (a_version *)lua_touserdata(L, 1);
101 if (ctx)
103 a_version_parse(ctx, lua_tostring(L, 2));
104 lua_pushvalue(L, 1);
105 return 1;
107 return 0;
110 /***
111 algorithm library version check
112 @tparam integer major required major number
113 @tparam integer minor required minor number
114 @tparam integer patch required patch number
115 @treturn integer <0 library version is higher than required version
116 @treturn integer >0 library version is lower than required version
117 @treturn integer 0 library version is equal to required version
118 @function check
120 static int liba_version_check(lua_State *L)
122 a_version v = A_VERSION_0();
123 switch (lua_gettop(L) & 0x3)
125 case 3:
126 v.third = (unsigned int)luaL_checkinteger(L, 3);
127 A_FALLTHROUGH;
128 case 2:
129 v.minor = (unsigned int)luaL_checkinteger(L, 2);
130 A_FALLTHROUGH;
131 case 1:
132 v.major = (unsigned int)luaL_checkinteger(L, 1);
133 A_FALLTHROUGH;
134 default:
135 break;
137 lua_pushinteger(L, a_version_check(v.major, v.minor, v.third));
138 return 1;
141 /***
142 compare the version lhs with the version rhs
143 @tparam a.version lhs version userdata on the left
144 @tparam a.version rhs version userdata on the right
145 @treturn integer <0 version lhs < version rhs
146 @treturn integer >0 version lhs > version rhs
147 @treturn integer 0 version lhs == version rhs
148 @function cmp
150 int liba_version_cmp(lua_State *L)
152 luaL_checktype(L, 1, LUA_TUSERDATA);
153 luaL_checktype(L, 2, LUA_TUSERDATA);
154 a_version const *const lhs = (a_version const *)lua_touserdata(L, 1);
155 a_version const *const rhs = (a_version const *)lua_touserdata(L, 2);
156 lua_pushinteger(L, a_version_cmp(lhs, rhs));
157 return 1;
160 #undef F2
161 #define F2(func) \
162 int liba_version_##func(lua_State *L) \
164 luaL_checktype(L, 1, LUA_TUSERDATA); \
165 luaL_checktype(L, 2, LUA_TUSERDATA); \
166 a_version *lhs = (a_version *)lua_touserdata(L, 1); \
167 a_version *rhs = (a_version *)lua_touserdata(L, 2); \
168 lua_pushboolean(L, a_version_##func(lhs, rhs)); \
169 return 1; \
171 /***
172 version lhs is less than version rhs
173 @tparam a.version lhs version userdata on the left
174 @tparam a.version rhs version userdata on the right
175 @treturn bool result of comparison
176 @function lt
178 F2(lt)
179 /***
180 version lhs is greater than version rhs
181 @tparam a.version lhs version userdata on the left
182 @tparam a.version rhs version userdata on the right
183 @treturn bool result of comparison
184 @function gt
186 F2(gt)
187 /***
188 version lhs is less than or equal to version rhs
189 @tparam a.version lhs version userdata on the left
190 @tparam a.version rhs version userdata on the right
191 @treturn bool result of comparison
192 @function le
194 F2(le)
195 /***
196 version lhs is greater than or equal to version rhs
197 @tparam a.version lhs version userdata on the left
198 @tparam a.version rhs version userdata on the right
199 @treturn bool result of comparison
200 @function ge
202 F2(ge)
203 /***
204 version lhs is equal to version rhs
205 @tparam a.version lhs version userdata on the left
206 @tparam a.version rhs version userdata on the right
207 @treturn bool result of comparison
208 @function eq
210 F2(eq)
211 /***
212 version lhs is not equal to version rhs
213 @tparam a.version lhs version userdata on the left
214 @tparam a.version rhs version userdata on the right
215 @treturn bool result of comparison
216 @function ne
218 F2(ne)
220 static int liba_version_set(lua_State *L)
222 a_version *const ctx = (a_version *)lua_touserdata(L, 1);
223 switch (a_hash_bkdr(lua_tostring(L, 2), 0))
225 case 0x86720331: // major
226 ctx->major = (unsigned int)luaL_checkinteger(L, 3);
227 break;
228 case 0x87857C2D: // minor
229 ctx->minor = (unsigned int)luaL_checkinteger(L, 3);
230 break;
231 case 0x0241DD17: // third
232 ctx->third = (unsigned int)luaL_checkinteger(L, 3);
233 break;
234 case 0xFD1BE968: // extra
235 ctx->extra = (unsigned int)luaL_checkinteger(L, 3);
236 break;
237 case 0xB5485B9E: // alpha
239 char const *alpha = luaL_checklstring(L, 3, 0);
240 a_version_set_alpha(ctx, alpha);
241 break;
243 case 0x0CD3E494: // __lt
244 case 0x0CD3E485: // __le
245 case 0x0CD3E0FC: // __eq
246 case 0xE8859EEB: // __name
247 case 0xE70C48C6: // __call
248 case 0xA65758B2: // __index
249 case 0xAEB551C6: // __newindex
250 case 0x5DA21A54: // __tostring
251 break;
252 default:
253 lua_getmetatable(L, 1);
254 lua_replace(L, 1);
255 lua_rawset(L, 1);
257 return 0;
260 static int liba_version_get(lua_State *L)
262 a_version const *const ctx = (a_version const *)lua_touserdata(L, 1);
263 switch (a_hash_bkdr(lua_tostring(L, 2), 0))
265 case 0x86720331: // major
266 lua_pushinteger(L, (lua_Integer)ctx->major);
267 break;
268 case 0x87857C2D: // minor
269 lua_pushinteger(L, (lua_Integer)ctx->minor);
270 break;
271 case 0x0241DD17: // third
272 lua_pushinteger(L, (lua_Integer)ctx->third);
273 break;
274 case 0xFD1BE968: // extra
275 lua_pushinteger(L, (lua_Integer)ctx->extra);
276 break;
277 case 0xB5485B9E: // alpha
279 char alpha[sizeof(ctx->alpha_) + 1];
280 a_version_alpha(ctx, alpha);
281 lua_pushstring(L, alpha);
282 break;
284 case 0xA65758B2: // __index
285 lua_registry_get(L, liba_version_new);
286 lua_int_set(L, -1, "major", (lua_Integer)ctx->major);
287 lua_int_set(L, -1, "minor", (lua_Integer)ctx->minor);
288 lua_int_set(L, -1, "third", (lua_Integer)ctx->third);
289 lua_int_set(L, -1, "extra", (lua_Integer)ctx->extra);
290 lua_str_set(L, -1, "alpha", ".");
291 break;
292 default:
293 lua_getmetatable(L, 1);
294 lua_replace(L, 1);
295 lua_rawget(L, 1);
297 return 1;
300 static int liba_version_(lua_State *L)
302 lua_pushcfunction(L, liba_version_new);
303 lua_replace(L, 1);
304 lua_call(L, lua_gettop(L) - 1, 1);
305 return 1;
308 int luaopen_liba_version(lua_State *L)
310 /***
311 algorithm library version number
312 @field MAJOR algorithm library version major
313 @field MINOR algorithm library version minor
314 @field PATCH algorithm library version patch
315 @field TWEAK algorithm library version tweak
316 @table liba.version
318 static lua_int const enums[] = {
319 {"MAJOR", A_VERSION_MAJOR},
320 {"MINOR", A_VERSION_MINOR},
321 {"PATCH", A_VERSION_PATCH},
322 {"TWEAK", A_VERSION_TWEAK},
324 static lua_fun const funcs[] = {
325 {"check", liba_version_check},
326 {"parse", liba_version_parse},
327 {"init", liba_version_init},
328 {"new", liba_version_new},
329 {"cmp", liba_version_cmp},
330 {"lt", liba_version_lt},
331 {"gt", liba_version_gt},
332 {"le", liba_version_le},
333 {"ge", liba_version_ge},
334 {"eq", liba_version_eq},
335 {"ne", liba_version_ne},
337 lua_createtable(L, 0, A_LEN(enums) + A_LEN(funcs));
338 lua_int_reg(L, -1, enums, A_LEN(enums));
339 lua_fun_reg(L, -1, funcs, A_LEN(funcs));
340 lua_createtable(L, 0, 1);
341 lua_fun_set(L, -1, "__call", liba_version_);
342 lua_setmetatable(L, -2);
344 static lua_fun const metas[] = {
345 {"__tostring", liba_version_tostring},
346 {"__newindex", liba_version_set},
347 {"__index", liba_version_get},
348 {"__call", liba_version_init},
349 {"__eq", liba_version_eq},
350 {"__lt", liba_version_lt},
351 {"__le", liba_version_le},
353 lua_createtable(L, 0, A_LEN(metas) + A_LEN(funcs));
354 lua_fun_reg(L, -1, metas, A_LEN(metas));
355 lua_fun_reg(L, -1, funcs + 1, A_LEN(funcs) - 1);
356 lua_str_set(L, -1, "__name", "a.version");
357 lua_registry_set(L, liba_version_new);
359 return 1;