Skip to content

Commit

Permalink
Version checking in a2_Open()
Browse files Browse the repository at this point in the history
Added a2_OpenVersion(), which takes an additional argument specifying the
lowest A2 library version that's acceptable to the application.

Major and minor versions need to match. For development branches (1.9.x,
2.1.x etc), the micro versions need to match, whereas for stable branches
(2.0.x, 2.2.x etc), the library needs to be of the version requested, or
higher.

If the version check fails, a2_OpenVersion() returns NULL, and the global
error status (read with a2_LastError()) is set to A2_BADLIBVERSION.

a2_Open() is now an inline wrapper which passes the A2 header version to
the new a2_OpenVersion().

Closes #314.
  • Loading branch information
olofson committed Jan 30, 2017
1 parent 77cc368 commit f049ce2
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 5 deletions.
3 changes: 2 additions & 1 deletion include/a2_types.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* a2_types.h - Audiality 2 basic data types
*
* Copyright 2012-2016 David Olofson <[email protected]>
* Copyright 2012-2017 David Olofson <[email protected]>
*
* This software is provided 'as-is', without any express or implied warranty.
* In no event will the authors be held liable for any damages arising from the
Expand Down Expand Up @@ -226,6 +226,7 @@ typedef enum A2_sampleformats
A2_DEFERR(BADHEXESCAPE, "Bad hex escape format in string literal")\
A2_DEFERR(BADIFNEST, "Nested 'if' without braces")\
A2_DEFERR(BADELSE, "Use of 'else' after non-braced statement")\
A2_DEFERR(BADLIBVERSION, "Linked A2 lib incompatible with application")\
\
A2_DEFERR(CANTEXPORT, "Cannot export from this scope")\
A2_DEFERR(CANTINPUT, "Unit cannot have inputs")\
Expand Down
23 changes: 21 additions & 2 deletions include/audiality2.h.cmake
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* audiality2.h - Audiality 2 Realtime Scriptable Audio Engine
*
* Copyright 2010-2016 David Olofson <[email protected]>
* Copyright 2010-2017 David Olofson <[email protected]>
*
* This software is provided 'as-is', without any express or implied warranty.
* In no event will the authors be held liable for any damages arising from the
Expand Down Expand Up @@ -122,8 +122,27 @@ unsigned a2_LinkedVersion(void);
* The 'flags' argument is only passed on to the driver 'flags' field when
* a driver is opened by the state! That is, flags are not passed on to a
* driver that is already open when a2_Open() is called.
*
* Version checking:
* a2_OpenVersion() verifies that the linked library is compatible with
* the header version specified by the application. If it is not, the call
* will fail with A2_BADLIBVERSION, and return NULL.
*
* a2_Open() automatically passes the version of the headers the
* application is compiled against, which means that applications using
* this call will not work with older library versions; only same or
* newer.
*
* When distributing binaries, it may be useful to specify the Audiality 2
* version explicitly via a2_OpenVersion(), so that applications will not
* be prevented from running with older libraries, unless they actually
* need features added in later versions.
*/
A2_interface *a2_Open(A2_config *config);
A2_interface *a2_OpenVersion(A2_config *config, unsigned headerversion);
static inline A2_interface *a2_Open(A2_config *config)
{
return a2_OpenVersion(config, a2_HeaderVersion());
}

/*
* Create a substate to the state behind interface 'master'.
Expand Down
49 changes: 47 additions & 2 deletions src/audiality2.c
Original file line number Diff line number Diff line change
Expand Up @@ -514,12 +514,57 @@ static A2_errors a2_Open2(A2_state *st)
}


A2_interface *a2_Open(A2_config *config)
static A2_errors a2_verify_version(unsigned headerversion)
{
/* Major and minor versions need to match. */
if((A2_MAJOR(headerversion) == A2_MAJOR(A2_VERSION)) &&
(A2_MINOR(headerversion) == A2_MINOR(A2_VERSION)))
{
if(A2_MINOR(A2_VERSION) & 1)
{
/*
* Development branches are assumed to break binary
* compatibility with every micro release!
*/
if(A2_MICRO(headerversion) == A2_MICRO(A2_VERSION))
return A2_OK;
}
else
{
/*
* Stable branch; lib needs to be of same or higher
* micro version.
*/
if(A2_MICRO(headerversion) <= A2_MICRO(A2_VERSION))
return A2_OK;
}
}

/* Check failed! This will not work. */
fprintf(stderr, "CRITICAL: Incompatible Audiality library!\n");
fprintf(stderr, "This library is version %d.%d.%d.%d\n",
A2_MAJOR(A2_VERSION),
A2_MINOR(A2_VERSION),
A2_MICRO(A2_VERSION),
A2_BUILD(A2_VERSION));
fprintf(stderr, "Application is built for %d.%d.%d.%d\n",
A2_MAJOR(headerversion),
A2_MINOR(headerversion),
A2_MICRO(headerversion),
A2_BUILD(headerversion));
return A2_BADLIBVERSION;
}


A2_interface *a2_OpenVersion(A2_config *config, unsigned headerversion)
{
A2_errors res;
A2_state *st;
A2_interface_i *j;
a2_last_error = A2_OK;

if((a2_last_error = a2_verify_version(headerversion)))
return NULL;

DUMPSIZES(
printf("A2_wave:\t%d\n", sizeof(A2_wave));
printf("A2_bank:\t%d\n", sizeof(A2_bank));
Expand Down

0 comments on commit f049ce2

Please sign in to comment.