Compile time and runtime checks for library compatibility

This commit is contained in:
2008-01-31 21:47:39 +00:00
parent 897045c51c
commit 33b236523a
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 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;
if(iso_init()<0) {
@ -57,33 +139,56 @@ int isoburn_initialize(char msg[1024], int flag)
return(0);
}
iso_lib_version(&major, &minor, &micro);
sprintf(msg+strlen(msg), "libisofs-%d.%d.%d , ", major, minor, micro);
/* >>> check for suitability of library */
sprintf(msg+strlen(msg), "libisofs-%d.%d.%d ", major, minor, micro);
#ifdef iso_lib_header_version_major
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()) {
sprintf(msg+strlen(msg), "Cannot initialize libburn\n");
return(0);
}
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
|| (major == burn_header_version_major
&& (minor > burn_header_version_minor
|| (minor == burn_header_version_minor
&& micro >= burn_header_version_micro)))) {
; /* ok */
sprintf(msg+strlen(msg), "ok, ");
} 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_micro);
return(0);
bad_match= 1;
}
isoburn_destroy_all(&isoburn_list_start, 0); /* isoburn_list_start= NULL */
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);
}