On Tue, Apr 16, 2002 at 09:21:35PM -0400, packet steve wrote:
> I need to allow a protocol to be called from multiple, but varying, UDP
> ports.
> The obvious technique
> prefs_register_uint_preference(my_module, "udp.port", " UDP Port#1",
> ... 10, &global_my_udp_port1)
> prefs_register_uint_preference(my_module, "udp.port", " UDP Port#2",
> ... 10, &global_my_udp_port2)
>
> doesn't seem to work:
>
> ** ERROR **: file prefs.c: line 274 (register_preference): assertion failed:
> (find_preference(module, name) == NULL)
> aborting...
>
> Am I trying to do something unreasonable?
Well, to some extent, yes, you are - it is unreasonable to register two
different preferences with the *same* name, which is why Ethereal
explicitly checks for that and aborts; people have supplied code to do
that in the past, and there's somewhat gross code that attempts to work
around that so that old bogus preference files can be read and dealt
with not *too* painfully.
The reason why this is unreasonable is that there's no way for Ethereal
or Tethereal to know to which of those two options "foo.udp.port", as
used in a "-o" command-line option or in a preferences file, refers.
For example, if the preference file had
foo.udp.port: 666
foo.udp.port: 777
it'd probably set "global_my_udp_port1" to 666 and then to 777 as it's
reading the file (as I think that'd be the first "udp.port" it found
when searching the list of preferences for "foo"; if not, it'd set
"global_my_udp_port2", instead), and not set "global_my_udp_port2" at
all.
It is not unreasonable to have multiple ports, but it *is* unreasonable
to implement them in the fashion you show above.
An alternative would be to add a new type of preference, which would be
a "list of integers" preference. You might have
void prefs_register_uint_list_preference(module_t *module, const
char *name, const char *title, const char *description,
guint base, guint *var_nvalues, guint **values);
which would take, as its last two arguments, a pointer to a "guint"
variable in which the number of integers would be stored, and a pointer
to a "guint *" in which a pointer to the first element of an array of
unsigned integers would be stored.
The list would be represented, in text form, as a comma-separated list,
so that's what you'd put in the preferences dialog box, in the
preferences file, or in a "-o" option.
> I could work around a
> limitation by having multiple preference panels. This seems ugly.
Presumably by "multiple preference panels" you mean "multiple preference
items", as in
prefs_register_uint_preference(my_module, "udp.port1", " UDP Port#1",
... 10, &global_my_udp_port1)
prefs_register_uint_preference(my_module, "udp.port2", " UDP Port#2",
... 10, &global_my_udp_port2)
so that the preference dialog would have
UDP Port#1: [ ]
UDP Port#2: [ ]
I.e., there would be only one pane for the protocol, not multiple panes,
but there'd be two text fields.
If so, what was the GUI you would have expected from
prefs_register_uint_preference(my_module, "udp.port", " UDP Port#1",
... 10, &global_my_udp_port1)
prefs_register_uint_preference(my_module, "udp.port", " UDP Port#2",
... 10, &global_my_udp_port2)
How would the user have modified both ports from the pane for your
protocol? There'd have to have been more than one text field, but
that'd look the same.