Specifications
CHAPTER 5. IMPLEMENTATION 35
The do {...} while(0) loop is run once and encapsulates the invocation of log setup()
and log output(). Without this encapsulation, errors could occur if the macro is used
in conjunction with an if-else construct. The function log setup() stores the values of
the function arguments to variables used by the subsequently called function, log output().
The preprocessor can not dissolve FUNCTION since it is not a macro. The function name
FUNCTION is therefore dissolved at compilation time. The function log output() first
checks whether the priority of the issued log entry is less than or equal to priority. In case
of using the macro INFO(expr ) a log entry is reported if priority equals LOGPRIO INFO or
LOGPRIO DEBUG. It is not reported in case of priority being set to either LOGPRIO WARNING or
LOGPRIO ERROR. The advantage of the logging system gets more obvious when looking at the
corresponding log entry for the log request INFO(("Initialization successful.")). The
log entry is:
Info: iald.c:397 main(): Initialization successful.
The single line of code—INFO(("Initialization successful."))—results in a mean-
ingful log entry. The log entry provides information about the source file, the line number and
the function name of the original log request. The logging system assists the development of
the Input Abstraction Layer in two ways: on the one hand, log requests are brief commands
which automatically get enriched with additional information about the context. On the other
hand, the logging priority gives a flexible control about which log entries should be reported
and which should be suppressed.
5.3 Modules
The Input Abstraction Layer’s modules are performing the actual abstraction of the input
events. Each module is responsible for one kernel input event interface. Thus, the module
knows how the interface is accessed and how its input events are translated to abstract input
events (IalEvent). All modules have to comply with the following requirements:
– Define an array of ModuleOption
– Define a structure of type ModuleData
– Define a function mod get data()
The ModuleData structure defines all information needed by the daemon to load the module
at run time: it contains module specific information and a pointer to the array of the module
options (ModuleOption). The daemon invokes the module’s function mod get data() to access
the ModuleData. It is required that the function mod get data() returns a pointer to the
ModuleData structure. This pointer enables the daemon to access all relevant data structures
of the module.
All modules are implemented as dynamically loaded shared libraries. The daemon provides
a module loader which implements all necessary functions to handle the modules at run time
(§5.4).