summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNedko Arnaudov <nedko@arnaudov.name>2014-03-10 20:17:44 +0200
committerNedko Arnaudov <nedko@arnaudov.name>2014-03-10 22:01:13 +0200
commit00f468fa29d588a3659dd0a74f569c6505b98836 (patch)
tree50759f288f59aed021ba78c1b138b909ae0873c4
parentc8cac65cadfbac03c5a86e39d7400624ca2197bc (diff)
downloadjack2-00f468fa29d588a3659dd0a74f569c6505b98836.tar.gz
use descriptors for initializing enum constraints
Descriptor initialization reduces risk of mismatch between array size and element initialization. It also improves code readability by separating the parameter descriptions separate from the code that composes the enum constraint structures. As a side effect this commit makes the self-connect-mode constraint allocated in dedicated memory chunks, like others enum constraints.
-rw-r--r--common/JackControlAPI.cpp44
-rw-r--r--common/JackDriverLoader.cpp119
-rw-r--r--common/driver_interface.h42
-rw-r--r--linux/alsa/JackAlsaDriver.cpp158
4 files changed, 219 insertions, 144 deletions
diff --git a/common/JackControlAPI.cpp b/common/JackControlAPI.cpp
index 3be9fb0b..42b04ee1 100644
--- a/common/JackControlAPI.cpp
+++ b/common/JackControlAPI.cpp
@@ -47,13 +47,16 @@
using namespace Jack;
-/* JackEngine::CheckPortsConnect() has some assumptions about values of these */
-#define SELF_CONNECT_MODE_ALLOW_CHAR ' '
-#define SELF_CONNECT_MODE_FAIL_EXTERNAL_ONLY_CHAR 'E'
-#define SELF_CONNECT_MODE_IGNORE_EXTERNAL_ONLY_CHAR 'e'
-#define SELF_CONNECT_MODE_FAIL_ALL_CHAR 'A'
-#define SELF_CONNECT_MODE_IGNORE_ALL_CHAR 'a'
-#define SELF_CONNECT_MODES_COUNT 5
+/* JackEngine::CheckPortsConnect() has some assumptions about char values */
+static struct jack_constraint_enum_char_descriptor self_connect_mode_constraint_descr_array[] =
+{
+ { ' ', "Don't restrict self connect requests" },
+ { 'E', "Fail self connect requests to external ports only" },
+ { 'e', "Ignore self connect requests to external ports only" },
+ { 'A', "Fail all self connect requests" },
+ { 'a', "Ignore all self connect requests" },
+ { 0 }
+};
struct jackctl_server
{
@@ -106,8 +109,6 @@ struct jackctl_server
/* char enum, self connect mode mode */
union jackctl_parameter_value self_connect_mode;
union jackctl_parameter_value default_self_connect_mode;
- jack_driver_param_value_enum_t self_connect_mode_possible_values[SELF_CONNECT_MODES_COUNT];
- jack_driver_param_constraint_desc_t self_connect_mode_constraint;
};
struct jackctl_driver
@@ -883,26 +884,7 @@ SERVER_EXPORT jackctl_server_t * jackctl_server_create(
goto fail_free_parameters;
}
- server_ptr->self_connect_mode_constraint.flags = JACK_CONSTRAINT_FLAG_STRICT | JACK_CONSTRAINT_FLAG_FAKE_VALUE;
- server_ptr->self_connect_mode_constraint.constraint.enumeration.count = SELF_CONNECT_MODES_COUNT;
- server_ptr->self_connect_mode_constraint.constraint.enumeration.possible_values_array = server_ptr->self_connect_mode_possible_values;
-
- server_ptr->self_connect_mode_possible_values[0].value.c = SELF_CONNECT_MODE_ALLOW_CHAR;
- strcpy(server_ptr->self_connect_mode_possible_values[0].short_desc, "Don't restrict self connect requests");
-
- server_ptr->self_connect_mode_possible_values[1].value.c = SELF_CONNECT_MODE_FAIL_EXTERNAL_ONLY_CHAR ;
- strcpy(server_ptr->self_connect_mode_possible_values[1].short_desc, "Fail self connect requests to external ports only");
-
- server_ptr->self_connect_mode_possible_values[2].value.c = SELF_CONNECT_MODE_IGNORE_EXTERNAL_ONLY_CHAR;
- strcpy(server_ptr->self_connect_mode_possible_values[2].short_desc, "Ignore self connect requests to external ports only");
-
- server_ptr->self_connect_mode_possible_values[3].value.c = SELF_CONNECT_MODE_FAIL_ALL_CHAR;
- strcpy(server_ptr->self_connect_mode_possible_values[3].short_desc, "Fail all self connect requests");
-
- server_ptr->self_connect_mode_possible_values[4].value.c = SELF_CONNECT_MODE_IGNORE_ALL_CHAR;
- strcpy(server_ptr->self_connect_mode_possible_values[4].short_desc, "Ignore all self connect requests");
-
- value.c = SELF_CONNECT_MODE_ALLOW_CHAR;
+ value.c = JACK_DEFAULT_SELF_CONNECT_MODE;
if (jackctl_add_parameter(
&server_ptr->parameters,
"self-connect-mode",
@@ -912,7 +894,9 @@ SERVER_EXPORT jackctl_server_t * jackctl_server_create(
&server_ptr->self_connect_mode,
&server_ptr->default_self_connect_mode,
value,
- &server_ptr->self_connect_mode_constraint) == NULL)
+ jack_constraint_compose_enum_char(
+ JACK_CONSTRAINT_FLAG_STRICT | JACK_CONSTRAINT_FLAG_FAKE_VALUE,
+ self_connect_mode_constraint_descr_array)) == NULL)
{
goto fail_free_parameters;
}
diff --git a/common/JackDriverLoader.cpp b/common/JackDriverLoader.cpp
index 488cb43f..1571d94a 100644
--- a/common/JackDriverLoader.cpp
+++ b/common/JackDriverLoader.cpp
@@ -880,3 +880,122 @@ SERVER_EXPORT int jack_driver_descriptor_add_parameter(
desc_ptr->nparams++;
return true;
}
+
+SERVER_EXPORT
+int
+jack_constraint_add_enum(
+ jack_driver_param_constraint_desc_t ** constraint_ptr_ptr,
+ uint32_t * array_size_ptr,
+ jack_driver_param_value_t * value_ptr,
+ const char * short_desc)
+{
+ jack_driver_param_constraint_desc_t * constraint_ptr;
+ uint32_t array_size;
+ jack_driver_param_value_enum_t * possible_value_ptr;
+ size_t len;
+
+ len = strlen(short_desc) + 1;
+ if (len > sizeof(possible_value_ptr->short_desc))
+ {
+ assert(false);
+ return false;
+ }
+
+ constraint_ptr = *constraint_ptr_ptr;
+ if (constraint_ptr == NULL)
+ {
+ constraint_ptr = (jack_driver_param_constraint_desc_t *)calloc(1, sizeof(jack_driver_param_constraint_desc_t));
+ if (constraint_ptr == NULL)
+ {
+ jack_error("calloc() failed to allocate memory for param constraint struct");
+ return false;
+ }
+
+ array_size = 0;
+ }
+ else
+ {
+ array_size = *array_size_ptr;
+ }
+
+ if (constraint_ptr->constraint.enumeration.count == array_size)
+ {
+ array_size += 10;
+ possible_value_ptr =
+ (jack_driver_param_value_enum_t *)realloc(
+ constraint_ptr->constraint.enumeration.possible_values_array,
+ sizeof(jack_driver_param_value_enum_t) * array_size);
+ if (possible_value_ptr == NULL)
+ {
+ jack_error("calloc() failed to (re)allocate memory for possible values array");
+ return false;
+ }
+ constraint_ptr->constraint.enumeration.possible_values_array = possible_value_ptr;
+ }
+ else
+ {
+ possible_value_ptr = constraint_ptr->constraint.enumeration.possible_values_array;
+ }
+
+ possible_value_ptr += constraint_ptr->constraint.enumeration.count;
+ constraint_ptr->constraint.enumeration.count++;
+
+ possible_value_ptr->value = *value_ptr;
+ memcpy(possible_value_ptr->short_desc, short_desc, len);
+
+ *constraint_ptr_ptr = constraint_ptr;
+ *array_size_ptr = array_size;
+
+ return true;
+}
+
+SERVER_EXPORT
+void
+jack_constraint_free(
+ jack_driver_param_constraint_desc_t * constraint_ptr)
+{
+ if (constraint_ptr != NULL)
+ {
+ if ((constraint_ptr->flags & JACK_CONSTRAINT_FLAG_RANGE) == 0)
+ {
+ free(constraint_ptr->constraint.enumeration.possible_values_array);
+ }
+
+ free(constraint_ptr);
+ }
+}
+
+#define JACK_CONSTRAINT_COMPOSE_ENUM_IMPL(type, copy) \
+JACK_CONSTRAINT_COMPOSE_ENUM(type) \
+{ \
+ jack_driver_param_constraint_desc_t * constraint_ptr; \
+ uint32_t array_size; \
+ jack_driver_param_value_t value; \
+ struct jack_constraint_enum_ ## type ## _descriptor * descr_ptr; \
+ \
+ constraint_ptr = NULL; \
+ for (descr_ptr = descr_array_ptr; \
+ descr_ptr->value; \
+ descr_ptr++) \
+ { \
+ copy; \
+ if (!jack_constraint_add_enum( \
+ &constraint_ptr, \
+ &array_size, \
+ &value, \
+ descr_ptr->short_desc)) \
+ { \
+ jack_constraint_free(constraint_ptr); \
+ return NULL; \
+ } \
+ } \
+ \
+ constraint_ptr->flags = flags; \
+ \
+ return constraint_ptr; \
+}
+
+JACK_CONSTRAINT_COMPOSE_ENUM_IMPL(uint32, value.c = descr_ptr->value);
+JACK_CONSTRAINT_COMPOSE_ENUM_IMPL(sint32, value.c = descr_ptr->value);
+JACK_CONSTRAINT_COMPOSE_ENUM_IMPL(char, value.c = descr_ptr->value);
+JACK_CONSTRAINT_COMPOSE_ENUM_IMPL(str, strcpy(value.str, descr_ptr->value));
diff --git a/common/driver_interface.h b/common/driver_interface.h
index 87b6fae7..2dd2e32b 100644
--- a/common/driver_interface.h
+++ b/common/driver_interface.h
@@ -74,6 +74,26 @@ typedef struct {
char short_desc[64]; /**< A short (~30 chars) description for the user */
} jack_driver_param_value_enum_t;
+struct jack_constraint_enum_uint32_descriptor {
+ uint32_t value;
+ const char * short_desc;
+};
+
+struct jack_constraint_enum_sint32_descriptor {
+ int32_t value;
+ const char * short_desc;
+};
+
+struct jack_constraint_enum_char_descriptor {
+ char value;
+ const char * short_desc;
+};
+
+struct jack_constraint_enum_str_descriptor {
+ const char * value;
+ const char * short_desc;
+};
+
typedef struct {
uint32_t flags; /**< JACK_CONSTRAINT_FLAG_XXX */
union {
@@ -148,6 +168,28 @@ jack_driver_descriptor_add_parameter(
const char * short_desc, /* A short (~30 chars) description for the user */
const char * long_desc); /* A longer description for the user, if NULL short_desc will be used */
+SERVER_EXPORT
+int jack_constraint_add_enum(
+ jack_driver_param_constraint_desc_t ** constraint_ptr_ptr,
+ uint32_t * array_size_ptr,
+ jack_driver_param_value_t * value_ptr,
+ const char * short_desc);
+
+SERVER_EXPORT
+void jack_constraint_free(jack_driver_param_constraint_desc_t * constraint_ptr);
+
+#define JACK_CONSTRAINT_COMPOSE_ENUM(type) \
+SERVER_EXPORT \
+jack_driver_param_constraint_desc_t * \
+jack_constraint_compose_enum_ ## type( \
+ uint32_t flags, \
+ struct jack_constraint_enum_ ## type ## _descriptor * descr_array_ptr)
+
+JACK_CONSTRAINT_COMPOSE_ENUM(uint32);
+JACK_CONSTRAINT_COMPOSE_ENUM(sint32);
+JACK_CONSTRAINT_COMPOSE_ENUM(char);
+JACK_CONSTRAINT_COMPOSE_ENUM(str);
+
typedef jack_driver_desc_t * (*JackDriverDescFunction) ();
#ifdef __cplusplus
diff --git a/linux/alsa/JackAlsaDriver.cpp b/linux/alsa/JackAlsaDriver.cpp
index c2b9bd39..421ac903 100644
--- a/linux/alsa/JackAlsaDriver.cpp
+++ b/linux/alsa/JackAlsaDriver.cpp
@@ -47,6 +47,23 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "JackCompilerDeps.h"
#include "JackServerGlobals.h"
+static struct jack_constraint_enum_str_descriptor midi_constraint_descr_array[] =
+{
+ { "none", "no MIDI driver" },
+ { "seq", "ALSA Sequencer driver" },
+ { "raw", "ALSA RawMIDI driver" },
+ { 0 }
+};
+
+static struct jack_constraint_enum_char_descriptor dither_constraint_descr_array[] =
+{
+ { 'n', "none" },
+ { 'r', "rectangular" },
+ { 's', "shaped" },
+ { 't', "triangular" },
+ { 0 }
+};
+
namespace Jack
{
@@ -530,39 +547,6 @@ extern "C"
#endif
static
-void
-fill_device(
- jack_driver_param_constraint_desc_t ** constraint_ptr_ptr,
- uint32_t * array_size_ptr,
- const char * device_id,
- const char * device_description)
-{
- jack_driver_param_value_enum_t * possible_value_ptr;
-
- //jack_info("%6s - %s", device_id, device_description);
-
- if (*constraint_ptr_ptr == NULL)
- {
- *constraint_ptr_ptr = (jack_driver_param_constraint_desc_t *)calloc(1, sizeof(jack_driver_param_constraint_desc_t));
- *array_size_ptr = 0;
- }
-
- if ((*constraint_ptr_ptr)->constraint.enumeration.count == *array_size_ptr)
- {
- *array_size_ptr += 10;
- (*constraint_ptr_ptr)->constraint.enumeration.possible_values_array =
- (jack_driver_param_value_enum_t *)realloc(
- (*constraint_ptr_ptr)->constraint.enumeration.possible_values_array,
- sizeof(jack_driver_param_value_enum_t) * *array_size_ptr);
- }
-
- possible_value_ptr = (*constraint_ptr_ptr)->constraint.enumeration.possible_values_array + (*constraint_ptr_ptr)->constraint.enumeration.count;
- (*constraint_ptr_ptr)->constraint.enumeration.count++;
- strcpy(possible_value_ptr->value.str, device_id);
- strcpy(possible_value_ptr->short_desc, device_description);
-}
-
-static
jack_driver_param_constraint_desc_t *
enum_alsa_devices()
{
@@ -571,8 +555,8 @@ enum_alsa_devices()
snd_pcm_info_t * pcminfo_capture;
snd_pcm_info_t * pcminfo_playback;
int card_no = -1;
- char card_id[JACK_DRIVER_PARAM_STRING_MAX + 1];
- char device_id[JACK_DRIVER_PARAM_STRING_MAX + 1];
+ jack_driver_param_value_t card_id;
+ jack_driver_param_value_t device_id;
char description[64];
int device_no;
bool has_capture;
@@ -588,19 +572,24 @@ enum_alsa_devices()
while(snd_card_next(&card_no) >= 0 && card_no >= 0)
{
- snprintf(card_id, sizeof(card_id), "hw:%d", card_no);
+ snprintf(card_id.str, sizeof(card_id.str), "hw:%d", card_no);
- if (snd_ctl_open(&handle, card_id, 0) >= 0 &&
+ if (snd_ctl_open(&handle, card_id.str, 0) >= 0 &&
snd_ctl_card_info(handle, info) >= 0)
{
- snprintf(card_id, sizeof(card_id), "hw:%s", snd_ctl_card_info_get_id(info));
- fill_device(&constraint_ptr, &array_size, card_id, snd_ctl_card_info_get_name(info));
+ snprintf(card_id.str, sizeof(card_id.str), "hw:%s", snd_ctl_card_info_get_id(info));
+ if (!jack_constraint_add_enum(
+ &constraint_ptr,
+ &array_size,
+ &card_id,
+ snd_ctl_card_info_get_name(info)))
+ goto fail;
device_no = -1;
while (snd_ctl_pcm_next_device(handle, &device_no) >= 0 && device_no != -1)
{
- snprintf(device_id, sizeof(device_id), "%s,%d", card_id, device_no);
+ snprintf(device_id.str, sizeof(device_id.str), "%s,%d", card_id.str, device_no);
snd_pcm_info_set_device(pcminfo_capture, device_no);
snd_pcm_info_set_subdevice(pcminfo_capture, 0);
@@ -629,7 +618,12 @@ enum_alsa_devices()
continue;
}
- fill_device(&constraint_ptr, &array_size, device_id, description);
+ if (!jack_constraint_add_enum(
+ &constraint_ptr,
+ &array_size,
+ &device_id,
+ description))
+ goto fail;
}
snd_ctl_close(handle);
@@ -637,77 +631,9 @@ enum_alsa_devices()
}
return constraint_ptr;
-}
-
-static
-jack_driver_param_constraint_desc_t *
-get_midi_driver_constraint()
-{
- jack_driver_param_constraint_desc_t * constraint_ptr;
- jack_driver_param_value_enum_t * possible_value_ptr;
-
- //jack_info("%6s - %s", device_id, device_description);
-
- constraint_ptr = (jack_driver_param_constraint_desc_t *)calloc(1, sizeof(jack_driver_param_value_enum_t));
- constraint_ptr->flags = JACK_CONSTRAINT_FLAG_STRICT | JACK_CONSTRAINT_FLAG_FAKE_VALUE;
-
- constraint_ptr->constraint.enumeration.possible_values_array = (jack_driver_param_value_enum_t *)malloc(3 * sizeof(jack_driver_param_value_enum_t));
- constraint_ptr->constraint.enumeration.count = 3;
-
- possible_value_ptr = constraint_ptr->constraint.enumeration.possible_values_array;
-
- strcpy(possible_value_ptr->value.str, "none");
- strcpy(possible_value_ptr->short_desc, "no MIDI driver");
-
- possible_value_ptr++;
-
- strcpy(possible_value_ptr->value.str, "seq");
- strcpy(possible_value_ptr->short_desc, "ALSA Sequencer driver");
-
- possible_value_ptr++;
-
- strcpy(possible_value_ptr->value.str, "raw");
- strcpy(possible_value_ptr->short_desc, "ALSA RawMIDI driver");
-
- return constraint_ptr;
-}
-
-static
-jack_driver_param_constraint_desc_t *
-get_dither_constraint()
-{
- jack_driver_param_constraint_desc_t * constraint_ptr;
- jack_driver_param_value_enum_t * possible_value_ptr;
-
- //jack_info("%6s - %s", device_id, device_description);
-
- constraint_ptr = (jack_driver_param_constraint_desc_t *)calloc(1, sizeof(jack_driver_param_value_enum_t));
- constraint_ptr->flags = JACK_CONSTRAINT_FLAG_STRICT | JACK_CONSTRAINT_FLAG_FAKE_VALUE;
-
- constraint_ptr->constraint.enumeration.possible_values_array = (jack_driver_param_value_enum_t *)malloc(4 * sizeof(jack_driver_param_value_enum_t));
- constraint_ptr->constraint.enumeration.count = 4;
-
- possible_value_ptr = constraint_ptr->constraint.enumeration.possible_values_array;
-
- possible_value_ptr->value.c = 'n';
- strcpy(possible_value_ptr->short_desc, "none");
-
- possible_value_ptr++;
-
- possible_value_ptr->value.c = 'r';
- strcpy(possible_value_ptr->short_desc, "rectangular");
-
- possible_value_ptr++;
-
- possible_value_ptr->value.c = 's';
- strcpy(possible_value_ptr->short_desc, "shaped");
-
- possible_value_ptr++;
-
- possible_value_ptr->value.c = 't';
- strcpy(possible_value_ptr->short_desc, "triangular");
-
- return constraint_ptr;
+fail:
+ jack_constraint_free(constraint_ptr);
+ return NULL;
}
static int
@@ -789,7 +715,9 @@ SERVER_EXPORT const jack_driver_desc_t* driver_get_descriptor ()
'z',
JackDriverParamChar,
&value,
- get_dither_constraint(),
+ jack_constraint_compose_enum_char(
+ JACK_CONSTRAINT_FLAG_STRICT | JACK_CONSTRAINT_FLAG_FAKE_VALUE,
+ dither_constraint_descr_array),
"Dithering mode",
"Dithering mode:\n"
" n - none\n"
@@ -816,7 +744,9 @@ SERVER_EXPORT const jack_driver_desc_t* driver_get_descriptor ()
'X',
JackDriverParamString,
&value,
- get_midi_driver_constraint(),
+ jack_constraint_compose_enum_str(
+ JACK_CONSTRAINT_FLAG_STRICT | JACK_CONSTRAINT_FLAG_FAKE_VALUE,
+ midi_constraint_descr_array),
"ALSA device name",
"ALSA MIDI driver:\n"
" none - no MIDI driver\n"