4 * Wireshark's interface to the Lua Programming Language
6 * (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
7 * (c) 2008, Balint Reczey <balint.reczey@ericsson.com>
8 * (c) 2011, Stig Bjorlykke <stig@bjorlykke.org>
9 * (c) 2014, Hadriel Kaplan <hadrielk@yahoo.com>
11 * Wireshark - Network traffic analyzer
12 * By Gerald Combs <gerald@wireshark.org>
13 * Copyright 1998 Gerald Combs
15 * SPDX-License-Identifier: GPL-2.0-or-later
22 /* WSLUA_CONTINUE_MODULE Proto */
25 WSLUA_CLASS_DEFINE(Pref
,NOP
); /* A preference of a <<lua_class_Proto,`Proto`>>. */
27 static range_t
* get_range(lua_State
*L
, int idx_r
, int idx_m
);
29 static enum_val_t
* get_enum(lua_State
*L
, int idx
)
32 const char *str1
, *str2
;
33 enum_val_t
*ret
, last
= {NULL
, NULL
, -1};
34 GArray
* es
= g_array_new(true,true,sizeof(enum_val_t
));
36 luaL_checktype(L
, idx
, LUA_TTABLE
);
37 lua_pushnil(L
); /* first key */
39 while (lua_next(L
, idx
)) {
40 enum_val_t e
= {NULL
, NULL
, -1};
42 luaL_checktype(L
, -1, LUA_TTABLE
);
45 if (! lua_isstring(L
,-1)) {
46 luaL_argerror(L
,idx
,"First value of an enum table must be string");
47 g_array_free(es
,true);
50 str1
= lua_tostring(L
, -1);
54 if (! lua_isstring(L
,-1)) {
55 luaL_argerror(L
,idx
,"Second value of an enum table must be string");
56 g_array_free(es
,true);
59 str2
= lua_tostring(L
, -1);
63 if (! lua_isnumber(L
,-1)) {
64 luaL_argerror(L
,idx
,"Third value of an enum table must be an integer");
65 g_array_free(es
,true);
68 seq
= lua_tonumber(L
, -1);
70 e
.name
= g_strdup(str1
);
71 e
.description
= g_strdup(str2
);
72 e
.value
= (uint32_t)seq
;
74 g_array_append_val(es
,e
);
76 lua_pop(L
, 3); /* removes 'value'; keeps 'key' for next iteration */
79 g_array_append_val(es
,last
);
81 ret
= (enum_val_t
*)(void*)g_array_free(es
, false);
86 static int new_pref(lua_State
* L
, pref_type_t type
) {
87 const char* label
= luaL_optstring(L
,1,NULL
);
88 const char* descr
= luaL_optstring(L
,3,"");
90 Pref pref
= g_new0(wslua_pref_t
, 1);
91 pref
->label
= g_strdup(label
);
92 pref
->desc
= g_strdup(descr
);
94 pref
->ref
= LUA_NOREF
;
98 bool def
= wslua_toboolean(L
,2);
103 uint32_t def
= wslua_optint32(L
,2,0);
108 char* def
= g_strdup(luaL_optstring(L
,2,""));
110 * prefs_register_string_preference() assumes that the
111 * variable for the preference points to a static
112 * string that is the initial (default) value of the
113 * preference. It makes a g_strdup()ed copy of that
114 * string, and assigns a pointer to that string to
117 * Our default string is *not* a static string, it's
118 * a g_strdup()ed copy of a string from Lua, so it would
121 * We save it in info.default_s, as well as setting the
122 * initial value of the preference from it, so that we
123 * can free it after prefs_register_string_preference()
126 * (Would that we were programming in a language where
127 * the details of memory management were handled by the
128 * compiler and language support....)
131 pref
->info
.default_s
= def
;
135 uint32_t def
= wslua_optint32(L
,2,0);
136 enum_val_t
*enum_val
= get_enum(L
,4);
137 bool radio
= wslua_toboolean(L
,5);
139 pref
->info
.enum_info
.enumvals
= enum_val
;
140 pref
->info
.enum_info
.radio_buttons
= radio
;
144 range_t
*range
= get_range(L
,2,4);
145 uint32_t max
= wslua_optint32(L
,4,0);
146 pref
->value
.r
= range
;
147 pref
->info
.max_value
= max
;
150 case PREF_STATIC_TEXT
: {
151 /* This is just a static text. */
155 ws_assert_not_reached();
164 WSLUA_CONSTRUCTOR
Pref_bool(lua_State
* L
) {
166 Creates a boolean preference to be added to a <<lua_class_attrib_proto_prefs,`Proto.prefs`>> Lua table.
172 -- create a Boolean preference named "bar" for Foo Protocol
173 -- (assuming Foo doesn't already have a preference named "bar")
174 proto_foo.prefs.bar = Pref.bool( "Bar", true, "Baz and all the rest" )
177 #define WSLUA_ARG_Pref_bool_LABEL 1 /* The Label (text in the right side of the
178 preference input) for this preference. */
179 #define WSLUA_ARG_Pref_bool_DEFAULT 2 /* The default value for this preference. */
180 #define WSLUA_ARG_Pref_bool_DESCRIPTION 3 /* A description of this preference. */
181 return new_pref(L
,PREF_BOOL
);
184 WSLUA_CONSTRUCTOR
Pref_uint(lua_State
* L
) {
185 /* Creates an (unsigned) integer preference to be added to a <<lua_class_attrib_proto_prefs,`Proto.prefs`>> Lua table. */
186 #define WSLUA_ARG_Pref_uint_LABEL 1 /* The Label (text in the right side of the
187 preference input) for this preference. */
188 #define WSLUA_ARG_Pref_uint_DEFAULT 2 /* The default value for this preference. */
189 #define WSLUA_ARG_Pref_uint_DESCRIPTION 3 /* A description of what this preference is. */
190 return new_pref(L
,PREF_UINT
);
193 WSLUA_CONSTRUCTOR
Pref_string(lua_State
* L
) {
194 /* Creates a string preference to be added to a <<lua_class_attrib_proto_prefs,`Proto.prefs`>> Lua table. */
195 #define WSLUA_ARG_Pref_string_LABEL 1 /* The Label (text in the right side of the
196 preference input) for this preference. */
197 #define WSLUA_ARG_Pref_string_DEFAULT 2 /* The default value for this preference. */
198 #define WSLUA_ARG_Pref_string_DESCRIPTION 3 /* A description of what this preference is. */
199 return new_pref(L
,PREF_STRING
);
202 WSLUA_CONSTRUCTOR
Pref_enum(lua_State
* L
) {
204 Creates an enum preference to be added to a <<lua_class_attrib_proto_prefs,`Proto.prefs`>> Lua table.
211 local OUTPUT_DEBUG = 1
212 local OUTPUT_INFO = 2
213 local OUTPUT_WARN = 3
214 local OUTPUT_ERROR = 4
217 { 1, "Off" , OUTPUT_OFF },
218 { 2, "Debug" , OUTPUT_DEBUG },
219 { 3, "Information" , OUTPUT_INFO },
220 { 4, "Warning" , OUTPUT_WARN },
221 { 5, "Error" , OUTPUT_ERROR },
224 -- Create enum preference that shows as Combo Box under
225 -- Foo Protocol's preferences
226 proto_foo.prefs.outputlevel = Pref.enum(
227 "Output Level", -- label
228 OUTPUT_INFO, -- default value
229 "Verbosity of log output", -- description
230 output_tab, -- enum table
231 false -- show as combo box
234 -- Then, we can query the value of the selected preference.
235 -- This line prints "Output Level: 3" assuming the selected
236 -- output level is _INFO.
237 debug( "Output Level: " .. proto_foo.prefs.outputlevel )
240 #define WSLUA_ARG_Pref_enum_LABEL 1 /* The Label (text in the right side of the
241 preference input) for this preference. */
242 #define WSLUA_ARG_Pref_enum_DEFAULT 2 /* The default value for this preference. */
243 #define WSLUA_ARG_Pref_enum_DESCRIPTION 3 /* A description of what this preference is. */
244 #define WSLUA_ARG_Pref_enum_ENUM 4 /* An enum Lua table. */
245 #define WSLUA_ARG_Pref_enum_RADIO 5 /* Radio button (true) or Combobox (false). */
246 return new_pref(L
,PREF_ENUM
);
249 WSLUA_CONSTRUCTOR
Pref_range(lua_State
* L
) {
250 /* Creates a range (numeric text entry) preference to be added to a <<lua_class_attrib_proto_prefs,`Proto.prefs`>> Lua table. */
251 #define WSLUA_ARG_Pref_range_LABEL 1 /* The Label (text in the right side of the preference
252 input) for this preference. */
253 #define WSLUA_ARG_Pref_range_DEFAULT 2 /* The default value for this preference, e.g., "53",
254 "10-30", or "10-30,53,55,100-120". */
255 #define WSLUA_ARG_Pref_range_DESCRIPTION 3 /* A description of what this preference is. */
256 #define WSLUA_ARG_Pref_range_MAX 4 /* The maximum value. */
257 return new_pref(L
,PREF_RANGE
);
260 WSLUA_CONSTRUCTOR
Pref_statictext(lua_State
* L
) {
261 /* Creates a static text string to be added to a <<lua_class_attrib_proto_prefs,`Proto.prefs`>> Lua table. */
262 #define WSLUA_ARG_Pref_statictext_LABEL 1 /* The static text. */
263 #define WSLUA_ARG_Pref_statictext_DESCRIPTION 2 /* The static text description. */
264 return new_pref(L
,PREF_STATIC_TEXT
);
267 static range_t
* get_range(lua_State
*L
, int idx_r
, int idx_m
)
269 static range_t
*ret
= NULL
;
270 const char *pattern
= luaL_checkstring(L
, idx_r
);
272 switch (range_convert_str(wmem_epan_scope(), &ret
, pattern
, wslua_toint32(L
, idx_m
))) {
275 case CVT_SYNTAX_ERROR
:
276 WSLUA_ARG_ERROR(Pref_range
,DEFAULT
,"syntax error in default range");
278 case CVT_NUMBER_TOO_BIG
:
279 WSLUA_ARG_ERROR(Pref_range
,DEFAULT
,"value too large in default range");
282 WSLUA_ARG_ERROR(Pref_range
,DEFAULT
,"unknown error in default range");
289 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
290 static int Pref__gc(lua_State
* L
) {
291 Pref pref
= toPref(L
,1);
293 if (pref
->ref
!= LUA_NOREF
) {
294 // Did the user try to call __gc explicitly while it was registered to a
295 // protocol? Forbid that!
296 luaL_error(L
, "Direct call to __gc is forbidden");
303 switch (pref
->type
) {
306 * Free the initial string value; if it's not NULL, that
307 * means this is a never-registered preference, so the
308 * initial value hasn't been freed.
310 g_free(pref
->info
.default_s
);
314 * Free the enum values allocated in get_enum().
316 const enum_val_t
*enum_valp
= pref
->info
.enum_info
.enumvals
;
317 while (enum_valp
->name
) {
318 g_free((char *)enum_valp
->name
);
319 g_free((char *)enum_valp
->description
);
322 g_free((enum_val_t
*)pref
->info
.enum_info
.enumvals
);
333 WSLUA_METHODS Pref_methods
[] = {
334 WSLUA_CLASS_FNREG(Pref
,bool),
335 WSLUA_CLASS_FNREG(Pref
,uint
),
336 WSLUA_CLASS_FNREG(Pref
,string
),
337 WSLUA_CLASS_FNREG(Pref
,enum),
338 WSLUA_CLASS_FNREG(Pref
,range
),
339 WSLUA_CLASS_FNREG(Pref
,statictext
),
343 WSLUA_META Pref_meta
[] = {
348 WSLUA_REGISTER
Pref_register(lua_State
* L
) {
349 WSLUA_REGISTER_CLASS(Pref
);
353 WSLUA_CLASS_DEFINE(Prefs
,NOP
); /* The table of preferences of a protocol. */
355 WSLUA_METAMETHOD
Prefs__newindex(lua_State
* L
) {
356 /* Creates a new preference. */
357 #define WSLUA_ARG_Prefs__newindex_NAME 2 /* The abbreviation of this preference. */
358 #define WSLUA_ARG_Prefs__newindex_PREF 3 /* A valid but still unassigned Pref object. */
360 Pref prefs_p
= checkPrefs(L
,1);
361 const char* name
= luaL_checkstring(L
,WSLUA_ARG_Prefs__newindex_NAME
);
362 Pref pref
= checkPref(L
,WSLUA_ARG_Prefs__newindex_PREF
);
366 if (! prefs_p
) return 0;
369 WSLUA_ARG_ERROR(Prefs__newindex
,PREF
,"must be a valid Pref");
374 WSLUA_ARG_ERROR(Prefs__newindex
,NAME
,"cannot change existing preference");
379 WSLUA_ARG_ERROR(Prefs__newindex
,PREF
,"cannot be added to more than one protocol");
386 if ( p
->name
&& g_str_equal(p
->name
,name
) ) {
387 luaL_error(L
,"a preference named %s exists already",name
);
391 * Make sure that only lower-case ASCII letters, numbers,
392 * underscores, and dots appear in the preference name.
394 for (c
= name
; *c
!= '\0'; c
++) {
395 if (!g_ascii_islower(*c
) && !g_ascii_isdigit(*c
) && *c
!= '_' && *c
!= '.')
397 luaL_error(L
,"illegal preference name \"%s\", only lower-case ASCII letters, "
398 "numbers, underscores and dots may be used", name
);
404 // Keep a reference to the Pref to ensure it remains valid
405 // until the protocol is deregistered.
406 lua_pushvalue(L
, WSLUA_ARG_Prefs__newindex_PREF
);
407 pref
->ref
= luaL_ref(L
, LUA_REGISTRYINDEX
);
410 pref
->name
= g_strdup(name
);
413 pref
->label
= g_strdup(name
);
415 if (!prefs_p
->proto
->prefs_module
) {
416 prefs_p
->proto
->prefs_module
= prefs_register_protocol(prefs_p
->proto
->hfid
,
417 wslua_prefs_changed
);
422 prefs_register_bool_preference(prefs_p
->proto
->prefs_module
,
429 prefs_register_uint_preference(prefs_p
->proto
->prefs_module
,
437 prefs_register_string_preference(prefs_p
->proto
->prefs_module
,
441 (const char **)(&(pref
->value
.s
)));
443 * We're finished with the initial string value; see
444 * the comment in new_pref().
446 g_free(pref
->info
.default_s
);
447 pref
->info
.default_s
= NULL
;
450 prefs_register_enum_preference(prefs_p
->proto
->prefs_module
,
455 pref
->info
.enum_info
.enumvals
,
456 pref
->info
.enum_info
.radio_buttons
);
459 prefs_register_range_preference(prefs_p
->proto
->prefs_module
,
464 pref
->info
.max_value
);
466 case PREF_STATIC_TEXT
:
467 prefs_register_static_text_preference(prefs_p
->proto
->prefs_module
,
473 WSLUA_ERROR(Prefs__newindex
,"Unknown Pref type");
477 pref
->proto
= p
->proto
;
481 } while (( p
= p
->next
));
483 luaL_error(L
,"this should not happen!");
488 WSLUA_METAMETHOD
Prefs__index(lua_State
* L
) {
490 Get the value of a preference setting.
496 -- print the value of Foo's preference named "bar"
497 debug( "bar = " .. proto_foo.prefs.bar )
500 #define WSLUA_ARG_Prefs__index_NAME 2 /* The abbreviation of this preference. */
502 Pref prefs_p
= checkPrefs(L
,1);
503 const char* name
= luaL_checkstring(L
,WSLUA_ARG_Prefs__index_NAME
);
505 if (! prefs_p
) return 0;
507 if (!prefs_p
->next
) {
508 luaL_error(L
,"No preference is registered yet");
512 prefs_p
= prefs_p
->next
;
515 if ( g_str_equal(prefs_p
->name
,name
) ) {
516 switch (prefs_p
->type
) {
517 case PREF_BOOL
: lua_pushboolean(L
, prefs_p
->value
.b
); break;
518 case PREF_UINT
: lua_pushinteger(L
,(lua_Integer
)prefs_p
->value
.u
); break;
519 case PREF_STRING
: lua_pushstring(L
,prefs_p
->value
.s
); break;
520 case PREF_ENUM
: lua_pushinteger(L
,(lua_Integer
)prefs_p
->value
.e
); break;
523 char *push_str
= range_convert_range(NULL
, prefs_p
->value
.r
);
524 lua_pushstring(L
, push_str
);
525 wmem_free(NULL
, push_str
);
528 default: WSLUA_ERROR(Prefs__index
,"Unknown Pref type"); return 0;
530 WSLUA_RETURN(1); /* The current value of the preference. */
532 } while (( prefs_p
= prefs_p
->next
));
534 WSLUA_ARG_ERROR(Prefs__index
,NAME
,"no preference named like this");
538 /* Gets registered as metamethod automatically by WSLUA_REGISTER_CLASS/META */
539 static int Prefs__gc(lua_State
* L _U_
) {
540 /* do NOT free Prefs, it's a static part of Proto */
544 WSLUA_META Prefs_meta
[] = {
545 WSLUA_CLASS_MTREG(Prefs
,newindex
),
546 WSLUA_CLASS_MTREG(Prefs
,index
),
550 WSLUA_REGISTER
Prefs_register(lua_State
* L
) {
551 WSLUA_REGISTER_META(Prefs
);
557 * Editor modelines - https://www.wireshark.org/tools/modelines.html
562 * indent-tabs-mode: nil
565 * vi: set shiftwidth=4 tabstop=8 expandtab:
566 * :indentSize=4:tabSize=8:noTabs=true: