[sane-devel] Sane API

Johannes Meixner jsmeix at suse.de
Mon Oct 19 13:41:32 BST 2020


On 2020-10-14 13:12, Olaf Meeuwissen wrote:
> Assuming for simplicity's sake that the backward compatibility breaking
> version is SANE 2 and what we use now is SANE 1, breaking backward
> compatibility means that
>  - SANE 1 frontends will continue to work with SANE 1 backends
>  - SANE 1 frontends will not work with SANE 2 backends
>  - SANE 2 frontends will work with SANE 2 backends
>  - SANE 2 frontends will not work with SANE 1 backends

I fear such a hard incompatible disruptive move forward might even
basically "kill" the SANE project in practice "out there".
I mean that it might annoy so many users in practice "out there"
that in the end "SANE doesn't work" might become a commonplace.

To avoid that I think it is mandatory in practice that SANE 1 frontends
will continue to work as they did all the time so that for the users
there is no noticeable disruption in how things work for them.

This means all SANE 1 things must still be there in SANE 2
so that SANE 2 is a strict superset of SANE 1.

I am not a SANE backends developer so I could be plain wrong
with my following proposal:

As far as I know each backend has to implement the whole SANE API
so there are as many SANE API implementations as there are backends.

I think what is described in section "4.1 Version Control" at
therein in particular the part
  "A frontend may implement backwards compatibility by allowing
   major numbers that are smaller than the expected major number
   (provided the frontend really can cope with the older version).
   In contrast, a backend always provides support for one
   and only one version of the standard."
and therin in particular the last sentence points to the root
of the problems with how to move forward with SANE.

I think it must be allowed that both frontends and backends
support more than one version of the SANE API.

To implement e.g. two versions of the SANE API in one backend
the names of operations (functions) and data types must be different.

So just as offhanded example there might be two initialization functions

SANE_Status sane_init (SANE_Int * version_code,
                        SANE_Authorization_Callback authorize);

plus additionally a new one

SANE2_Status sane2_init (SANE_Int * version_code,
                          SANE2_Authorization_Callback authorize);

where SANE2_Authorization_Callback could be an enhanced version of
SANE_Authorization_Callback (e.g. to support some new kind of 
and sane2_init results an enhanced status as SANE2_Status
(but it can still use SANE_Int when that is still sufficient).

A SANE 1 frontend will not call sane2_init but sane_init that is still 

A SANE 2 frontend can call sane2_init but it can also call sane_init as 
because that is still there.

All SANE 1 backends would have to implement at least a dummy stub of 
so that the function is there in each backend and the linker can link
a SANE 2 frontend with all SANE 1 backends.

A dummy stub of sane2_init would have to notify its SANE 2 frontend 
via the enhanced SANE2_Status that the sane2_init functionality is not
actually implemented so that the SANE 2 frontend can automatically
call sane_init as fallback.

In this example only the sane_init function was enhanced as new 
sane2_init function together with its needed new additional data types
but nothing else was changed.

So I think this way it is possible to move forward step by step as 
for each particular kind of functionality and there is no longer the 
to either jump the whole API forward or to not move at all.

When this works there is lo longer a strict separation of different
SANE API versions - in contrast there is only one single SANE API
that moves forward step by step as needed.

When after a longer time there is no longer the need for old sane_* 
because all is implemented as new sane[234...] functions and there are
no longer old SANE 1 frontends in use "in practice out there in real 
the old sane_* functions can be declared deprecated and their prototypes
get removed from the sane.h header file to make compiling of old 
software fail
that needs old sane_* functions to denote developers (developers don't
read deprecation announcements - you must let compilation fail because
"when it compiles it proves all is OK" ;-)

I made this proposal based on what I noitced how the CUPS library moved 
step by step as needed in the past without noticeable breakage of 
compatibility, cf. the "someFunction" versus "someFunction2" names in

I am not a SANE backends developer so I could be plain wrong.

Kind Regards
Johannes Meixner
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5 - 90409 Nuernberg - Germany
(HRB 36809, AG Nuernberg) GF: Felix Imendoerffer

More information about the sane-devel mailing list