]> git.ipfire.org Git - people/ms/libloc.git/blob - src/lua/country.c
importer: Drop EDROP as it has been merged into DROP
[people/ms/libloc.git] / src / lua / country.c
1 /*
2 libloc - A library to determine the location of someone on the Internet
3
4 Copyright (C) 2024 IPFire Development Team <info@ipfire.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15 */
16
17 #include <errno.h>
18 #include <string.h>
19 #include <stdlib.h>
20
21 #include <lua.h>
22 #include <lauxlib.h>
23
24 #include <libloc/country.h>
25
26 #include "location.h"
27 #include "compat.h"
28 #include "country.h"
29
30 typedef struct country {
31 struct loc_country* country;
32 } Country;
33
34 static Country* luaL_checkcountry(lua_State* L, int i) {
35 void* userdata = luaL_checkudata(L, i, "location.Country");
36
37 // Throw an error if the argument doesn't match
38 luaL_argcheck(L, userdata, i, "Country expected");
39
40 return (Country*)userdata;
41 }
42
43 int create_country(lua_State* L, struct loc_country* country) {
44 // Allocate a new object
45 Country* self = (Country*)lua_newuserdata(L, sizeof(*self));
46
47 // Set metatable
48 luaL_setmetatable(L, "location.Country");
49
50 // Store country
51 self->country = loc_country_ref(country);
52
53 return 1;
54 }
55
56 static int Country_new(lua_State* L) {
57 struct loc_country* country = NULL;
58 const char* code = NULL;
59 int r;
60
61 // Fetch the code
62 code = luaL_checkstring(L, 1);
63
64 // Parse the string
65 r = loc_country_new(ctx, &country, code);
66 if (r)
67 return luaL_error(L, "Could not create country %s: %s\n", code, strerror(errno));
68
69 // Return the country
70 r = create_country(L, country);
71 loc_country_unref(country);
72
73 return r;
74 }
75
76 static int Country_gc(lua_State* L) {
77 Country* self = luaL_checkcountry(L, 1);
78
79 // Free country
80 if (self->country) {
81 loc_country_unref(self->country);
82 self->country = NULL;
83 }
84
85 return 0;
86 }
87
88 static int Country_eq(lua_State* L) {
89 Country* self = luaL_checkcountry(L, 1);
90 Country* other = luaL_checkcountry(L, 2);
91
92 // Push comparison result
93 lua_pushboolean(L, loc_country_cmp(self->country, other->country) == 0);
94
95 return 1;
96 }
97
98 // Name
99
100 static int Country_get_name(lua_State* L) {
101 Country* self = luaL_checkcountry(L, 1);
102
103 // Return the code
104 lua_pushstring(L, loc_country_get_name(self->country));
105
106 return 1;
107 }
108
109 // Code
110
111 static int Country_get_code(lua_State* L) {
112 Country* self = luaL_checkcountry(L, 1);
113
114 // Return the code
115 lua_pushstring(L, loc_country_get_code(self->country));
116
117 return 1;
118 }
119
120 // Continent Code
121
122 static int Country_get_continent_code(lua_State* L) {
123 Country* self = luaL_checkcountry(L, 1);
124
125 // Return the code
126 lua_pushstring(L, loc_country_get_continent_code(self->country));
127
128 return 1;
129 }
130
131 static const struct luaL_Reg Country_functions[] = {
132 { "new", Country_new },
133 { "get_code", Country_get_code },
134 { "get_continent_code", Country_get_continent_code },
135 { "get_name", Country_get_name },
136 { "__eq", Country_eq },
137 { "__gc", Country_gc },
138 { "__tostring", Country_get_code },
139 { NULL, NULL },
140 };
141
142 int register_country(lua_State* L) {
143 return register_class(L, "location.Country", Country_functions);
144 }