For the special case of a library, some of the design goals for software are particularly important. These are:
Since re-use is the very reason for existence of a library, some principles of re-use will be given in the next section, and how the spectral envelope library fulfills these.
After [Utt93], software is reusable if:
An automated testing mechanism has been adopted for the development of the spectral envelope library which will be outlined in this section:
All the functions of the library are also accessible from command-line programs. These programs can be run from a test script, defining a number of test cases with their input data and program parameters. The generated output data will be automatically compared to stored reference data, which has been checked manually for validity. The test cases and the reference data are of course under version control.
It has to be taken care that the test cases cover all possible control paths in the program, especially the ``unexpected'' cases of error handling code and the like.
Although it is rather a question of implementation, some thoughts will be given to the error handling in a library in general, after which the mechanism adopted in the spectral envelope library will be explained.
Error handling in a function library is always a difficult point. Ideally, all errors will be detected and handled in the library, if possible. If not, they will be passed to the calling program. In any case, a library must never call the system functions exit() or abort() and thus stop the process if any unexpected situation occurs, because it is up to the caller to decide what to do in such cases, not up to the library. Who knows, maybe the calling program has a method to handle the error and can recover from it. What's more, detecting the cause of an error is made more difficult, when suddenly the program stops in some low level library function, without knowing when and by whom it was called. (Example: Compare the usefulness of the error message ``error reading 4 bytes'' with ``error reading file header''.)
In an environment without exception handling such as ANSI-C, however, this behaviour of passing on error conditions requires some discipline on the side of the user of the library. It is mandatory that all return codes of library functions are checked for their status, since there may have been an error after which the program can not continue.
In the spectral envelope library, the error behaviour is controlled by the function seSetErrorBehaviour which can take a member of the enumeration type seErrorBehaviour as parameter. If the bit seEbAbort is set in the parameter, the library aborts (and core dumps) on any error8.2. If the seEbPrint is set, an error message is printed on the console (standard error). If the seEbLog is set, a detailed error message is also written to a log file. Various predefined combinations of the error behaviour flags exist: seEbFull, the default, has all three flags set; seEbNorm is the normal behaviour for well-behaved programs, and means: continue on error, but print and log the error message (seEbLog | seEbPrint).