/* Return the concatenation of all the strings in a list, or NULL * if the list is empty. */ char *lists_strs_cat (const lists_t_strs *list) { char *result; assert (list); result = lists_strs_fmt (list, "%s"); return result; }
/* Log the command line which launched MOC. */ static void log_command_line (int argc, char *argv[]) { lists_t_strs *cmdline; char *str; assert (argc >= 0); assert (argv != NULL); assert (argv[argc] == NULL); cmdline = lists_strs_new (argc); if (lists_strs_load (cmdline, argv) > 0) str = lists_strs_fmt (cmdline, "%s "); else str = xstrdup ("No command line available"); logit ("%s", str); free (str); lists_strs_free (cmdline); }
/* 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; }
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; }