From: Michael Tremer Date: Thu, 22 Feb 2024 15:10:51 +0000 (+0000) Subject: lua: Create Country objects X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0ddfebb382b9ef4699a143e384f491e0971f71a4;p=people%2Fms%2Flibloc.git lua: Create Country objects Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index e3ed1fc..f61997e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -237,6 +237,8 @@ lua_LTLIBRARIES = \ luadir = $(LUA_INSTALL_CMOD) src_lua_location_la_SOURCES = \ + src/lua/country.c \ + src/lua/country.h \ src/lua/database.c \ src/lua/database.h \ src/lua/location.c \ @@ -261,6 +263,8 @@ src_lua_location_la_LIBADD = \ endif EXTRA_DIST += \ + src/lua/country.c \ + src/lua/country.h \ src/lua/database.c \ src/lua/database.h \ src/lua/location.c \ diff --git a/src/lua/country.c b/src/lua/country.c new file mode 100644 index 0000000..5a9652e --- /dev/null +++ b/src/lua/country.c @@ -0,0 +1,126 @@ +/* + libloc - A library to determine the location of someone on the Internet + + Copyright (C) 2024 IPFire Development Team + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. +*/ + +#include +#include +#include + +#include +#include + +#include + +#include "location.h" +#include "country.h" + +typedef struct country { + struct loc_country* country; +} Country; + +static Country* luaL_checkcountry(lua_State* L, int i) { + void* userdata = luaL_checkudata(L, i, "location.Country"); + + // Throw an error if the argument doesn't match + luaL_argcheck(L, userdata, i, "Country expected"); + + return (Country*)userdata; +} + +int create_country(lua_State* L, struct loc_country* country) { + // Allocate a new object + Country* self = (Country*)lua_newuserdata(L, sizeof(*self)); + + // Set metatable + luaL_setmetatable(L, "location.Country"); + + // Store country + self->country = loc_country_ref(country); + + return 1; +} + +static int Country_new(lua_State* L) { + struct loc_country* country = NULL; + const char* code = NULL; + int r; + + // Fetch the code + code = luaL_checkstring(L, 1); + + // Parse the string + r = loc_country_new(ctx, &country, code); + if (r) + return luaL_error(L, "Could not create country %s: %s\n", code, strerror(errno)); + + // Return the country + r = create_country(L, country); + loc_country_unref(country); + + return r; +} + +static int Country_close(lua_State* L) { + Country* self = luaL_checkcountry(L, 1); + + // Free country + if (self->country) { + loc_country_unref(self->country); + self->country = NULL; + } + + return 0; +} + +static int Country_gc(lua_State* L) { + Country* self = luaL_checkcountry(L, 1); + + // Free the object + free(self); + + return 0; +} + +static int Country_eq(lua_State* L) { + Country* self = luaL_checkcountry(L, 1); + Country* other = luaL_checkcountry(L, 2); + + // Push comparison result + lua_pushboolean(L, loc_country_cmp(self->country, other->country) == 0); + + return 1; +} + +static int Country_get_code(lua_State* L) { + Country* self = luaL_checkcountry(L, 1); + + // Return the code + lua_pushstring(L, loc_country_get_code(self->country)); + + return 1; +} + +static const struct luaL_Reg Country_functions[] = { + { "new", Country_new }, + { "get_code", Country_get_code }, + { "__close", Country_close }, + { "__eq", Country_eq }, + { "__gc", Country_gc }, + { NULL, NULL }, +}; + +int register_country(lua_State* L) { + return register_class(L, "location.Country", Country_functions); +} diff --git a/src/lua/country.h b/src/lua/country.h new file mode 100644 index 0000000..4997d9d --- /dev/null +++ b/src/lua/country.h @@ -0,0 +1,29 @@ +/* + libloc - A library to determine the location of someone on the Internet + + Copyright (C) 2024 IPFire Development Team + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. +*/ + +#ifndef LUA_LOCATION_COUNTRY_H +#define LUA_LOCATION_COUNTRY_H + +#include +#include + +#include + +int register_country(lua_State* L); + +int create_country(lua_State* L, struct loc_country* country); + +#endif /* LUA_LOCATION_COUNTRY_H */ diff --git a/src/lua/location.c b/src/lua/location.c index 315a790..797d2e8 100644 --- a/src/lua/location.c +++ b/src/lua/location.c @@ -24,6 +24,7 @@ #include #include "location.h" +#include "country.h" #include "database.h" #include "network.h" @@ -51,6 +52,11 @@ int luaopen_location(lua_State* L) { // Register functions luaL_newlib(L, location_functions); + // Register Country type + register_country(L); + + lua_setfield(L, -2, "Country"); + // Register Database type register_database(L); diff --git a/tests/lua/main.lua b/tests/lua/main.lua index 38823de..7349a80 100755 --- a/tests/lua/main.lua +++ b/tests/lua/main.lua @@ -65,6 +65,16 @@ function test_network() luaunit.assertNil(n1:get_country_code()) end +function test_country() + location = require("location") + + c1 = location.Country.new("DE") + luaunit.assertEquals(c1:get_code(), "DE") + + c2 = location.Country.new("GB") + luaunit.assertNotEquals(c1, c2) +end + -- This test is not very deterministic but should help to test the GC methods function test_gc() print("GC: " .. collectgarbage("collect"))