]> git.ipfire.org Git - people/ms/libloc.git/commitdiff
lua: Create Country objects
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 22 Feb 2024 15:10:51 +0000 (15:10 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 22 Feb 2024 15:10:51 +0000 (15:10 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
src/lua/country.c [new file with mode: 0644]
src/lua/country.h [new file with mode: 0644]
src/lua/location.c
tests/lua/main.lua

index e3ed1fcdb1fae96808a26cd124d257c56fc364a7..f61997edbc3c56d312e0fde438ca0c1c7c2e22b4 100644 (file)
@@ -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 (file)
index 0000000..5a9652e
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+       libloc - A library to determine the location of someone on the Internet
+
+       Copyright (C) 2024 IPFire Development Team <info@ipfire.org>
+
+       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 <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include <libloc/country.h>
+
+#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 (file)
index 0000000..4997d9d
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+       libloc - A library to determine the location of someone on the Internet
+
+       Copyright (C) 2024 IPFire Development Team <info@ipfire.org>
+
+       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 <lua.h>
+#include <lauxlib.h>
+
+#include <libloc/country.h>
+
+int register_country(lua_State* L);
+
+int create_country(lua_State* L, struct loc_country* country);
+
+#endif /* LUA_LOCATION_COUNTRY_H */
index 315a790413113f7186b66b33b654af12d3875e8a..797d2e81535f626c2788ac432a39bdce376a45bf 100644 (file)
@@ -24,6 +24,7 @@
 #include <libloc/libloc.h>
 
 #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);
 
index 38823de20774d29e758dbf22b25ecc8896da0a16..7349a80ac73c82b14cebb55cd262418a30586009 100755 (executable)
@@ -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"))