Rafael Laboissiere
2003-02-04 13:48:02 UTC
Preamble
========
The big recent cvs commit regarding the dyndrivers database was on the top
of my TODO list. It is a necessary step towards clean
configuration/building and also packaging for Debian.
I am not yet completely happy with my implementation, but my changes
(apparently) did not break PLplot. My simple test script succeeded, at
least. I am committing without previous discussion here because, as Alan
uses to say, getting novelties in cvs HEAD is the best way to foster
discussions.
The Problem
===========
The way PLplot used to get information about the available devices provided
by the dyndrivers was through the DATA_DIR/drivers.db file. This file was
generated at configuration time and parsed when the library was initialized.
This approach has two drawbacks:
1) Information about the devices are scattered in different places (namely
in the driver source file and in configure.ac). This is ugly and may
result in unnecessary maintenance burden.
2) Since the list of available devices is hardcoded in the drivers.db it is
almost impossible to do clean packaging of Plplot. In Debian, for
instance, packaging is granular in order to reduce the dependencies:
plplot-xwin, plplot-tk, plplot-gd, etc. Users can install a subset of
the available packages at will. However, they will always get the full
list of available devices when plinit is called. That is not a critical
problem, but annoying.
The Solution
============
I have elaborated a full fix for this problem, but I just committed an
intermediary solution for it. Here is how it works:
1) drivers.db does not exist anymore.
2) In each driver file, there is a global declaration like this:
char* DEVICE_INFO_gd = "jpeg:JPEG file:0:gd:40:jpeg\n"
"png:PNG file:0:gd:39:png";
containing the entries that used to go into drivers.db. If a driver
provides more than one device, their entries must be separated by a
newline character ('\n').
3) When the library is initialized, if dyndrivers are enabled, the drivers
directory is scanned for the *.la files. Each found driver is dlopened
and the DEVICE_INFO_<driver> symbol is read and put in a temporary file.
4) This temporary file plays the role of the old drivers.db file.
Noticed that I did minimal changes to Geoff's code in plcore.c. In the
plInitDispatchTable function, I replaced the initial code (where the
drivers.db were scanned) by the scanning of the drivers directory described
in point 3 above.
Also, all references to drivers.db and DRIVERS_DB have disappeared from the
sources.
Drawbacks and improvements
==========================
I see two potential problems with my approach:
1) Portability. I am using new libc functions (POSIX tmpfile, opendir,
readdir and closedir). Although am I following the recommended procedure
found in the Autoconf docs (i.e. using AC_HEADER_DIRENT and a couple of
tests with HAVE_DIRENT_H), I am sure that there will be some weird system
out there (MacIntosh, say) for which my code won't compile. If that
happens, we have to port that part of the code.
2) With my approach, I have to open all and every module before using them.
This may appear as a regression as regards the "cache file" approach
provided by the use of drivers.db. In terms of performance, with our
current computer power, the overload is negligible. However, as I wrote
above, my original design was much better, but harder to implement (of
course). It looks like this:
a) Forget about that entries a la drivers.db.
b) In each driver file <driver>.c define symbols DEV_DESC_*, DEV_SEQ_*,
DEV_TAG_*, etc. These symbols can be used when filling fields in
function plD_dispatch_init_<device>. This would further reduce the
maintenance problem due to duplication of information.
c) At build time (not configuration time), a small C program dlopen the
<driver>.c files, get the symbols described above and write the
associated device entries in <driver>.rc (or whichever name).
d) Those <driver>.rc are installed in the drivers directory, along with
the <driver>.la and <driver>.so files.
e) When PLplot is initialized, the <driver>.rc files are scanned.
If I have some time before the 5.2.1 release, I will try to implement
this idea.
Postscript
==========
In doing my changes, I noticed that the following drivers have never had
entries in drivers.db: plbuf.c and next.c. Does anyone know why?
I introduced the DEVICE_INFO_<driver> symbol in all drivers listed in
variable EXTRA_LTLIBRARIES of drivers/Makefile.am. I also noticed that the
pstex entry was wrongly written in drivers.db. Apparently, this bug have
never bothered our users...
========
The big recent cvs commit regarding the dyndrivers database was on the top
of my TODO list. It is a necessary step towards clean
configuration/building and also packaging for Debian.
I am not yet completely happy with my implementation, but my changes
(apparently) did not break PLplot. My simple test script succeeded, at
least. I am committing without previous discussion here because, as Alan
uses to say, getting novelties in cvs HEAD is the best way to foster
discussions.
The Problem
===========
The way PLplot used to get information about the available devices provided
by the dyndrivers was through the DATA_DIR/drivers.db file. This file was
generated at configuration time and parsed when the library was initialized.
This approach has two drawbacks:
1) Information about the devices are scattered in different places (namely
in the driver source file and in configure.ac). This is ugly and may
result in unnecessary maintenance burden.
2) Since the list of available devices is hardcoded in the drivers.db it is
almost impossible to do clean packaging of Plplot. In Debian, for
instance, packaging is granular in order to reduce the dependencies:
plplot-xwin, plplot-tk, plplot-gd, etc. Users can install a subset of
the available packages at will. However, they will always get the full
list of available devices when plinit is called. That is not a critical
problem, but annoying.
The Solution
============
I have elaborated a full fix for this problem, but I just committed an
intermediary solution for it. Here is how it works:
1) drivers.db does not exist anymore.
2) In each driver file, there is a global declaration like this:
char* DEVICE_INFO_gd = "jpeg:JPEG file:0:gd:40:jpeg\n"
"png:PNG file:0:gd:39:png";
containing the entries that used to go into drivers.db. If a driver
provides more than one device, their entries must be separated by a
newline character ('\n').
3) When the library is initialized, if dyndrivers are enabled, the drivers
directory is scanned for the *.la files. Each found driver is dlopened
and the DEVICE_INFO_<driver> symbol is read and put in a temporary file.
4) This temporary file plays the role of the old drivers.db file.
Noticed that I did minimal changes to Geoff's code in plcore.c. In the
plInitDispatchTable function, I replaced the initial code (where the
drivers.db were scanned) by the scanning of the drivers directory described
in point 3 above.
Also, all references to drivers.db and DRIVERS_DB have disappeared from the
sources.
Drawbacks and improvements
==========================
I see two potential problems with my approach:
1) Portability. I am using new libc functions (POSIX tmpfile, opendir,
readdir and closedir). Although am I following the recommended procedure
found in the Autoconf docs (i.e. using AC_HEADER_DIRENT and a couple of
tests with HAVE_DIRENT_H), I am sure that there will be some weird system
out there (MacIntosh, say) for which my code won't compile. If that
happens, we have to port that part of the code.
2) With my approach, I have to open all and every module before using them.
This may appear as a regression as regards the "cache file" approach
provided by the use of drivers.db. In terms of performance, with our
current computer power, the overload is negligible. However, as I wrote
above, my original design was much better, but harder to implement (of
course). It looks like this:
a) Forget about that entries a la drivers.db.
b) In each driver file <driver>.c define symbols DEV_DESC_*, DEV_SEQ_*,
DEV_TAG_*, etc. These symbols can be used when filling fields in
function plD_dispatch_init_<device>. This would further reduce the
maintenance problem due to duplication of information.
c) At build time (not configuration time), a small C program dlopen the
<driver>.c files, get the symbols described above and write the
associated device entries in <driver>.rc (or whichever name).
d) Those <driver>.rc are installed in the drivers directory, along with
the <driver>.la and <driver>.so files.
e) When PLplot is initialized, the <driver>.rc files are scanned.
If I have some time before the 5.2.1 release, I will try to implement
this idea.
Postscript
==========
In doing my changes, I noticed that the following drivers have never had
entries in drivers.db: plbuf.c and next.c. Does anyone know why?
I introduced the DEVICE_INFO_<driver> symbol in all drivers listed in
variable EXTRA_LTLIBRARIES of drivers/Makefile.am. I also noticed that the
pstex entry was wrongly written in drivers.db. Apparently, this bug have
never bothered our users...
--
Rafael
Rafael