Compile time and runtime checks for library compatibility

This commit is contained in:
Thomas Schmitt 2008-01-31 21:47:39 +00:00
parent 06145dfdc9
commit 599b966b41
5 changed files with 199 additions and 30 deletions

View File

@ -49,7 +49,89 @@ extern struct isoburn *isoburn_list_start; /* in isoburn.c */
int isoburn_initialize(char msg[1024], int flag) int isoburn_initialize(char msg[1024], int flag)
{ {
int major, minor, micro; int major, minor, micro, bad_match= 0;
/* First two ugly compile time checks for header version compatibility.
If everthing matches, then they produce no C code. In case of mismatch,
intentionally faulty C code will be inserted.
*/
#ifdef iso_lib_header_version_major
/* The minimum requirement of libisoburn towards the libisofs header
at compile time is defined in libisoburn/libisoburn.h :
isoburn_libisofs_req_major
isoburn_libisofs_req_minor
isoburn_libisofs_req_micro
It gets compared against the version macros in libisofs/libisofs.h :
iso_lib_header_version_major
iso_lib_header_version_minor
iso_lib_header_version_micro
If the header is too old then the following code shall cause failure of
cdrskin compilation rather than to allow production of a program with
unpredictable bugs or memory corruption.
The compiler messages supposed to appear in this case are:
error: 'LIBISOFS_MISCONFIGURATION' undeclared (first use in this function)
error: 'INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libisofs_dot_h_TOO_OLD__SEE_libisoburn_dot_h_and_burn_wrap_dot_h' undeclared (first use in this function)
error: 'LIBISOFS_MISCONFIGURATION_' undeclared (first use in this function)
*/
/* The indendation is an advise of man gcc to help old compilers ignoring */
#if isoburn_libisofs_req_major > iso_lib_header_version_major
#define Isoburn_libisofs_dot_h_too_olD 1
#endif
#if isoburn_libisofs_req_major == iso_lib_header_version_major && isoburn_libisofs_req_minor > iso_lib_header_version_minor
#define Isoburn_libisofs_dot_h_too_olD 1
#endif
#if isoburn_libisofs_req_minor == iso_lib_header_version_minor && isoburn_libisofs_req_micro > iso_lib_header_version_micro
#define Isoburn_libisofs_dot_h_too_olD 1
#endif
#ifdef Isoburn_libisofs_dot_h_too_olD
LIBISOFS_MISCONFIGURATION = 0;
INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libisofs_dot_h_TOO_OLD__SEE_libisoburn_dot_h_and_burn_wrap_dot_h = 0;
LIBISOFS_MISCONFIGURATION_ = 0;
#endif
#endif /* iso_lib_header_version_major */
/* The minimum requirement of libisoburn towards the libburn header
at compile time is defined in libisoburn/libisoburn.h :
isoburn_libburn_req_major
isoburn_libburn_req_minor
isoburn_libburn_req_micro
It gets compared against the version macros in libburn/libburn.h :
burn_header_version_major
burn_header_version_minor
burn_header_version_micro
If the header is too old then the following code shall cause failure of
cdrskin compilation rather than to allow production of a program with
unpredictable bugs or memory corruption.
The compiler messages supposed to appear in this case are:
error: 'LIBBURN_MISCONFIGURATION' undeclared (first use in this function)
error: 'INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libburn_dot_h_TOO_OLD__SEE_libisoburn_dot_h_and_burn_wrap_dot_h' undeclared (first use in this function)
error: 'LIBBURN_MISCONFIGURATION_' undeclared (first use in this function)
*/
/* The indendation is an advise of man gcc to help old compilers ignoring */
#if isoburn_libburn_req_major > burn_header_version_major
#define Isoburn_libburn_dot_h_too_olD 1
#endif
#if isoburn_libburn_req_major == burn_header_version_major && isoburn_libburn_req_minor > burn_header_version_minor
#define Isoburn_libburn_dot_h_too_olD 1
#endif
#if isoburn_libburn_req_minor == burn_header_version_minor && isoburn_libburn_req_micro > burn_header_version_micro
#define Isoburn_libburn_dot_h_too_olD 1
#endif
#ifdef Isoburn_libburn_dot_h_too_olD
LIBBURN_MISCONFIGURATION = 0;
INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libburn_dot_h_TOO_OLD__SEE_libisoburn_dot_h_and_burn_wrap_dot_h = 0;
LIBBURN_MISCONFIGURATION_ = 0;
#endif
/* End of ugly compile time tests (scroll up for explanation) */
msg[0]= 0; msg[0]= 0;
if(iso_init()<0) { if(iso_init()<0) {
@ -57,33 +139,56 @@ int isoburn_initialize(char msg[1024], int flag)
return(0); return(0);
} }
iso_lib_version(&major, &minor, &micro); iso_lib_version(&major, &minor, &micro);
sprintf(msg+strlen(msg), "libisofs-%d.%d.%d , ", major, minor, micro); sprintf(msg+strlen(msg), "libisofs-%d.%d.%d ", major, minor, micro);
#ifdef iso_lib_header_version_major
/* >>> check for suitability of library */ if(iso_lib_is_compatible(iso_lib_header_version_major,
iso_lib_header_version_minor,
iso_lib_header_version_micro)) {
sprintf(msg+strlen(msg), "ok, ");
} else {
sprintf(msg+strlen(msg),"- TOO OLD -, need at least libisofs-%d.%d.%d ,\n",
iso_lib_header_version_major, iso_lib_header_version_minor,
iso_lib_header_version_micro);
bad_match= 1;
}
#else
if(iso_lib_is_compatible(isoburn_libisofs_req_major,
isoburn_libisofs_req_minor,
isoburn_libisofs_req_micro)) {
sprintf(msg+strlen(msg), "suspicious, ");
} else {
sprintf(msg+strlen(msg),"- TOO OLD -, need at least libisofs-%d.%d.%d ,\n",
isoburn_libisofs_req_major, isoburn_libisofs_req_minor,
isoburn_libisofs_req_micro);
bad_match= 1;
}
#endif /* ! iso_lib_header_version_major */
if(!burn_initialize()) { if(!burn_initialize()) {
sprintf(msg+strlen(msg), "Cannot initialize libburn\n"); sprintf(msg+strlen(msg), "Cannot initialize libburn\n");
return(0); return(0);
} }
burn_version(&major, &minor, &micro); burn_version(&major, &minor, &micro);
sprintf(msg+strlen(msg), "libburn-%d.%d.%d , ", major, minor, micro); sprintf(msg+strlen(msg), "libburn-%d.%d.%d ", major, minor, micro);
if(major > burn_header_version_major if(major > burn_header_version_major
|| (major == burn_header_version_major || (major == burn_header_version_major
&& (minor > burn_header_version_minor && (minor > burn_header_version_minor
|| (minor == burn_header_version_minor || (minor == burn_header_version_minor
&& micro >= burn_header_version_micro)))) { && micro >= burn_header_version_micro)))) {
; /* ok */ sprintf(msg+strlen(msg), "ok, ");
} else { } else {
sprintf(msg+strlen(msg), "- TOO OLD -, need at least libburn-%d.%d.%d ,\n", sprintf(msg+strlen(msg), "- TOO OLD -, need at least libburn-%d.%d.%d ,\n",
burn_header_version_major, burn_header_version_minor, burn_header_version_major, burn_header_version_minor,
burn_header_version_micro); burn_header_version_micro);
return(0); bad_match= 1;
} }
isoburn_destroy_all(&isoburn_list_start, 0); /* isoburn_list_start= NULL */
isoburn_version(&major, &minor, &micro); isoburn_version(&major, &minor, &micro);
sprintf(msg+strlen(msg), "libisoburn-%d.%d.%d", major, minor, micro); sprintf(msg+strlen(msg), "for libisoburn-%d.%d.%d", major, minor, micro);
if(bad_match)
return(0);
isoburn_destroy_all(&isoburn_list_start, 0); /* isoburn_list_start= NULL */
return(1); return(1);
} }

View File

@ -138,21 +138,6 @@ int isoburn_initialize(char msg[1024], int flag);
int isoburn_is_compatible(int major, int minor, int micro, int flag); int isoburn_is_compatible(int major, int minor, int micro, int flag);
/** These three release version numbers tell the revision of this header file
and of the API it describes. They are memorized by applications at build
time.
*/
#define isoburn_header_version_major 0
#define isoburn_header_version_minor 0
#define isoburn_header_version_micro 1
/** Note:
Above version numbers are also recorded in configure.ac because libtool
wants them as parameters at build time.
For the library compatibility check ISOBURN_*_VERSION in configure.ac
are not decisive. Only the three numbers above do matter.
*/
/** Obtain the three release version numbers of the library. These are the /** Obtain the three release version numbers of the library. These are the
numbers encountered by the application when linking with libisoburn, numbers encountered by the application when linking with libisoburn,
i.e. possibly not before run time. i.e. possibly not before run time.
@ -174,6 +159,77 @@ int isoburn_is_compatible(int major, int minor, int micro, int flag);
*/ */
void isoburn_version(int *major, int *minor, int *micro); void isoburn_version(int *major, int *minor, int *micro);
/** The minimum version of libisofs to be used with this version of libisoburn
*/
#define isoburn_libisofs_req_major 0
#define isoburn_libisofs_req_minor 6
#define isoburn_libisofs_req_micro 1
/** The minimum version of libburn to be used with this version of libisoburn
*/
#define isoburn_libburn_req_major 0
#define isoburn_libburn_req_minor 4
#define isoburn_libburn_req_micro 2
/** These three release version numbers tell the revision of this header file
and of the API it describes. They are memorized by applications at build
time.
*/
#define isoburn_header_version_major 0
#define isoburn_header_version_minor 0
#define isoburn_header_version_micro 1
/** Note:
Above version numbers are also recorded in configure.ac because libtool
wants them as parameters at build time.
For the library compatibility check ISOBURN_*_VERSION in configure.ac
are not decisive. Only the three numbers above do matter.
*/
/** Usage discussion:
Some developers of the libburnia project have differing
opinions how to ensure the compatibility of libaries
and applications.
It is about whether to use at compile time and at runtime
the version numbers isoburn_header_version_* provided here.
Thomas Schmitt advises to use them.
Vreixo Formoso advises to use other means.
At compile time:
Vreixo Formoso advises to leave proper version matching
to properly programmed checks in the the application's
build system, which will eventually refuse compilation.
Thomas Schmitt advises to use the macros defined here
for comparison with the application's requirements of
library revisions and to eventually break compilation.
Both advises are combinable. I.e. be master of your
build system and have #if checks in the source code
of your application, nevertheless.
At runtime (via *_is_compatible()):
Vreixo Formoso advises to compare the application's
requirements of library revisions with the runtime
library. This is to allow runtime libraries which are
young enough for the application but too old for
the lib*.h files seen at compile time.
Thomas Schmitt advises to compare the header
revisions defined here with the runtime library.
This is to enforce a strictly monotonous chain
of revisions from app to header to library,
at the cost of excluding some older libraries.
These two advises are mutually exclusive.
For an implementation of the Thomas Schmitt approach,
see libisoburn/burn_wrap.c : isoburn_initialize()
*/
/** Aquire a target drive by its filesystem path resp. libburn persistent /** Aquire a target drive by its filesystem path resp. libburn persistent
address. address.

View File

@ -134,14 +134,16 @@ copy_files libisofs/*.[ch] "$lone_dir"/libisofs
# To get a common version.h # To get a common version.h
cat version.h.in >> "$lone_dir"/version.h.in cat version.h.in >> "$lone_dir"/version.h.in
sed -e 's/FNM_FILE_NAME/FNM_PATHNAME/g' \
<libisofs/tree.c >"$lone_dir"/libisofs/tree.c
# <<< obsoleted patchings
# <<< obsoleted
if test 1 = 0 if test 1 = 0
then then
# Change GNU macro name to POSIX name
sed -e 's/FNM_FILE_NAME/FNM_PATHNAME/g' \
<libisofs/tree.c >"$lone_dir"/libisofs/tree.c
# Filter out the semi-illegal TODO comments # Filter out the semi-illegal TODO comments
( cd "$lone_dir"/libisofs && grep '^[[:space:]]*//' *.[ch] | less ) ( cd "$lone_dir"/libisofs && grep '^[[:space:]]*//' *.[ch] | less )
echo "Is it ok delete all shown //-lines ?" echo "Is it ok delete all shown //-lines ?"

View File

@ -1 +1 @@
#define Xorriso_timestamP "2008.01.31.152131" #define Xorriso_timestamP "2008.01.31.214647"

View File

@ -17,6 +17,12 @@
struct XorrisO; struct XorrisO;
struct FindjoB; struct FindjoB;
/* The minimum version of libisoburn to be used with this version of xorriso
*/
#define xorriso_libisoburn_req_major 0
#define xorriso_libisoburn_req_minor 0
#define xorriso_libisoburn_req_micro 1
int Xorriso_startup_libraries(struct XorrisO *xorriso, int flag); int Xorriso_startup_libraries(struct XorrisO *xorriso, int flag);
/* @param flag bit0= global shutdown of libraries */ /* @param flag bit0= global shutdown of libraries */