Пример #1
0
char *lists_strs_fmt (const lists_t_strs *list, const char *fmt)
{
	int len, ix, rc;
	char *result, *ptr;

	assert (list);
	assert (strstr (fmt, "%s"));

	result = NULL;
	if (!lists_strs_empty (list)) {
		len = 0;
		for (ix = 0; ix < lists_strs_size (list); ix += 1)
			len += strlen (lists_strs_at (list, ix));
		len += ix * (strlen (fmt) - 2);

		ptr = result = xmalloc (len + 1);
		for (ix = 0; ix < lists_strs_size (list); ix += 1) {
			rc = snprintf (ptr, len + 1, fmt, lists_strs_at (list, ix));
			if (rc > len)
				fatal ("Allocated string area was too small!");
			len -= rc;
			ptr += rc;
		}
	}

	return result;
}
Пример #2
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;
}
Пример #3
0
/* Load all preferences given by the user in PreferredDecoders. */
static void load_preferences ()
{
    int ix;
    const char *preference;
    lists_t_strs *list;

    list = options_get_list ("PreferredDecoders");

    for (ix = 0; ix < lists_strs_size (list); ix += 1) {
        preference = lists_strs_at (list, ix);
        load_each_preference (preference);
    }

#ifdef DEBUG
    {
        char *names;
        decoder_t_preference *pref;

        for (pref = preferences; pref; pref = pref->next) {
            names = list_decoder_names (pref->decoder_list, pref->decoders);
            debug ("%s:%s", pref->source, names);
            free (names);
        }
    }
#endif
}
Пример #4
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);
}
Пример #5
0
/* Put something into the log */
void internal_logit (const char *file, const int line, const char *function,
		const char *format, ...)
{
	int len;
	char *msg, time_str[20];
	struct timeval utc_time;
	va_list va;
	struct tm tm_time;
	const char fmt[] = "%s.%06u: %s:%d %s(): %s\n";

	if (!logfp) {
		switch (logging_state) {
		case UNINITIALISED:
			buffered_log = lists_strs_new (128);
			logging_state = BUFFERING;
			break;
		case BUFFERING:
			/* Don't let storage run away on us. */
			if (lists_strs_size (buffered_log) < lists_strs_capacity (buffered_log))
				break;
			log_records_spilt += 1;
			return;
		case LOGGING:
			return;
		}
	}

	va_start (va, format);
	len = vsnprintf (NULL, 0, format, va) + 1;
	va_end (va);
	msg = xmalloc (len);
	va_start (va, format);
	vsnprintf (msg, len, format, va);
	va_end (va);

	gettimeofday (&utc_time, NULL);
	localtime_r (&utc_time.tv_sec, &tm_time);
	strftime (time_str, sizeof (time_str), "%b %e %T", &tm_time);

	if (logfp) {
		fprintf (logfp, fmt, time_str, (unsigned)utc_time.tv_usec,
		                     file, line, function, msg);
		fflush (logfp);
	}
	else {
		char *str;

		len = snprintf (NULL, 0, fmt, time_str, (unsigned)utc_time.tv_usec,
		                              file, line, function, msg);
		str = xmalloc (len + 1);
		snprintf (str, len + 1, fmt, time_str, (unsigned)utc_time.tv_usec,
		                             file, line, function, msg);

		lists_strs_push (buffered_log, str);
	}

	free (msg);
}
Пример #6
0
/* Given a string, return true iff it exists in the list. */
bool lists_strs_exists (lists_t_strs *list, const char *sought)
{
	bool result = false;

	assert (list);
	assert (sought);

	if (lists_strs_find (list, sought) < lists_strs_size (list))
		result = true;

	return result;
}
Пример #7
0
/* Given a string, return the index of the first list entry which matches
 * it.  If not found, return the total number of entries.
 * The comparison is case-insensitive. */
int lists_strs_find (lists_t_strs *list, const char *sought)
{
	int result;

	assert (list);
	assert (sought);

	for (result = 0; result < lists_strs_size (list); result += 1) {
		if (!strcasecmp (lists_strs_at (list, result), sought))
			break;
	}

	return result;
}
Пример #8
0
/* Build a preference's decoder list. */
static void load_decoders (decoder_t_preference *pref, lists_t_strs *tokens)
{
    int ix, dx, asterisk_at;
    int decoder[PLUGINS_NUM];
    const char *name;

    assert (pref);
    assert (tokens);

    asterisk_at = -1;

    /* Add the index of each known decoder to the decoders list.
     * Note the position following the first asterisk. */
    for (ix = 1; ix < lists_strs_size (tokens); ix += 1) {
        name = lists_strs_at (tokens, ix);
        if (strcmp (name, "*"))
            load_each_decoder (pref, name);
        else if (asterisk_at == -1)
            asterisk_at = pref->decoders;
    }

    if (asterisk_at == -1)
        return;

    dx = 0;

    /* Find decoders not already listed. */
    for (ix = 0; ix < plugins_num; ix += 1) {
        if (!is_listed_decoder (pref, ix))
            decoder[dx++] = ix;
    }

    /* Splice asterisk decoders into the decoder list. */
    for (ix = 0; ix < dx; ix += 1) {
        pref->decoder_list[pref->decoders++] =
            pref->decoder_list[asterisk_at + ix];
        pref->decoder_list[asterisk_at + ix] = decoder[ix];
    }

    assert (RANGE(0, pref->decoders, plugins_num));
}
Пример #9
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;
}
Пример #10
0
/* Initialize logging stream */
void log_init_stream (FILE *f, const char *fn)
{
	logfp = f;

	if (logging_state == BUFFERING) {
		if (logfp) {
			int ix;

			for (ix = 0; ix < lists_strs_size (buffered_log); ix += 1)
				fprintf (logfp, "%s", lists_strs_at (buffered_log, ix));

			fflush (logfp);
		}
		lists_strs_free (buffered_log);
		buffered_log = NULL;
	}

	logging_state = LOGGING;

	logit ("Writing log to: %s", fn);
	if (log_records_spilt > 0)
		logit ("%d log records spilt", log_records_spilt);
}
Пример #11
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;
}
Пример #12
0
		strncpy (result, line, max);
		len = max;
	}
	strcpy (&result[len], "\n");

	return result;
}

/* Centre all the lines in the lyrics. */
static lists_t_strs *centre_style (lists_t_strs *lines, int height ATTR_UNUSED,
                                   int width, void *data ATTR_UNUSED)
{
	lists_t_strs *result;
	int ix, size;

	size = lists_strs_size (lines);
	result = lists_strs_new (size);
	for (ix = 0; ix < size; ix += 1) {
		char *old_line, *new_line;

		old_line = lists_strs_at (lines, ix);
		new_line = centre_line (old_line, width);
		lists_strs_push (result, new_line);
	}

	return result;
}

/* Formatting function information. */
static lyrics_t_formatter *lyrics_formatter = centre_style;
static lyrics_t_reaper *formatter_reaper = NULL;