[sane-devel] Proposal to change function signatures of a couple of sanei_usb_* functions

Povilas Kanapickas povilas at radix.lt
Tue Aug 9 18:07:16 BST 2022


On 2022-08-06 21:55, Ralph Little wrote:
> Hi,
> On 2022-08-06 10:35, Thierry Huchard wrote:
>> Le 6 août 2022 18:17:12 GMT+02:00, Ralph Little <skelband at gmail.com> a
>> écrit :
>>> Hi,
>>> I'm having a go at writing my first SANE backend for a learning
>>> exercise.
>>> I notice that a few backends that use the functions:
>>> sanei_usb_attach_matching_devices() and sanei_usb_find_devices()
>>> require some context information in the callback function to complete
>>> the find function.
>>> This is typically because the backend is looping through a list of
>>> known device configurations and calling the sanei_* function on each
>>> one: the callback needs to know the element in that loop to complete
>>> the attach function in the callback.
>>> This is typically achieved with setting some global variables to be
>>> picked up by the callback function, or searching again through the
>>> original loop using information gleaned from the devicename (such as
>>> vendor and product), both of which are messy and ugly hacks.
>>> I propose that we change the function signature of the functions and
>>> the callback to include a (void *) context pointer:
>>> SANE_Status
>>> sanei_usb_find_devices (SANE_Int vendor, SANE_Int product, void
>>> *context,
>>>              SANE_Status (*attach) (SANE_String_Const dev, void
>>> *context));
>>> void
>>> sanei_usb_attach_matching_devices (const char *name, void *context,
>>>                     SANE_Status (*attach) (const char *dev, void
>>> *context));
>> Hi Ralph,
>> Your change may impact proprietary backends (Brother, Canon, ...).
>> Thierry
> That is a good point.
> We could introduce additional functions with the above signatures (e.g.
> sanei_usb_find_devices2()) but I feel that to be an unsatisfactory
> solution.
> Any other suggestions/comments welcome.

I think introducing a new function is the only clean solution in this
case. Essentially, we want to pass new information. Currently it's done
via global variables, so it's not really passing. In new functions you
need to pass the data explicitly. Any other way without new arguments is
just a different solution of having a global variable.

Introducing new functions is not that bad though. You could implement
the old functions in terms of new ones(*) and as a result the
duplication is limited to just few lines.


* - Have a new format callback that receives the old format callback as
context and then calls it. Then the old format function can call be
implemented by calling the new format function.

More information about the sane-devel mailing list