| 
									
										
										
										
											2003-09-30 14:03:30 +00:00
										 |  |  | 2003-09-30 | 
					
						
							| 
									
										
										
										
											2003-09-30 13:51:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Here are a few rules and tips that should help writing a | 
					
						
							|  |  |  | SANE-conforming backend and including it into the SANE package: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | GETTING STARTED | 
					
						
							|  |  |  | --------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * You will need information about the protocol the scanner (or other image | 
					
						
							|  |  |  |   application device) is using. The easiest way is to ask the manufacturer | 
					
						
							|  |  |  |   about it. You should mention that the code will be open-source, however. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * Read the SANE standard. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * One approach is to write a stand-alone scanning program first. Debugging | 
					
						
							|  |  |  |   this program is usually easier than using the SANE libraries. However, keep | 
					
						
							|  |  |  |   in mind what you learned from the SANE standard. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * Once your program works basically, insert its functions into a basically | 
					
						
							|  |  |  |   empty SANE backend. You can get one by removing everything but the SANE | 
					
						
							|  |  |  |   includes and SANE API function definitions from an existing backend (e.g. | 
					
						
							|  |  |  |   test.c). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * If you have any information about the scanner you want to support that | 
					
						
							|  |  |  |   is not already mentioned in one of the .desc files, please contact the | 
					
						
							|  |  |  |   sane-devel mailing list. Especially if you have written code (e.g. a test | 
					
						
							|  |  |  |   program) or started writing a backend, contact us. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * Keep other users informed about what you did and want to do. This way no | 
					
						
							|  |  |  |   work is done twice and you may get volunteers for coding or testing. | 
					
						
							|  |  |  |   Set up a website or at least write to sane-devel. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * When you have a working backend but you don't want to have it included | 
					
						
							|  |  |  |   in the SANE distribution yet, at least the .desc file can be included | 
					
						
							|  |  |  |   (see below for details). So people will find a link to your backend at | 
					
						
							|  |  |  |   the SANE webpage. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PROGRAMMING | 
					
						
							|  |  |  | ----------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * Please follow the GNU coding standards.  It's clear that the style | 
					
						
							|  |  |  |   outlined there is nobody's favorite, but it's much easier to | 
					
						
							|  |  |  |   maintain SANE if everybody follows more or less the same coding | 
					
						
							|  |  |  |   style.  It also looks more professional.  The GNU standards can be | 
					
						
							|  |  |  |   found at: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	http://www.gnu.org/prep/standards_toc.html | 
					
						
							|  |  |  | 	ftp://ftp.gnu.org/pub/gnu/standards/standards.text | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Note that GNU emacs supports automatic indentation according to this | 
					
						
							|  |  |  |   standard.  The command "indent -gnu" can be used to reformat | 
					
						
							|  |  |  |   existing sources according to this standard. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * Please be courteous to programmer's with terminals that are 80 | 
					
						
							|  |  |  |   characters wide.  It's not difficult to avoid long lines, so please | 
					
						
							|  |  |  |   do so.  Note that in ANSI C you can split long strings into pieces | 
					
						
							|  |  |  |   separated by white space.  For example, | 
					
						
							|  |  |  |   "this is an awfully long string" can be written as "this is an " | 
					
						
							|  |  |  |   "awfully long string". | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * Use only ANSI C for your backend. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * Please do not depend on compiler specific features or, if you do, make | 
					
						
							|  |  |  |   the dependency conditional so other compilers will still be able to | 
					
						
							|  |  |  |   compile the files.  In particular: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     - do not use C++ style comments (//-line comments) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     - do not declare dynamically sized automatic arrays; instead, | 
					
						
							|  |  |  |       use alloca() after including "../include/lalloca.h".  For example: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		void | 
					
						
							|  |  |  | 		func (int n) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 		  char buf[n]; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       should be re-written as: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		#ifdef _AIX | 
					
						
							|  |  |  | 		# include "../include/lalloca.h" /* MUST come first for AIX! */ | 
					
						
							|  |  |  | 		#endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		#include "../include/sane/config.h" | 
					
						
							|  |  |  | 		#include "../include/lalloca.h" | 
					
						
							|  |  |  | 			: | 
					
						
							|  |  |  | 		void | 
					
						
							|  |  |  | 		func (int n) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 		  char *buf = alloca (n); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  |     - Don't use any #pragma directives---they're completely | 
					
						
							|  |  |  |       compiler-dependent. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * If you use headers or libraries that may not be available on all systems, | 
					
						
							|  |  |  |   write a check for configure.in and include it conditionally. If your backend | 
					
						
							|  |  |  |   depends on these libraries or headers, compile the backend only if they are  | 
					
						
							|  |  |  |   available (see pint for an example). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * Use #include ".../include/sane/..." to include the sane header files | 
					
						
							|  |  |  |   instead of #include <sane/...>. Otherwise problems with different installed | 
					
						
							|  |  |  |   SANE versions may occur. Also this makes clear that the local files are used. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * Don't forget to #include ".../include/sane/config.h" in your backend before | 
					
						
							|  |  |  |   any other includes. If you use lalloca.h see above for the correct | 
					
						
							|  |  |  |   includes. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * Include sanei_backend.h after the other includes. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * It's no longer necessary to #define PATH_MAX (now in sanei_backend.h). | 
					
						
							|  |  |  |   If you define it, do so *after* the system includes. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * Please use sanei functions whenever possible (e.g.  | 
					
						
							|  |  |  |   sanei_config_read()). This makes porting to other os/platforms much | 
					
						
							|  |  |  |   easier. Most of these functions are documented in their respective  | 
					
						
							| 
									
										
										
										
											2003-09-30 14:03:30 +00:00
										 |  |  |   header files in include/sane/sanei_*.h. For most of them there is also | 
					
						
							|  |  |  |   documentation in doxygen format: http://www.sane-project.org/sanei/. These | 
					
						
							| 
									
										
										
										
											2003-09-30 13:51:25 +00:00
										 |  |  |   HTML pages can be generated by calling "doxygen sanei-doxygen.conf" in | 
					
						
							|  |  |  |   the doc/ directory. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * Initialize global variables explicitly in sane_init. Keep in mind that | 
					
						
							|  |  |  |   sane_init can be called more than once (if sane_exit is called everytime | 
					
						
							|  |  |  |   after sane_init). Therefore don't depend on automatic initialization to | 
					
						
							|  |  |  |   0 / NULL. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * Do make sure that your code is byte-order independent.  This is | 
					
						
							|  |  |  |   particularly important for networking-related code and when dealing | 
					
						
							|  |  |  |   with non-textual data files. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * Don't use printf, fprintf or perror to output debug or error messages. | 
					
						
							|  |  |  |   Use the DBG macro instead. If your backend can't detect a scanner for | 
					
						
							|  |  |  |   whatever reason it shouldn't output anything as long as | 
					
						
							|  |  |  |   SANE_DEBUG_BACKENDNAME isn't set. So don't use DBG(0, ...) in this case. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * Please do not assume that `size_t' is `unsigned int'.  On some | 
					
						
							|  |  |  |   systems, it's `unsigned long' and the size of this type may be | 
					
						
							|  |  |  |   bigger than that of an int (this is true for practically any of the | 
					
						
							|  |  |  |   64-bit systems).  To print a variable of type size_t portably, cast | 
					
						
							|  |  |  |   the variable to u_long and print it with the %lu specifier.  E.g.: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	size_t len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	DBG(3, "len=%lu\n", (u_long) len); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * Please do not assume that `void *' has the same size as `int'.  On some | 
					
						
							|  |  |  |   systems, it's `long' and the size of this type may be bigger than that of | 
					
						
							|  |  |  |   an int (this is true for practically any of the 64-bit systems). Where this | 
					
						
							|  |  |  |   comes up is with opaque handles. For example: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   int OpaqueHandle; | 
					
						
							|  |  |  |   MyScanner *s = (MyScanner *)OpaqueHandle; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   will FAIL on most 64 bit systems. Please use `void *' or better | 
					
						
							|  |  |  |   `SANE_Handle'. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * Don't use exit() in your backend. You will exit the whole program, not only | 
					
						
							|  |  |  |   your backend. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * If you use wait() or waitpid() in your backend, check its return value. This | 
					
						
							|  |  |  |   is important, if the status value is checked for e.g. WIFEXITED after the | 
					
						
							|  |  |  |   call of wait() or waitpid(). Both functions may fail if the frontend already | 
					
						
							|  |  |  |   did a wait for the children. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * Please try to avoid compilation warnings. At least with "--disable-warnings" | 
					
						
							|  |  |  |   there shouldn't be warnings when compiling backends. It's not necessary to | 
					
						
							|  |  |  |   fix every "unused parameter" warning but take care that no warnings pointing | 
					
						
							|  |  |  |   to really existing problems or ambiguities are missed. Some programming | 
					
						
							|  |  |  |   techniques generating warnings on gcc may lead to errors on other systems. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * To support translation of SANE options, please mark the descriptions (desc) | 
					
						
							|  |  |  |   and title of options with SANE_I18N(). See po/README for details. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * Please check for TL_X < BR_X and TL_Y < BR_Y to avoid segfaults or even | 
					
						
							|  |  |  |   scanner damage. This should NOT be done in sane_control_option, it should | 
					
						
							|  |  |  |   be possible to temporary set TL_X > BR_X or TL_ > BR, otherwise it is hard | 
					
						
							|  |  |  |   for a frontend to set the correct values. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TESTING | 
					
						
							|  |  |  | ------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * Please test a backend with "scanimage -T" (plus other options, | 
					
						
							|  |  |  |   as appropriate/necessary) as this will make sure that sane_read() | 
					
						
							|  |  |  |   always returns the correct amount of data etc. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * You can also test a backend with tstbackend. tstbackend is not | 
					
						
							|  |  |  |   compiled nor installed by default. To do that, cd into frontend and | 
					
						
							|  |  |  |   edit the Makefile. Add "tstbackend" to BINPROGS. "tstbackend --help" | 
					
						
							|  |  |  |   gives a short help. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * Please test a backend not just with scanimage and xscanimage  | 
					
						
							|  |  |  |   (+ other frontends), but also with saned.  Based on past experience, | 
					
						
							|  |  |  |   it is often the case that remote scanning can uncover subtle bugs. | 
					
						
							|  |  |  |   Note that you don't  have to use two different machines to test "remote" | 
					
						
							|  |  |  |   scanning---you can use one and the same machine to test a backend via saned | 
					
						
							|  |  |  |   (just be sure to enable the "net" backend in dll.conf and follow the | 
					
						
							|  |  |  |   steps described in saned(1)). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * Please test on every available platform/os. Even if no scanner is attached | 
					
						
							|  |  |  |   to this system, test compilation and running scanimage. If you don't have | 
					
						
							|  |  |  |   access to other platforms, ask sane-devel. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * Please make sure that all global symbols exported from a SANE backend start | 
					
						
							|  |  |  |   with the prefix "sane" or "sanei" to avoid clashes with exported symbols  | 
					
						
							|  |  |  |   of other backends. Make sure, the sanei_* symbols are unique, e.g. by using | 
					
						
							|  |  |  |   sanei_backendname_*.  Only export symbols that are absolutely necessary. | 
					
						
							|  |  |  |   You can verify this by running GNU "nm" on the static library.  For example: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	nm -g  backend/.libs/libsane-hp.a | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   would list all global symbols in the HP backend.  | 
					
						
							|  |  |  |   "./configure --disable-shared; make; make libcheck" in the sane-backends | 
					
						
							|  |  |  |   root directory will name all backend libraries, that contain "illegal" | 
					
						
							|  |  |  |   symbols. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DOCUMENTATION | 
					
						
							|  |  |  | ------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * Even if you haven't written a man-page for your backend yet, you *must* | 
					
						
							|  |  |  |   create a .desc file which describes it. Anytime you submit source code for | 
					
						
							|  |  |  |   your backend, you should include an update to the .desc file which reflects | 
					
						
							|  |  |  |   the new state of the backend. The .desc files are used to create the HTML | 
					
						
							|  |  |  |   lists of supported devices. These lists are updated automatically when you | 
					
						
							|  |  |  |   change a .desc file in CVS. See e.g. | 
					
						
							|  |  |  |   http://www.sane-project.org/lists/sane-mfgs-cvs.html for the results. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * The .desc files are located in the directories "doc/descriptions" and | 
					
						
							|  |  |  |   "doc/descriptions-external" (for included and external backends). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * "doc/descriptions.txt" describes the format of the ".desc" files. There is | 
					
						
							|  |  |  |   also a template for new .desc files: "template.desc.". The format of the | 
					
						
							|  |  |  |   files in the two directories is very similar.  If you'd like to try parsing | 
					
						
							|  |  |  |   your creation to recreate the sane-backends webpages, cd into "tools/" and | 
					
						
							|  |  |  |   enter "make sane-desc". You can either use sane-desc directly (try  | 
					
						
							|  |  |  |   "./sane-desc -h") or use "make html-pages" in "doc/".  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * For external backends, you don't need to supply :manpage and :version. The | 
					
						
							|  |  |  |   manpage link won't work anyway and version will be outdated soon. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * When your backend is included in the SANE distribution, add an entry to | 
					
						
							|  |  |  |   doc/sane.man, AUTHORS and sane-backends.lsm. The sane.man entry should point | 
					
						
							|  |  |  |   to your documentation (man-page, website, readme).  Also move your .desc | 
					
						
							|  |  |  |   file from "doc/descriptions-external" to "doc/descriptions" and update | 
					
						
							|  |  |  |   them. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * In your manual page (backend.man), use @LIBDIR@ and the other macros for | 
					
						
							|  |  |  |   path names to the libraries, config files and documentation. Don't use fixed | 
					
						
							|  |  |  |   paths as they will be wrong if SANE is installed with a different prefix | 
					
						
							|  |  |  |   (e.g. /usr instead of /usr/local). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * If you want to include READMEs, HTML files or other documentation, please | 
					
						
							|  |  |  |   create your own directory (doc/backendname) and store your files in this | 
					
						
							|  |  |  |   directory. If you only have a manual page a subdirectory isn't necessary. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * Please keep your manpages and .desc files up-to-date especially regarding | 
					
						
							|  |  |  |   version numbers. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CHECKLIST: SUBMITTING A NEW BACKEND  | 
					
						
							|  |  |  | ----------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | In sane-backends/ | 
					
						
							|  |  |  | * Add the author(s) name(s) to AUTHORS | 
					
						
							|  |  |  | * Correct any related entries in the bug-tracking system | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | In sane-backends/backend/ | 
					
						
							|  |  |  | * Use the command "indent -gnu" to reformat your code according to the | 
					
						
							|  |  |  |   standard. | 
					
						
							|  |  |  | * Add the backend name to dll.conf | 
					
						
							|  |  |  | * Check that the SANE license is in the backend source files. | 
					
						
							|  |  |  | * Add the source file names and the .conf file | 
					
						
							|  |  |  |   to DISTFILES in Makefile.in | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | In sane-backends/doc/ | 
					
						
							|  |  |  | * Add an entry for the man page in sane.man | 
					
						
							|  |  |  | * Add the man page file in doc/Makefile.in | 
					
						
							|  |  |  | * Move the description file from descriptions-external/ to doc/descriptions/ | 
					
						
							|  |  |  | * Check that the description file is correct: "cd doc; make html-pages" and check the html pages result with a browser. | 
					
						
							|  |  |  | * Check that the backend version is the same in the source and in the | 
					
						
							|  |  |  |   description file. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | INCLUDING INTO CVS | 
					
						
							|  |  |  | ------------------ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * If you want to include your backend into CVS use the latest CVS to make | 
					
						
							|  |  |  |   patches. Check the mailing list and the bug-tracking system for information | 
					
						
							|  |  |  |   about bugs to avoid. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * If your backend isn't included yet in the SANE CVS tree, write an email to | 
					
						
							|  |  |  |   the SANE mailing list (sane-devel) and ask for inclusion. Usually one | 
					
						
							|  |  |  |   of the developers will check the backend for common mistakes and test | 
					
						
							|  |  |  |   compilation. If everything is ok the backend will be added to the CVS tree. |