diff --git a/DEVELOPERS.txt b/DEVELOPERS similarity index 100% rename from DEVELOPERS.txt rename to DEVELOPERS diff --git a/Makefile b/Makefile index 27b1946..1e3b254 100644 --- a/Makefile +++ b/Makefile @@ -11,19 +11,20 @@ LDEPS=$(TAGLIB_LIBS) $(GSTREAMER_LIBS) ODEPS=$(GSTREAMER_OBJS) # build variables -CC ?= /usr/bin/cc -CFLAGS += -c -std=c89 -Wall -Wextra -Wno-unused-value $(CDEBUG) $(CDEPS) -LIBS += -lm -lncurses -lutil $(LDEPS) +CC ?= /usr/bin/cc +CPPFLAGS += -I. -Icompat -Iplayers -iquote. +CFLAGS += -c -std=c89 -Wall -Wextra -Wno-unused-value $(CDEBUG) $(CDEPS) +LIBS += -lm -lncurses -lutil $(LDEPS) # object files OBJS=commands.o compat.o ecmd.o \ ecmd_add.o ecmd_addurl.o ecmd_check.o \ ecmd_flush.o ecmd_help.o ecmd_init.o \ ecmd_rmfile.o ecmd_tag.o ecmd_update.o \ - keybindings.o medialib.o meta_info.o \ + error.o keybindings.o medialib.o meta_info.o \ mplayer.o paint.o player.o player_utils.o \ playlist.o socket.o str2argv.o \ - uinterface.o vitunes.o \ + uinterface.o vitunes.o xmalloc.o \ $(ODEPS) # subdirectories with code (.PATH for BSD make, VPATH for GNU make) @@ -39,10 +40,10 @@ vitunes: $(OBJS) $(CC) -o $@ $(LDFLAGS) $(OBJS) $(LIBS) .c.o: - $(CC) $(CFLAGS) $< + $(CC) $(CPPFLAGS) $(CFLAGS) $< debug: - make CDEBUG="-DDEBUG -g" + make CDEBUG="-g" clean: rm -f *.o @@ -93,4 +94,3 @@ reports: report.mandoc report.cppcheck report.scan-build @figlet "Static Checks Complete" cat report.mandoc cat report.cppcheck - diff --git a/commands.c b/commands.c index e310fca..df03fdb 100644 --- a/commands.c +++ b/commands.c @@ -14,7 +14,20 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include +#include + #include "commands.h" +#include "enums.h" +#include "error.h" +#include "keybindings.h" +#include "medialib.h" +#include "paint.h" +#include "player.h" +#include "str2argv.h" +#include "uinterface.h" +#include "vitunes.h" +#include "xmalloc.h" bool sorts_need_saving = false; @@ -57,9 +70,8 @@ void toggleset_init() { const int max_size = 52; /* since we only have registers a-z and A-Z */ - if ((toggleset = calloc(max_size, sizeof(toggle_list*))) == NULL) - err(1, "%s: calloc(3) failed", __FUNCTION__); + toggleset = xcalloc(max_size, sizeof(toggle_list*)); toggleset_size = 0; } @@ -77,29 +89,20 @@ toggleset_free() void toggle_list_add_command(toggle_list *t, char *cmd) { - char **new_cmds; - int idx; + int idx; /* resize array */ if (t->size == 0) { - if ((t->commands = malloc(sizeof(char*))) == NULL) - err(1, "%s: malloc(3) failed", __FUNCTION__); - + t->commands = xmalloc(sizeof(char*)); idx = 0; t->size = 1; } else { - int new_size = (t->size + 1) * sizeof(char*); - if ((new_cmds = realloc(t->commands, new_size)) == NULL) - err(1, "%s: realloc(3) failed", __FUNCTION__); - - idx = t->size; - t->commands = new_cmds; - t->size++; + t->commands = xrealloc(t->commands, t->size + 1, sizeof(char *)); + idx = t->size++; } /* add command */ - if ((t->commands[idx] = strdup(cmd)) == NULL) - err(1, "%s: strdup(3) failed", __FUNCTION__); + t->commands[idx] = xstrdup(cmd); } toggle_list* @@ -109,9 +112,7 @@ toggle_list_create(int registr, int argc, char *argv[]) char *cmd = NULL; int i, j; - if ((t = malloc(sizeof(toggle_list))) == NULL) - err(1, "%s: malloc(3) failed", __FUNCTION__); - + t = xmalloc(sizeof(toggle_list)); t->commands = NULL; t->registr = registr; t->size = 0; @@ -243,7 +244,7 @@ cmd_quit(int argc, char *argv[]) bool forced; if (argc != 1) { - paint_error("usage: q[!]"); + fatalx("usage: q[!]"); return 1; } @@ -255,7 +256,7 @@ cmd_quit(int argc, char *argv[]) int i; for (i = 0; i < mdb.nplaylists; i++) { if (mdb.playlists[i]->needs_saving) { - paint_error("there are playlists with unsaved changes. use \"q!\" to force."); + fatalx("there are playlists with unsaved changes. use \"q!\" to force."); return 2; } } @@ -272,7 +273,7 @@ cmd_write(int argc, char *argv[]) bool forced; if (argc > 2) { - paint_error("usage: w[!] [name]"); + fatalx("usage: w[!] [name]"); return 1; } @@ -283,13 +284,13 @@ cmd_write(int argc, char *argv[]) /* can't save library or filter results */ if (viewing_playlist == mdb.library || viewing_playlist == mdb.filter_results) { - paint_error("use \"w name\" when saving pseudo-playlists like library/filter"); + fatalx("use \"w name\" when saving pseudo-playlists like library/filter"); return 2; } /* can't save a new playlist that has no name */ if (viewing_playlist->filename == NULL) { - paint_error("use \"w name\" for new playlists"); + fatalx("use \"w name\" for new playlists"); return 3; } @@ -297,7 +298,7 @@ cmd_write(int argc, char *argv[]) playlist_save(viewing_playlist); viewing_playlist->needs_saving = false; paint_library(); - paint_message("\"%s\" %d songs written", + infox("\"%s\" %d songs written", viewing_playlist->filename, viewing_playlist->nfiles); } else { /* "save as" */ @@ -305,8 +306,7 @@ cmd_write(int argc, char *argv[]) bool will_clobber; /* build filename for playlist */ - if (asprintf(&filename, "%s/%s.playlist", mdb.playlist_dir, argv[1]) == -1) - err(1, "cmd_write: asprintf failed"); + xasprintf(&filename, "%s/%s.playlist", mdb.playlist_dir, argv[1]); /* check to see if playlist with that name already exists */ will_clobber = false; @@ -320,7 +320,7 @@ cmd_write(int argc, char *argv[]) } if (will_clobber && !forced) { - paint_error("playlist with that name exists (use \"w!\" to overwrite)"); + fatalx("playlist with that name exists (use \"w!\" to overwrite)"); free(filename); return 4; } @@ -348,7 +348,7 @@ cmd_write(int argc, char *argv[]) viewing_playlist->needs_saving = false; paint_library(); - paint_message("\"%s\" %d songs written", + infox("\"%s\" %d songs written", filename, viewing_playlist->nfiles); free(filename); @@ -361,7 +361,7 @@ int cmd_mode(int argc, char *argv[]) { if (argc != 2) { - paint_error("usage: mode [ linear | loop | random ]"); + fatalx("usage: mode [ linear | loop | random ]"); return 1; } @@ -372,11 +372,11 @@ cmd_mode(int argc, char *argv[]) else if (strcasecmp(argv[1], "random") == 0) player_info.mode = MODE_RANDOM; else { - paint_error("invalid mode \"%s\". must be one of: linear, loop, or random", argv[1]); + fatalx("invalid mode \"%s\". must be one of: linear, loop, or random", argv[1]); return 2; } - paint_message("mode changed to: %s", argv[1]); + infox("mode changed to: %s", argv[1]); return 0; } @@ -388,7 +388,7 @@ cmd_new(int argc, char *argv[]) char *filename; if (argc > 2) { - paint_error("usage: new [name]"); + fatalx("usage: new [name]"); return 1; } @@ -402,22 +402,20 @@ cmd_new(int argc, char *argv[]) int i; for (i = 0; i < mdb.nplaylists; i++) { if (strcmp(mdb.playlists[i]->name, argv[1]) == 0) { - paint_error("playlist \"%s\" already exists.", argv[1]); + fatalx("playlist \"%s\" already exists.", argv[1]); return 2; } } name = argv[1]; - if (asprintf(&filename, "%s/%s.playlist", mdb.playlist_dir, name) == -1) - err(1, "cmd_new: asprintf failed"); + xasprintf(&filename, "%s/%s.playlist", mdb.playlist_dir, name); } /* create & setup playlist */ p = playlist_new(); p->needs_saving = true; p->filename = filename; - if ((p->name = strdup(name)) == NULL) - err(1, "cmd_new: strdup(3) failed"); + p->name = xstrdup(name); /* add playlist to media library and update ui */ medialib_playlist_add(p); @@ -427,7 +425,7 @@ cmd_new(int argc, char *argv[]) /* redraw */ paint_library(); - paint_message("playlist \"%s\" added", name); + infox("playlist \"%s\" added", name); return 0; } @@ -441,7 +439,7 @@ cmd_filter(int argc, char *argv[]) int i; if (argc == 1) { - paint_error("usage: filter[!] token [token2 ...]"); + fatalx("usage: filter[!] token [token2 ...]"); return 1; } @@ -481,13 +479,13 @@ cmd_sort(int argc, char *argv[]) const char *errmsg; if (argc != 2) { - paint_error("usage: sort "); + fatalx("usage: sort "); return 1; } /* setup global sort description */ if (mi_sort_set(argv[1], &errmsg) != 0) { - paint_error("%s: bad sort description: %s", argv[0], errmsg); + fatalx("%s: bad sort description: %s", argv[0], errmsg); return 2; } @@ -516,13 +514,13 @@ cmd_display(int argc, char *argv[]) const char *errmsg; if (argc != 2) { - paint_error("usage: display [ reset | show | ]"); + fatalx("usage: display [ reset | show | ]"); return 1; } /* show existng display? */ if (strcasecmp(argv[1], "show") == 0) { - paint_message(":display %s", mi_display_tostr()); + infox(":display %s", mi_display_tostr()); return 0; } @@ -538,7 +536,7 @@ cmd_display(int argc, char *argv[]) /* if reached here, setup global display description */ if (mi_display_set(argv[1], &errmsg) != 0) { - paint_error("%s: bad display description: %s", argv[0], errmsg); + fatalx("%s: bad display description: %s", argv[0], errmsg); return 1; } @@ -556,21 +554,21 @@ cmd_color(int argc, char *argv[]) int i_item, i_fg, i_bg, j; if (argc != 2) { - paint_error("usage: %s ITEM=FG,BG", argv[0]); + fatalx("usage: %s ITEM=FG,BG", argv[0]); return 1; } /* extract item and foreground/background colors */ item = argv[1]; if ((fg = strchr(item, '=')) == NULL) { - paint_error("usage: %s ITEM=FG,BG", argv[0]); + fatalx("usage: %s ITEM=FG,BG", argv[0]); return 2; } *fg = '\0'; fg++; if ((bg = strchr(fg, ',')) == NULL) { - paint_error("usage: %s ITEM=FG,BG", argv[0]); + fatalx("usage: %s ITEM=FG,BG", argv[0]); return 3; } *bg = '\0'; @@ -578,17 +576,17 @@ cmd_color(int argc, char *argv[]) /* convert all */ if ((i_item = paint_str2item(item)) < 0) { - paint_error("invalid item '%s'", item); + fatalx("invalid item '%s'", item); return 4; } if ((i_fg = paint_str2color(fg)) == -2) { - paint_error("invalid foreground color '%s'", fg); + fatalx("invalid foreground color '%s'", fg); return 5; } if ((i_bg = paint_str2color(bg)) == -2) { - paint_error("invalid background color '%s'", bg); + fatalx("invalid background color '%s'", bg); return 6; } @@ -620,7 +618,7 @@ cmd_set(int argc, char *argv[]) bool player_is_setup; if (argc != 2) { - paint_error("usage: %s =", argv[0]); + fatalx("usage: %s =", argv[0]); return 1; } @@ -631,7 +629,7 @@ cmd_set(int argc, char *argv[]) /* extract property and value */ property = argv[1]; if ((value = strchr(property, '=')) == NULL) { - paint_error("usage: %s =", argv[0]); + fatalx("usage: %s =", argv[0]); return 2; } *value = '\0'; @@ -647,7 +645,7 @@ cmd_set(int argc, char *argv[]) /* validate and convert width user provided */ new_width = (int)strtonum(value, 1, max_w, &err); if (err != NULL) { - paint_error("%s %s: bad width: '%s' %s", + fatalx("%s %s: bad width: '%s' %s", argv[0], property, value, err); return 3; } @@ -662,7 +660,7 @@ cmd_set(int argc, char *argv[]) } else if (strcasecmp(property, "lhide") == 0) { if (str2bool(value, &tf) < 0) { - paint_error("%s %s: value must be boolean", + fatalx("%s %s: value must be boolean", argv[0], property); return 4; } @@ -673,40 +671,40 @@ cmd_set(int argc, char *argv[]) if (player_is_setup && ui_is_init()) { ui_clear(); paint_all(); - paint_message("library window hidden"); + infox("library window hidden"); } } else { if (ui.library->cwin == NULL) ui_unhide_library(); if (player_is_setup && ui_is_init()) paint_all(); - paint_message("library window un-hidden"); + infox("library window un-hidden"); } } else if (strcasecmp(property, "match-fname") == 0) { if (str2bool(value, &tf) < 0) { - paint_error("%s %s: value must be boolean", + fatalx("%s %s: value must be boolean", argv[0], property); return 5; } mi_query_match_filename = tf; if (mi_query_match_filename) - paint_message("filenames will be matched against"); + infox("filenames will be matched against"); else - paint_message("filenames will NOT be matched against"); + infox("filenames will NOT be matched against"); } else if (strcasecmp(property, "save-sorts") == 0) { if (str2bool(value, &tf) < 0) { - paint_error("%s %s: value must be boolean", + fatalx("%s %s: value must be boolean", argv[0], property); return 6; } sorts_need_saving = tf; if (sorts_need_saving) - paint_message("changing sort will be prompted for saving"); + infox("changing sort will be prompted for saving"); else - paint_message("changing sort will NOT be prompted for saving"); + infox("changing sort will NOT be prompted for saving"); } else { - paint_error("%s: unknown property '%s'", argv[0], property); + fatalx("%s: unknown property '%s'", argv[0], property); return 7; } @@ -717,17 +715,14 @@ int cmd_reload(int argc, char *argv[]) { if (argc != 2) { - paint_error("usage: %s [ db | conf ]", argv[0]); + fatalx("usage: %s [ db | conf ]", argv[0]); return 1; } /* reload database or config file */ if (strcasecmp(argv[1], "db") == 0) { - - char *db_file = strdup(mdb.db_file); - char *playlist_dir = strdup(mdb.playlist_dir); - if (db_file == NULL || playlist_dir == NULL) - err(1, "cmd_reload: strdup(3) failed"); + char *db_file = xstrdup(mdb.db_file); + char *playlist_dir = xstrdup(mdb.playlist_dir); /* stop playback TODO investigate a nice way around this */ player_stop(); @@ -752,9 +747,9 @@ cmd_reload(int argc, char *argv[]) } else if (strcasecmp(argv[1], "conf") == 0) { load_config(); - paint_message("configuration reloaded"); + infox("configuration reloaded"); } else { - paint_error("usage: %s [ db | conf ]", argv[0]); + fatalx("usage: %s [ db | conf ]", argv[0]); return 2; } @@ -768,23 +763,23 @@ cmd_bind(int argc, char *argv[]) KeyCode code; if (argc < 3 || argc > 4) { - paint_error("usage: %s ", argv[0]); + fatalx("usage: %s ", argv[0]); return 1; } if (!kb_str2action(argv[1], &action)) { - paint_error("Unknown action '%s'", argv[1]); + fatalx("Unknown action '%s'", argv[1]); return 1; } if (argc == 3) { if ((code = kb_str2keycode(argv[2])) < 0) { - paint_error("Invalid keycode '%s'", argv[2]); + fatalx("Invalid keycode '%s'", argv[2]); return 1; } } else { if ((code = kb_str2keycode2(argv[2], argv[3])) < 0) { - paint_error("Invalid keycode '%s'", argv[2]); + fatalx("Invalid keycode '%s'", argv[2]); return 1; } } @@ -811,7 +806,7 @@ cmd_unbind(int argc, char *argv[]) kb_unbind_action(action); return 0; } else { - paint_error("Unknown action '%s'", argv[2]); + fatalx("Unknown action '%s'", argv[2]); return 1; } } @@ -819,7 +814,7 @@ cmd_unbind(int argc, char *argv[]) /* unbind key case, no control ("unbind key X") */ if (argc == 3 && strcasecmp(argv[1], "key") == 0) { if ((key = kb_str2keycode(argv[2])) < 0) { - paint_error("Invalid keycode '%s'", argv[2]); + fatalx("Invalid keycode '%s'", argv[2]); return 1; } @@ -830,7 +825,7 @@ cmd_unbind(int argc, char *argv[]) /* unbind key case, with control ("unbind key control X") */ if (argc == 4 && strcasecmp(argv[1], "key") == 0) { if ((key = kb_str2keycode2(argv[2], argv[3])) < 0) { - paint_error("Invalid keycode '%s %s'", argv[2], argv[3]); + fatalx("Invalid keycode '%s %s'", argv[2], argv[3]); return 1; } @@ -838,7 +833,7 @@ cmd_unbind(int argc, char *argv[]) return 0; } - paint_error("usage: unbind [* | action | key ]"); + fatalx("usage: unbind [* | action | key ]"); return 1; } @@ -851,12 +846,12 @@ cmd_toggle(int argc, char *argv[]) int registr; if (argc < 3) { - paint_error("usage: %s / ...", argv[0]); + fatalx("usage: %s / ...", argv[0]); return 1; } if (strlen(argv[1]) != 1) { - paint_error("error: register name must be a single letter (in [a-zA-Z])"); + fatalx("error: register name must be a single letter (in [a-zA-Z])"); return 1; } @@ -864,7 +859,7 @@ cmd_toggle(int argc, char *argv[]) if (!( ('a' <= registr && registr <= 'z') || ('A' <= registr && registr <= 'Z'))) { - paint_error("error: invalid register name. Must be one of [a-zA-Z]"); + fatalx("error: invalid register name. Must be one of [a-zA-Z]"); return 1; } @@ -882,7 +877,7 @@ cmd_playlist(int argc, char *argv[]) int idx = -1; if (argc != 2) { - paint_error("usage: playlist "); + fatalx("usage: playlist "); return 1; } @@ -902,17 +897,17 @@ cmd_playlist(int argc, char *argv[]) setup_viewing_playlist(mdb.playlists[idx]); ui.active = ui.playlist; paint_all(); - paint_message("jumped to playlist: %s", mdb.playlists[idx]->name); + infox("jumped to playlist: %s", mdb.playlists[idx]->name); return 0; } if(idx == -1) { - paint_error("no match for: %s", argv[1]); + fatalx("no match for: %s", argv[1]); return 0; } if(idx == -2) - paint_error("no unique match for: %s", argv[1]); + fatalx("no unique match for: %s", argv[1]); return 0; } @@ -929,7 +924,7 @@ cmd_execute(char *cmd) int i; if (str2argv(cmd, &argc, &argv, &errmsg) != 0) { - paint_error("parse error: %s in '%s'", errmsg, cmd); + fatalx("parse error: %s in '%s'", errmsg, cmd); return; } @@ -946,9 +941,9 @@ cmd_execute(char *cmd) if (found && num_matches == 1) (CommandPath[found_idx].func)(argc, argv); else if (num_matches > 1) - paint_error("Ambiguous abbreviation '%s'", argv[0]); + fatalx("Ambiguous abbreviation '%s'", argv[0]); else - paint_error("Unknown commands '%s'", argv[0]); + fatalx("Unknown commands '%s'", argv[0]); argv_free(&argc, &argv); } @@ -980,10 +975,7 @@ user_getstr(const char *prompt, char **response) wrefresh(ui.command); /* allocate input space and clear */ - if ((input = calloc(MAX_INPUT_SIZE, sizeof(char))) == NULL) - err(1, "user_getstr: calloc(3) failed for input string"); - - bzero(input, MAX_INPUT_SIZE); + input = xcalloc(MAX_INPUT_SIZE, sizeof(char)); /* start getting input */ ret = 0; @@ -1039,7 +1031,7 @@ user_getstr(const char *prompt, char **response) /* see todo above - realloc input buffer here if position reaches max */ if (pos >= MAX_INPUT_SIZE) - errx(1, "user_getstr: shamefull limit reached"); + fatalx("user_getstr: shamefull limit reached"); } /* For lack of input, bail out */ @@ -1054,9 +1046,7 @@ user_getstr(const char *prompt, char **response) input[pos] = '\0'; /* trim the fat */ - if ((*response = calloc(strlen(input) + 1, sizeof(char))) == NULL) - err(1, "user_getstr: calloc(3) failed for result"); - + *response = xcalloc(strlen(input) + 1, sizeof(char)); snprintf(*response, strlen(input) + 1, "%s", input); end: diff --git a/commands.h b/commands.h index 521efe7..53b03b8 100644 --- a/commands.h +++ b/commands.h @@ -17,14 +17,9 @@ #ifndef COMMANDS_H #define COMMANDS_H -#include "compat.h" - -#include "enums.h" -#include "paint.h" -#include "str2argv.h" -#include "vitunes.h" -#include "debug.h" -#include "keybindings.h" +#include + +#include "playlist.h" /**************************************************************************** * Toggle-list handling stuff diff --git a/compat.c b/compat.c index 0e2d9f0..8cd144d 100644 --- a/compat.c +++ b/compat.c @@ -17,7 +17,7 @@ #include "compat.h" #ifdef COMPAT_NEED_FPARSELN -# include "compat/fparseln.c" +# include "fparseln.c" #endif #ifdef COMPAT_NEED_OPTRESET @@ -25,10 +25,10 @@ #endif #ifdef COMPAT_NEED_STRLCAT -# include "compat/strlcat.c" +# include "strlcat.c" #endif #ifdef COMPAT_NEED_STRTONUM -# include "compat/strtonum.c" +# include "strtonum.c" #endif diff --git a/doc/vitunes.1 b/doc/vitunes.1 index 7495bef..17e0d49 100644 --- a/doc/vitunes.1 +++ b/doc/vitunes.1 @@ -21,6 +21,7 @@ .Sh SYNOPSIS .Nm vitunes .Bk -words +.Op Fl v .Op Fl c Ar command .Op Fl d Ar database-file .Op Fl e Ar command Op argument ... @@ -138,6 +139,10 @@ will be created here. .Pp The default location is .Pa ~/.vitunes/playlists/ . +.It Fl v +Turn verbose logging on. +Log messages will be saved in the vitunes-debug.log file in the current +directory. .El .Sh GETTING STARTED .Nm diff --git a/ecmd.c b/ecmd.c index eb0fbdb..3478426 100644 --- a/ecmd.c +++ b/ecmd.c @@ -15,7 +15,13 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include +#include +#include + #include "ecmd.h" +#include "error.h" +#include "vitunes.h" static int ecmd_parse(const struct ecmd *ecmd, int argc, char ***argv) @@ -76,7 +82,7 @@ ecmd_exec(const char *ecmd, int argc, char **argv) } /* not found; bail out */ if (i == ecmdtab_size) { - warnx("Unknown e-command '%s'. See 'vitunes -e help' for list.", ecmd); + infox("Unknown e-command '%s'. See 'vitunes -e help' for list.", ecmd); return -1; } diff --git a/ecmd.h b/ecmd.h index 95c4a31..4ae8e47 100644 --- a/ecmd.h +++ b/ecmd.h @@ -18,13 +18,6 @@ #ifndef ECMD_H #define ECMD_H -#include -#include -#include -#include - -#include "vitunes.h" - struct ecmd { const char *name; const char *alias; /* may be NULL */ diff --git a/ecmd_addurl.c b/ecmd_addurl.c index bb58717..3c06352 100644 --- a/ecmd_addurl.c +++ b/ecmd_addurl.c @@ -15,15 +15,16 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include #include #include #include "ecmd.h" +#include "error.h" #include "medialib.h" #include "meta_info.h" #include "playlist.h" #include "vitunes.h" +#include "xmalloc.h" static void ecmd_addurl_exec(UNUSED int argc, char **argv) @@ -37,15 +38,14 @@ ecmd_addurl_exec(UNUSED int argc, char **argv) /* start new record, set filename */ m = mi_new(); m->is_url = true; - if ((m->filename = strdup(argv[0])) == NULL) - err(1, "%s: strdup failed (filename)", __FUNCTION__); + m->filename = xstrdup(argv[0]); /* get fields from user */ for (field = 0; field < MI_NUM_CINFO; field++) { printf("%10.10s: ", MI_CINFO_NAMES[field]); if (fgets(input, sizeof(input), stdin) == NULL) { - warnx("Operation canceled. Database unchanged."); + infox("Operation canceled. Database unchanged."); mi_free(m); return; } @@ -53,8 +53,7 @@ ecmd_addurl_exec(UNUSED int argc, char **argv) if (input[strlen(input) - 1] == '\n') input[strlen(input) - 1] = '\0'; - if ((m->cinfo[field] = strdup(input)) == NULL) - err(1, "%s: strdup failed (field)", __FUNCTION__); + m->cinfo[field] = xstrdup(input); } /* load existing database and see if file/URL already exists */ @@ -76,7 +75,7 @@ ecmd_addurl_exec(UNUSED int argc, char **argv) if (fgets(input, sizeof(input), stdin) == NULL || (strcasecmp(input, "yes\n") != 0 && strcasecmp(input, "y\n") != 0)) { - warnx("Operation Canceled. Database unchanged."); + infox("Operation Canceled. Database unchanged."); mi_free(m); medialib_destroy(); return; diff --git a/ecmd_check.c b/ecmd_check.c index dabfb49..8d6dfe7 100644 --- a/ecmd_check.c +++ b/ecmd_check.c @@ -15,12 +15,14 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include +#include #include +#include #include #include #include "ecmd.h" +#include "error.h" #include "medialib.h" #include "vitunes.h" @@ -39,7 +41,7 @@ ecmd_check_show_db(const char *path) if (show_database == false) return; if (realpath(path, realfile) == NULL) { - warn("realpath failed for %s: skipping", path); + info("realpath failed for %s: skipping", path); return; } @@ -55,7 +57,7 @@ ecmd_check_show_db(const char *path) } if (!found) - warnx("File '%s' does NOT exist in the database", path); + infox("File '%s' does NOT exist in the database", path); else { printf("\tThe meta-information in the DATABASE is:\n"); for (i = 0; i < MI_NUM_CINFO; i++) @@ -74,7 +76,7 @@ ecmd_check_show_raw(const char *path) if (show_raw == false) return; if ((mi = mi_extract(path)) == NULL) { - warnx("Failed to extract any meta-information from '%s'", path); + infox("Failed to extract any meta-information from '%s'", path); return; } @@ -92,7 +94,7 @@ ecmd_check_show_sanitized(const char *path) if (show_sanitized == false) return; if ((mi = mi_extract(path)) == NULL) { - warnx("Failed to extract any meta-information from '%s'", path); + infox("Failed to extract any meta-information from '%s'", path); return; } diff --git a/ecmd_flush.c b/ecmd_flush.c index 6eeb158..66a1d68 100644 --- a/ecmd_flush.c +++ b/ecmd_flush.c @@ -15,13 +15,14 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include #include #include #include "ecmd.h" +#include "error.h" #include "medialib.h" #include "vitunes.h" +#include "xmalloc.h" static char *time_format = "%Y %m %d %H:%M:%S"; @@ -33,8 +34,7 @@ ecmd_flush_parse(int argc, char **argv) while ((ch = getopt(argc, argv, "t:")) != -1) { switch (ch) { case 't': - if ((time_format = strdup(optarg)) == NULL) - err(1, "%s: strdup of time_format failed", argv[0]); + time_format = xstrdup(optarg); break; case '?': case 'h': diff --git a/ecmd_help.c b/ecmd_help.c index ad85528..15bb476 100644 --- a/ecmd_help.c +++ b/ecmd_help.c @@ -15,13 +15,14 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include #include #include #include #include "ecmd.h" +#include "error.h" #include "vitunes.h" +#include "xmalloc.h" static void ecmd_help_exec(UNUSED int argc, char **argv) @@ -60,12 +61,11 @@ The list of available commands are:\n\n\ } man_args[0] = "man"; - if (asprintf(&man_args[1], "vitunes-%s", argv[0]) == -1) - err(1, "ecmd_help: asprintf failed"); + xasprintf(&man_args[1], "vitunes-%s", argv[0]); man_args[2] = NULL; execvp("man", man_args); - err(1, "ecmd_help: execvp failed"); + fatal("ecmd_help: execvp failed"); } const struct ecmd ecmd_help = { diff --git a/ecmd_rmfile.c b/ecmd_rmfile.c index 39af3cf..ff49675 100644 --- a/ecmd_rmfile.c +++ b/ecmd_rmfile.c @@ -15,12 +15,13 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include #include +#include #include #include #include "ecmd.h" +#include "error.h" #include "medialib.h" #include "playlist.h" #include "vitunes.h" @@ -69,7 +70,8 @@ ecmd_rmfile_exec(UNUSED int argc, char **argv) /* if not found then error */ if (!found) { i = (forced ? 0 : 1); - errx(i, "%s: %s: No such file or URL", argv[0], argv[0]); + infox("%s: No such file or URL", argv[0]); + exit(i); } /* if not forced, prompt user if they are sure */ @@ -77,7 +79,7 @@ ecmd_rmfile_exec(UNUSED int argc, char **argv) printf("Are you sure you want to delete '%s'? [y/n] ", argv[0]); if (fgets(input, sizeof(input), stdin) == NULL || (strcasecmp(input, "yes\n") != 0 && strcasecmp(input, "y\n") != 0)) - errx(1, "Operation canceled. Database unchanged."); + fatalx("Operation canceled. Database unchanged."); } playlist_files_remove(mdb.library, found_idx, 1, false); diff --git a/ecmd_tag.c b/ecmd_tag.c index d17c7cd..b4f3c85 100644 --- a/ecmd_tag.c +++ b/ecmd_tag.c @@ -15,14 +15,18 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include +#include #include #include #include #include +#include + #include "ecmd.h" +#include "error.h" #include "meta_info.h" +#include "xmalloc.h" static char *artist; static char *album; @@ -42,38 +46,33 @@ ecmd_tag_parse(int argc, char **argv) switch (ch) { case 'A': free(album); - if ((album = strdup(optarg)) == NULL) - err(1, "%s: strdup ALBUM failed", argv[0]); + album = xstrdup(optarg); break; case 'T': track = (unsigned int) strtonum(optarg, 0, INT_MAX, &errstr); if (errstr != NULL) - errx(1, "invalid track '%s': %s", optarg, errstr); + fatalx("invalid track '%s': %s", optarg, errstr); break; case 'a': free(artist); - if ((artist = strdup(optarg)) == NULL) - err(1, "%s: strdup ARTIST failed", argv[0]); + artist = xstrdup(optarg); break; case 'c': free(comment); - if ((comment = strdup(optarg)) == NULL) - err(1, "%s: strdup COMMENT failed", argv[0]); + comment = xstrdup(optarg); break; case 'g': free(genre); - if ((genre = strdup(optarg)) == NULL) - err(1, "%s: strdup GENRE failed", argv[0]); + genre = xstrdup(optarg); break; case 't': free(title); - if ((title = strdup(optarg)) == NULL) - err(1, "%s: strdup TITLE failed", argv[0]); + title = xstrdup(optarg); break; case 'y': year = (unsigned int) strtonum(optarg, 0, INT_MAX, &errstr); if (errstr != NULL) - errx(1, "invalid year '%s': %s", optarg, errstr); + fatalx("invalid year '%s': %s", optarg, errstr); break; case 'h': case '?': @@ -119,8 +118,8 @@ ecmd_tag_exec(int argc, char **argv) /* extract taglib stuff */ if ((tag_file = taglib_file_new(argv[i])) == NULL) { - warnx("TagLib: failed to open file '%s': skipping.", argv[i]); - warnx(" => Causes: format not supported by TagLib or format doesn't support tags"); + infox("TagLib: failed to open file '%s': skipping.", argv[i]); + infox(" => Causes: format not supported by TagLib or format doesn't support tags"); continue; } diff --git a/error.c b/error.c new file mode 100644 index 0000000..0b7d4c9 --- /dev/null +++ b/error.c @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2010, 2011, 2012 Ryan Flannery + * Copyright (c) 2013 Tiago Cunha + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "error.h" +#include "paint.h" +#include "uinterface.h" +#include "vitunes.h" + +static FILE *error_fp; /* error debug file */ +static int error_type; /* error type which depends on the context */ + +/* + * Starts by fetching the needed attributes that depend on the type of the + * message. It, then, paints it to the command/status window and, if wanted + * appends the errno message string. A beep is also issued if it's an error + * message. + */ +static void +error_paint(bool errnoflag, bool iserr, const char *fmt, va_list ap) +{ + int attrs, which; + + which = iserr ? colors.errors : colors.messages; + attrs = COLOR_PAIR(which); + + werase(ui.command); + wmove(ui.command, 0, 0); + wattron(ui.command, attrs); + vwprintw(ui.command, fmt, ap); + + if (errnoflag) + wprintw(ui.command, ": %s", strerror(errno)); + if (iserr) + beep(); + + wattroff(ui.command, attrs); + wrefresh(ui.command); +} + +/* + * Prints the provided error message to standard error and, if wanted, appends + * the errno message string. + */ +static void +error_file(FILE *fp, bool errnoflag, const char *fmt, va_list ap) +{ + fprintf(fp, "%s:", progname); + if (error_type == ERROR_CFG) + fprintf(fp, " %s line %zd:", conf_file, conf_linenum); + + fputs(" ", fp); + vfprintf(fp, fmt, ap); + + if (errnoflag) + fprintf(fp, ": %s", strerror(errno)); + fputs("\n", fp); +} + +/* + * Prints a fatal message (informational messages are pointless in this context) + * and terminates the process. + */ +static void +error_cfg(bool errnoflag, bool iserr, const char *fmt, va_list ap) +{ + if (!iserr) + return; + + endwin(); + error_file(stderr, errnoflag, fmt, ap); + exit(1); +} + +/* + * Prints a message to standard error and terminates the process if it's an + * error. + */ +static void +error_stderr(bool errnoflag, bool iserr, const char *fmt, va_list ap) +{ + error_file(stderr, errnoflag, fmt, ap); + if (iserr) + exit(1); +} + +/* + * Check which context we are in and call the function responsible to output the + * error message. + */ +static void +error_doit(bool errnoflag, bool iserr, const char *fmt, va_list ap) +{ + switch (error_type) { + case ERROR_CFG: + error_cfg(errnoflag, iserr, fmt, ap); + break; + case ERROR_PAINT: + error_paint(errnoflag, iserr, fmt, ap); + break; + default: + error_stderr(errnoflag, iserr, fmt, ap); + break; + } +} + +/* Outputs a message if debugging is turned on. */ +void +debug(const char *fmt, ...) +{ + va_list ap; + + if (error_fp == NULL) + return; + + va_start(ap, fmt); + error_file(error_fp, false, fmt, ap); + va_end(ap); +} + +void +error_init(int type) +{ + error_type = type; +} + +void +error_open(void) +{ + if (error_fp != NULL) + return; + if ((error_fp = fopen(ERROR_LOG_PATH, "w")) == NULL) + error_file(stderr, true, "%s: fopen", ERROR_LOG_PATH); +} + +/* + * Outputs a fatal message with the errno message string appended and terminates + * the process. + */ +void +die(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + error_file(stderr, true, fmt, ap); + va_end(ap); + exit(1); +} + +/* Outputs a fatal message and terminates the process. */ +void +diex(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + error_file(stderr, false, fmt, ap); + va_end(ap); + exit(1); +} + +/* Outputs a fatal message with the errno message string appended. */ +void +fatal(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + error_doit(true, true, fmt, ap); + va_end(ap); +} + +/* Outputs a fatal message. */ +void +fatalx(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + error_doit(false, true, fmt, ap); + va_end(ap); +} + +/* Outputs an informational message with the errno message string appended. */ +void +info(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + error_doit(true, false, fmt, ap); + va_end(ap); +} + +/* Outputs an informational message. */ +void +infox(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + error_doit(false, false, fmt, ap); + va_end(ap); +} diff --git a/error.h b/error.h new file mode 100644 index 0000000..27396b2 --- /dev/null +++ b/error.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2013 Tiago Cunha + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef ERROR_H +#define ERROR_H + +#define ERROR_LOG_PATH "vitunes-debug.log" + +#define ERROR_STDERR 0 +#define ERROR_CFG 1 +#define ERROR_PAINT 2 + +void debug(const char *, ...); +void die(const char *, ...); +void diex(const char *, ...); +void error_init(int); +void error_open(void); +void fatal(const char *, ...); +void fatalx(const char *, ...); +void info(const char *, ...); +void infox(const char *, ...); + +#endif diff --git a/add_urls.sh b/examples/add_urls.sh similarity index 100% rename from add_urls.sh rename to examples/add_urls.sh diff --git a/keybindings.c b/keybindings.c index 242e868..9744894 100644 --- a/keybindings.c +++ b/keybindings.c @@ -14,8 +14,22 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include +#include +#include + +#include "commands.h" +#include "compat.h" +#include "enums.h" +#include "error.h" #include "keybindings.h" - +#include "medialib.h" +#include "paint.h" +#include "player.h" +#include "str2argv.h" +#include "uinterface.h" +#include "vitunes.h" +#include "xmalloc.h" /* This table maps KeyActions to their string representations */ typedef struct { @@ -255,15 +269,8 @@ size_t KeyBindingsCapacity; void kb_increase_capacity() { - KeyBinding *new_buffer; - size_t nbytes; - KeyBindingsCapacity += KEYBINDINGS_CHUNK_SIZE; - nbytes = KeyBindingsCapacity * sizeof(KeyBinding); - if ((new_buffer = realloc(KeyBindings, nbytes)) == NULL) - err(1, "%s: failed to realloc(3) keybindings", __FUNCTION__); - - KeyBindings = new_buffer; + KeyBindings = xrealloc(KeyBindings, KeyBindingsCapacity, sizeof(KeyBinding)); } @@ -487,7 +494,7 @@ kba_scroll_row(KbaArgs a) ui.active->crow -= n; break; default: - errx(1, "%s: invalid direction", __FUNCTION__); + fatalx("%s: invalid direction", __FUNCTION__); } /* handle off-the-edge cases */ @@ -551,7 +558,8 @@ kba_scroll_page(KbaArgs a) maintain_row_idx = false; break; default: - errx(1, "scroll_page: invalid amount"); + fatalx("scroll_page: invalid amount"); + return; } swindow_scroll(ui.active, a.direction, diff); @@ -647,11 +655,11 @@ kba_scroll_col(KbaArgs a) ui.active->hoffset = maxhoff; break; default: - errx(1, "scroll_col: invalid direction"); + fatalx("scroll_col: invalid direction"); } break; default: - errx(1, "scroll_col: invalid amount"); + fatalx("scroll_col: invalid amount"); } /* redraw */ @@ -690,7 +698,7 @@ kba_jumpto_screen(KbaArgs a) ui.active->crow = max_row - n + 1; break; default: - errx(1, "jumpto_page: invalid location"); + fatalx("jumpto_page: invalid location"); } /* sanitize current row */ @@ -753,7 +761,8 @@ kba_jumpto_file(KbaArgs a) break; default: - errx(1, "jumpto_file: NUMBER type with no num!"); + fatalx("jumpto_file: NUMBER type with no num!"); + return; } break; @@ -767,7 +776,8 @@ kba_jumpto_file(KbaArgs a) break; default: - errx(1, "jumpto_file: invalid scale"); + fatalx("jumpto_file: invalid scale"); + return; } /* jump */ @@ -821,7 +831,7 @@ kba_search(KbaArgs a) prompt = "?"; break; default: - errx(1, "search: invalid direction"); + fatalx("search: invalid direction"); } /* get search phrase from user */ @@ -832,7 +842,7 @@ kba_search(KbaArgs a) /* set the global query description and the search direction */ if (str2argv(search_phrase, &argc, &argv, &errmsg) != 0) { - paint_error("parse error: %s in '%s'", errmsg, search_phrase); + fatalx("parse error: %s in '%s'", errmsg, search_phrase); free(search_phrase); return; } @@ -878,7 +888,8 @@ kba_search_find(KbaArgs a) break; default: - errx(1, "search_find: invalid direction"); + fatalx("search_find: invalid direction"); + return; } /* start looking from current row */ @@ -911,7 +922,7 @@ kba_search_find(KbaArgs a) /* found one, jump to it */ if (matches) { if (msg != NULL) - paint_message(msg); + infox("%s", msg); gnum_set(idx + 1); foo = get_dummy_args(); @@ -922,7 +933,7 @@ kba_search_find(KbaArgs a) } } - paint_error("Pattern not found: %s", mi_query_getraw()); + fatalx("Pattern not found: %s", mi_query_getraw()); } @@ -930,7 +941,7 @@ void kba_visual(KbaArgs a UNUSED) { if (ui.active == ui.library) { - paint_message("No visual mode in library window. Sorry."); + infox("No visual mode in library window. Sorry."); return; } @@ -1005,7 +1016,7 @@ kba_cut(KbaArgs a UNUSED) } if (start >= ui.active->nrows) { - paint_message("nothing to delete here!"); + infox("nothing to delete here!"); return; } @@ -1020,25 +1031,24 @@ kba_cut(KbaArgs a UNUSED) * while drunk. */ if (end != start + 1) { - paint_error("cannot delete multiple playlists"); + fatalx("cannot delete multiple playlists"); return; } if (p == mdb.library || p == mdb.filter_results) { - paint_error("cannot delete pseudo-playlists like LIBRARY or FILTER"); + fatalx("cannot delete pseudo-playlists like LIBRARY or FILTER"); return; } - if (asprintf(&warning, "Are you sure you want to delete '%s'?", p->name) == -1) - err(1, "cut: asprintf failed"); + xasprintf(&warning, "Are you sure you want to delete '%s'?", p->name); /* make sure user wants this */ if (user_get_yesno(warning, &response) != 0) { - paint_message("delete of '%s' cancelled", p->name); + infox("delete of '%s' cancelled", p->name); free(warning); return; } if (response != 1) { - paint_message("playlist '%s' not deleted", p->name); + infox("playlist '%s' not deleted", p->name); free(warning); return; } @@ -1066,7 +1076,7 @@ kba_cut(KbaArgs a UNUSED) /* can't delete from library */ if (viewing_playlist == mdb.library) { - paint_error("cannot delete from library"); + fatalx("cannot delete from library"); return; } @@ -1092,7 +1102,7 @@ kba_cut(KbaArgs a UNUSED) /* redraw */ paint_playlist(); paint_library(); - paint_message("%d fewer files.", end - start); + infox("%d fewer files.", end - start); } void @@ -1104,12 +1114,12 @@ kba_yank(KbaArgs a UNUSED) int n; if (ui.active == ui.library) { - paint_error("cannot yank in library window"); + fatalx("cannot yank in library window"); return; } if (viewing_playlist->nfiles == 0) { - paint_error("nothing to yank!"); + fatalx("nothing to yank!"); return; } @@ -1175,7 +1185,7 @@ kba_yank(KbaArgs a UNUSED) paint_playlist(); /* notify user # of rows yanked */ - paint_message("Yanked %d files.", end - start); + infox("Yanked %d files.", end - start); } void @@ -1185,7 +1195,7 @@ kba_paste(KbaArgs a) int start = 0; if (_yank_buffer.nfiles == 0) { - paint_error("nothing to paste"); + fatalx("nothing to paste"); return; } @@ -1199,7 +1209,7 @@ kba_paste(KbaArgs a) /* can't alter library */ if (p == mdb.library) { - paint_error("Cannot alter %s pseudo-playlist", mdb.library->name); + fatalx("Cannot alter %s pseudo-playlist", mdb.library->name); return; } @@ -1213,7 +1223,7 @@ kba_paste(KbaArgs a) start = p->nfiles; break; default: - errx(1, "paste: invalid placement [if]"); + fatalx("paste: invalid placement [if]"); } } else { @@ -1227,7 +1237,7 @@ kba_paste(KbaArgs a) if (start > p->nfiles) start = p->nfiles; break; default: - errx(1, "paste: invalid placement [else]"); + fatalx("paste: invalid placement [else]"); } } @@ -1243,9 +1253,9 @@ kba_paste(KbaArgs a) paint_library(); paint_playlist(); if (ui.active == ui.library) - paint_message("Pasted %d files to '%s'", _yank_buffer.nfiles, p->name); + infox("Pasted %d files to '%s'", _yank_buffer.nfiles, p->name); else - paint_message("Pasted %d files.", _yank_buffer.nfiles); + infox("Pasted %d files.", _yank_buffer.nfiles); } @@ -1253,14 +1263,14 @@ void kba_undo(KbaArgs a UNUSED) { if (ui.active == ui.library) { - paint_message("Cannot undo in library window."); + infox("Cannot undo in library window."); return; } if (playlist_undo(viewing_playlist) != 0) - paint_message("Nothing to undo."); + infox("Nothing to undo."); else - paint_message("Undo successfull."); + infox("Undo successfull."); /* TODO more informative message like in vim */ @@ -1275,14 +1285,14 @@ void kba_redo(KbaArgs a UNUSED) { if (ui.active == ui.library) { - paint_message("Cannot redo in library window."); + infox("Cannot redo in library window."); return; } if (playlist_redo(viewing_playlist) != 0) - paint_message("Nothing to redo."); + infox("Nothing to redo."); else - paint_message("Redo successfull."); + infox("Redo successfull."); /* TODO */ @@ -1368,7 +1378,7 @@ kba_show_file_info(KbaArgs a UNUSED) return; if (ui.active->crow >= ui.active->nrows) { - paint_message("no file here"); + infox("no file here"); return; } @@ -1398,7 +1408,7 @@ kba_load_playlist(KbaArgs a UNUSED) } else { /* play song */ if (ui.active->crow >= ui.active->nrows) { - paint_message("no file here"); + infox("no file here"); return; } player_set_queue(viewing_playlist, ui.active->voffset + ui.active->crow); @@ -1424,7 +1434,7 @@ kba_play(KbaArgs a UNUSED) } else { /* play song */ if (ui.active->crow >= ui.active->nrows) { - paint_message("no file here"); + infox("no file here"); return; } player_set_queue(viewing_playlist, ui.active->voffset + ui.active->crow); @@ -1491,7 +1501,7 @@ kba_volume(KbaArgs a) pcnt *= -1; break; default: - errx(1, "kba_volume: invalid direction"); + fatalx("kba_volume: invalid direction"); } player_volume_step(pcnt); @@ -1511,7 +1521,8 @@ kba_seek(KbaArgs a) secs = a.num * 60; break; default: - errx(1, "seek_playback: invalid scale"); + fatalx("seek_playback: invalid scale"); + return; } /* adjust for direction */ @@ -1523,7 +1534,8 @@ kba_seek(KbaArgs a) secs *= -1; break; default: - errx(1, "seek_playback: invalid direction"); + fatalx("seek_playback: invalid direction"); + return; } /* is there a multiplier? */ @@ -1568,7 +1580,7 @@ kba_toggle(KbaArgs a) /* get the command to execute */ if ((t = toggle_get(registr)) == NULL) { - paint_error("No toggle list in register %c (%i).", registr, registr); + fatalx("No toggle list in register %c (%i).", registr, registr); return; } @@ -1588,7 +1600,7 @@ kba_toggle(KbaArgs a) } break; default: - errx(1, "%s: invalid direction", __FUNCTION__); + fatalx("%s: invalid direction", __FUNCTION__); } /* execute */ @@ -1657,10 +1669,7 @@ yank_buffer _yank_buffer; void ybuffer_init() { - _yank_buffer.files = calloc(YANK_BUFFER_CHUNK_SIZE, sizeof(meta_info*)); - if (_yank_buffer.files == NULL) - err(1, "ybuffer_init: calloc(3) failed"); - + _yank_buffer.files = xcalloc(YANK_BUFFER_CHUNK_SIZE, sizeof(meta_info*)); _yank_buffer.capacity = YANK_BUFFER_CHUNK_SIZE; _yank_buffer.nfiles = 0; } @@ -1682,16 +1691,11 @@ ybuffer_free() void ybuffer_add(meta_info *f) { - meta_info **new_buff; - /* do we need to realloc()? */ if (_yank_buffer.nfiles == _yank_buffer.capacity) { _yank_buffer.capacity += YANK_BUFFER_CHUNK_SIZE; - int new_capacity = _yank_buffer.capacity * sizeof(meta_info*); - if ((new_buff = realloc(_yank_buffer.files, new_capacity)) == NULL) - err(1, "ybuffer_add: realloc(3) failed [%i]", new_capacity); - - _yank_buffer.files = new_buff; + _yank_buffer.files = xrealloc(_yank_buffer.files, _yank_buffer.capacity, + sizeof(meta_info *)); } /* add the file */ @@ -1733,8 +1737,7 @@ match_command_name(const char *input, const char *cmd) /* check for '!' weirdness and abbreviations */ - if ((icopy = strdup(input)) == NULL) - err(1, "match_command_name: strdup(3) failed"); + icopy = xstrdup(input); /* remove '!' from input, if present */ if (strstr(icopy, "!") != NULL) diff --git a/keybindings.h b/keybindings.h index 4ad5ccb..5df52d7 100644 --- a/keybindings.h +++ b/keybindings.h @@ -17,12 +17,9 @@ #ifndef KEYBINDINGS_H #define KEYBINDINGS_H -#include "compat.h" +#include -#include "debug.h" -#include "enums.h" -#include "paint.h" -#include "vitunes.h" +#include "meta_info.h" /* * List of all actions that can be bound by keybindings. diff --git a/medialib.c b/medialib.c index 35cfd2e..f577743 100644 --- a/medialib.c +++ b/medialib.c @@ -14,7 +14,22 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "compat.h" +#include "error.h" #include "medialib.h" +#include "meta_info.h" +#include "playlist.h" +#include "xmalloc.h" /* The global media library struct */ medialib mdb; @@ -32,22 +47,17 @@ medialib_load(const char *db_file, const char *playlist_dir) int i; /* copy file/directory names */ - mdb.db_file = strdup(db_file); - mdb.playlist_dir = strdup(playlist_dir); - if (mdb.db_file == NULL || mdb.playlist_dir == NULL) - err(1, "failed to strdup db file and playlist dir in medialib_init"); + mdb.db_file = xstrdup(db_file); + mdb.playlist_dir = xstrdup(playlist_dir); /* setup pseudo-playlists */ mdb.library = playlist_new(); mdb.library->filename = NULL; - mdb.library->name = strdup("--LIBRARY--"); + mdb.library->name = xstrdup("--LIBRARY--"); mdb.filter_results = playlist_new(); mdb.filter_results->filename = NULL; - mdb.filter_results->name = strdup("--FILTER--"); - - if (mdb.library->name == NULL || mdb.filter_results->name == NULL) - err(1, "failed to strdup pseudo-names in medialib_load"); + mdb.filter_results->name = xstrdup("--FILTER--"); /* load the actual database */ medialib_db_load(db_file); @@ -55,9 +65,7 @@ medialib_load(const char *db_file, const char *playlist_dir) /* setup initial record keeping for playlists */ mdb.nplaylists = 0; mdb.playlists_capacity = 2; - mdb.playlists = calloc(2, sizeof(playlist*)); - if (mdb.playlists == NULL) - err(1, "medialib_load: failed to allocate initial playlists"); + mdb.playlists = xcalloc(2, sizeof(playlist*)); /* add library/filter pseudo-playlists */ medialib_playlist_add(mdb.library); @@ -65,17 +73,18 @@ medialib_load(const char *db_file, const char *playlist_dir) /* load the rest */ npfiles = retrieve_playlist_filenames(mdb.playlist_dir, &pfiles); - for (i = 0; i < npfiles; i++) { - p = playlist_load(pfiles[i], mdb.library->files, mdb.library->nfiles); - medialib_playlist_add(p); - free(pfiles[i]); + if (npfiles) { + for (i = 0; i < npfiles; i++) { + p = playlist_load(pfiles[i], mdb.library->files, mdb.library->nfiles); + medialib_playlist_add(p); + free(pfiles[i]); + } + free(pfiles); } /* set all playlists as saved initially */ for (i = 0; i < mdb.nplaylists; i++) mdb.playlists[i]->needs_saving = false; - - free(pfiles); } /* free() all memory associated with global media library */ @@ -106,16 +115,11 @@ medialib_destroy() void medialib_playlist_add(playlist *p) { - playlist **new_playlists; - /* check to see if we need to resize the array */ if (mdb.nplaylists == mdb.playlists_capacity) { mdb.playlists_capacity += MEDIALIB_PLAYLISTS_CHUNK_SIZE; - int size = mdb.playlists_capacity * sizeof(playlist*); - if ((new_playlists = realloc(mdb.playlists, size)) == NULL) - err(1, "medialib_playlist_add: realloc failed"); - - mdb.playlists = new_playlists; + mdb.playlists = xrealloc(mdb.playlists, mdb.playlists_capacity, + sizeof(playlist *)); } mdb.playlists[mdb.nplaylists++] = p; @@ -131,7 +135,7 @@ medialib_playlist_remove(int pindex) int i; if (pindex < 0 || pindex >= mdb.nplaylists) - errx(1, "medialib_playlist_remove: index %d out of range", pindex); + fatalx("medialib_playlist_remove: index %d out of range", pindex); playlist_delete(mdb.playlists[pindex]); @@ -155,20 +159,20 @@ medialib_setup_files(const char *vitunes_dir, const char *db_file, /* create vitunes directory */ if (mkdir(vitunes_dir, S_IRWXU) == -1) { if (errno == EEXIST) - warnx("vitunes directory '%s' already exists (OK)", vitunes_dir); + infox("vitunes directory '%s' already exists (OK)", vitunes_dir); else - err(1, "unable to create vitunes directory '%s'", vitunes_dir); + fatal("unable to create vitunes directory '%s'", vitunes_dir); } else - warnx("vitunes directory '%s' created", vitunes_dir); + infox("vitunes directory '%s' created", vitunes_dir); /* create playlists directory */ if (mkdir(playlist_dir, S_IRWXU) == -1) { if (errno == EEXIST) - warnx("playlists directory '%s' already exists (OK)", playlist_dir); + infox("playlists directory '%s' already exists (OK)", playlist_dir); else - err(1, "unable to create playlists directory '%s'", playlist_dir); + fatal("unable to create playlists directory '%s'", playlist_dir); } else - warnx("playlists directory '%s' created", playlist_dir); + infox("playlists directory '%s' created", playlist_dir); /* create database file */ if (stat(db_file, &sb) < 0) { @@ -179,18 +183,18 @@ medialib_setup_files(const char *vitunes_dir, const char *db_file, /* open for writing */ if ((f = fopen(db_file, "w")) == NULL) - err(1, "failed to create database file '%s'", db_file); + fatal("failed to create database file '%s'", db_file); /* save header & version */ fwrite("vitunes", strlen("vitunes"), 1, f); fwrite(version, sizeof(version), 1, f); - warnx("empty database at '%s' created", db_file); + infox("empty database at '%s' created", db_file); fclose(f); } else - err(1, "database file '%s' exists, but cannot access it", db_file); + fatal("database file '%s' exists, but cannot access it", db_file); } else - warnx("database file '%s' already exists (OK)", db_file); + infox("database file '%s' already exists (OK)", db_file); } /* used to sort media db by filenames. */ @@ -214,12 +218,12 @@ medialib_db_load(const char *db_file) int version[3]; if ((fin = fopen(db_file, "r")) == NULL) - err(1, "Failed to open database file '%s'", db_file); + fatal("Failed to open database file '%s'", db_file); /* read and check header & version */ fread(header, strlen("vitunes"), 1, fin); if (strncmp(header, "vitunes", strlen("vitunes")) != 0) - errx(1, "Database file '%s' NOT a vitunes database", db_file); + fatalx("Database file '%s' NOT a vitunes database", db_file); fread(version, sizeof(version), 1, fin); if (version[0] != DB_VERSION_MAJOR || version[1] != DB_VERSION_MINOR @@ -244,7 +248,7 @@ medialib_db_load(const char *db_file) if (feof(fin)) mi_free(mi); else if (ferror(fin)) - err(1, "Error loading database file '%s'", db_file); + fatal("Error loading database file '%s'", db_file); else playlist_files_append(mdb.library, &mi, 1, false); } @@ -264,7 +268,7 @@ medialib_db_save(const char *db_file) int i; if ((fout = fopen(db_file, "w")) == NULL) - err(1, "medialib_db_save: failed to open database file '%s'", db_file); + fatal("medialib_db_save: failed to open database file '%s'", db_file); /* save header & version */ fwrite("vitunes", strlen("vitunes"), 1, fout); @@ -274,7 +278,7 @@ medialib_db_save(const char *db_file) for (i = 0; i < mdb.library->nfiles; i++) { mi_fwrite(mdb.library->files[i], fout); if (ferror(fout)) - err(1, "medialib_db_save: error saving database"); + fatal("medialib_db_save: error saving database"); } fclose(fout); @@ -449,7 +453,7 @@ medialib_db_scan_dirs(char *dirlist[]) fts = fts_open(dirlist, FTS_LOGICAL | FTS_NOCHDIR, NULL); if (fts == NULL) - err(1, "medialib_db_scan_dirs: fts_open failed"); + fatal("medialib_db_scan_dirs: fts_open failed"); while ((ftsent = fts_read(fts)) != NULL) { @@ -476,7 +480,7 @@ medialib_db_scan_dirs(char *dirlist[]) /* get the full name for the file */ if (realpath(ftsent->fts_accpath, fullname) == NULL) { - err(1, "medialib_db_scan_dirs: realpath failed for '%s'", + fatal("medialib_db_scan_dirs: realpath failed for '%s'", ftsent->fts_accpath); } @@ -536,7 +540,7 @@ medialib_db_scan_dirs(char *dirlist[]) } if (fts_close(fts) == -1) - err(1, "medialib_db_scan_dirs: failed to close file heirarchy"); + fatal("medialib_db_scan_dirs: failed to close file heirarchy"); /* save to file */ medialib_db_save(mdb.db_file); diff --git a/medialib.h b/medialib.h index 5f6e3af..20e707d 100644 --- a/medialib.h +++ b/medialib.h @@ -25,19 +25,6 @@ #ifndef MEDIALIB_H #define MEDIALIB_H -#include "compat.h" - -#include -#include -#include - -#include -#include -#include -#include - -#include "debug.h" -#include "meta_info.h" #include "playlist.h" #define MEDIALIB_PLAYLISTS_CHUNK_SIZE 100 diff --git a/meta_info.c b/meta_info.c index b2c81d2..be446c8 100644 --- a/meta_info.c +++ b/meta_info.c @@ -14,7 +14,25 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* non-baes includes (just TagLib) */ +#include + +#include "compat.h" +#include "enums.h" +#include "error.h" #include "meta_info.h" +#include "xmalloc.h" /* human-readable names of all of the string-type meta information values */ const char *MI_CINFO_NAMES[] = { @@ -38,9 +56,7 @@ mi_new(void) meta_info *mi; int i; - if ((mi = malloc(sizeof(meta_info))) == NULL) - err(1, "mi_new: meta_info malloc failed"); - + mi = xmalloc(sizeof(meta_info)); mi->filename = NULL; mi->length = 0; mi->last_updated = 0; @@ -111,18 +127,11 @@ mi_fread(meta_info *mi, FILE *fin) fread(lengths, sizeof(lengths), 1, fin); /* allocate all needed space in the meta_info struct, and zero */ - if ((mi->filename = calloc(lengths[0] + 1, sizeof(char))) == NULL) - err(1, "mi_fread: calloc filename failed"); - - bzero(mi->filename, sizeof(char) * (lengths[0] + 1)); + mi->filename = xcalloc(lengths[0] + 1, sizeof(char)); for (i = 0; i < MI_NUM_CINFO; i++) { - if (lengths[i+1] > 0) { - if ((mi->cinfo[i] = calloc(lengths[i+1] + 1, sizeof(char))) == NULL) - err(1, "mi_fread: failed to calloc cinfo"); - - bzero(mi->cinfo[i], sizeof(char) * (lengths[i+1] + 1)); - } + if (lengths[i+1] > 0) + mi->cinfo[i] = xcalloc(lengths[i+1] + 1, sizeof(char)); } /* read */ @@ -181,10 +190,9 @@ mi_extract(const char *filename) /* store full filename in meta_info struct */ bzero(fullname, sizeof(fullname)); if (realpath(filename, fullname) == NULL) - err(1, "mi_extract: realpath failed to resolve '%s'", filename); + fatal("mi_extract: realpath failed to resolve '%s'", filename); - if ((mi->filename = strdup(fullname)) == NULL) - errx(1, "mi_extract: strdup failed for '%s'", fullname); + mi->filename = xstrdup(fullname); /* start extracting fields using TagLib... */ @@ -202,45 +210,32 @@ mi_extract(const char *filename) /* artist/album/title/genre */ if ((str = taglib_tag_artist(tag)) != NULL) - mi->cinfo[MI_CINFO_ARTIST] = strdup(str); + mi->cinfo[MI_CINFO_ARTIST] = xstrdup(str); if ((str = taglib_tag_album(tag)) != NULL) - mi->cinfo[MI_CINFO_ALBUM] = strdup(str); + mi->cinfo[MI_CINFO_ALBUM] = xstrdup(str); if ((str = taglib_tag_title(tag)) != NULL) - mi->cinfo[MI_CINFO_TITLE] = strdup(str); + mi->cinfo[MI_CINFO_TITLE] = xstrdup(str); if ((str = taglib_tag_genre(tag)) != NULL) - mi->cinfo[MI_CINFO_GENRE] = strdup(str); + mi->cinfo[MI_CINFO_GENRE] = xstrdup(str); if ((str = taglib_tag_comment(tag)) != NULL) - mi->cinfo[MI_CINFO_COMMENT] = strdup(str); - - if (mi->cinfo[MI_CINFO_ARTIST] == NULL - || mi->cinfo[MI_CINFO_ALBUM] == NULL - || mi->cinfo[MI_CINFO_TITLE] == NULL - || mi->cinfo[MI_CINFO_GENRE] == NULL - || mi->cinfo[MI_CINFO_COMMENT] == NULL) - err(1, "mi_extract: strdup for CINFO failed"); + mi->cinfo[MI_CINFO_COMMENT] = xstrdup(str); /* track number */ - if (taglib_tag_track(tag) > 0) { - if (asprintf(&(mi->cinfo[MI_CINFO_TRACK]), "%3i", taglib_tag_track(tag)) == -1) - err(1, "mi_extract: asprintf failed for CINFO_TRACK"); - } + if (taglib_tag_track(tag) > 0) + xasprintf(&(mi->cinfo[MI_CINFO_TRACK]), "%3i", taglib_tag_track(tag)); /* year */ - if (taglib_tag_year(tag) > 0) { - if (asprintf(&(mi->cinfo[MI_CINFO_YEAR]), "%i", taglib_tag_year(tag)) == -1) - err(1, "mi_extract: asprintf failed for CINFO_YEAR"); - } + if (taglib_tag_year(tag) > 0) + xasprintf(&(mi->cinfo[MI_CINFO_YEAR]), "%i", taglib_tag_year(tag)); /* playlength in seconds (will be 0 if unavailable) */ mi->length = taglib_audioproperties_length(properties); - if (mi->length > 0) { - if ((mi->cinfo[MI_CINFO_LENGTH] = strdup(time2str(mi->length))) == NULL) - err(1, "mi_extract: strdup failed for CINO_LENGTH"); - } + if (mi->length > 0) + mi->cinfo[MI_CINFO_LENGTH] = xstrdup(time2str(mi->length)); /* record the time we extracted this info */ time(&mi->last_updated); @@ -336,7 +331,7 @@ void mi_query_add_token(const char *token) { if (_mi_query.ntokens == MI_MAX_QUERY_TOKENS) - errx(1, "mi_query_add_token: reached shamefull limit"); + fatalx("mi_query_add_token: reached shamefull limit"); /* match or no? */ if (token[0] == '!') { @@ -346,8 +341,7 @@ mi_query_add_token(const char *token) _mi_query.match[_mi_query.ntokens] = true; /* copy token */ - if ((_mi_query.tokens[_mi_query.ntokens++] = strdup(token)) == NULL) - err(1, "mi_query_add_token: strdup failed"); + _mi_query.tokens[_mi_query.ntokens++] = xstrdup(token); } void @@ -356,8 +350,7 @@ mi_query_setraw(const char *query) if (_mi_query.raw != NULL) free(_mi_query.raw); - if ((_mi_query.raw = strdup(query)) == NULL) - err(1, "mi_query_setraw: query strdup failed"); + _mi_query.raw = xstrdup(query); } const char * @@ -491,9 +484,7 @@ mi_sort_set(const char *s, const char **errmsg) }; *errmsg = NULL; - if ((line = strdup(s)) == NULL) - err(1, "mi_sort_set: sort strdup failed"); - + line = xstrdup(s); idx = 0; copy = line; @@ -699,9 +690,7 @@ mi_display_set(const char *display, const char **errmsg) *errmsg = NULL; new_display.nfields = 0; - if ((s = strdup(display)) == NULL) - err(1, "mi_display_set: display strdup failed"); - + s = xstrdup(display); copy = s; idx = 0; diff --git a/meta_info.h b/meta_info.h index 19c04d7..24fead9 100644 --- a/meta_info.h +++ b/meta_info.h @@ -17,24 +17,9 @@ #ifndef META_INFO_H #define META_INFO_H -#include "compat.h" - -#include -#include -#include -#include -#include -#include +#include #include -#include -#include -#include -#include -/* non-baes includes (just TagLib) */ -#include - -#include "debug.h" #include "enums.h" /* the character-info fields. used for all meta-info that's shown */ diff --git a/paint.c b/paint.c index e0b4a8f..aa2737d 100644 --- a/paint.c +++ b/paint.c @@ -14,7 +14,25 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include +#include +#include +#include +#include +#include +#include + +#include "compat.h" +#include "enums.h" +#include "error.h" +#include "medialib.h" +#include "meta_info.h" #include "paint.h" +#include "player.h" +#include "playlist.h" +#include "uinterface.h" +#include "vitunes.h" +#include "xmalloc.h" /* globals */ _colors colors; @@ -67,7 +85,7 @@ num2fmt(int n, Direction d) if (n <= 0) { endwin(); - errx(1, "num2sfmt: invalid number %d provided", n); + fatalx("num2sfmt: invalid number %d provided", n); } if (d == LEFT) @@ -547,49 +565,6 @@ paint_all() paint_playlist(); } -/* - * Paints an error message to the command/status window. The usage is - * identical to that of printf(3) (vwprintw(3) actually). - */ -void -paint_error(char *fmt, ...) -{ - va_list ap; - - werase(ui.command); - wmove(ui.command, 0, 0); - wattron(ui.command, COLOR_PAIR(colors.errors)); - - va_start(ap, fmt); - vwprintw(ui.command, fmt, ap); - va_end(ap); - - beep(); - wattroff(ui.command, COLOR_PAIR(colors.errors)); - wrefresh(ui.command); -} - -/* - * Paints an informational message to the command/status window. The usage - * is identical to that of printf(3) (vwprintw(3) actually). - */ -void -paint_message(char *fmt, ...) -{ - va_list ap; - - werase(ui.command); - wmove(ui.command, 0, 0); - wattron(ui.command, COLOR_PAIR(colors.messages)); - - va_start(ap, fmt); - vwprintw(ui.command, fmt, ap); - va_end(ap); - - wattroff(ui.command, COLOR_PAIR(colors.messages)); - wrefresh(ui.command); -} - /* * Each of these members of the global color object will be * run through init_pair(3) @@ -687,8 +662,7 @@ paint_str2color(const char *str) char *numberstr; int number; - if ((color = strdup(str)) == NULL) - err(1, "%s: strdup of '%s' failed.", __FUNCTION__, str); + color = xstrdup(str); if ((numberstr = strtok(color, "color")) == NULL) { free(color); diff --git a/paint.h b/paint.h index b8c8643..d5078a1 100644 --- a/paint.h +++ b/paint.h @@ -17,21 +17,7 @@ #ifndef PAINT_H #define PAINT_H -#include "compat.h" - -#include -#include -#include -#include -#include -#include - -#include "enums.h" #include "meta_info.h" -#include "player.h" -#include "playlist.h" -#include "uinterface.h" -#include "vitunes.h" /* colors used by paint - each of these will be a number for a COLOR_PAIR */ typedef struct { @@ -80,10 +66,6 @@ void paint_all(); extern bool showing_file_info; void paint_playlist_file_info(const meta_info *m); -/* routines for painting errors/messages in the command/status window */ -void paint_error(char *fmt, ...); -void paint_message(char *fmt, ...); - /* for setting up and working with the colors */ void paint_setup_colors(); int paint_str2item(const char *str); diff --git a/player.c b/player.c index 37bf637..c1d5ffe 100644 --- a/player.c +++ b/player.c @@ -14,7 +14,23 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include +#include +#include + +#include "compat.h" +#include "error.h" +#include "paint.h" #include "player.h" +#include "playlist.h" +#include "uinterface.h" +#include "vitunes.h" + +/* "static" backends (those that aren't dynamically loaded) */ +#include "mplayer.h" +#if defined(ENABLE_GSTREAMER) +# include "gstplayer.h" +#endif /* globals */ player_backend_t player; @@ -25,7 +41,7 @@ player_info_t player_info; static void callback_playnext() { player_skip_song(1); } static void -callback_fatal(char *fmt, ...) +callback_fatal(const char *fmt, ...) { va_list ap; @@ -119,16 +135,14 @@ player_init(const char *backend) } if (!found) - errx(1, "media backend '%s' is unknown", backend); + fatalx("media backend '%s' is unknown", backend); - if (player.dynamic) { - ui_destroy(); - errx(1, "dynamically loaded backends not yet supported"); - } + if (player.dynamic) + fatalx("dynamically loaded backends not yet supported"); player.set_callback_playnext(callback_playnext); - player.set_callback_notice(paint_message); - player.set_callback_error(paint_error); + player.set_callback_notice(infox); + player.set_callback_error(fatalx); player.set_callback_fatal(callback_fatal); player.start(); } @@ -150,10 +164,10 @@ void player_play() { if (player_info.queue == NULL) - errx(1, "player_play: bad queue/qidx"); + fatalx("player_play: bad queue/qidx"); if (player_info.qidx < 0 || player_info.qidx > player_info.queue->nfiles) - errx(1, "player_play: qidx %i out-of-range", player_info.qidx); + fatalx("player_play: qidx %i out-of-range", player_info.qidx); player.play(player_info.queue->files[player_info.qidx]->filename); diff --git a/player.h b/player.h index 029fb43..e05a40b 100644 --- a/player.h +++ b/player.h @@ -17,19 +17,7 @@ #ifndef PLAYER_H #define PLAYER_H -#include "compat.h" - -#include - #include "playlist.h" -#include "paint.h" -#include "debug.h" - -/* "static" backends (those that aren't dynamically loaded) */ -#include "players/mplayer.h" -#if defined(ENABLE_GSTREAMER) -# include "players/gstplayer.h" -#endif /* * Available play-modes. @@ -98,9 +86,9 @@ typedef struct { /* callback functions */ void (*set_callback_playnext)(void (*f)(void)); - void (*set_callback_notice)(void (*f)(char *, ...)); - void (*set_callback_error)(void (*f)(char *, ...)); - void (*set_callback_fatal)(void (*f)(char *, ...)); + void (*set_callback_notice)(void (*f)(const char *, ...)); + void (*set_callback_error)(void (*f)(const char *, ...)); + void (*set_callback_fatal)(void (*f)(const char *, ...)); /* monitor function */ void (*monitor)(void); diff --git a/players/gstplayer.c b/players/gstplayer.c index 01f77a7..4d60c42 100644 --- a/players/gstplayer.c +++ b/players/gstplayer.c @@ -22,7 +22,8 @@ */ #include "gstplayer.h" -#include "../player.h" +#include "player.h" +#include "vitunes.h" /* player data */ static gst_player gplayer; @@ -269,17 +270,17 @@ gstplayer_set_callback_playnext(void (*f)(void)) gplayer.playnext_cb = f; } void -gstplayer_set_callback_notice(void (*f)(char *, ...)) +gstplayer_set_callback_notice(void (*f)(const char *, ...)) { gplayer.notice_cb = f; } void -gstplayer_set_callback_error(void (*f)(char *, ...)) +gstplayer_set_callback_error(void (*f)(const char *, ...)) { gplayer.error_cb = f; } void -gstplayer_set_callback_fatal(void (*f)(char *, ...)) +gstplayer_set_callback_fatal(void (*f)(const char *, ...)) { gplayer.fatal_cb = f; } diff --git a/players/gstplayer.h b/players/gstplayer.h index b23c8f7..0972644 100644 --- a/players/gstplayer.h +++ b/players/gstplayer.h @@ -34,10 +34,10 @@ typedef struct { bool paused; bool about_to_finish; /* callback functions */ - void (*playnext_cb)(void); - void (*notice_cb)(char *, ...); - void (*error_cb)(char *, ...); - void (*fatal_cb)(char *, ...); + void (*playnext_cb)(void); + void (*notice_cb)(const char *, ...); + void (*error_cb)(const char *, ...); + void (*fatal_cb)(const char *, ...); /* backend data */ GstElement *player; @@ -60,9 +60,9 @@ bool gstplayer_is_playing(); bool gstplayer_is_paused(); void gstplayer_set_callback_playnext(void (*f)(void)); -void gstplayer_set_callback_notice(void (*f)(char *, ...)); -void gstplayer_set_callback_error(void (*f)(char *, ...)); -void gstplayer_set_callback_fatal(void (*f)(char *, ...)); +void gstplayer_set_callback_notice(void (*f)(const char *, ...)); +void gstplayer_set_callback_error(void (*f)(const char *, ...)); +void gstplayer_set_callback_fatal(void (*f)(const char *, ...)); void gstplayer_monitor(); diff --git a/players/mplayer.c b/players/mplayer.c index fcc8f71..4b468bb 100644 --- a/players/mplayer.c +++ b/players/mplayer.c @@ -14,14 +14,32 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "compat.h" #include "mplayer.h" #include "mplayer_conf.h" +#include "player_utils.h" +#include "xmalloc.h" /* callback functions */ void (*mplayer_callback_playnext)(void) = NULL; -void (*mplayer_callback_notice)(char *, ...) = NULL; -void (*mplayer_callback_error)(char *, ...) = NULL; -void (*mplayer_callback_fatal)(char *, ...) = NULL; +void (*mplayer_callback_notice)(const char *, ...) = NULL; +void (*mplayer_callback_error)(const char *, ...) = NULL; +void (*mplayer_callback_fatal)(const char *, ...) = NULL; /* record keeping */ @@ -178,9 +196,7 @@ mplayer_play(const char *file) static const char *cmd_fmt = "\nloadfile \"%s\" 0\nget_property time_pos\n"; char *cmd; - if (asprintf(&cmd, cmd_fmt, file) == -1) - err(1, "%s: asprintf failed", __FUNCTION__); - + xasprintf(&cmd, cmd_fmt, file); mplayer_send_cmd(cmd); free(cmd); @@ -222,9 +238,7 @@ mplayer_seek(int seconds) if (!mplayer_state.playing) return; - if (asprintf(&cmd, cmd_fmt, seconds) == -1) - err(1, "%s: asprintf failed", __FUNCTION__); - + xasprintf(&cmd, cmd_fmt, seconds); mplayer_send_cmd(cmd); free(cmd); @@ -250,9 +264,7 @@ mplayer_volume_step(float percent) return; } - if (asprintf(&cmd, cmd_fmt, percent) == -1) - err(1, "%s: asprintf failed", __FUNCTION__); - + xasprintf(&cmd, cmd_fmt, percent); mplayer_send_cmd(cmd); free(cmd); @@ -271,10 +283,7 @@ mplayer_volume_set(float percent) if (percent > 100) percent = 100; if (percent < 0) percent = 0; - if (asprintf(&cmd, cmd_fmt, percent) == -1) - err(1, "%s: asprintf failed", __FUNCTION__); - - + xasprintf(&cmd, cmd_fmt, percent); mplayer_send_cmd(cmd); free(cmd); @@ -306,19 +315,19 @@ mplayer_set_callback_playnext(void (*f)(void)) } void -mplayer_set_callback_notice(void (*f)(char *, ...)) +mplayer_set_callback_notice(void (*f)(const char *, ...)) { mplayer_callback_notice = f; } void -mplayer_set_callback_error(void (*f)(char *, ...)) +mplayer_set_callback_error(void (*f)(const char *, ...)) { mplayer_callback_error = f; } void -mplayer_set_callback_fatal(void (*f)(char *, ...)) +mplayer_set_callback_fatal(void (*f)(const char *, ...)) { mplayer_callback_fatal = f; } diff --git a/players/mplayer.h b/players/mplayer.h index 03700cd..4d86fef 100644 --- a/players/mplayer.h +++ b/players/mplayer.h @@ -17,28 +17,6 @@ #ifndef MPLAYER_H #define MPLAYER_H -#include "../compat.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "player_utils.h" - -#ifdef DEBUG -# include "../debug.h" -#endif - void mplayer_start(); void mplayer_finish(); void mplayer_sigchld(); @@ -55,9 +33,9 @@ bool mplayer_is_playing(); bool mplayer_is_paused(); void mplayer_set_callback_playnext(void (*f)(void)); -void mplayer_set_callback_notice(void (*f)(char *, ...)); -void mplayer_set_callback_error(void (*f)(char *, ...)); -void mplayer_set_callback_fatal(void (*f)(char *, ...)); +void mplayer_set_callback_notice(void (*f)(const char *, ...)); +void mplayer_set_callback_error(void (*f)(const char *, ...)); +void mplayer_set_callback_fatal(void (*f)(const char *, ...)); void mplayer_monitor(); diff --git a/players/player_utils.c b/players/player_utils.c index 271774a..c2ac83d 100644 --- a/players/player_utils.c +++ b/players/player_utils.c @@ -14,7 +14,16 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include +#include +#include +#include +#include +#include + +#include "compat.h" #include "player_utils.h" +#include "xmalloc.h" bool exe_in_path(const char *e) @@ -22,17 +31,13 @@ exe_in_path(const char *e) char *path, *path_copy, *part, *test; bool found; - if ((path = strdup(getenv("PATH"))) == NULL) - err(1, "%s: strdup/getenv failed for $PATH", __FUNCTION__); - + path = xstrdup(getenv("PATH")); path_copy = path; found = false; while ((part = strsep(&path, ":")) != NULL && !found) { if (strlen(part) == 0) continue; - if (asprintf(&test, "%s/%s", part, e) == -1) - err(1, "%s: failed to build path", __FUNCTION__); - + xasprintf(&test, "%s/%s", part, e); if (access(test, X_OK) == 0) found = true; diff --git a/players/player_utils.h b/players/player_utils.h index f54b72e..d6ff969 100644 --- a/players/player_utils.h +++ b/players/player_utils.h @@ -17,15 +17,6 @@ #ifndef PLAYER_UTILS_H #define PLAYER_UTILS_H -#include "../compat.h" - -#include -#include -#include -#include -#include -#include - bool exe_in_path(const char *e); #endif diff --git a/playlist.c b/playlist.c index ceac2fc..080c357 100644 --- a/playlist.c +++ b/playlist.c @@ -14,22 +14,31 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "compat.h" +#include "error.h" +#include "meta_info.h" #include "playlist.h" +#include "xmalloc.h" int history_size = DEFAULT_HISTORY_SIZE; void playlist_increase_capacity(playlist *p) { - meta_info **new_files; - size_t nbytes; - p->capacity += PLAYLIST_CHUNK_SIZE; - nbytes = p->capacity * sizeof(meta_info*); - if ((new_files = realloc(p->files, nbytes)) == NULL) - err(1, "%s: failed to realloc(3) files", __FUNCTION__); - - p->files = new_files; + p->files = xrealloc(p->files, p->capacity, sizeof(meta_info *)); } /* @@ -41,12 +50,8 @@ playlist_new(void) { playlist *p; - if ((p = malloc(sizeof(playlist))) == NULL) - err(1, "playlist_new: failed to allocate playlist"); - - if ((p->files = calloc(PLAYLIST_CHUNK_SIZE, sizeof(meta_info*))) == NULL) - err(1, "playlist_new: failed to allocate files"); - + p = xmalloc(sizeof(playlist)); + p->files = xcalloc(PLAYLIST_CHUNK_SIZE, sizeof(meta_info*)); p->capacity = PLAYLIST_CHUNK_SIZE; p->filename = NULL; p->name = NULL; @@ -85,20 +90,13 @@ playlist_dup(const playlist *original, const char *filename, newplist->nfiles = original->nfiles; newplist->capacity = original->nfiles; - if (name != NULL) { - if ((newplist->name = strdup(name)) == NULL) - err(1, "playlist_dup: strdup name failed"); - } - if (filename != NULL) { - if ((newplist->filename = strdup(filename)) == NULL) - err(1, "playlist_dup: strdup filename failed"); - } + if (name != NULL) + newplist->name = xstrdup(name); + if (filename != NULL) + newplist->filename = xstrdup(filename); /* copy all of the files */ - newplist->files = calloc(original->nfiles, sizeof(meta_info*)); - if (newplist->files == NULL) - err(1, "playlist_dup: failed to allocate files"); - + newplist->files = xcalloc(original->nfiles, sizeof(meta_info*)); for (i = 0; i < original->nfiles; i++) newplist->files[i] = original->files[i]; @@ -115,7 +113,7 @@ playlist_files_add(playlist *p, meta_info **f, int start, int size, bool record) int i; if (start < 0 || start > p->nfiles) - errx(1, "playlist_file_add: index %d out of range", start); + fatalx("playlist_file_add: index %d out of range", start); while (p->capacity <= p->nfiles + size) playlist_increase_capacity(p); @@ -154,7 +152,7 @@ playlist_files_remove(playlist *p, int start, int size, bool record) int i; if (start < 0 || start >= p->nfiles) - errx(1, "playlist_remove_file: index %d out of range", start); + fatalx("playlist_remove_file: index %d out of range", start); if (record) { changes = changeset_create(CHANGE_REMOVE, size, &(p->files[start]), start); @@ -174,7 +172,7 @@ void playlist_file_replace(playlist *p, int index, meta_info *newEntry) { if (index < 0 || index >= p->nfiles) - errx(1, "playlist_file_replace: index %d out of range", index); + fatalx("playlist_file_replace: index %d out of range", index); p->files[index] = newEntry; } @@ -209,14 +207,12 @@ playlist_load(const char *filename, meta_info **db, int ndb) /* open file */ if ((fin = fopen(filename, "r")) == NULL) - err(1, "playlist_load: failed to open playlist '%s'", filename); + fatal("playlist_load: failed to open playlist '%s'", filename); /* create playlist and setup */ playlist *p = playlist_new(); - p->filename = strdup(filename); - p->name = strdup(basename(p->filename)); - if (p->filename == NULL || p->name == NULL) - err(1, "playlist_load: failed to allocate info for playlist '%s'", filename); + p->filename = xstrdup(filename); + p->name = xstrdup(basename(p->filename)); /* hack to remove '.playlist' from name */ period = strrchr(p->name, '.'); @@ -236,13 +232,11 @@ playlist_load(const char *filename, meta_info **db, int ndb) } else { /* file does NOT exist in DB */ /* create empty meta-info object with just the file name */ mi = mi_new(); - mi->filename = strdup(entry); - if (mi->filename == NULL) - err(1, "playlist_load: failed to strdup filename"); + mi->filename = xstrdup(entry); /* add new record to the db and link it to the playlist */ playlist_files_append(p, &mi, 1, false); - warnx("playlist \"%s\", file \"%s\" is NOT in media database (added for now)", + infox("playlist \"%s\", file \"%s\" is NOT in media database (added for now)", p->name, entry); } } @@ -262,12 +256,12 @@ playlist_save(const playlist *p) int i; if ((fout = fopen(p->filename, "w")) == NULL) - err(1, "playlist_save: failed to open playlist \"%s\"", p->filename); + fatal("playlist_save: failed to open playlist \"%s\"", p->filename); /* write each song to file */ for (i = 0; i < p->nfiles; i++) { if (fprintf(fout, "%s\n", p->files[i]->filename) == -1) - err(1, "playlist_save: failed to record playlist \"%s\"", p->filename); + fatal("playlist_save: failed to record playlist \"%s\"", p->filename); } fclose(fout); @@ -282,7 +276,7 @@ playlist_delete(playlist *p) { /* delete file if the playlist is stored in a file */ if (p->filename != NULL && unlink(p->filename) != 0) - err(1, "playlist_delete: failed to delete playlist \"%s\"", p->filename); + fatal("playlist_delete: failed to delete playlist \"%s\"", p->filename); /* destroy/free() all memory */ playlist_free(p); @@ -353,24 +347,24 @@ retrieve_playlist_filenames(const char *dirname, char ***fnames) # endif /* build the search pattern */ - if (asprintf(&glob_pattern, "%s/*.playlist", dirname) == -1) - errx(1, "failed in building glob pattern"); + xasprintf(&glob_pattern, "%s/*.playlist", dirname); /* get the files */ + fcount = 0; globbed = glob(glob_pattern, 0, NULL, &files); if (globbed != 0 && globbed != GLOB_NOMATCH && errno != 0) - err(1, "failed to glob playlists directory"); + fatal("failed to glob playlists directory"); + if (files.gl_pathc == 0) + goto out; /* allocate & copy each of the filenames found into the filenames array */ - if ((*fnames = calloc(files.gl_pathc, sizeof(char*))) == NULL) - err(1, "failed to allocate playlist filenames array"); + *fnames = xcalloc(files.gl_pathc, sizeof(char*)); - for (fcount = 0; fcount < files.gl_pathc; fcount++) { - if (asprintf(&((*fnames)[fcount]), "%s", files.gl_pathv[fcount]) == -1) - errx(1, "failed to allocate filename for playlist"); - } + for (fcount = 0; fcount < files.gl_pathc; fcount++) + xasprintf(&((*fnames)[fcount]), "%s", files.gl_pathv[fcount]); /* cleanup */ +out: globfree(&files); free(glob_pattern); @@ -381,15 +375,10 @@ playlist_changeset* changeset_create(short type, size_t size, meta_info **files, int loc) { size_t i; - playlist_changeset *c; - if ((c = malloc(sizeof(playlist_changeset))) == NULL) - err(1, "%s: malloc(3) failed", __FUNCTION__); - - if ((c->files = calloc(size, sizeof(meta_info*))) == NULL) - err(1, "%s: calloc(3) failed", __FUNCTION__); - + c = xmalloc(sizeof(playlist_changeset)); + c->files = xcalloc(size, sizeof(meta_info*)); c->type = type; c->size = size; c->location = loc; @@ -410,16 +399,7 @@ changeset_free(playlist_changeset *c) playlist_changeset** playlist_history_new(void) { - playlist_changeset **h; - int i; - - if ((h = calloc(history_size, sizeof(playlist_changeset*))) == NULL) - err(1, "%s: calloc(3) failed", __FUNCTION__); - - for (i = 0; i < history_size; i++) - h[i] = NULL; - - return h; + return xcalloc(history_size, sizeof(playlist_changeset*)); } void @@ -479,7 +459,7 @@ playlist_undo(playlist *p) playlist_files_add(p, c->files, c->location, c->size, false); break; default: - errx(1, "%s: invalid change type", __FUNCTION__); + fatalx("%s: invalid change type", __FUNCTION__); } p->hist_present--; @@ -506,7 +486,7 @@ playlist_redo(playlist *p) playlist_files_remove(p, c->location, c->size, false); break; default: - errx(1, "%s: invalid change type", __FUNCTION__); + fatalx("%s: invalid change type", __FUNCTION__); } p->hist_present++; diff --git a/playlist.h b/playlist.h index 60c06a0..a6d98f5 100644 --- a/playlist.h +++ b/playlist.h @@ -17,21 +17,6 @@ #ifndef PLAYLIST_H #define PLAYLIST_H -#include "compat.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "debug.h" #include "meta_info.h" #define PLAYLIST_CHUNK_SIZE 100 diff --git a/socket.c b/socket.c index af4dcfb..8cacd5a 100644 --- a/socket.c +++ b/socket.c @@ -13,19 +13,22 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include -#include + #include #include #include + +#include +#include +#include #include -#include "socket.h" #include "commands.h" +#include "keybindings.h" +#include "socket.h" #define VITUNES_SOCK "/tmp/.vitunes" - int sock_send_msg(const char *msg) { diff --git a/socket.h b/socket.h index 155f3f0..056d2b1 100644 --- a/socket.h +++ b/socket.h @@ -16,8 +16,6 @@ #ifndef SOCKET_H #define SOCKET_H -#include - #define VITUNES_RUNNING "WHOWASPHONE?" /* diff --git a/str2argv.c b/str2argv.c index 5922ffb..2ebc6fd 100644 --- a/str2argv.c +++ b/str2argv.c @@ -14,19 +14,22 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include +#include +#include +#include + +#include "compat.h" +#include "error.h" #include "str2argv.h" +#include "xmalloc.h" /* initialize empty argc/argv struct */ void argv_init(int *argc, char ***argv) { - if ((*argv = calloc(ARGV_MAX_ENTRIES, sizeof(char*))) == NULL) - err(1, "argv_init: argv calloc fail"); - - if (((*argv)[0] = calloc(ARGV_MAX_TOKEN_LEN, sizeof(char))) == NULL) - err(1, "argv_init: argv[i] calloc fail"); - - bzero((*argv)[0], ARGV_MAX_TOKEN_LEN * sizeof(char)); + *argv = xcalloc(ARGV_MAX_ENTRIES, sizeof(char*)); + (*argv)[0] = xcalloc(ARGV_MAX_TOKEN_LEN, sizeof(char)); *argc = 0; } @@ -51,7 +54,7 @@ argv_addch(int argc, char **argv, int c) n = strlen(argv[argc]); if (n == ARGV_MAX_TOKEN_LEN - 1) - errx(1, "argv_addch: reached max token length (%d)", ARGV_MAX_TOKEN_LEN); + fatalx("argv_addch: reached max token length (%d)", ARGV_MAX_TOKEN_LEN); argv[argc][n] = c; } @@ -61,16 +64,13 @@ void argv_finish_token(int *argc, char ***argv) { if (*argc == ARGV_MAX_ENTRIES - 1) - errx(1, "argv_finish_token: reached max argv entries(%d)", ARGV_MAX_ENTRIES); + fatalx("argv_finish_token: reached max argv entries(%d)", ARGV_MAX_ENTRIES); if (strlen((*argv)[*argc]) == 0) return; *argc = *argc + 1; - if (((*argv)[*argc] = calloc(ARGV_MAX_TOKEN_LEN, sizeof(char))) == NULL) - err(1, "argv_finish_token: failed to calloc argv[i]"); - - bzero((*argv)[*argc], ARGV_MAX_TOKEN_LEN * sizeof(char)); + (*argv)[*argc] = xcalloc(ARGV_MAX_TOKEN_LEN, sizeof(char)); } /* @@ -240,9 +240,7 @@ argv2str(int argc, char *argv[]) } /* allocate result */ - if ((result = calloc(len, sizeof(char))) == NULL) - err(1, "argv2str: calloc failed"); - bzero(result, len); + result = xcalloc(len, sizeof(char)); /* build result */ off = 0; diff --git a/str2argv.h b/str2argv.h index ab77c19..d826d07 100644 --- a/str2argv.h +++ b/str2argv.h @@ -17,16 +17,6 @@ #ifndef STR2ARGV_H #define STR2ARGV_H -#include "compat.h" - -#include -#include -#include -#include -#include - -#include "debug.h" - /* hard limits on the size of an argv and each entry/token w/in an argv */ #define ARGV_MAX_ENTRIES 255 #define ARGV_MAX_TOKEN_LEN 255 diff --git a/uinterface.c b/uinterface.c index eef84e3..24dbb73 100644 --- a/uinterface.c +++ b/uinterface.c @@ -14,7 +14,23 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "compat.h" +#include "enums.h" +#include "error.h" #include "uinterface.h" +#include "xmalloc.h" /* the global user interface object */ uinterface ui; @@ -26,10 +42,9 @@ uinterface ui; swindow* swindow_new(int h, int w, int y, int x) { - swindow *swin = malloc(sizeof(swindow)); - if (swin == NULL) - err(1, "swindow_new failed to allocate swin"); - + swindow *swin; + + swin = xmalloc(sizeof(swindow)); swin->w = w; swin->h = h; swin->voffset = 0; @@ -38,7 +53,7 @@ swindow_new(int h, int w, int y, int x) swin->nrows = 0; swin->cwin = newwin(h, w, y, x); if (swin->cwin == NULL) - errx(1, "swindow_new: failed to create window"); + fatalx("swindow_new: failed to create window"); return swin; } @@ -95,7 +110,7 @@ swindow_scroll(swindow *win, Direction d, int n) break; default: - err(1, "swindow_scroll: bad direction"); + fatal("swindow_scroll: bad direction"); } } @@ -129,7 +144,7 @@ ui_init(int library_width) ui.player = newwin(1, cols, 0, 0); ui.command = newwin(1, cols, lines - 1, 0); if (ui.player == NULL || ui.command == NULL) - errx(1, "ui_init: failed to create player/command windows"); + fatalx("ui_init: failed to create player/command windows"); /* and the rest */ ui.library = swindow_new(lines - 3, ui.lwidth, 2, 0); @@ -172,16 +187,16 @@ ui_resize() /* get new dimensions and check for changes */ if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) < 0) - err(1, "ui_resize: ioctl failed"); + fatal("ui_resize: ioctl failed"); /* can we even handle the new display size? if not, just exit */ if (ws.ws_col < ui.lwidth + 2) { endwin(); - errx(1, "ui_resize: not enough columns to render vitunes nicely"); + fatalx("ui_resize: not enough columns to render vitunes nicely"); } if (ws.ws_row < 4) { endwin(); - errx(1, "ui_resize: not enough rows to render vitunes nicely"); + fatalx("ui_resize: not enough rows to render vitunes nicely"); } /* resize ncurses */ @@ -234,7 +249,7 @@ ui_unhide_library() /* create library window */ ui.library->cwin = newwin(h - 3, ui.lwidth, 2, 0); if (ui.library->cwin == NULL) - errx(1, "ui_unhide_library: failed to create newwin"); + fatalx("ui_unhide_library: failed to create newwin"); /* resize & move playlist window */ swindow_resize(ui.playlist, h - 3, w - ui.lwidth - 1, 2, ui.lwidth + 1); diff --git a/uinterface.h b/uinterface.h index e28e15a..2fb1560 100644 --- a/uinterface.h +++ b/uinterface.h @@ -17,23 +17,7 @@ #ifndef UINTERFACE_H #define UINTERFACE_H -#include "compat.h" - -#include - -#include -#include #include -#include -#include -#include -#include -#include -#include -#include - -#include "debug.h" -#include "enums.h" /* struct & methods for a scrollable window */ typedef struct diff --git a/vitunes.c b/vitunes.c index 7d1abbb..b09bc22 100644 --- a/vitunes.c +++ b/vitunes.c @@ -14,9 +14,33 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "commands.h" +#include "compat.h" +#include "ecmd.h" +#include "enums.h" +#include "error.h" +#include "keybindings.h" +#include "medialib.h" +#include "paint.h" +#include "player.h" +#include "socket.h" +#include "str2argv.h" +#include "uinterface.h" #include "vitunes.h" +#include "xmalloc.h" #include "config.h" /* NOTE: must be after vitunes.h */ -#include "socket.h" /***************************************************************************** * GLOBALS, EXPORTED @@ -43,9 +67,6 @@ volatile sig_atomic_t VSIG_PLAYER_MONITOR = 0; /* 1 = update player stats */ enum { EXIT_NORMAL, BAD_PLAYER }; volatile sig_atomic_t QUIT_CAUSE = EXIT_NORMAL; -/* used with -DDEBUG */ -FILE *debug_log; - /***************************************************************************** * GLOBALS, LOCAL @@ -67,6 +88,9 @@ char *player_backend; /* program name with directories removed */ char *progname; +/* configuration file line number */ +size_t conf_linenum; + /***************************************************************************** * local functions @@ -95,10 +119,8 @@ main(int argc, char *argv[]) else progname++; -#ifdef DEBUG - if ((debug_log = fopen("vitunes-debug.log", "w")) == NULL) - err(1, "failed to open debug log"); -#endif + /* error messages go to stderr before the user interface is set up */ + error_init(ERROR_STDERR); /*------------------------------------------------------------------------ * build paths names needed by vitunes & handle switches @@ -107,21 +129,17 @@ main(int argc, char *argv[]) /* get home dir */ if ((home = getenv("HOME")) == NULL || *home == '\0') { if ((pw = getpwuid(getuid())) == NULL) - errx(1, "Couldn't determine home directory. Can't find my config files."); - home = pw->pw_dir; + home = "/"; + else + home = pw->pw_dir; } /* build paths & other needed strings */ - if (asprintf(&vitunes_dir, VITUNES_DIR_FMT, home) == -1) - err(1, "main: asprintf failed"); - if (asprintf(&conf_file, CONF_FILE_FMT, home) == -1) - err(1, "main: asprintf failed"); - if (asprintf(&db_file, DB_FILE_FMT, home) == -1) - err(1, "main: asprintf failed"); - if (asprintf(&playlist_dir, PLAYLIST_DIR_FMT, home) == -1) - err(1, "main: asprintf failed"); - if (asprintf(&player_backend, "%s", DEFAULT_PLAYER_BACKEND) == -1) - err(1, "main: asprintf failed"); + xasprintf(&vitunes_dir, VITUNES_DIR_FMT, home); + xasprintf(&conf_file, CONF_FILE_FMT, home); + xasprintf(&db_file, DB_FILE_FMT, home); + xasprintf(&playlist_dir, PLAYLIST_DIR_FMT, home); + xasprintf(&player_backend, "%s", DEFAULT_PLAYER_BACKEND); /* handle command-line switches & e-commands */ handle_switches(argc, argv); @@ -130,7 +148,7 @@ main(int argc, char *argv[]) printf("Vitunes appears to be running already. Won't open socket."); } else { if((sock = sock_listen()) == -1) - errx(1, "failed to open socket."); + fatalx("failed to open socket."); } @@ -179,6 +197,9 @@ main(int argc, char *argv[]) /* setup user interface and default colors */ kb_init(); + + /* user interface being initialised; set context, accordingly */ + error_init(ERROR_CFG); ui_init(DEFAULT_LIBRARY_WINDOW_WIDTH); paint_setup_colors(); @@ -193,6 +214,9 @@ main(int argc, char *argv[]) /* initial painting of the display */ paint_all(); + /* configuration file ok; paint messages from now on */ + error_init(ERROR_PAINT); + /* ----------------------------------------------------------------------- * begin input loop * -------------------------------------------------------------------- */ @@ -252,7 +276,7 @@ main(int argc, char *argv[]) if (QUIT_CAUSE != EXIT_NORMAL) { switch (QUIT_CAUSE) { case BAD_PLAYER: - warnx("It appears the media player is misbehaving. Apologies."); + infox("It appears the media player is misbehaving. Apologies."); break; } } @@ -265,9 +289,8 @@ void usage(void) { fprintf(stderr,"\ -usage: %s [-f config-file] [-d database-file] [-p playlist-dir] [-m player-path] [-e COMMAND ...]\n\ -See \"%s -e help\" for information about what e-commands are available.\n\ -", +usage: %s [-v] [-f config-file] [-d database-file] [-p playlist-dir] [-m player-path]\n\ +\t[-e COMMAND ...]\nSee \"%s -e help\" for information about what e-commands are available.\n", progname, progname); exit(1); } @@ -338,7 +361,7 @@ process_signals() paint_playlist(); } if (prev_volume != player.volume()) { - paint_message("volume: %3.0f%%", player.volume()); + infox("volume: %3.0f%%", player.volume()); prev_volume = player.volume(); } @@ -364,12 +387,12 @@ setup_timer() /* create timer signal handler */ if (sigemptyset(&sig_act.sa_mask) < 0) - err(1, "setup_timer: sigemptyset failed"); + fatal("setup_timer: sigemptyset failed"); sig_act.sa_flags = 0; sig_act.sa_handler = signal_handler; if (sigaction(SIGALRM, &sig_act, NULL) < 0) - err(1, "setup_timer: sigaction failed"); + fatal("setup_timer: sigaction failed"); /* setup timer details */ timer.it_value.tv_sec = 0; @@ -379,7 +402,7 @@ setup_timer() /* register timer */ if (setitimer(ITIMER_REAL, &timer, NULL) < 0) - err(1, "setup_timer: setitimer failed"); + fatal("setup_timer: setitimer failed"); } /* @@ -389,32 +412,16 @@ setup_timer() void load_config() { - const char *errmsg = NULL; - size_t length, linenum; + size_t length; FILE *fin; char *line; char *copy; - char **argv; - int argc; - bool found; - int found_idx = 0; - int num_matches; - int i, ret; if ((fin = fopen(conf_file, "r")) == NULL) return; - linenum = 0; - while (!feof(fin)) { - - /* get next line */ - if ((line = fparseln(fin, &length, &linenum, NULL, 0)) == NULL) { - if (ferror(fin)) - err(1, "error reading config file '%s'", conf_file); - else - break; - } - + /* get next line */ + while ((line = fparseln(fin, &length, &conf_linenum, NULL, 0)) != NULL) { /* skip whitespace */ copy = line; copy += strspn(copy, " \t\n"); @@ -423,42 +430,11 @@ load_config() continue; } - /* parse line into argc/argv */ - if (str2argv(copy, &argc, &argv, &errmsg) != 0) { - endwin(); - errx(1, "%s line %zd: parse error: %s", conf_file, linenum, errmsg); - } - - /* run command */ - found = false; - num_matches = 0; - for (i = 0; i < CommandPathSize; i++) { - if (match_command_name(argv[0], CommandPath[i].name)) { - found = true; - found_idx = i; - num_matches++; - } - } - - if (found && num_matches == 1) { - if ((ret = (CommandPath[found_idx].func)(argc, argv)) != 0) { - endwin(); - errx(1, "%s line %zd: error with command '%s' [%i]", - conf_file, linenum, argv[0], ret); - } - } else if (num_matches > 1) { - endwin(); - errx(1, "%s line %zd: ambiguous abbreviation '%s'", - conf_file, linenum, argv[0]); - } else { - endwin(); - errx(1, "%s line %zd: unknown command '%s'", - conf_file, linenum, argv[0]); - } - - argv_free(&argc, &argv); + cmd_execute(line); free(line); } + if (ferror(fin)) + fatal("error reading config file"); fclose(fin); } @@ -472,17 +448,16 @@ handle_switches(int argc, char *argv[]) { int ch; - while ((ch = getopt(argc, argv, "he:f:d:p:m:c:")) != -1) { + while ((ch = getopt(argc, argv, "he:f:d:p:m:c:v")) != -1) { switch (ch) { case 'c': if(sock_send_msg(optarg) == -1) - errx(1, "Failed to send message. Vitunes not running?"); + fatalx("Failed to send message. Vitunes not running?"); exit(0); case 'd': free(db_file); - if ((db_file = strdup(optarg)) == NULL) - err(1, "handle_switches: strdup db_file failed"); + db_file = xstrdup(optarg); break; case 'e': @@ -494,20 +469,21 @@ handle_switches(int argc, char *argv[]) case 'f': free(conf_file); - if ((conf_file = strdup(optarg)) == NULL) - err(1, "handle_switches: strdup conf_file failed"); + conf_file = xstrdup(optarg); break; case 'm': free(player_backend); - if ((player_backend = strdup(optarg)) == NULL) - err(1, "handle_switches: strdup player_backend failed"); + player_backend = xstrdup(optarg); break; case 'p': free(playlist_dir); - if ((playlist_dir = strdup(optarg)) == NULL) - err(1, "handle_switches: strdup playlist_dir failed"); + playlist_dir = xstrdup(optarg); + break; + + case 'v': + error_open(); break; case 'h': diff --git a/vitunes.h b/vitunes.h index 8348da0..0552e18 100644 --- a/vitunes.h +++ b/vitunes.h @@ -17,26 +17,9 @@ #ifndef VITUNES_H #define VITUNES_H -#include "compat.h" - -#include - -#include -#include -#include #include -#include -#include -#include -#include "debug.h" -#include "enums.h" -#include "commands.h" -#include "keybindings.h" -#include "medialib.h" -#include "player.h" -#include "uinterface.h" -#include "ecmd.h" +#include "playlist.h" /* for unused arguments */ #if defined(__GNUC__) || defined(__clang__) @@ -51,10 +34,12 @@ /* configurable paths */ extern char *vitunes_dir; +extern char *conf_file; extern char *playlist_dir; extern char *db_file; extern char *progname; +size_t conf_linenum; /* record keeping */ extern playlist *viewing_playlist; diff --git a/xmalloc.c b/xmalloc.c new file mode 100644 index 0000000..2cf48ed --- /dev/null +++ b/xmalloc.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013 Tiago Cunha + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#include "error.h" +#include "xmalloc.h" + +void +xasprintf(char **ret, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + if (vasprintf(ret, fmt, ap) == -1 || *ret == NULL) + diex("vasprintf"); + va_end(ap); +} + +void * +xcalloc(size_t nmemb, size_t size) +{ + void *ptr; + + if (nmemb == 0) + diex("xcalloc: zero objects"); + if (size == 0) + diex("xcalloc: zero size"); + if (nmemb > SIZE_MAX / size) { + errno = ENOMEM; + die("xcalloc: overflow"); + } + if ((ptr = calloc(nmemb, size)) == NULL) + die("calloc"); + + return (ptr); +} + +void * +xmalloc(size_t size) +{ + void *ptr; + + if (size == 0) + diex("xmalloc: zero size"); + if ((ptr = malloc(size)) == NULL) + die("malloc"); + + return (ptr); +} + +void * +xrealloc(void *ptr, size_t nmemb, size_t size) +{ + void *newptr; + + if (nmemb == 0) + diex("xrealloc: zero objects"); + if (size == 0) + diex("xrealloc: zero size"); + if (nmemb > SIZE_MAX / size) { + errno = ENOMEM; + die("xrealloc: overflow"); + } + if ((newptr = realloc(ptr, nmemb * size)) == NULL) + die("realloc"); + + return (newptr); +} + +char * +xstrdup(const char *s) +{ + char *ptr; + + if (s == NULL) + diex("xstrdup: null pointer"); + if ((ptr = strdup(s)) == NULL) + die("strdup"); + + return (ptr); +} diff --git a/debug.h b/xmalloc.h similarity index 51% rename from debug.h rename to xmalloc.h index 45a9cd8..cd41be4 100644 --- a/debug.h +++ b/xmalloc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2011 Ryan Flannery + * Copyright (c) 2013 Tiago Cunha * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,37 +14,16 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef DEBUG_H -#define DEBUG_H +#ifndef XMALLOC_H +#define XMALLOC_H +#include #include -/* log file for debugging */ -extern FILE *debug_log; - -#ifdef DEBUG - -/* debug file logger that goes to the file opened in vitunes.c */ -#define DFLOG(format, args...) \ - fprintf(debug_log, "%s.%d (%s): ", __FILE__, __LINE__, __FUNCTION__); \ - fprintf(debug_log, format, ## args); \ - fprintf(debug_log, "\n"); \ - fflush(debug_log); - -/* console logger. goes to stdout. doesn't work well in curses */ -#define DCLOG(format, args...) \ - printf("%d: ", __LINE__); \ - printf(format, ## args); \ - printf("\n"); \ - fflush(stdout); - - -#else - -#define DFLOG(format, args...) 0; -#define DCLOG(format, args...) 0; - -#endif - +void xasprintf(char **, const char *, ...); +void *xcalloc(size_t, size_t); +void *xmalloc(size_t); +void *xrealloc(void *, size_t, size_t); +char *xstrdup(const char *); #endif