Beispiel #1
0
static void process_deferred_overrides (lists_t_strs *deferred)
{
	int ix;
	bool cleared;
	const char marker[] = "*Marker*";
	char **config_decoders;
	lists_t_strs *decoders_option;

	/* We need to shuffle the PreferredDecoders list into the
	 * right order as we load any deferred overriding options. */

	decoders_option = options_get_list ("PreferredDecoders");
	lists_strs_reverse (decoders_option);
	config_decoders = lists_strs_save (decoders_option);
	lists_strs_clear (decoders_option);
	lists_strs_append (decoders_option, marker);

	for (ix = 0; ix < lists_strs_size (deferred); ix += 1)
		override_config_option (lists_strs_at (deferred, ix), NULL);

	cleared = lists_strs_empty (decoders_option) ||
	          strcmp (lists_strs_at (decoders_option, 0), marker) != 0;
	lists_strs_reverse (decoders_option);
	if (!cleared) {
		char **override_decoders;

		free (lists_strs_pop (decoders_option));
		override_decoders = lists_strs_save (decoders_option);
		lists_strs_clear (decoders_option);
		lists_strs_load (decoders_option, config_decoders);
		lists_strs_load (decoders_option, override_decoders);
		free (override_decoders);
	}
	free (config_decoders);
}
Beispiel #2
0
static void override_config_option (const char *optarg, lists_t_strs *deferred)
{
	int len;
	bool append;
	char *ptr, *name, *value;
	enum option_type type;

	assert (optarg != NULL);

	ptr = strchr (optarg, '=');
	if (ptr == NULL)
		goto error;

	/* Allow for list append operator ("+="). */
	append = (ptr > optarg && *(ptr - 1) == '+');

	name = trim (optarg, ptr - optarg - (append ? 1 : 0));
	if (!name || !name[0])
		goto error;
	type = options_get_type (name);

	if (type == OPTION_LIST) {
		if (deferred) {
			lists_strs_append (deferred, optarg);
			free (name);
			return;
		}
	}
	else if (append)
		goto error;

	value = trim (ptr + 1, strlen (ptr + 1));
	if (!value || !value[0])
		goto error;

	if (value[0] == '\'' || value[0] == '"') {
		len = strlen (value);
		if (value[0] != value[len - 1])
			goto error;
		if (strlen (value) < 2)
			goto error;
		memmove (value, value + 1, len - 2);
		value[len - 2] = 0x00;
	}

	if (!options_set_pair (name, value, append))
		goto error;
	options_ignore_config (name);

	free (name);
	free (value);
	return;

error:
	fatal ("Malformed override option: %s", optarg);
}
Beispiel #3
0
static void load_extn_list ()
{
	const int counts[] = {SFC_GET_SIMPLE_FORMAT_COUNT,
	                      SFC_GET_FORMAT_MAJOR_COUNT};
	const int formats[] = {SFC_GET_SIMPLE_FORMAT,
	                       SFC_GET_FORMAT_MAJOR};

	supported_extns = lists_strs_new (16);

	for (size_t ix = 0; ix < ARRAY_SIZE(counts); ix += 1) {
		int limit;
		SF_FORMAT_INFO format_info;

		sf_command (NULL, counts[ix], &limit, sizeof (limit));
		for (int iy = 0 ; iy < limit ; iy += 1) {
			format_info.format = iy ;
			sf_command (NULL, formats[ix], &format_info, sizeof (format_info));
			if (!lists_strs_exists (supported_extns, format_info.extension))
				lists_strs_append (supported_extns, format_info.extension);
		}
	}

	/* These are synonyms of supported extensions. */
	if (lists_strs_exists (supported_extns, "aiff"))
		lists_strs_append (supported_extns, "aif");
	if (lists_strs_exists (supported_extns, "au"))
		lists_strs_append (supported_extns, "snd");
	if (lists_strs_exists (supported_extns, "wav")) {
		lists_strs_append (supported_extns, "nist");
		lists_strs_append (supported_extns, "sph");
	}
	if (lists_strs_exists (supported_extns, "iff"))
		lists_strs_append (supported_extns, "svx");
	if (lists_strs_exists (supported_extns, "oga"))
		lists_strs_append (supported_extns, "ogg");
	if (lists_strs_exists (supported_extns, "sf"))
		lists_strs_append (supported_extns, "ircam");
	if (lists_strs_exists (supported_extns, "mat")) {
		lists_strs_append (supported_extns, "mat4");
		lists_strs_append (supported_extns, "mat5");
	}
}
Beispiel #4
0
/* Reload saved strings into a list.  The reloaded strings are appended
 * to the list.  The number of items reloaded is returned. */
int lists_strs_load (lists_t_strs *list, const char **saved)
{
	int size;

	assert (list);
	assert (saved);

	size = lists_strs_size (list);
	while (*saved)
		lists_strs_append (list, *saved++);

	return lists_strs_size (list) - size;
}
Beispiel #5
0
/* Read and return a line from 'stream' in a dynamically allocated buffer.
 * Return NULL at end of file. */
char *xgetline (FILE *stream)
{
	static char buffer[64];
	char *result;
	lists_t_strs *line;

	line = lists_strs_new (4);

	do {
		if (!fgets (buffer, sizeof (buffer), stream))
			break;
		lists_strs_append (line, buffer);
	} while (buffer[strlen (buffer) - 1] != '\n');

	result = lists_strs_cat (line);
	lists_strs_free (line);

	return result;
}
Beispiel #6
0
/* Split a string at any delimiter in given string.  The resulting segments
 * are appended to the given string list.  Returns the number of tokens
 * appended. */
int lists_strs_split (lists_t_strs *list, const char *s, const char *delim)
{
	int result;
	char *str, *token, *saveptr;

	assert (list);
	assert (s);
	assert (delim);

	result = 0;
	str = xstrdup (s);
	token = strtok_r (str, delim, &saveptr);
	while (token) {
		result += 1;
		lists_strs_append (list, token);
		token = strtok_r (NULL, delim, &saveptr);
	}

	free (str);
	return result;
}
Beispiel #7
0
/* Return a string of concatenated driver names. */
static char *list_decoder_names (int *decoder_list, int count)
{
    int ix;
    char *result;
    lists_t_strs *names;

    if (count == 0)
        return xstrdup ("");

    names = lists_strs_new (count);
    for (ix = 0; ix < count; ix += 1)
        lists_strs_append (names, plugins[decoder_list[ix]].name);
    if (have_tremor) {
        ix = lists_strs_find (names, "vorbis");
        if (ix < lists_strs_size (names))
            lists_strs_replace (names, ix, "vorbis(tremor)");
    }
    result = lists_strs_fmt (names, " %s");
    lists_strs_free (names);

    return result;
}
Beispiel #8
0
static void on_song_change ()
{
	static char *last_file = NULL;
	static lists_t_strs *on_song_change = NULL;

	int ix;
	bool same_file, unpaused;
	char *curr_file, **args;
	struct file_tags *curr_tags;
	lists_t_strs *arg_list;

	/* We only need to do OnSongChange tokenisation once. */
	if (on_song_change == NULL) {
		char *command;

		on_song_change = lists_strs_new (4);
		command = options_get_str ("OnSongChange");

		if (command)
			lists_strs_tokenise (on_song_change, command);
	}

	if (lists_strs_empty (on_song_change))
		return;

	curr_file = audio_get_sname ();

	if (curr_file == NULL)
		return;

	same_file = (last_file && !strcmp (last_file, curr_file));
	unpaused = (audio_get_prev_state () == STATE_PAUSE);
	if (same_file && (unpaused || !options_get_bool ("RepeatSongChange"))) {
		free (curr_file);
		return;
	}

	curr_tags = tags_cache_get_immediate (tags_cache, curr_file,
	                                      TAGS_COMMENTS | TAGS_TIME);
	arg_list = lists_strs_new (lists_strs_size (on_song_change));
	for (ix = 0; ix < lists_strs_size (on_song_change); ix += 1) {
		char *arg, *str;

		arg = lists_strs_at (on_song_change, ix);
		if (arg[0] != '%')
			lists_strs_append (arg_list, arg);
		else if (!curr_tags)
			lists_strs_append (arg_list, "");
		else {
			switch (arg[1]) {
			case 'a':
				str = curr_tags->artist ? curr_tags->artist : "";
				lists_strs_append (arg_list, str);
				break;
			case 'r':
				str = curr_tags->album ? curr_tags->album : "";
				lists_strs_append (arg_list, str);
				break;
			case 't':
				str = curr_tags->title ? curr_tags->title : "";
				lists_strs_append (arg_list, str);
				break;
			case 'n':
				if (curr_tags->track >= 0) {
					str = (char *) xmalloc (sizeof (char) * 4);
					snprintf (str, 4, "%d", curr_tags->track);
					lists_strs_push (arg_list, str);
				}
				else
					lists_strs_append (arg_list, "");
				break;
			case 'f':
				lists_strs_append (arg_list, curr_file);
				break;
			case 'D':
				if (curr_tags->time >= 0) {
					str = (char *) xmalloc (sizeof (char) * 10);
					snprintf (str, 10, "%d", curr_tags->time);
					lists_strs_push (arg_list, str);
				}
				else
					lists_strs_append (arg_list, "");
				break;
			case 'd':
				if (curr_tags->time >= 0) {
					str = (char *) xmalloc (sizeof (char) * 12);
					sec_to_min (str, curr_tags->time);
					lists_strs_push (arg_list, str);
				}
				else
					lists_strs_append (arg_list, "");
				break;
			default:
				lists_strs_append (arg_list, arg);
			}
		}
	}
	tags_free (curr_tags);

#ifndef NDEBUG
	{
		char *cmd;

		cmd = lists_strs_fmt (arg_list, " %s");
		debug ("Running command: %s", cmd);
		free (cmd);
	}
#endif

	switch (fork ()) {
	case 0:
		args = lists_strs_save (arg_list);
		execve (args[0], args, environ);
		exit (EXIT_FAILURE);
	case -1:
		log_errno ("Failed to fork()", errno);
	}

	lists_strs_free (arg_list);
	free (last_file);
	last_file = curr_file;
}