2015-07-07 15:30:44 +00:00
|
|
|
/*
|
|
|
|
* wslua_pref.c
|
|
|
|
*
|
|
|
|
* Wireshark's interface to the Lua Programming Language
|
|
|
|
*
|
|
|
|
* (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
|
|
|
|
* (c) 2008, Balint Reczey <balint.reczey@ericsson.com>
|
|
|
|
* (c) 2011, Stig Bjorlykke <stig@bjorlykke.org>
|
|
|
|
* (c) 2014, Hadriel Kaplan <hadrielk@yahoo.com>
|
|
|
|
*
|
|
|
|
* Wireshark - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@wireshark.org>
|
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
2018-02-08 16:33:09 +00:00
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
2015-07-07 15:30:44 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include "wslua.h"
|
|
|
|
|
|
|
|
/* WSLUA_CONTINUE_MODULE Proto */
|
|
|
|
|
|
|
|
|
2020-03-29 22:46:46 +00:00
|
|
|
WSLUA_CLASS_DEFINE(Pref,NOP); /* A preference of a <<lua_class_Proto,`Proto`>>. */
|
2015-07-07 15:30:44 +00:00
|
|
|
|
|
|
|
static range_t* get_range(lua_State *L, int idx_r, int idx_m);
|
|
|
|
|
|
|
|
static enum_val_t* get_enum(lua_State *L, int idx)
|
|
|
|
{
|
|
|
|
double seq;
|
|
|
|
const gchar *str1, *str2;
|
|
|
|
enum_val_t *ret, last = {NULL, NULL, -1};
|
|
|
|
GArray* es = g_array_new(TRUE,TRUE,sizeof(enum_val_t));
|
|
|
|
|
|
|
|
luaL_checktype(L, idx, LUA_TTABLE);
|
|
|
|
lua_pushnil(L); /* first key */
|
|
|
|
|
|
|
|
while (lua_next(L, idx)) {
|
|
|
|
enum_val_t e = {NULL, NULL, -1};
|
|
|
|
|
|
|
|
luaL_checktype(L, -1, LUA_TTABLE);
|
|
|
|
lua_pushnil(L);
|
|
|
|
lua_next(L, -2);
|
|
|
|
if (! lua_isstring(L,-1)) {
|
|
|
|
luaL_argerror(L,idx,"First value of an enum table must be string");
|
|
|
|
g_array_free(es,TRUE);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
str1 = lua_tostring(L, -1);
|
|
|
|
|
|
|
|
lua_pop(L, 1);
|
|
|
|
lua_next(L, -2);
|
|
|
|
if (! lua_isstring(L,-1)) {
|
|
|
|
luaL_argerror(L,idx,"Second value of an enum table must be string");
|
|
|
|
g_array_free(es,TRUE);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
str2 = lua_tostring(L, -1);
|
|
|
|
|
|
|
|
lua_pop(L, 1);
|
|
|
|
lua_next(L, -2);
|
|
|
|
if (! lua_isnumber(L,-1)) {
|
|
|
|
luaL_argerror(L,idx,"Third value of an enum table must be an integer");
|
|
|
|
g_array_free(es,TRUE);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
seq = lua_tonumber(L, -1);
|
|
|
|
|
|
|
|
e.name = g_strdup(str1);
|
|
|
|
e.description = g_strdup(str2);
|
|
|
|
e.value = (guint32)seq;
|
|
|
|
|
|
|
|
g_array_append_val(es,e);
|
|
|
|
|
|
|
|
lua_pop(L, 3); /* removes 'value'; keeps 'key' for next iteration */
|
|
|
|
}
|
|
|
|
|
|
|
|
g_array_append_val(es,last);
|
|
|
|
|
2018-05-09 20:37:41 +00:00
|
|
|
ret = (enum_val_t*)(void*)g_array_free(es, FALSE);
|
2015-07-07 15:30:44 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int new_pref(lua_State* L, pref_type_t type) {
|
|
|
|
const gchar* label = luaL_optstring(L,1,NULL);
|
|
|
|
const gchar* descr = luaL_optstring(L,3,"");
|
|
|
|
|
2020-12-21 02:30:28 +00:00
|
|
|
Pref pref = g_new0(wslua_pref_t, 1);
|
2015-12-14 18:40:51 +00:00
|
|
|
pref->label = g_strdup(label);
|
2015-07-07 15:30:44 +00:00
|
|
|
pref->desc = g_strdup(descr);
|
|
|
|
pref->type = type;
|
2019-01-25 21:55:24 +00:00
|
|
|
pref->ref = LUA_NOREF;
|
2015-07-07 15:30:44 +00:00
|
|
|
|
|
|
|
switch(type) {
|
|
|
|
case PREF_BOOL: {
|
|
|
|
gboolean def = wslua_toboolean(L,2);
|
|
|
|
pref->value.b = def;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case PREF_UINT: {
|
|
|
|
guint32 def = wslua_optgint32(L,2,0);
|
|
|
|
pref->value.u = def;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case PREF_STRING: {
|
|
|
|
gchar* def = g_strdup(luaL_optstring(L,2,""));
|
2015-12-14 19:24:53 +00:00
|
|
|
/*
|
|
|
|
* prefs_register_string_preference() assumes that the
|
|
|
|
* variable for the preference points to a static
|
|
|
|
* string that is the initial (default) value of the
|
|
|
|
* preference. It makes a g_strdup()ed copy of that
|
|
|
|
* string, and assigns a pointer to that string to
|
|
|
|
* the variable.
|
|
|
|
*
|
|
|
|
* Our default string is *not* a static string, it's
|
|
|
|
* a g_strdup()ed copy of a string from Lua, so it would
|
|
|
|
* be leaked.
|
|
|
|
*
|
|
|
|
* We save it in info.default_s, as well as setting the
|
|
|
|
* initial value of the preference from it, so that we
|
|
|
|
* can free it after prefs_register_string_preference()
|
|
|
|
* returns.
|
|
|
|
*
|
|
|
|
* (Would that we were programming in a language where
|
|
|
|
* the details of memory management were handled by the
|
|
|
|
* compiler and language support....)
|
|
|
|
*/
|
2015-07-07 15:30:44 +00:00
|
|
|
pref->value.s = def;
|
2015-12-14 18:40:51 +00:00
|
|
|
pref->info.default_s = def;
|
2015-07-07 15:30:44 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case PREF_ENUM: {
|
|
|
|
guint32 def = wslua_optgint32(L,2,0);
|
|
|
|
enum_val_t *enum_val = get_enum(L,4);
|
|
|
|
gboolean radio = wslua_toboolean(L,5);
|
|
|
|
pref->value.e = def;
|
|
|
|
pref->info.enum_info.enumvals = enum_val;
|
|
|
|
pref->info.enum_info.radio_buttons = radio;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case PREF_RANGE: {
|
|
|
|
range_t *range = get_range(L,2,4);
|
|
|
|
guint32 max = wslua_optgint32(L,4,0);
|
|
|
|
pref->value.r = range;
|
|
|
|
pref->info.max_value = max;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case PREF_STATIC_TEXT: {
|
|
|
|
/* This is just a static text. */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
2021-03-20 01:58:26 +00:00
|
|
|
ws_assert_not_reached();
|
2015-07-07 15:30:44 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
pushPref(L,pref);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
WSLUA_CONSTRUCTOR Pref_bool(lua_State* L) {
|
2020-03-29 22:46:46 +00:00
|
|
|
/*
|
|
|
|
Creates a boolean preference to be added to a <<lua_class_attrib_proto_prefs,`Proto.prefs`>> Lua table.
|
|
|
|
|
|
|
|
===== Example
|
|
|
|
|
|
|
|
[source,lua]
|
|
|
|
----
|
|
|
|
-- create a Boolean preference named "bar" for Foo Protocol
|
|
|
|
-- (assuming Foo doesn't already have a preference named "bar")
|
|
|
|
proto_foo.prefs.bar = Pref.bool( "Bar", true, "Baz and all the rest" )
|
|
|
|
----
|
|
|
|
*/
|
2015-07-07 15:30:44 +00:00
|
|
|
#define WSLUA_ARG_Pref_bool_LABEL 1 /* The Label (text in the right side of the
|
|
|
|
preference input) for this preference. */
|
|
|
|
#define WSLUA_ARG_Pref_bool_DEFAULT 2 /* The default value for this preference. */
|
2020-03-29 22:46:46 +00:00
|
|
|
#define WSLUA_ARG_Pref_bool_DESCR 3 /* A description of this preference. */
|
2015-07-07 15:30:44 +00:00
|
|
|
return new_pref(L,PREF_BOOL);
|
|
|
|
}
|
|
|
|
|
|
|
|
WSLUA_CONSTRUCTOR Pref_uint(lua_State* L) {
|
2020-03-29 22:46:46 +00:00
|
|
|
/* Creates an (unsigned) integer preference to be added to a <<lua_class_attrib_proto_prefs,`Proto.prefs`>> Lua table. */
|
2015-07-07 15:30:44 +00:00
|
|
|
#define WSLUA_ARG_Pref_uint_LABEL 1 /* The Label (text in the right side of the
|
|
|
|
preference input) for this preference. */
|
|
|
|
#define WSLUA_ARG_Pref_uint_DEFAULT 2 /* The default value for this preference. */
|
|
|
|
#define WSLUA_ARG_Pref_uint_DESCR 3 /* A description of what this preference is. */
|
|
|
|
return new_pref(L,PREF_UINT);
|
|
|
|
}
|
|
|
|
|
|
|
|
WSLUA_CONSTRUCTOR Pref_string(lua_State* L) {
|
2020-03-29 22:46:46 +00:00
|
|
|
/* Creates a string preference to be added to a <<lua_class_attrib_proto_prefs,`Proto.prefs`>> Lua table. */
|
2015-07-07 15:30:44 +00:00
|
|
|
#define WSLUA_ARG_Pref_string_LABEL 1 /* The Label (text in the right side of the
|
|
|
|
preference input) for this preference. */
|
|
|
|
#define WSLUA_ARG_Pref_string_DEFAULT 2 /* The default value for this preference. */
|
|
|
|
#define WSLUA_ARG_Pref_string_DESCR 3 /* A description of what this preference is. */
|
|
|
|
return new_pref(L,PREF_STRING);
|
|
|
|
}
|
|
|
|
|
|
|
|
WSLUA_CONSTRUCTOR Pref_enum(lua_State* L) {
|
2020-03-29 22:46:46 +00:00
|
|
|
/*
|
|
|
|
Creates an enum preference to be added to a <<lua_class_attrib_proto_prefs,`Proto.prefs`>> Lua table.
|
|
|
|
|
|
|
|
===== Example:
|
|
|
|
|
|
|
|
[source,lua]
|
|
|
|
----
|
|
|
|
local OUTPUT_OFF = 0
|
|
|
|
local OUTPUT_DEBUG = 1
|
|
|
|
local OUTPUT_INFO = 2
|
|
|
|
local OUTPUT_WARN = 3
|
|
|
|
local OUTPUT_ERROR = 4
|
|
|
|
|
|
|
|
local output_tab = {
|
|
|
|
{ 1, "Off" , OUTPUT_OFF },
|
|
|
|
{ 2, "Debug" , OUTPUT_DEBUG },
|
|
|
|
{ 3, "Information" , OUTPUT_INFO },
|
|
|
|
{ 4, "Warning" , OUTPUT_WARN },
|
|
|
|
{ 5, "Error" , OUTPUT_ERROR },
|
|
|
|
}
|
|
|
|
|
|
|
|
-- Create enum preference that shows as Combo Box under
|
|
|
|
-- Foo Protocol's preferences
|
|
|
|
proto_foo.prefs.outputlevel = Pref.enum(
|
|
|
|
"Output Level", -- label
|
|
|
|
OUTPUT_INFO, -- default value
|
|
|
|
"Verbosity of log output", -- description
|
|
|
|
output_tab, -- enum table
|
|
|
|
false -- show as combo box
|
|
|
|
)
|
|
|
|
|
|
|
|
-- Then, we can query the value of the selected preference.
|
|
|
|
-- This line prints "Output Level: 3" assuming the selected
|
|
|
|
-- output level is _INFO.
|
|
|
|
debug( "Output Level: " .. proto_foo.prefs.outputlevel )
|
|
|
|
----
|
|
|
|
*/
|
2015-07-07 15:30:44 +00:00
|
|
|
#define WSLUA_ARG_Pref_enum_LABEL 1 /* The Label (text in the right side of the
|
|
|
|
preference input) for this preference. */
|
|
|
|
#define WSLUA_ARG_Pref_enum_DEFAULT 2 /* The default value for this preference. */
|
|
|
|
#define WSLUA_ARG_Pref_enum_DESCR 3 /* A description of what this preference is. */
|
|
|
|
#define WSLUA_ARG_Pref_enum_ENUM 4 /* An enum Lua table. */
|
|
|
|
#define WSLUA_ARG_Pref_enum_RADIO 5 /* Radio button (true) or Combobox (false). */
|
|
|
|
return new_pref(L,PREF_ENUM);
|
|
|
|
}
|
|
|
|
|
|
|
|
WSLUA_CONSTRUCTOR Pref_range(lua_State* L) {
|
2020-03-29 22:46:46 +00:00
|
|
|
/* Creates a range (numeric text entry) preference to be added to a <<lua_class_attrib_proto_prefs,`Proto.prefs`>> Lua table. */
|
2015-07-07 15:30:44 +00:00
|
|
|
#define WSLUA_ARG_Pref_range_LABEL 1 /* The Label (text in the right side of the preference
|
|
|
|
input) for this preference. */
|
|
|
|
#define WSLUA_ARG_Pref_range_DEFAULT 2 /* The default value for this preference, e.g., "53",
|
|
|
|
"10-30", or "10-30,53,55,100-120". */
|
|
|
|
#define WSLUA_ARG_Pref_range_DESCR 3 /* A description of what this preference is. */
|
|
|
|
#define WSLUA_ARG_Pref_range_MAX 4 /* The maximum value. */
|
|
|
|
return new_pref(L,PREF_RANGE);
|
|
|
|
}
|
|
|
|
|
|
|
|
WSLUA_CONSTRUCTOR Pref_statictext(lua_State* L) {
|
2020-03-29 22:46:46 +00:00
|
|
|
/* Creates a static text string to be added to a <<lua_class_attrib_proto_prefs,`Proto.prefs`>> Lua table. */
|
2015-07-07 15:30:44 +00:00
|
|
|
#define WSLUA_ARG_Pref_statictext_LABEL 1 /* The static text. */
|
|
|
|
#define WSLUA_ARG_Pref_statictext_DESCR 2 /* The static text description. */
|
|
|
|
return new_pref(L,PREF_STATIC_TEXT);
|
|
|
|
}
|
|
|
|
|
|
|
|
static range_t* get_range(lua_State *L, int idx_r, int idx_m)
|
|
|
|
{
|
|
|
|
static range_t *ret = NULL;
|
|
|
|
const gchar *pattern = luaL_checkstring(L, idx_r);
|
|
|
|
|
2016-12-22 20:12:27 +00:00
|
|
|
switch (range_convert_str(wmem_epan_scope(), &ret, pattern, wslua_togint32(L, idx_m))) {
|
2015-07-07 15:30:44 +00:00
|
|
|
case CVT_NO_ERROR:
|
|
|
|
break;
|
|
|
|
case CVT_SYNTAX_ERROR:
|
|
|
|
WSLUA_ARG_ERROR(Pref_range,DEFAULT,"syntax error in default range");
|
|
|
|
return 0;
|
|
|
|
case CVT_NUMBER_TOO_BIG:
|
|
|
|
WSLUA_ARG_ERROR(Pref_range,DEFAULT,"value too large in default range");
|
|
|
|
return 0;
|
|
|
|
default:
|
|
|
|
WSLUA_ARG_ERROR(Pref_range,DEFAULT,"unknown error in default range");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2015-08-11 12:08:08 +00:00
|
|
|
|
2015-07-07 15:30:44 +00:00
|
|
|
/* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
|
|
|
|
static int Pref__gc(lua_State* L) {
|
2015-08-11 12:08:08 +00:00
|
|
|
Pref pref = toPref(L,1);
|
2015-07-07 15:30:44 +00:00
|
|
|
|
2019-01-25 21:55:24 +00:00
|
|
|
if (pref->ref != LUA_NOREF) {
|
|
|
|
// Did the user try to call __gc explicitly while it was registered to a
|
|
|
|
// protocol? Forbid that!
|
|
|
|
luaL_error(L, "Direct call to __gc is forbidden");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free(pref->name);
|
|
|
|
g_free(pref->label);
|
|
|
|
g_free(pref->desc);
|
|
|
|
switch (pref->type) {
|
|
|
|
case PREF_STRING:
|
|
|
|
/*
|
|
|
|
* Free the initial string value; if it's not NULL, that
|
|
|
|
* means this is a never-registered preference, so the
|
|
|
|
* initial value hasn't been freed.
|
|
|
|
*/
|
|
|
|
g_free(pref->info.default_s);
|
|
|
|
break;
|
|
|
|
case PREF_ENUM: {
|
|
|
|
/*
|
|
|
|
* Free the enum values allocated in get_enum().
|
|
|
|
*/
|
|
|
|
const enum_val_t *enum_valp = pref->info.enum_info.enumvals;
|
|
|
|
while (enum_valp->name) {
|
|
|
|
g_free((char *)enum_valp->name);
|
|
|
|
g_free((char *)enum_valp->description);
|
|
|
|
enum_valp++;
|
2015-12-14 21:17:46 +00:00
|
|
|
}
|
2019-01-25 21:55:24 +00:00
|
|
|
g_free((enum_val_t *)pref->info.enum_info.enumvals);
|
|
|
|
break;
|
2015-12-14 19:24:53 +00:00
|
|
|
}
|
2019-01-25 21:55:24 +00:00
|
|
|
default:
|
|
|
|
break;
|
2015-07-07 15:30:44 +00:00
|
|
|
}
|
2019-01-25 21:55:24 +00:00
|
|
|
g_free(pref);
|
2015-07-07 15:30:44 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
WSLUA_METHODS Pref_methods[] = {
|
|
|
|
WSLUA_CLASS_FNREG(Pref,bool),
|
|
|
|
WSLUA_CLASS_FNREG(Pref,uint),
|
|
|
|
WSLUA_CLASS_FNREG(Pref,string),
|
|
|
|
WSLUA_CLASS_FNREG(Pref,enum),
|
|
|
|
WSLUA_CLASS_FNREG(Pref,range),
|
|
|
|
WSLUA_CLASS_FNREG(Pref,statictext),
|
|
|
|
{ NULL, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
WSLUA_META Pref_meta[] = {
|
|
|
|
{ NULL, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
WSLUA_REGISTER Pref_register(lua_State* L) {
|
|
|
|
WSLUA_REGISTER_CLASS(Pref);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-04-03 08:58:44 +00:00
|
|
|
WSLUA_CLASS_DEFINE(Prefs,NOP); /* The table of preferences of a protocol. */
|
2015-07-07 15:30:44 +00:00
|
|
|
|
|
|
|
WSLUA_METAMETHOD Prefs__newindex(lua_State* L) {
|
|
|
|
/* Creates a new preference. */
|
|
|
|
#define WSLUA_ARG_Prefs__newindex_NAME 2 /* The abbreviation of this preference. */
|
|
|
|
#define WSLUA_ARG_Prefs__newindex_PREF 3 /* A valid but still unassigned Pref object. */
|
|
|
|
|
|
|
|
Pref prefs_p = checkPrefs(L,1);
|
|
|
|
const gchar* name = luaL_checkstring(L,WSLUA_ARG_Prefs__newindex_NAME);
|
|
|
|
Pref pref = checkPref(L,WSLUA_ARG_Prefs__newindex_PREF);
|
|
|
|
Pref p;
|
|
|
|
const gchar *c;
|
|
|
|
|
|
|
|
if (! prefs_p ) return 0;
|
|
|
|
|
|
|
|
if (! pref ) {
|
|
|
|
WSLUA_ARG_ERROR(Prefs__newindex,PREF,"must be a valid Pref");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pref->name) {
|
|
|
|
WSLUA_ARG_ERROR(Prefs__newindex,NAME,"cannot change existing preference");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pref->proto) {
|
|
|
|
WSLUA_ARG_ERROR(Prefs__newindex,PREF,"cannot be added to more than one protocol");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
p = prefs_p;
|
|
|
|
|
|
|
|
do {
|
|
|
|
if ( p->name && g_str_equal(p->name,name) ) {
|
|
|
|
luaL_error(L,"a preference named %s exists already",name);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* Make sure that only lower-case ASCII letters, numbers,
|
|
|
|
* underscores, and dots appear in the preference name.
|
|
|
|
*/
|
|
|
|
for (c = name; *c != '\0'; c++) {
|
|
|
|
if (!g_ascii_islower(*c) && !g_ascii_isdigit(*c) && *c != '_' && *c != '.')
|
|
|
|
{
|
|
|
|
luaL_error(L,"illegal preference name \"%s\", only lower-case ASCII letters, "
|
|
|
|
"numbers, underscores and dots may be used", name);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ! p->next) {
|
2019-01-25 21:55:24 +00:00
|
|
|
// Keep a reference to the Pref to ensure it remains valid
|
|
|
|
// until the protocol is deregistered.
|
|
|
|
lua_pushvalue(L, WSLUA_ARG_Prefs__newindex_PREF);
|
|
|
|
pref->ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
|
|
|
|
2015-07-07 15:30:44 +00:00
|
|
|
p->next = pref;
|
|
|
|
pref->name = g_strdup(name);
|
|
|
|
|
|
|
|
if (!pref->label)
|
|
|
|
pref->label = g_strdup(name);
|
|
|
|
|
|
|
|
if (!prefs_p->proto->prefs_module) {
|
|
|
|
prefs_p->proto->prefs_module = prefs_register_protocol(prefs_p->proto->hfid,
|
|
|
|
wslua_prefs_changed);
|
|
|
|
}
|
|
|
|
|
|
|
|
switch(pref->type) {
|
|
|
|
case PREF_BOOL:
|
|
|
|
prefs_register_bool_preference(prefs_p->proto->prefs_module,
|
|
|
|
pref->name,
|
|
|
|
pref->label,
|
|
|
|
pref->desc,
|
|
|
|
&(pref->value.b));
|
|
|
|
break;
|
|
|
|
case PREF_UINT:
|
|
|
|
prefs_register_uint_preference(prefs_p->proto->prefs_module,
|
|
|
|
pref->name,
|
|
|
|
pref->label,
|
|
|
|
pref->desc,
|
|
|
|
10,
|
|
|
|
&(pref->value.u));
|
|
|
|
break;
|
|
|
|
case PREF_STRING:
|
|
|
|
prefs_register_string_preference(prefs_p->proto->prefs_module,
|
|
|
|
pref->name,
|
|
|
|
pref->label,
|
|
|
|
pref->desc,
|
|
|
|
(const char **)(&(pref->value.s)));
|
2015-12-14 19:24:53 +00:00
|
|
|
/*
|
|
|
|
* We're finished with the initial string value; see
|
|
|
|
* the comment in new_pref().
|
|
|
|
*/
|
2015-12-14 18:40:51 +00:00
|
|
|
g_free(pref->info.default_s);
|
|
|
|
pref->info.default_s = NULL;
|
2015-07-07 15:30:44 +00:00
|
|
|
break;
|
|
|
|
case PREF_ENUM:
|
|
|
|
prefs_register_enum_preference(prefs_p->proto->prefs_module,
|
|
|
|
pref->name,
|
|
|
|
pref->label,
|
|
|
|
pref->desc,
|
|
|
|
&(pref->value.e),
|
|
|
|
pref->info.enum_info.enumvals,
|
|
|
|
pref->info.enum_info.radio_buttons);
|
|
|
|
break;
|
|
|
|
case PREF_RANGE:
|
|
|
|
prefs_register_range_preference(prefs_p->proto->prefs_module,
|
|
|
|
pref->name,
|
|
|
|
pref->label,
|
|
|
|
pref->desc,
|
|
|
|
&(pref->value.r),
|
|
|
|
pref->info.max_value);
|
|
|
|
break;
|
|
|
|
case PREF_STATIC_TEXT:
|
|
|
|
prefs_register_static_text_preference(prefs_p->proto->prefs_module,
|
|
|
|
pref->name,
|
|
|
|
pref->label,
|
|
|
|
pref->desc);
|
|
|
|
break;
|
|
|
|
default:
|
2016-10-26 19:44:25 +00:00
|
|
|
WSLUA_ERROR(Prefs__newindex,"Unknown Pref type");
|
2015-07-07 15:30:44 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
pref->proto = p->proto;
|
|
|
|
|
|
|
|
WSLUA_RETURN(0);
|
|
|
|
}
|
|
|
|
} while (( p = p->next ));
|
|
|
|
|
|
|
|
luaL_error(L,"this should not happen!");
|
|
|
|
|
|
|
|
WSLUA_RETURN(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
WSLUA_METAMETHOD Prefs__index(lua_State* L) {
|
2020-03-29 22:46:46 +00:00
|
|
|
/*
|
|
|
|
Get the value of a preference setting.
|
|
|
|
|
|
|
|
===== Example
|
|
|
|
|
|
|
|
[source,lua]
|
|
|
|
----
|
|
|
|
-- print the value of Foo's preference named "bar"
|
|
|
|
debug( "bar = " .. proto_foo.prefs.bar )
|
|
|
|
----
|
|
|
|
*/
|
2015-07-07 15:30:44 +00:00
|
|
|
#define WSLUA_ARG_Prefs__index_NAME 2 /* The abbreviation of this preference. */
|
|
|
|
|
|
|
|
Pref prefs_p = checkPrefs(L,1);
|
|
|
|
const gchar* name = luaL_checkstring(L,WSLUA_ARG_Prefs__index_NAME);
|
|
|
|
|
|
|
|
if (! prefs_p ) return 0;
|
|
|
|
|
|
|
|
if (!prefs_p->next) {
|
|
|
|
luaL_error(L,"No preference is registered yet");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
prefs_p = prefs_p->next;
|
|
|
|
|
|
|
|
do {
|
|
|
|
if ( g_str_equal(prefs_p->name,name) ) {
|
|
|
|
switch (prefs_p->type) {
|
|
|
|
case PREF_BOOL: lua_pushboolean(L, prefs_p->value.b); break;
|
|
|
|
case PREF_UINT: lua_pushnumber(L,(lua_Number)prefs_p->value.u); break;
|
|
|
|
case PREF_STRING: lua_pushstring(L,prefs_p->value.s); break;
|
|
|
|
case PREF_ENUM: lua_pushnumber(L,(lua_Number)prefs_p->value.e); break;
|
|
|
|
case PREF_RANGE:
|
|
|
|
{
|
|
|
|
char *push_str = range_convert_range(NULL, prefs_p->value.r);
|
|
|
|
lua_pushstring(L, push_str);
|
|
|
|
wmem_free(NULL, push_str);
|
|
|
|
}
|
|
|
|
break;
|
2016-10-26 19:44:25 +00:00
|
|
|
default: WSLUA_ERROR(Prefs__index,"Unknown Pref type"); return 0;
|
2015-07-07 15:30:44 +00:00
|
|
|
}
|
|
|
|
WSLUA_RETURN(1); /* The current value of the preference. */
|
|
|
|
}
|
|
|
|
} while (( prefs_p = prefs_p->next ));
|
|
|
|
|
|
|
|
WSLUA_ARG_ERROR(Prefs__index,NAME,"no preference named like this");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
|
|
|
|
static int Prefs__gc(lua_State* L _U_) {
|
2015-08-11 12:08:08 +00:00
|
|
|
/* do NOT free Prefs, it's a static part of Proto */
|
2015-07-07 15:30:44 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
WSLUA_META Prefs_meta[] = {
|
|
|
|
WSLUA_CLASS_MTREG(Prefs,newindex),
|
|
|
|
WSLUA_CLASS_MTREG(Prefs,index),
|
|
|
|
{ NULL, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
WSLUA_REGISTER Prefs_register(lua_State* L) {
|
|
|
|
WSLUA_REGISTER_META(Prefs);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2019-07-26 18:43:17 +00:00
|
|
|
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
2015-07-07 15:30:44 +00:00
|
|
|
*
|
|
|
|
* Local variables:
|
|
|
|
* c-basic-offset: 4
|
|
|
|
* tab-width: 8
|
|
|
|
* indent-tabs-mode: nil
|
|
|
|
* End:
|
|
|
|
*
|
|
|
|
* vi: set shiftwidth=4 tabstop=8 expandtab:
|
|
|
|
* :indentSize=4:tabSize=8:noTabs=true:
|
|
|
|
*/
|