[Pkg-mpd-commits] [pkg-mpc] 02/07: Imported Upstream version 0.25

Florian Schlichting fsfs at moszumanska.debian.org
Wed Nov 20 21:59:39 UTC 2013


This is an automated email from the git hooks/post-receive script.

fsfs pushed a commit to branch master
in repository pkg-mpc.

commit 3ffe7f2c85577d1feabe3bde1d3b3ce2d715a920
Author: Florian Schlichting <fsfs at debian.org>
Date:   Mon Nov 11 20:35:00 2013 +0100

    Imported Upstream version 0.25
---
 INSTALL                 |    2 +-
 Makefile.am             |   46 ++--
 Makefile.in             |  107 +++++++---
 NEWS                    |    6 +
 configure               |   40 ++--
 configure.ac            |    8 +-
 doc/mpc.1               |    2 +-
 src/Compiler.h          |  159 ++++++++++++++
 src/args.c              |  202 ++++++++++++++++++
 src/args.h              |   73 +++++++
 src/charset.c           |   61 +++---
 src/charset.h           |   21 +-
 src/command.c           |  537 +++++++----------------------------------------
 src/command.h           |   28 +--
 src/gcc.h               |   67 ------
 src/idle.c              |   10 +-
 src/idle.h              |    3 +-
 src/list.c              |   20 +-
 src/list.h              |   18 +-
 src/main.c              |   76 +++----
 src/message.c           |   12 +-
 src/message.h           |   18 +-
 src/mpc.h               |   18 +-
 src/options.c           |   17 +-
 src/options.h           |    3 +-
 src/password.c          |   18 +-
 src/password.h          |   18 +-
 src/path.c              |   17 +-
 src/path.h              |   21 +-
 src/queue.c             |  245 +++++++++++++++++++++
 src/{idle.h => queue.h} |   28 ++-
 src/search.c            |   23 +-
 src/search.h            |    3 +-
 src/status.c            |   29 +--
 src/status.h            |   18 +-
 src/sticker.c           |   12 +-
 src/sticker.h           |    3 +-
 src/tab.c               |  124 +++++++++++
 src/{idle.h => tab.h}   |   14 +-
 src/util.c              |  203 +++---------------
 src/util.h              |   53 +++--
 41 files changed, 1287 insertions(+), 1096 deletions(-)

diff --git a/INSTALL b/INSTALL
index 891a6fb..fa88677 100644
--- a/INSTALL
+++ b/INSTALL
@@ -5,7 +5,7 @@ Requirements
 ------------
 
   * a C99 compliant compiler (e.g. gcc)
-  * libmpdclient 2.2
+  * libmpdclient 2.3
 
 
 Download
diff --git a/Makefile.am b/Makefile.am
index 2187b16..7b84b2d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,5 +1,5 @@
 ACLOCAL_AMFLAGS = -I m4
-AUTOMAKE_OPTIONS = foreign 1.11 dist-bzip2 dist-xz
+AUTOMAKE_OPTIONS = foreign 1.11 dist-xz
 
 man_MANS = doc/mpc.1
 doc_DATA = AUTHORS COPYING NEWS README \
@@ -9,38 +9,26 @@ EXTRA_DIST = $(man_MANS) $(doc_DATA)
 
 bin_PROGRAMS = src/mpc
 
-src_mpc_headers = \
-	src/list.h \
-	src/password.h \
-	src/charset.h \
-	src/status.h \
-	src/util.h \
-	src/command.h \
-	src/idle.h \
-	src/search.h \
-	src/sticker.h \
-	src/mpc.h \
-	src/options.h \
-	src/gcc.h
-
 src_mpc_SOURCES = \
-	src/main.c \
-	src/list.c \
-	src/password.c \
-	src/status.c \
-	src/util.c \
-	src/command.c \
-	src/sticker.c \
-	src/idle.c \
-	src/message.h \
-	src/message.c \
-	src/search.c \
-	src/options.c \
+	src/main.c src/mpc.h \
+	src/list.c src/list.h \
+	src/password.c src/password.h \
+	src/status.c src/status.h \
+	src/args.c src/args.h \
+	src/util.c src/util.h \
+	src/command.c src/command.h \
+	src/queue.c src/queue.h \
+	src/sticker.c src/sticker.h \
+	src/tab.c src/tab.h \
+	src/idle.c src/idle.h \
+	src/message.c src/message.h \
+	src/search.c src/search.h \
+	src/options.c src/options.h \
 	src/path.c src/path.h \
-	$(src_mpc_headers)
+	src/Compiler.h
 
 if HAVE_ICONV
-src_mpc_SOURCES += src/charset.c
+src_mpc_SOURCES += src/charset.c src/charset.h
 endif
 
 src_mpc_CPPFLAGS = $(AM_CPPFLAGS) $(ICONV_CFLAGS) $(LIBMPDCLIENT_CFLAGS)
diff --git a/Makefile.in b/Makefile.in
index 3b98f75..3d24e5f 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -51,7 +51,7 @@ NORMAL_UNINSTALL = :
 PRE_UNINSTALL = :
 POST_UNINSTALL = :
 bin_PROGRAMS = src/mpc$(EXEEXT)
- at HAVE_ICONV_TRUE@am__append_1 = src/charset.c
+ at HAVE_ICONV_TRUE@am__append_1 = src/charset.c src/charset.h
 subdir = .
 DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
 	$(srcdir)/Makefile.in $(srcdir)/config.h.in \
@@ -75,21 +75,23 @@ CONFIG_CLEAN_VPATH_FILES =
 am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \
 	"$(DESTDIR)$(docdir)"
 PROGRAMS = $(bin_PROGRAMS)
-am__src_mpc_SOURCES_DIST = src/main.c src/list.c src/password.c \
-	src/status.c src/util.c src/command.c src/sticker.c src/idle.c \
-	src/message.h src/message.c src/search.c src/options.c \
-	src/path.c src/path.h src/list.h src/password.h src/charset.h \
-	src/status.h src/util.h src/command.h src/idle.h src/search.h \
-	src/sticker.h src/mpc.h src/options.h src/gcc.h src/charset.c
-am__objects_1 =
- at HAVE_ICONV_TRUE@am__objects_2 = src_mpc-charset.$(OBJEXT)
+am__src_mpc_SOURCES_DIST = src/main.c src/mpc.h src/list.c src/list.h \
+	src/password.c src/password.h src/status.c src/status.h \
+	src/args.c src/args.h src/util.c src/util.h src/command.c \
+	src/command.h src/queue.c src/queue.h src/sticker.c \
+	src/sticker.h src/tab.c src/tab.h src/idle.c src/idle.h \
+	src/message.c src/message.h src/search.c src/search.h \
+	src/options.c src/options.h src/path.c src/path.h \
+	src/Compiler.h src/charset.c src/charset.h
+ at HAVE_ICONV_TRUE@am__objects_1 = src_mpc-charset.$(OBJEXT)
 am_src_mpc_OBJECTS = src_mpc-main.$(OBJEXT) src_mpc-list.$(OBJEXT) \
 	src_mpc-password.$(OBJEXT) src_mpc-status.$(OBJEXT) \
-	src_mpc-util.$(OBJEXT) src_mpc-command.$(OBJEXT) \
-	src_mpc-sticker.$(OBJEXT) src_mpc-idle.$(OBJEXT) \
-	src_mpc-message.$(OBJEXT) src_mpc-search.$(OBJEXT) \
-	src_mpc-options.$(OBJEXT) src_mpc-path.$(OBJEXT) \
-	$(am__objects_1) $(am__objects_2)
+	src_mpc-args.$(OBJEXT) src_mpc-util.$(OBJEXT) \
+	src_mpc-command.$(OBJEXT) src_mpc-queue.$(OBJEXT) \
+	src_mpc-sticker.$(OBJEXT) src_mpc-tab.$(OBJEXT) \
+	src_mpc-idle.$(OBJEXT) src_mpc-message.$(OBJEXT) \
+	src_mpc-search.$(OBJEXT) src_mpc-options.$(OBJEXT) \
+	src_mpc-path.$(OBJEXT) $(am__objects_1)
 src_mpc_OBJECTS = $(am_src_mpc_OBJECTS)
 am__DEPENDENCIES_1 =
 src_mpc_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
@@ -166,7 +168,7 @@ am__remove_distdir = \
       && rm -rf "$(distdir)" \
       || { sleep 5 && rm -rf "$(distdir)"; }; \
   else :; fi
-DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 $(distdir).tar.xz
+DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.xz
 GZIP_ENV = --best
 distuninstallcheck_listfiles = find . -type f -print
 am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
@@ -269,31 +271,21 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 ACLOCAL_AMFLAGS = -I m4
-AUTOMAKE_OPTIONS = foreign 1.11 dist-bzip2 dist-xz
+AUTOMAKE_OPTIONS = foreign 1.11 dist-xz
 man_MANS = doc/mpc.1
 doc_DATA = AUTHORS COPYING NEWS README \
 	doc/mpd-m3u-handler.sh doc/mpd-pls-handler.sh doc/mppledit \
 	doc/mpc-completion.bash
 
 EXTRA_DIST = $(man_MANS) $(doc_DATA)
-src_mpc_headers = \
-	src/list.h \
-	src/password.h \
-	src/charset.h \
-	src/status.h \
-	src/util.h \
-	src/command.h \
-	src/idle.h \
-	src/search.h \
-	src/sticker.h \
-	src/mpc.h \
-	src/options.h \
-	src/gcc.h
-
-src_mpc_SOURCES = src/main.c src/list.c src/password.c src/status.c \
-	src/util.c src/command.c src/sticker.c src/idle.c \
-	src/message.h src/message.c src/search.c src/options.c \
-	src/path.c src/path.h $(src_mpc_headers) $(am__append_1)
+src_mpc_SOURCES = src/main.c src/mpc.h src/list.c src/list.h \
+	src/password.c src/password.h src/status.c src/status.h \
+	src/args.c src/args.h src/util.c src/util.h src/command.c \
+	src/command.h src/queue.c src/queue.h src/sticker.c \
+	src/sticker.h src/tab.c src/tab.h src/idle.c src/idle.h \
+	src/message.c src/message.h src/search.c src/search.h \
+	src/options.c src/options.h src/path.c src/path.h \
+	src/Compiler.h $(am__append_1)
 src_mpc_CPPFLAGS = $(AM_CPPFLAGS) $(ICONV_CFLAGS) $(LIBMPDCLIENT_CFLAGS)
 src_mpc_LDADD = $(ICONV_LIBS) $(LIBMPDCLIENT_LIBS)
 
@@ -412,6 +404,7 @@ mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/src_mpc-args.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/src_mpc-charset.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/src_mpc-command.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/src_mpc-idle.Po at am__quote@
@@ -421,9 +414,11 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/src_mpc-options.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/src_mpc-password.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/src_mpc-path.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/src_mpc-queue.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/src_mpc-search.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/src_mpc-status.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/src_mpc-sticker.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/src_mpc-tab.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/src_mpc-util.Po at am__quote@
 
 .c.o:
@@ -496,6 +491,20 @@ src_mpc-status.obj: src/status.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_mpc_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src_mpc-status.obj `if test -f 'src/status.c'; then $(CYGPATH_W) 'src/status.c'; else $(CYGPATH_W) '$(srcdir)/src/status.c'; fi`
 
+src_mpc-args.o: src/args.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_mpc_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src_mpc-args.o -MD -MP -MF $(DEPDIR)/src_mpc-args.Tpo -c -o src_mpc-args.o `test -f 'src/args.c' || echo '$(srcdir)/'`src/args.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/src_mpc-args.Tpo $(DEPDIR)/src_mpc-args.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='src/args.c' object='src_mpc-args.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_mpc_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src_mpc-args.o `test -f 'src/args.c' || echo '$(srcdir)/'`src/args.c
+
+src_mpc-args.obj: src/args.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_mpc_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src_mpc-args.obj -MD -MP -MF $(DEPDIR)/src_mpc-args.Tpo -c -o src_mpc-args.obj `if test -f 'src/args.c'; then $(CYGPATH_W) 'src/args.c'; else $(CYGPATH_W) '$(srcdir)/src/args.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/src_mpc-args.Tpo $(DEPDIR)/src_mpc-args.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='src/args.c' object='src_mpc-args.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_mpc_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src_mpc-args.obj `if test -f 'src/args.c'; then $(CYGPATH_W) 'src/args.c'; else $(CYGPATH_W) '$(srcdir)/src/args.c'; fi`
+
 src_mpc-util.o: src/util.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_mpc_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src_mpc-util.o -MD -MP -MF $(DEPDIR)/src_mpc-util.Tpo -c -o src_mpc-util.o `test -f 'src/util.c' || echo '$(srcdir)/'`src/util.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/src_mpc-util.Tpo $(DEPDIR)/src_mpc-util.Po
@@ -524,6 +533,20 @@ src_mpc-command.obj: src/command.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_mpc_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src_mpc-command.obj `if test -f 'src/command.c'; then $(CYGPATH_W) 'src/command.c'; else $(CYGPATH_W) '$(srcdir)/src/command.c'; fi`
 
+src_mpc-queue.o: src/queue.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_mpc_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src_mpc-queue.o -MD -MP -MF $(DEPDIR)/src_mpc-queue.Tpo -c -o src_mpc-queue.o `test -f 'src/queue.c' || echo '$(srcdir)/'`src/queue.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/src_mpc-queue.Tpo $(DEPDIR)/src_mpc-queue.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='src/queue.c' object='src_mpc-queue.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_mpc_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src_mpc-queue.o `test -f 'src/queue.c' || echo '$(srcdir)/'`src/queue.c
+
+src_mpc-queue.obj: src/queue.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_mpc_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src_mpc-queue.obj -MD -MP -MF $(DEPDIR)/src_mpc-queue.Tpo -c -o src_mpc-queue.obj `if test -f 'src/queue.c'; then $(CYGPATH_W) 'src/queue.c'; else $(CYGPATH_W) '$(srcdir)/src/queue.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/src_mpc-queue.Tpo $(DEPDIR)/src_mpc-queue.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='src/queue.c' object='src_mpc-queue.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_mpc_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src_mpc-queue.obj `if test -f 'src/queue.c'; then $(CYGPATH_W) 'src/queue.c'; else $(CYGPATH_W) '$(srcdir)/src/queue.c'; fi`
+
 src_mpc-sticker.o: src/sticker.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_mpc_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src_mpc-sticker.o -MD -MP -MF $(DEPDIR)/src_mpc-sticker.Tpo -c -o src_mpc-sticker.o `test -f 'src/sticker.c' || echo '$(srcdir)/'`src/sticker.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/src_mpc-sticker.Tpo $(DEPDIR)/src_mpc-sticker.Po
@@ -538,6 +561,20 @@ src_mpc-sticker.obj: src/sticker.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_mpc_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src_mpc-sticker.obj `if test -f 'src/sticker.c'; then $(CYGPATH_W) 'src/sticker.c'; else $(CYGPATH_W) '$(srcdir)/src/sticker.c'; fi`
 
+src_mpc-tab.o: src/tab.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_mpc_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src_mpc-tab.o -MD -MP -MF $(DEPDIR)/src_mpc-tab.Tpo -c -o src_mpc-tab.o `test -f 'src/tab.c' || echo '$(srcdir)/'`src/tab.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/src_mpc-tab.Tpo $(DEPDIR)/src_mpc-tab.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='src/tab.c' object='src_mpc-tab.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_mpc_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src_mpc-tab.o `test -f 'src/tab.c' || echo '$(srcdir)/'`src/tab.c
+
+src_mpc-tab.obj: src/tab.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_mpc_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src_mpc-tab.obj -MD -MP -MF $(DEPDIR)/src_mpc-tab.Tpo -c -o src_mpc-tab.obj `if test -f 'src/tab.c'; then $(CYGPATH_W) 'src/tab.c'; else $(CYGPATH_W) '$(srcdir)/src/tab.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/src_mpc-tab.Tpo $(DEPDIR)/src_mpc-tab.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='src/tab.c' object='src_mpc-tab.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_mpc_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src_mpc-tab.obj `if test -f 'src/tab.c'; then $(CYGPATH_W) 'src/tab.c'; else $(CYGPATH_W) '$(srcdir)/src/tab.c'; fi`
+
 src_mpc-idle.o: src/idle.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_mpc_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src_mpc-idle.o -MD -MP -MF $(DEPDIR)/src_mpc-idle.Tpo -c -o src_mpc-idle.o `test -f 'src/idle.c' || echo '$(srcdir)/'`src/idle.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/src_mpc-idle.Tpo $(DEPDIR)/src_mpc-idle.Po
@@ -793,6 +830,7 @@ distdir: $(DISTFILES)
 dist-gzip: distdir
 	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
 	$(am__remove_distdir)
+
 dist-bzip2: distdir
 	tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
 	$(am__remove_distdir)
@@ -823,7 +861,6 @@ dist-zip: distdir
 
 dist dist-all: distdir
 	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
-	tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
 	tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
 	$(am__remove_distdir)
 
diff --git a/NEWS b/NEWS
index 2c6fdc2..a75cd57 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,9 @@
+0.25 (2013/11/09)
+* fix "insert" with directory argument
+* optimize tab completion commands
+* do character set conversion for tab completion commands
+* require libmpdclient 2.3, MPD 0.16
+
 0.24 (2013/10/29)
 * configure.ac: fix syntax error
 * new command "toggleoutput"
diff --git a/configure b/configure
index ad00e18..33e22c5 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for mpc 0.24.
+# Generated by GNU Autoconf 2.69 for mpc 0.25.
 #
 # Report bugs to <musicpd-dev-team at lists.sourceforge.net>.
 #
@@ -580,8 +580,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='mpc'
 PACKAGE_TARNAME='mpc'
-PACKAGE_VERSION='0.24'
-PACKAGE_STRING='mpc 0.24'
+PACKAGE_VERSION='0.25'
+PACKAGE_STRING='mpc 0.25'
 PACKAGE_BUGREPORT='musicpd-dev-team at lists.sourceforge.net'
 PACKAGE_URL=''
 
@@ -1285,7 +1285,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures mpc 0.24 to adapt to many kinds of systems.
+\`configure' configures mpc 0.25 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1351,7 +1351,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of mpc 0.24:";;
+     short | recursive ) echo "Configuration of mpc 0.25:";;
    esac
   cat <<\_ACEOF
 
@@ -1452,7 +1452,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-mpc configure 0.24
+mpc configure 0.25
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1821,7 +1821,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by mpc $as_me 0.24, which was
+It was created by mpc $as_me 0.25, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2677,7 +2677,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='mpc'
- VERSION='0.24'
+ VERSION='0.25'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -4092,12 +4092,12 @@ if test -n "$LIBMPDCLIENT_CFLAGS"; then
     pkg_cv_LIBMPDCLIENT_CFLAGS="$LIBMPDCLIENT_CFLAGS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libmpdclient >= 2.2\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "libmpdclient >= 2.2") 2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libmpdclient >= 2.3\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libmpdclient >= 2.3") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_LIBMPDCLIENT_CFLAGS=`$PKG_CONFIG --cflags "libmpdclient >= 2.2" 2>/dev/null`
+  pkg_cv_LIBMPDCLIENT_CFLAGS=`$PKG_CONFIG --cflags "libmpdclient >= 2.3" 2>/dev/null`
 		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
@@ -4109,12 +4109,12 @@ if test -n "$LIBMPDCLIENT_LIBS"; then
     pkg_cv_LIBMPDCLIENT_LIBS="$LIBMPDCLIENT_LIBS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libmpdclient >= 2.2\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "libmpdclient >= 2.2") 2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libmpdclient >= 2.3\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libmpdclient >= 2.3") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_LIBMPDCLIENT_LIBS=`$PKG_CONFIG --libs "libmpdclient >= 2.2" 2>/dev/null`
+  pkg_cv_LIBMPDCLIENT_LIBS=`$PKG_CONFIG --libs "libmpdclient >= 2.3" 2>/dev/null`
 		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
@@ -4135,18 +4135,18 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        LIBMPDCLIENT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libmpdclient >= 2.2" 2>&1`
+	        LIBMPDCLIENT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libmpdclient >= 2.3" 2>&1`
         else
-	        LIBMPDCLIENT_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libmpdclient >= 2.2" 2>&1`
+	        LIBMPDCLIENT_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libmpdclient >= 2.3" 2>&1`
         fi
 	# Put the nasty error message in config.log where it belongs
 	echo "$LIBMPDCLIENT_PKG_ERRORS" >&5
 
-	as_fn_error $? "libmpdclient2 is required" "$LINENO" 5
+	as_fn_error $? "libmpdclient 2.3 is required" "$LINENO" 5
 elif test $pkg_failed = untried; then
      	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
-	as_fn_error $? "libmpdclient2 is required" "$LINENO" 5
+	as_fn_error $? "libmpdclient 2.3 is required" "$LINENO" 5
 else
 	LIBMPDCLIENT_CFLAGS=$pkg_cv_LIBMPDCLIENT_CFLAGS
 	LIBMPDCLIENT_LIBS=$pkg_cv_LIBMPDCLIENT_LIBS
@@ -6043,7 +6043,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by mpc $as_me 0.24, which was
+This file was extended by mpc $as_me 0.25, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -6109,7 +6109,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-mpc config.status 0.24
+mpc config.status 0.25
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
index 3c2a618..0e260c0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,8 +1,8 @@
 AC_PREREQ(2.60)
-AC_INIT(mpc, 0.24, musicpd-dev-team at lists.sourceforge.net)
+AC_INIT(mpc, 0.25, musicpd-dev-team at lists.sourceforge.net)
 AC_CONFIG_MACRO_DIR([m4])
 AC_CONFIG_SRCDIR(src/main.c)
-AM_INIT_AUTOMAKE([foreign 1.11 dist-bzip2 dist-xz silent-rules])
+AM_INIT_AUTOMAKE([foreign 1.11 dist-xz silent-rules])
 AC_CONFIG_HEADERS(config.h)
 
 
@@ -75,8 +75,8 @@ dnl
 dnl libc features
 dnl
 
-PKG_CHECK_MODULES([LIBMPDCLIENT], [libmpdclient >= 2.2],,
-	[AC_MSG_ERROR([libmpdclient2 is required])])
+PKG_CHECK_MODULES([LIBMPDCLIENT], [libmpdclient >= 2.3],,
+	[AC_MSG_ERROR([libmpdclient 2.3 is required])])
 
 
 dnl
diff --git a/doc/mpc.1 b/doc/mpc.1
index 20d5a61..1b7890b 100644
--- a/doc/mpc.1
+++ b/doc/mpc.1
@@ -271,7 +271,7 @@ Specifies the port the mpd server is listening on.
 For useful examples of mpc use in playlist parsing, see mpd\-m3u\-playlist.sh and mpd\-pls\-playlist.sh.
 .br
 .SH "BUGS"
-Report bugs on http://www.musicpd.org/mantis/
+Report bugs on http://bugs.musicpd.org/
 .SH "NOTE"
 Since MPD uses UTF\-8, mpc needs to convert characters to the
 charset used by the local system. If you get character conversion errors when you're running mpc you probably need to set up your locale. This is done by setting any of the LC_CTYPE, LANG or LC_ALL environment variables (LC_CTYPE only affects character handling).
diff --git a/src/Compiler.h b/src/Compiler.h
new file mode 100644
index 0000000..9756e1f
--- /dev/null
+++ b/src/Compiler.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef COMPILER_H
+#define COMPILER_H
+
+#define GCC_CHECK_VERSION(major, minor) \
+  (defined(__GNUC__) &&                                                 \
+   (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))))
+
+#ifdef __GNUC__
+#define GCC_VERSION (__GNUC__ * 10000 \
+                     + __GNUC_MINOR__ * 100 \
+                     + __GNUC_PATCHLEVEL__)
+#else
+#define GCC_VERSION 0
+#endif
+
+#if GCC_CHECK_VERSION(4,0)
+
+/* GCC 4.x */
+
+#define gcc_const __attribute__((const))
+#define gcc_deprecated __attribute__((deprecated))
+#define gcc_may_alias __attribute__((may_alias))
+#define gcc_malloc __attribute__((malloc))
+#define gcc_noreturn __attribute__((noreturn))
+#define gcc_packed __attribute__((packed))
+#define gcc_printf(a,b) __attribute__((format(printf, a, b)))
+#define gcc_pure __attribute__((pure))
+#define gcc_sentinel __attribute__((sentinel))
+#define gcc_unused __attribute__((unused))
+#define gcc_warn_unused_result __attribute__((warn_unused_result))
+
+#define gcc_nonnull(...) __attribute__((nonnull(__VA_ARGS__)))
+#define gcc_nonnull_all __attribute__((nonnull))
+
+#define gcc_likely(x) __builtin_expect (!!(x), 1)
+#define gcc_unlikely(x) __builtin_expect (!!(x), 0)
+
+#define gcc_aligned(n) __attribute__((aligned(n)))
+
+#define gcc_visibility_hidden __attribute__((visibility("hidden")))
+#define gcc_visibility_default __attribute__((visibility("default")))
+
+#define gcc_always_inline __attribute__((always_inline))
+
+#else
+
+/* generic C compiler */
+
+#define gcc_const
+#define gcc_deprecated
+#define gcc_may_alias
+#define gcc_malloc
+#define gcc_noreturn
+#define gcc_packed
+#define gcc_printf(a,b)
+#define gcc_pure
+#define gcc_sentinel
+#define gcc_unused
+#define gcc_warn_unused_result
+
+#define gcc_nonnull(...)
+#define gcc_nonnull_all
+
+#define gcc_likely(x) (x)
+#define gcc_unlikely(x) (x)
+
+#define gcc_aligned(n)
+
+#define gcc_visibility_hidden
+#define gcc_visibility_default
+
+#define gcc_always_inline inline
+
+#endif
+
+#if GCC_CHECK_VERSION(4,3)
+
+#define gcc_hot __attribute__((hot))
+#define gcc_cold __attribute__((cold))
+
+#else /* ! GCC_UNUSED >= 40300 */
+
+#define gcc_hot
+#define gcc_cold
+
+#endif /* ! GCC_UNUSED >= 40300 */
+
+#if GCC_CHECK_VERSION(4,6) && !defined(__clang__)
+#define gcc_flatten __attribute__((flatten))
+#else
+#define gcc_flatten
+#endif
+
+#ifndef __cplusplus
+/* plain C99 has "restrict" */
+#define gcc_restrict restrict
+#elif GCC_CHECK_VERSION(4,0)
+/* "__restrict__" is a GCC extension for C++ */
+#define gcc_restrict __restrict__
+#else
+/* disable it on other compilers */
+#define gcc_restrict
+#endif
+
+/* C++11 features */
+
+#if defined(__cplusplus)
+
+/* support for C++11 "override" was added in gcc 4.7 */
+#if !defined(__clang__) && !GCC_CHECK_VERSION(4,7)
+#define override
+#define final
+#endif
+
+#if defined(__clang__) || GCC_CHECK_VERSION(4,8)
+#define gcc_alignas(T, fallback) alignas(T)
+#else
+#define gcc_alignas(T, fallback) gcc_aligned(fallback)
+#endif
+
+#endif
+
+#ifndef __has_feature
+  // define dummy macro for non-clang compilers
+  #define __has_feature(x) 0
+#endif
+
+#if __has_feature(attribute_unused_on_fields)
+#define gcc_unused_field gcc_unused
+#else
+#define gcc_unused_field
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+#define gcc_unreachable() __builtin_unreachable()
+#else
+#define gcc_unreachable()
+#endif
+
+#endif
diff --git a/src/args.c b/src/args.c
new file mode 100644
index 0000000..0b6887d
--- /dev/null
+++ b/src/args.c
@@ -0,0 +1,202 @@
+/*
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "args.h"
+#include "charset.h"
+#include "list.h"
+#include "options.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <assert.h>
+#include <sys/param.h>
+
+int
+stdinToArgArray(char ***array)
+{
+	List *list = makeList(NULL);
+	char buffer[4096];
+
+	while (fgets(buffer, sizeof(buffer), stdin)) {
+		char *sp;
+		if((sp = strchr(buffer,'\n'))) *sp = '\0';
+		insertInListWithoutKey(list,strdup(buffer));
+	}
+
+	const unsigned size = list->numberOfNodes;
+	*array = malloc((sizeof(char *))*size);
+	unsigned i = 0;
+	ListNode * node = list->firstNode;
+	while(node) {
+		(*array)[i++] = (char *)node->data;
+		node = node->nextNode;
+	}
+	assert(i==size);
+
+	freeList(list);
+
+	return size;
+}
+
+void
+free_pipe_array(unsigned max, char ** array)
+{
+	for (unsigned i = 0 ; i < max; ++i)
+		free(array[i]);
+}
+
+bool
+contains_absolute_path(unsigned argc, char **argv)
+{
+	for (unsigned i = 0; i < argc; ++i)
+		if (argv[i][0] == '/')
+			return true;
+
+	return false;
+}
+
+gcc_pure
+static bool
+uri_has_scheme(const char *uri)
+{
+	return strstr(uri, "://") != NULL;
+}
+
+void
+strip_trailing_slash(char *s)
+{
+	if (uri_has_scheme(s))
+		/* strip slashes only if this string is relative to
+		   the music directory; absolute URLs are not, for
+		   sure */
+		return;
+
+	size_t len = strlen(s);
+
+	if (len == 0)
+		return;
+	--len;
+
+	if (s[len] == '/')
+		s[len] = '\0';
+
+	return;
+}
+
+int
+get_boolean(const char *arg)
+{
+	static const struct _bool_table {
+		const char * on;
+		const char * off;
+	} bool_table [] = {
+		{ "on", "off" },
+		{ "1", "0" },
+		{ "true", "false" },
+		{ "yes", "no" },
+		{ .on = NULL }
+	};
+
+	for (unsigned i = 0; bool_table[i].on != NULL; ++i) {
+		if (strcasecmp(arg,bool_table[i].on) == 0)
+			return 1;
+		else if (strcasecmp(arg,bool_table[i].off) == 0)
+			return 0;
+	}
+
+	fprintf(stderr,"\"%s\" is not a boolean value: <",arg);
+
+	for (unsigned i = 0; bool_table[i].on != NULL; ++i) {
+		fprintf(stderr,"%s|%s%s", bool_table[i].on,
+			bool_table[i].off,
+			( bool_table[i+1].off ? "|" : ">\n"));
+	}
+
+	return -1;
+}
+
+bool
+parse_int(const char *str, int *ret)
+{
+	char *test;
+	int temp = strtol(str, &test, 10);
+
+	if (*test != '\0')
+		return false; /* failure */
+
+	*ret = temp;
+	return true; /* success */
+}
+
+bool
+parse_float(const char *str, float *ret)
+{
+	char *test;
+	float temp = strtof(str, &test);
+
+	if (*test != '\0')
+		return false; /* failure */
+
+	*ret = temp;
+	return true; /* success */
+}
+
+bool
+parse_songnum(const char *str, int *ret)
+{
+	if (!str)
+		return false;
+	if (*str == '#')
+		str++;
+
+	char *endptr;
+	int song = strtol(str, &endptr, 10);
+
+	if (str == endptr || (*endptr != ')' && *endptr != '\0') || song < 0)
+		return false;
+
+	*ret = song;
+	return true;
+}
+
+bool
+parse_int_value_change(const char *str, struct int_value_change *ret)
+{
+	const size_t len = strlen(str);
+	if (len < 1)
+		return false;
+
+	int relative = 0;
+	if (*str == '+')
+		relative = 1;
+	else if (*str == '-')
+		relative = -1;
+
+	int change;
+	if (!parse_int(str, &change))
+		return false;
+
+	ret->value = change;
+	ret->is_relative = (relative != 0);
+	return true;
+}
diff --git a/src/args.h b/src/args.h
new file mode 100644
index 0000000..504fc36
--- /dev/null
+++ b/src/args.h
@@ -0,0 +1,73 @@
+/*
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MPC_ARGS_H
+#define MPC_ARGS_H
+
+#include "Compiler.h"
+
+#include <stdbool.h>
+
+struct int_value_change {
+	int value;
+	bool is_relative;
+};
+
+int
+stdinToArgArray(char ***array);
+
+void
+free_pipe_array(unsigned max, char **array);
+
+gcc_pure
+bool
+contains_absolute_path(unsigned argc, char **argv);
+
+void
+strip_trailing_slash(char *s);
+
+int
+get_boolean(const char *arg);
+
+/**
+ * @return true on success
+ */
+bool
+parse_int(const char *s, int *value_r);
+
+/**
+ * @return true on success
+ */
+bool
+parse_float(const char *s, float *value_r);
+
+/**
+ * note - simply strips number out of formatting; does not -1 or +1 or
+ * change the number in any other way for that matter
+ *
+ * @return true on success
+ */
+bool
+parse_songnum(const char *s, int *value_r);
+
+bool
+parse_int_value_change(const char *s, struct int_value_change *value_r);
+
+#endif
diff --git a/src/charset.c b/src/charset.c
index 495e2c8..0bd8cf7 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -1,24 +1,22 @@
-/* music player command (mpc)
- * Copyright (C) 2003-2008 Warren Dukes <warren.dukes at gmail.com>,
-				Eric Wong <normalperson at yhbt.net>,
-				Daniel Brown <danb at cs.utexas.edu>
- * Copyright (C) 2008-2010 Max Kellermann <max at duempel.org>
- * Project homepage: http://musicpd.org
- 
+/*
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
-
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
-
+ *
  * You should have received a copy of the GNU General Public License along
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
+ */
 
 #include "charset.h"
 
@@ -58,7 +56,6 @@ static char * skip_invalid(const char *to)
 {
 	const char *errhand = mpc_strchrnul(to, '/');
 	int nslash = 2;
-	char *newp, *cp;
 
 	if (*errhand == '/') {
 		--nslash;
@@ -70,9 +67,9 @@ static char * skip_invalid(const char *to)
 		}
 	}
 
-	newp = (char *)malloc(errhand - to + nslash + 7 + 1);
+	char *newp = (char *)malloc(errhand - to + nslash + 7 + 1);
 	memcpy(newp, to, errhand - to);
-	cp = newp + (errhand - to);
+	char *cp = newp + (errhand - to);
 	while (nslash-- > 0)
 		*cp++ = '/';
 	if (cp[-1] != '/')
@@ -102,17 +99,14 @@ static int
 charset_set(const char *to, const char *from)
 {
 	char *allocated;
-	int ret;
-
 	if (ignore_invalid)
 		to = allocated = skip_invalid(to);
 	else
 		allocated = NULL;
 
-	ret = charset_set2(to, from);
+	int ret = charset_set2(to, from);
 
-	if (allocated != NULL)
-		free(allocated);
+	free(allocated);
 
 	return ret;
 }
@@ -134,23 +128,20 @@ static inline size_t deconst_iconv(iconv_t cd,
 static char *
 charset_conv_strdup(const char *string)
 {
-	char buffer[BUFFER_SIZE];
+	if(!char_conv_to) return NULL;
+
 	size_t inleft = strlen(string);
-	char * ret;
-	size_t outleft;
 	size_t retlen = 0;
-	size_t err;
-	char * bufferPtr;
-
-	if(!char_conv_to) return NULL;
 
-	ret = strdup("");
+	char *ret = strdup("");
 
 	while(inleft) {
-		bufferPtr = buffer;
-		outleft = BUFFER_SIZE;
-		err = deconst_iconv(char_conv_iconv,&string,&inleft,&bufferPtr,
-				    &outleft);
+		char buffer[BUFFER_SIZE];
+		char *bufferPtr = buffer;
+		size_t outleft = BUFFER_SIZE;
+		size_t err = deconst_iconv(char_conv_iconv,
+					   &string, &inleft, &bufferPtr,
+					   &outleft);
 		if (outleft == BUFFER_SIZE ||
 		    (err == (size_t)-1 && errno != E2BIG)) {
 			free(ret);
@@ -181,18 +172,16 @@ charset_close(void)
 void
 charset_init(bool enable_input, bool enable_output)
 {
-	const char *original_locale, *charset;
-
 	if (!enable_input && !enable_output)
 		return;
 
 	ignore_invalid = isatty(STDOUT_FILENO) && isatty(STDIN_FILENO);
 
-	original_locale = setlocale(LC_CTYPE,"");
+	const char *original_locale = setlocale(LC_CTYPE,"");
 	if (original_locale == NULL)
 		return;
 
-	charset = nl_langinfo(CODESET);
+	const char *charset = nl_langinfo(CODESET);
 	if (charset != NULL)
 		locale_charset = strdup(charset);
 
@@ -219,7 +208,7 @@ charset_to_utf8(const char *from) {
 		/* no locale: return raw input */
 		return from;
 
-	if(to) free(to);
+	free(to);
 
 	charset_set("UTF-8", locale_charset);
 	to = charset_conv_strdup(from);
@@ -238,7 +227,7 @@ charset_from_utf8(const char *from) {
 		/* no locale: return raw UTF-8 */
 		return from;
 
-	if(to) free(to);
+	free(to);
 
 	charset_set(locale_charset, "UTF-8");
 	to = charset_conv_strdup(from);
diff --git a/src/charset.h b/src/charset.h
index 72ffadf..ddb3f17 100644
--- a/src/charset.h
+++ b/src/charset.h
@@ -1,29 +1,28 @@
-/* music player command (mpc)
- * Copyright (C) 2003-2008 Warren Dukes <warren.dukes at gmail.com>,
-				Eric Wong <normalperson at yhbt.net>,
-				Daniel Brown <danb at cs.utexas.edu>
- * Copyright (C) 2008-2010 Max Kellermann <max at duempel.org>
- * Project homepage: http://musicpd.org
- 
+/*
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
-
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
-
+ *
  * You should have received a copy of the GNU General Public License along
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
+ */
 
 #ifndef CHAR_CONV_H
 #define CHAR_CONV_H
 
 #include "config.h"
+#include "Compiler.h"
 
 #include <stdbool.h>
 
@@ -40,9 +39,11 @@ charset_init(bool enable_input, bool enable_output);
 
 void charset_deinit(void);
 
+gcc_pure
 const char *
 charset_to_utf8(const char *from);
 
+gcc_pure
 const char *
 charset_from_utf8(const char *from);
 
diff --git a/src/command.c b/src/command.c
index e01a2fa..340ff7b 100644
--- a/src/command.c
+++ b/src/command.c
@@ -1,33 +1,32 @@
-/* music player command (mpc)
- * Copyright (C) 2003-2008 Warren Dukes <warren.dukes at gmail.com>,
-				Eric Wong <normalperson at yhbt.net>,
-				Daniel Brown <danb at cs.utexas.edu>
- * Copyright (C) 2008-2010 Max Kellermann <max at duempel.org>
- * Project homepage: http://musicpd.org
-
+/*
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
-
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
-
+ *
  * You should have received a copy of the GNU General Public License along
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
+ */
 
 #include "command.h"
 #include "charset.h"
 #include "options.h"
 #include "util.h"
+#include "args.h"
 #include "search.h"
 #include "status.h"
 #include "path.h"
-#include "gcc.h"
+#include "Compiler.h"
 
 #include <mpd/client.h>
 
@@ -35,60 +34,9 @@
 #include <string.h>
 #include <stdlib.h>
 
-#define DIE(...) do { fprintf(stderr, __VA_ARGS__); return -1; } while(0)
-
-#define SIMPLE_CMD(funcname, libmpdclient_funcname, ret) \
-int funcname(mpd_unused int argc, mpd_unused char **argv, \
-	     struct mpd_connection *conn) { \
-        libmpdclient_funcname(conn); \
-        my_finishCommand(conn); \
-        return ret; \
-}
-
-#define SIMPLE_ONEARG_CMD(funcname, libmpdclient_funcname, ret) \
-int funcname (mpd_unused int argc, char **argv, struct mpd_connection *conn) { \
-	if (!libmpdclient_funcname(conn, charset_to_utf8(argv[0]))) \
-		printErrorAndExit(conn); \
-        return ret; \
-}
-
-static void my_finishCommand(struct mpd_connection *conn) {
-	if (!mpd_response_finish(conn))
-		printErrorAndExit(conn);
-}
-
-static bool
-uri_has_scheme(const char *uri)
-{
-	return strstr(uri, "://") != NULL;
-}
-
-static void
-strip_trailing_slash(char *s)
-{
-	if (uri_has_scheme(s))
-		/* strip slashes only if this string is relative to
-		   the music directory; absolute URLs are not, for
-		   sure */
-		return;
-
-	size_t len = strlen(s);
-
-	if (len == 0)
-		return;
-	--len;
-
-	if (s[len] == '/')
-		s[len] = '\0';
-
-	return;
-}
-
 SIMPLE_CMD(cmd_next, mpd_run_next, 1)
 SIMPLE_CMD(cmd_prev, mpd_run_previous, 1)
 SIMPLE_CMD(cmd_stop, mpd_run_stop, 1)
-SIMPLE_CMD(cmd_clear, mpd_run_clear, 1)
-SIMPLE_CMD(cmd_shuffle, mpd_run_shuffle, 1)
 
 #if LIBMPDCLIENT_CHECK_VERSION(2,4,0)
 SIMPLE_CMD(cmd_clearerror, mpd_run_clearerror, 1)
@@ -97,115 +45,6 @@ SIMPLE_CMD(cmd_clearerror, mpd_run_clearerror, 1)
 SIMPLE_ONEARG_CMD(cmd_save, mpd_run_save, 0)
 SIMPLE_ONEARG_CMD(cmd_rm, mpd_run_rm, 0)
 
-static struct mpd_status *
-getStatus(struct mpd_connection *conn) {
-	struct mpd_status *ret = mpd_run_status(conn);
-	if (ret == NULL)
-		printErrorAndExit(conn);
-
-	return ret;
-}
-
-static bool
-contains_absolute_path(unsigned argc, char **argv)
-{
-	for (unsigned i = 0; i < argc; ++i)
-		if (argv[i][0] == '/')
-			return true;
-
-	return false;
-}
-
-int cmd_add (int argc, char ** argv, struct mpd_connection *conn )
-{
-	if (contains_absolute_path(argc, argv) && !path_prepare(conn))
-		printErrorAndExit(conn);
-
-	int i;
-
-	if (!mpd_command_list_begin(conn, false))
-		printErrorAndExit(conn);
-
-	for(i=0;i<argc;i++) {
-		strip_trailing_slash(argv[i]);
-
-		const char *path = argv[i];
-		const char *relative_path = to_relative_path(path);
-		if (relative_path != NULL)
-			path = relative_path;
-
-		if (options.verbosity >= V_VERBOSE)
-			printf("adding: %s\n", path);
-		mpd_send_add(conn, charset_to_utf8(path));
-	}
-
-	if (!mpd_command_list_end(conn))
-		printErrorAndExit(conn);
-
-	if (!mpd_response_finish(conn)) {
-#if LIBMPDCLIENT_CHECK_VERSION(2,4,0)
-		if (mpd_connection_get_error(conn) == MPD_ERROR_SERVER) {
-			/* check which of the arguments has failed */
-			unsigned location =
-				mpd_connection_get_server_error_location(conn);
-			if (location < (unsigned)argc) {
-				/* we've got a valid location from the
-				   server */
-				const char *message =
-					mpd_connection_get_error_message(conn);
-				message = charset_from_utf8(message);
-				fprintf(stderr, "error adding %s: %s\n",
-					argv[location], message);
-				exit(EXIT_FAILURE);
-			}
-		}
-#endif
-
-		printErrorAndExit(conn);
-	}
-
-	return 0;
-}
-
-int
-cmd_crop(mpd_unused int argc, mpd_unused char **argv, struct mpd_connection *conn)
-{
-	struct mpd_status *status = getStatus( conn );
-	int length = mpd_status_get_queue_length(status) - 1;
-
-	if (length < 0) {
-
-		mpd_status_free(status);
-		DIE( "A playlist longer than 1 song in length is required to crop.\n" );
-
-	} else if (mpd_status_get_state(status) == MPD_STATE_PLAY ||
-		   mpd_status_get_state(status) == MPD_STATE_PAUSE) {
-		if (!mpd_command_list_begin(conn, false))
-			printErrorAndExit(conn);
-
-		while( length >= 0 )
-		{
-			if (length != mpd_status_get_song_pos(status)) {
-				mpd_send_delete(conn, length);
-			}
-			length--;
-		}
-
-		mpd_status_free(status);
-
-		if (!mpd_command_list_end(conn) || !mpd_response_finish(conn))
-			printErrorAndExit(conn);
-
-		return ( 0 );
-
-	} else {
-
-		mpd_status_free(status);
-		DIE( "You need to be playing to crop the playlist\n" );
-
-	}
-}
-
 /**
  * Returns the id of the current song, but only if it is really
  * playing (playing or paused).
@@ -225,9 +64,6 @@ get_active_song(const struct mpd_status *status)
 static void
 wait_current(struct mpd_connection *c)
 {
-	if (mpd_connection_cmp_server_version(c, 0, 14, 0) < 0)
-		fprintf(stderr, "warning: MPD 0.14 required for this command\n");
-
 	struct mpd_status *status = getStatus(c);
 
 	const int old_song = get_active_song(status);
@@ -245,31 +81,29 @@ wait_current(struct mpd_connection *c)
 	} while (new_song == old_song);
 }
 
-int cmd_current(mpd_unused int argc, mpd_unused char ** argv, struct mpd_connection *conn)
+int
+cmd_current(gcc_unused int argc, gcc_unused char **argv,
+	    struct mpd_connection *conn)
 {
 	if (options.wait)
 		wait_current(conn);
 
-	struct mpd_status *status;
-
 	if (!mpd_command_list_begin(conn, true) ||
 	    !mpd_send_status(conn) ||
 	    !mpd_send_current_song(conn) ||
 	    !mpd_command_list_end(conn))
 		printErrorAndExit(conn);
 
-	status = mpd_recv_status(conn);
+	struct mpd_status *status = mpd_recv_status(conn);
 	if (status == NULL)
 		printErrorAndExit(conn);
 
 	if (mpd_status_get_state(status) == MPD_STATE_PLAY ||
 	    mpd_status_get_state(status) == MPD_STATE_PAUSE) {
-		struct mpd_song *song;
-
 		if (!mpd_response_next(conn))
 			printErrorAndExit(conn);
 
-		song = mpd_recv_song(conn);
+		struct mpd_song *song = mpd_recv_song(conn);
 		if (song != NULL) {
 			pretty_print_song(song);
 			printf("\n");
@@ -280,94 +114,16 @@ int cmd_current(mpd_unused int argc, mpd_unused char ** argv, struct mpd_connect
 		if (!mpd_response_finish(conn))
 			printErrorAndExit(conn);
 	}
-	mpd_status_free(status);
-
-	return 0;
-}
-
-int cmd_del ( int argc, char ** argv, struct mpd_connection *conn )
-{
-	int i,j;
-	char * s;
-	char * t;
-	char * t2;
-	int range[2];
-	int songsDeleted = 0;
-	int plLength = 0;
-	char * songsToDel;
-	struct mpd_status *status;
-
-	status = getStatus(conn);
-
-	plLength = mpd_status_get_queue_length(status);
-
-	songsToDel = malloc(plLength);
-	memset(songsToDel,0,plLength);
-
-	for(i=0;i<argc;i++) {
-		if(argv[i][0]=='#') s = &(argv[i][1]);
-		else s = argv[i];
-
-		range[0] = strtol(s,&t,10);
-
-		/* If argument is 0 current song and we're not stopped */
-		if(range[0] == 0 && strlen(s) == 1 && \
-			(mpd_status_get_state(status) == MPD_STATE_PLAY ||
-			 mpd_status_get_state(status) == MPD_STATE_PAUSE))
-			range[0] = mpd_status_get_song_pos(status) + 1;
-
-		if(s==t)
-			DIE("error parsing song numbers from: %s\n",argv[i]);
-		else if(*t=='-') {
-			range[1] = strtol(t+1,&t2,10);
-			if(t+1==t2 || *t2!='\0')
-				DIE("error parsing range from: %s\n",argv[i]);
-		}
-		else if(*t==')' || *t=='\0') range[1] = range[0];
-		else
-			DIE("error parsing song numbers from: %s\n",argv[i]);
-
-		if(range[0]<=0 || range[1]<=0) {
-			if (range[0]==range[1])
-				DIE("song number must be positive: %i\n",range[0]);
-			else
-				DIE("song numbers must be positive: %i to %i\n",range[0],range[1]);
-		}
-
-		if(range[1]<range[0])
-			DIE("song range must be from low to high: %i to %i\n",range[0],range[1]);
-
-		if(range[1]>plLength)
-			DIE("song number does not exist: %i\n",range[1]);
-
-		for(j=range[0];j<=range[1];j++) songsToDel[j-1] = 1;
-	}
-
-	if (!mpd_command_list_begin(conn, false))
-		printErrorAndExit(conn);
-
-	for(i=0;i<plLength;i++) {
-		if(songsToDel[i]) {
-			mpd_send_delete(conn, i - songsDeleted);
-			songsDeleted++;
-		}
-	}
 
 	mpd_status_free(status);
-	free(songsToDel);
-
-	if (!mpd_command_list_end(conn) || !mpd_response_finish(conn))
-		printErrorAndExit(conn);
-
 	return 0;
 }
 
 int
-cmd_cdprev(mpd_unused int argc, mpd_unused char **argv,
+cmd_cdprev(gcc_unused int argc, gcc_unused char **argv,
 	   struct mpd_connection *conn)
 {
-	struct mpd_status *status;
-	status = getStatus(conn);
+	struct mpd_status *status = getStatus(conn);
 
 	/* go to previous track if mpd is playing first 3 seconds of
 	   current track otherwise seek to beginning of current
@@ -383,10 +139,9 @@ cmd_cdprev(mpd_unused int argc, mpd_unused char **argv,
 }
 
 int
-cmd_toggle(mpd_unused int argc, mpd_unused char **argv, struct mpd_connection *conn)
+cmd_toggle(gcc_unused int argc, gcc_unused char **argv, struct mpd_connection *conn)
 {
-	struct mpd_status *status;
-	status = getStatus(conn);
+	struct mpd_status *status = getStatus(conn);
 
 	if (mpd_status_get_state(status) == MPD_STATE_PLAY) {
 		cmd_pause(0, NULL, conn);
@@ -397,12 +152,11 @@ cmd_toggle(mpd_unused int argc, mpd_unused char **argv, struct mpd_connection *c
 }
 
 int
-cmd_outputs(mpd_unused int argc, mpd_unused char **argv, struct mpd_connection *conn)
+cmd_outputs(gcc_unused int argc, gcc_unused char **argv, struct mpd_connection *conn)
 {
-	struct mpd_output *output;
-
 	mpd_send_outputs(conn);
 
+	struct mpd_output *output;
 	while ((output = mpd_recv_output(conn)) != NULL) {
 		/* We increment by 1 to make it natural to the user  */
 		int id = mpd_output_get_id(output) + 1;
@@ -424,11 +178,11 @@ static unsigned
 match_outputs(struct mpd_connection *conn,
 	      char **names, char **names_end, unsigned **ids_end)
 {
-	struct mpd_output *output;
 	unsigned max = 0, *id = *ids_end;
 
 	mpd_send_outputs(conn);
 
+	struct mpd_output *output;
 	while ((output = mpd_recv_output(conn)) != NULL) {
 		const char *name = mpd_output_get_name(output);
 		max = mpd_output_get_id(output);
@@ -462,10 +216,8 @@ enable_disable(int argc, char **argv, struct mpd_connection *conn,
 	       bool (*not_matched)(struct mpd_connection *conn, unsigned id))
 {
 	char **names = argv, **names_end = argv;
-	unsigned *ids, *ids_end, max;
-	bool only = false;
-	int arg;
 
+	bool only = false;
 	if (not_matched != NULL && !strcmp(argv[0], "only")) {
 		only = true;
 		++argv;
@@ -474,10 +226,11 @@ enable_disable(int argc, char **argv, struct mpd_connection *conn,
 		}
 	}
 
-	ids = malloc(argc * sizeof *ids);
-	ids_end = ids;
+	unsigned *ids = malloc(argc * sizeof *ids);
+	unsigned *ids_end = ids;
 
 	for (int i = argc; i; --i, ++argv) {
+		int arg;
 		if (!parse_int(*argv, &arg)) {
 			*names_end = *argv;
 			++names_end;
@@ -489,6 +242,7 @@ enable_disable(int argc, char **argv, struct mpd_connection *conn,
 		}
 	}
 
+	unsigned max;
 	if (only || names != names_end) {
 		max = match_outputs(conn, names, names_end, &ids_end);
 	}
@@ -536,7 +290,7 @@ cmd_enable(int argc, char **argv, struct mpd_connection *conn)
 }
 
 int
-cmd_disable(mpd_unused int argc, char **argv, struct mpd_connection *conn)
+cmd_disable(gcc_unused int argc, char **argv, struct mpd_connection *conn)
 {
 	return enable_disable(argc, argv, conn, mpd_send_disable_output,
 			      mpd_send_enable_output);
@@ -556,23 +310,21 @@ cmd_toggle_output(int argc, char **argv, struct mpd_connection *conn)
 int cmd_play ( int argc, char ** argv, struct mpd_connection *conn )
 {
 	int song;
-	int i;
 
 	if(0==argc) song = -1;
 	else {
-		struct mpd_status *status;
-
-		for(i=0;i<argc-1;i++)
+		for (int i = 0; i < argc - 1; ++i)
 			printf("skipping: %s\n",argv[i]);
 
-                if(!parse_songnum(argv[i], &song))
-			DIE("error parsing song numbers from: %s\n",argv[i]);
+		if (!parse_songnum(argv[argc - 1], &song))
+			DIE("error parsing song numbers from: %s\n",
+			    argv[argc - 1]);
 
 		song--;
 
 		/* This is necessary, otherwise mpc will output the wrong playlist number */
-		status = getStatus(conn);
-		i = mpd_status_get_queue_length(status);
+		struct mpd_status *status = getStatus(conn);
+		int i = mpd_status_get_queue_length(status);
 		mpd_status_free(status);
 		if(song >= i)
 			DIE("song number greater than playlist length.\n");
@@ -587,15 +339,13 @@ int cmd_play ( int argc, char ** argv, struct mpd_connection *conn )
 }
 
 int
-cmd_seek(mpd_unused int argc, mpd_unused char **argv, struct mpd_connection *conn)
+cmd_seek(gcc_unused int argc, gcc_unused char **argv, struct mpd_connection *conn)
 {
 	struct mpd_status *status;
 	char * arg = argv[0];
-	char * test;
 
 	int seekchange;
 	int total_secs;
-	int seekto;
         int rel = 0;
 
 	status = getStatus(conn);
@@ -611,15 +361,12 @@ cmd_seek(mpd_unused int argc, mpd_unused char **argv, struct mpd_connection *con
 
 	/* If seeking by percent */
 	if( arg[strlen(arg)-1] == '%' ) {
-
-		double perc;
-
 		/* Remove the % */
 		arg[ strlen(arg) - 1 ] = '\0';
 
 		/* percent seek, strtod is needed for percent with decimals */
-		perc = strtod(arg,&test);
-
+		char *test;
+		double perc = strtod(arg,&test);
 		if(( *test!='\0' ) || (!rel && (perc<0 || perc>100)) || (rel && perc>abs(100)))
 			DIE("\"%s\" is not an number between 0 and 100\n",arg);
 
@@ -628,22 +375,19 @@ cmd_seek(mpd_unused int argc, mpd_unused char **argv, struct mpd_connection *con
 	} else { /* If seeking by absolute seek time */
 
 		if( strchr( arg, ':' )) {
-			char * sec_ptr;
-			char * min_ptr;
-			char * hr_ptr;
-
 			int hr = 0;
 			int min = 0;
 			int sec = 0;
 
 			/* Take the seconds off the end of arg */
-			sec_ptr = strrchr( arg, ':' );
+			char *sec_ptr = strrchr(arg, ':');
 
 			/* Remove ':' and move the pointer one byte up */
 			* sec_ptr = '\0';
 			++sec_ptr;
 
 			/* If hour is in the argument, else just point to the arg */
+			char *min_ptr;
 			if(( min_ptr = strrchr( arg, ':' ))) {
 
 				/* Remove ':' and move the pointer one byte up */
@@ -652,7 +396,8 @@ cmd_seek(mpd_unused int argc, mpd_unused char **argv, struct mpd_connection *con
 
 				/* If the argument still exists, it's the hour  */
 				if( arg != NULL ) {
-					hr_ptr = arg;
+					char *hr_ptr = arg;
+					char *test;
 					hr = strtol( hr_ptr, &test, 10 );
 
 					if( *test != '\0' || ( ! rel && hr < 0 ))
@@ -663,6 +408,7 @@ cmd_seek(mpd_unused int argc, mpd_unused char **argv, struct mpd_connection *con
 			}
 
 			/* Change the pointers to a integer  */
+			char *test;
 			sec = strtol( sec_ptr, &test, 10 );
 
 			if( *test != '\0' || ( ! rel && sec < 0 ))
@@ -690,6 +436,7 @@ cmd_seek(mpd_unused int argc, mpd_unused char **argv, struct mpd_connection *con
 		} else {
 
 			/* absolute seek (in seconds) */
+			char *test;
 			total_secs = strtol( arg, &test, 10 ); /* get the # of seconds */
 
 			if( *test != '\0' || ( ! rel && total_secs < 0 ))
@@ -699,6 +446,7 @@ cmd_seek(mpd_unused int argc, mpd_unused char **argv, struct mpd_connection *con
 	}
 
 	/* This detects +/- and is necessary due to the parsing of HH:MM:SS numbers*/
+	int seekto;
 	if(rel == 1) {
 		seekto = mpd_status_get_elapsed_time(status) + seekchange;
 	} else if (rel == -1) {
@@ -719,14 +467,13 @@ cmd_seek(mpd_unused int argc, mpd_unused char **argv, struct mpd_connection *con
 }
 
 int
-cmd_move(mpd_unused int argc, char **argv, struct mpd_connection *conn)
+cmd_move(gcc_unused int argc, char **argv, struct mpd_connection *conn)
 {
 	int from;
-	int to;
-
 	if(!parse_int(argv[0], &from) || from<=0)
 		DIE("\"%s\" is not a positive integer\n",argv[0]);
 
+	int to;
 	if(!parse_int(argv[1], &to) || to<=0)
 		DIE("\"%s\" is not a positive integer\n",argv[1]);
 
@@ -739,25 +486,6 @@ cmd_move(mpd_unused int argc, char **argv, struct mpd_connection *conn)
 	return 0;
 }
 
-int
-cmd_playlist(mpd_unused int argc, mpd_unused char **argv, struct mpd_connection *conn)
-{
-	struct mpd_song *song;
-
-	if (!mpd_send_list_queue_meta(conn))
-		printErrorAndExit(conn);
-
-	while ((song = mpd_recv_song(conn)) != NULL) {
-		pretty_print_song(song);
-		mpd_song_free(song);
-		printf("\n");
-	}
-
-	my_finishCommand(conn);
-
-	return 0;
-}
-
 int cmd_listall ( int argc, char ** argv, struct mpd_connection *conn )
 {
 	const char * listall = "";
@@ -794,13 +522,11 @@ int cmd_update ( int argc, char ** argv, struct mpd_connection *conn)
 	if (contains_absolute_path(argc, argv) && !path_prepare(conn))
 		printErrorAndExit(conn);
 
-	const char * update = "";
-	int i = 0;
-	unsigned id = 0;
-
 	if (!mpd_command_list_begin(conn, false))
 		printErrorAndExit(conn);
 
+	int i = 0;
+	const char * update = "";
 	if(argc > 0) update = charset_to_utf8(argv[i]);
 
 	do {
@@ -821,6 +547,7 @@ int cmd_update ( int argc, char ** argv, struct mpd_connection *conn)
 
 	/* obtain the last "update id" response */
 
+	unsigned id = 0;
 	while (true) {
 		unsigned next_id = mpd_recv_update_id(conn);
 		if (next_id == 0)
@@ -862,7 +589,6 @@ ls_entity(int argc, char **argv, struct mpd_connection *conn,
 {
 	const char *ls = "";
 	int i = 0;
-
 	if (argc > 0)
 		ls = charset_to_utf8(argv[i]);
 
@@ -892,12 +618,10 @@ int cmd_lsplaylists ( int argc, char ** argv, struct mpd_connection *conn )
 
 int cmd_load ( int argc, char ** argv, struct mpd_connection *conn )
 {
-	int i;
-
 	if (!mpd_command_list_begin(conn, false))
 		printErrorAndExit(conn);
 
-	for(i=0;i<argc;i++) {
+	for (int i = 0; i < argc; ++i) {
 		printf("loading: %s\n",argv[i]);
 		mpd_send_load(conn, charset_to_utf8(argv[i]));
 	}
@@ -907,29 +631,9 @@ int cmd_load ( int argc, char ** argv, struct mpd_connection *conn )
 	return 0;
 }
 
-int cmd_insert (int argc, char ** argv, struct mpd_connection *conn )
-{
-	int ret;
-	struct mpd_status *status = getStatus(conn);
-
-	const int from = mpd_status_get_queue_length(status);
-
-	ret = cmd_add(argc, argv, conn);
-	const int cur_pos = mpd_status_get_song_pos(status);
-	mpd_status_free(status);
-	if (ret != 0) {
-		return ret;
-	}
-	return mpd_run_move_range(conn, from, from+argc,
-		cur_pos+1);
-}
-
 int cmd_list ( int argc, char ** argv, struct mpd_connection *conn )
 {
-	enum mpd_tag_type type;
-	struct mpd_pair *pair;
-
-	type = get_search_type(argv[0]);
+	enum mpd_tag_type type = get_search_type(argv[0]);
 	if (type == MPD_TAG_UNKNOWN)
 		return -1;
 
@@ -944,6 +648,7 @@ int cmd_list ( int argc, char ** argv, struct mpd_connection *conn )
 	if (!mpd_search_commit(conn))
 		printErrorAndExit(conn);
 
+	struct mpd_pair *pair;
 	while ((pair = mpd_recv_pair_tag(conn, type)) != NULL) {
 		printf("%s\n", charset_from_utf8(pair->value));
 		mpd_return_pair(conn, pair);
@@ -957,13 +662,12 @@ int cmd_list ( int argc, char ** argv, struct mpd_connection *conn )
 int cmd_volume ( int argc, char ** argv, struct mpd_connection *conn )
 {
         struct int_value_change ch;
-	struct mpd_status *status;
 
 	if(argc==1) {
                 if(!parse_int_value_change(argv[0], &ch))
 			DIE("\"%s\" is not an integer\n", argv[0]);
 	} else {
-		status = getStatus(conn);
+		struct mpd_status *status = getStatus(conn);
 
 		if (mpd_status_get_volume(status) >= 0)
 			printf("volume:%3i%c\n",
@@ -987,10 +691,8 @@ int cmd_volume ( int argc, char ** argv, struct mpd_connection *conn )
 		}
 #endif
 
-		int old_volume;
-
-		status = getStatus(conn);
-		old_volume = mpd_status_get_volume(status);
+		struct mpd_status *status = getStatus(conn);
+		int old_volume = mpd_status_get_volume(status);
 		mpd_status_free(status);
 
 		ch.value += old_volume;
@@ -1009,7 +711,7 @@ int cmd_volume ( int argc, char ** argv, struct mpd_connection *conn )
 }
 
 int
-cmd_pause(mpd_unused int argc, mpd_unused char **argv, struct mpd_connection *conn)
+cmd_pause(gcc_unused int argc, gcc_unused char **argv, struct mpd_connection *conn)
 {
 	mpd_send_pause(conn, true);
 	my_finishCommand(conn);
@@ -1067,9 +769,8 @@ int cmd_consume(int argc, char ** argv, struct mpd_connection *conn)
 
 int cmd_crossfade ( int argc, char ** argv, struct mpd_connection *conn )
 {
-	int seconds;
-
 	if(argc==1) {
+		int seconds;
                 if(!parse_int(argv[0], &seconds) || seconds<0)
 			DIE("\"%s\" is not 0 or positive integer\n",argv[0]);
 
@@ -1087,12 +788,10 @@ int cmd_crossfade ( int argc, char ** argv, struct mpd_connection *conn )
 	return 0;
 }
 
-#if LIBMPDCLIENT_CHECK_VERSION(2,2,0)
 int cmd_mixrampdb ( int argc, char ** argv, struct mpd_connection *conn )
 {
-	float db;
-
 	if(argc==1) {
+		float db;
 		if(!parse_float(argv[0], &db))
 			DIE("\"%s\" is not a floating point number\n",argv[0]);
 
@@ -1100,8 +799,7 @@ int cmd_mixrampdb ( int argc, char ** argv, struct mpd_connection *conn )
                 my_finishCommand(conn);
 	}
 	else {
-		struct mpd_status *status;
-		status = getStatus(conn);
+		struct mpd_status *status = getStatus(conn);
 
 		printf("mixrampdb: %f\n", mpd_status_get_mixrampdb(status));
 
@@ -1112,9 +810,8 @@ int cmd_mixrampdb ( int argc, char ** argv, struct mpd_connection *conn )
 
 int cmd_mixrampdelay ( int argc, char ** argv, struct mpd_connection *conn )
 {
-	float seconds;
-
 	if(argc==1) {
+		float seconds;
 		if(!parse_float(argv[0], &seconds))
 			DIE("\"%s\" is not a floating point number\n",argv[0]);
 
@@ -1132,10 +829,9 @@ int cmd_mixrampdelay ( int argc, char ** argv, struct mpd_connection *conn )
 	}
 	return 0;
 }
-#endif
 
 int
-cmd_version(mpd_unused int argc, mpd_unused char **argv, struct mpd_connection *conn)
+cmd_version(gcc_unused int argc, gcc_unused char **argv, struct mpd_connection *conn)
 {
 	const unsigned *version = mpd_connection_get_server_version(conn);
 
@@ -1148,92 +844,9 @@ cmd_version(mpd_unused int argc, mpd_unused char **argv, struct mpd_connection *
 	return 0;
 }
 
-int cmd_loadtab ( int argc, char ** argv, struct mpd_connection *conn )
-{
-	struct mpd_playlist *pl;
-
-	if (argc != 1)
-		return 0;
-
-	if (!mpd_send_list_meta(conn, NULL))
-		printErrorAndExit(conn);
-
-	while ((pl = mpd_recv_playlist(conn)) != NULL) {
-		if (strncmp(mpd_playlist_get_path(pl), argv[0],
-			    strlen(argv[0])) == 0)
-			printf("%s\n",
-			       charset_from_utf8(mpd_playlist_get_path(pl)));
-
-		mpd_playlist_free(pl);
-	}
-
-	my_finishCommand(conn);
-	return 0;
-}
-
-int cmd_lstab ( int argc, char ** argv, struct mpd_connection *conn )
-{
-	struct mpd_directory *dir;
-
-	if (argc != 1)
-		return 0;
-
-	if (!mpd_send_list_all(conn, NULL))
-		printErrorAndExit(conn);
-
-	while ((dir = mpd_recv_directory(conn)) != NULL) {
-		if (strncmp(mpd_directory_get_path(dir), argv[0],
-			    strlen(argv[0])) == 0)
-			printf("%s\n",
-			       charset_from_utf8(mpd_directory_get_path(dir)));
-
-		mpd_directory_free(dir);
-	}
-
-	my_finishCommand(conn);
-
-	return 0;
-}
-
-int cmd_tab ( int argc, char ** argv, struct mpd_connection *conn )
-{
-	struct mpd_song *song;
-	char empty[] = "";
-	char *dir = empty;
-	char *tmp = NULL;
-
-	if (argc == 1) {
-		if (strrchr(argv[0], '/')) {
-			dir = strdup(argv[0]);
-			if (!dir) return 0;
-			tmp = strrchr(dir, '/');
-			if (tmp) *tmp = '\0'; // XXX: It's unpossible for tmp to be NULL.
-		}
-	}
-
-	if (!mpd_send_list_all(conn, dir))
-		printErrorAndExit(conn);
-
-	if (*dir) free(dir);
-
-	while ((song = mpd_recv_song(conn)) != NULL) {
-		if (argc != 1 ||
-		    strncmp(mpd_song_get_uri(song), argv[0],
-			    strlen(argv[0])) == 0)
-			printf("%s\n",
-			       charset_from_utf8(mpd_song_get_uri(song)));
-
-		mpd_song_free(song);
-	}
-
-	my_finishCommand(conn);
-	return 0;
-}
-
 static char * DHMS(unsigned long t)
 {
 	static char buf[32];	/* Ugh */
-	int days, hours, mins, secs;
 
 #ifndef SECSPERDAY
 #define SECSPERDAY 86400
@@ -1245,13 +858,13 @@ static char * DHMS(unsigned long t)
 #define SECSPERMIN 60
 #endif
 
-	days = t / SECSPERDAY;
+	unsigned days = t / SECSPERDAY;
 	t %= SECSPERDAY;
-	hours = t / SECSPERHOUR;
+	unsigned hours = t / SECSPERHOUR;
 	t %= SECSPERHOUR;
-	mins = t / SECSPERMIN;
+	unsigned mins = t / SECSPERMIN;
 	t %= SECSPERMIN;
-	secs = t;
+	unsigned secs = t;
 
 	snprintf(buf, sizeof(buf), "%d days, %d:%02d:%02d",
 	    days, hours, mins, secs);
@@ -1259,23 +872,22 @@ static char * DHMS(unsigned long t)
 }
 
 int
-cmd_stats(mpd_unused int argc, mpd_unused char **argv, struct mpd_connection *conn)
+cmd_stats(gcc_unused int argc, gcc_unused char **argv, struct mpd_connection *conn)
 {
-	struct mpd_stats *stats;
-	time_t t;
-
-	stats = mpd_run_stats(conn);
+	struct mpd_stats *stats = mpd_run_stats(conn);
 	if (stats == NULL)
 		printErrorAndExit(conn);
 
-	t = mpd_stats_get_db_update_time(stats);
 	printf("Artists: %6d\n", mpd_stats_get_number_of_artists(stats));
 	printf("Albums:  %6d\n", mpd_stats_get_number_of_albums(stats));
 	printf("Songs:   %6d\n", mpd_stats_get_number_of_songs(stats));
 	printf("\n");
 	printf("Play Time:    %s\n", DHMS(mpd_stats_get_play_time(stats)));
 	printf("Uptime:       %s\n", DHMS(mpd_stats_get_uptime(stats)));
+
+	time_t t = mpd_stats_get_db_update_time(stats);
 	printf("DB Updated:   %s", ctime(&t));	/* no \n needed */
+
 	printf("DB Play Time: %s\n", DHMS(mpd_stats_get_db_play_time(stats)));
 
 	mpd_stats_free(stats);
@@ -1283,7 +895,7 @@ cmd_stats(mpd_unused int argc, mpd_unused char **argv, struct mpd_connection *co
 }
 
 int
-cmd_status(mpd_unused  int argc, mpd_unused char **argv, struct mpd_connection *conn)
+cmd_status(gcc_unused  int argc, gcc_unused char **argv, struct mpd_connection *conn)
 {
 	if (options.verbosity >= V_DEFAULT)
 		print_status(conn);
@@ -1296,13 +908,10 @@ cmd_replaygain(int argc, char **argv, struct mpd_connection *connection)
 	/* libmpdclient 2.0 doesn't support these commands yet, we
 	   have to roll our own with mpd_send_command() */
 
-	if (mpd_connection_cmp_server_version(connection, 0, 16, 0) < 0)
-		fprintf(stderr, "warning: MPD 0.16 required for this command\n");
-
 	if (argc == 0) {
-		struct mpd_pair *pair;
-
 		mpd_send_command(connection, "replay_gain_status", NULL);
+
+		struct mpd_pair *pair;
 		while ((pair = mpd_recv_pair(connection)) != NULL) {
 			printf("%s: %s\n", pair->name, pair->value);
 			mpd_return_pair(connection, pair);
diff --git a/src/command.h b/src/command.h
index f1119fc..c4e713d 100644
--- a/src/command.h
+++ b/src/command.h
@@ -1,24 +1,22 @@
-/* music player command (mpc)
- * Copyright (C) 2003-2008 Warren Dukes <warren.dukes at gmail.com>,
-				Eric Wong <normalperson at yhbt.net>,
-				Daniel Brown <danb at cs.utexas.edu>
- * Copyright (C) 2008-2010 Max Kellermann <max at duempel.org>
- * Project homepage: http://musicpd.org
-
+/*
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
-
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
-
+ *
  * You should have received a copy of the GNU General Public License along
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
+ */
 
 #ifndef COMMAND_H
 #define COMMAND_H
@@ -26,26 +24,19 @@
 struct mpd_connection;
 
 int cmd_status(int argc, char **argv, struct mpd_connection *conn);
-int cmd_add(int argc, char **argv, struct mpd_connection *conn);
-int cmd_crop(int argc, char **argv, struct mpd_connection *conn);
 int cmd_current(int argc, char **argv, struct mpd_connection *conn);
-int cmd_del(int argc, char **argv, struct mpd_connection *conn);
 int cmd_play(int argc, char **argv, struct mpd_connection *conn);
 int cmd_next(int argc, char **argv, struct mpd_connection *conn);
 int cmd_prev(int argc, char **argv, struct mpd_connection *conn);
 int cmd_pause(int argc, char **argv, struct mpd_connection *conn);
 int cmd_stop(int argc, char **argv, struct mpd_connection *conn);
 int cmd_seek(int argc, char **argv, struct mpd_connection *conn);
-int cmd_clear(int argc, char **argv, struct mpd_connection *conn);
-int cmd_shuffle(int argc, char **argv, struct mpd_connection *conn);
 int cmd_clearerror(int argc, char **argv, struct mpd_connection *conn);
 int cmd_move(int argc, char **argv, struct mpd_connection *conn);
-int cmd_playlist(int argc, char **argv, struct mpd_connection *conn);
 int cmd_listall(int argc, char **argv, struct mpd_connection *conn);
 int cmd_ls(int argc, char **argv, struct mpd_connection *conn);
 int cmd_lsplaylists(int argc, char **argv, struct mpd_connection *conn);
 int cmd_load(int argc, char **argv, struct mpd_connection *conn);
-int cmd_insert(int argc, char **argv, struct mpd_connection *conn);
 int cmd_list(int argc, char **argv, struct mpd_connection *conn);
 int cmd_save(int argc, char **argv, struct mpd_connection *conn);
 int cmd_rm(int argc, char **argv, struct mpd_connection *conn);
@@ -66,9 +57,6 @@ cmd_toggle_output(int argc, char **argv, struct mpd_connection *conn);
 int cmd_outputs(int argc, char **argv, struct mpd_connection *conn);
 int cmd_update(int argc, char **argv, struct mpd_connection *conn);
 int cmd_version(int argc, char **argv, struct mpd_connection *conn);
-int cmd_loadtab(int argc, char **argv, struct mpd_connection *conn);
-int cmd_lstab(int argc, char **argv, struct mpd_connection *conn);
-int cmd_tab(int argc, char **argv, struct mpd_connection *conn);
 int cmd_stats(int argc, char **argv, struct mpd_connection *conn);
 int cmd_cdprev(int argc, char **argv, struct mpd_connection *conn);
 int cmd_toggle(int argc, char **argv, struct mpd_connection *conn);
diff --git a/src/gcc.h b/src/gcc.h
deleted file mode 100644
index f88f64b..0000000
--- a/src/gcc.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* music player command (mpc)
- * Copyright (C) 2003-2008 Warren Dukes <warren.dukes at gmail.com>,
-				Eric Wong <normalperson at yhbt.net>,
-				Daniel Brown <danb at cs.utexas.edu>
- * Copyright (C) 2008-2010 Max Kellermann <max at duempel.org>
- * Project homepage: http://musicpd.org
- 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef MPD_GCC_H
-#define MPD_GCC_H
-
-/* this allows us to take advantage of special gcc features while still
- * allowing other compilers to compile:
- */
-
-#ifdef mpd_unused
-#undef mpd_unused
-#endif
-
-#if defined(__GNUC__) && (__GNUC__ >= 3)
-#  define mpd_deprecated	__attribute__ ((deprecated))
-#  define mpd_must_check	__attribute__ ((warn_unused_result))
-#  define mpd_noreturn		__attribute__ ((noreturn))
-#  define mpd_packed		__attribute__ ((packed))
-/* these are very useful for type checking */
-#  define mpd_fprintf		__attribute__ ((format(printf,2,3)))
-#  define mpd_fprintf_		__attribute__ ((format(printf,3,4)))
-#  define mpd_fprintf__		__attribute__ ((format(printf,4,5)))
-#  define mpd_scanf		__attribute__ ((format(scanf,1,2)))
-#  define mpd_unused		__attribute__ ((unused))
-#  define mpd_used		__attribute__ ((used))
-/* #  define inline	inline __attribute__ ((always_inline)) */
-#  define mpd_noinline		__attribute__ ((noinline))
-#  define mpd_likely(x)		__builtin_expect (!!(x), 1)
-#  define mpd_unlikely(x)	__builtin_expect (!!(x), 0)
-#else
-#  define mpd_deprecated
-#  define mpd_must_check
-#  define mpd_noreturn
-#  define mpd_packed
-#  define mpd_fprintf
-#  define mpd_fprintf_
-#  define mpd_fprintf__
-#  define mpd_scanf
-#  define mpd_unused
-#  define mpd_used
-/* #  define inline */
-#  define mpd_noinline
-#  define mpd_likely(x)		(x)
-#  define mpd_unlikely(x)	(x)
-#endif
-
-#endif /* MPD_GCC_H */
diff --git a/src/idle.c b/src/idle.c
index dc556ba..e288dec 100644
--- a/src/idle.c
+++ b/src/idle.c
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2008-2010 The Music Player Daemon Project
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
  * http://www.musicpd.org
  *
  * This program is free software; you can redistribute it and/or modify
@@ -30,9 +31,6 @@ int cmd_idle(int argc, char **argv,
 {
 	enum mpd_idle idle = 0;
 
-	if (mpd_connection_cmp_server_version(connection, 0, 14, 0) < 0)
-		fprintf(stderr, "warning: MPD 0.14 required for this command\n");
-
 	for (int i = 0; i < argc; ++i) {
 		enum mpd_idle parsed = mpd_idle_name_parse(argv[i]);
 		if (parsed == 0) {
@@ -67,10 +65,8 @@ int cmd_idle(int argc, char **argv,
 int
 cmd_idleloop(int argc, char **argv, struct mpd_connection *connection)
 {
-	int ret;
-
 	while (true) {
-		ret = cmd_idle(argc, argv, connection);
+		int ret = cmd_idle(argc, argv, connection);
 		fflush(stdout);
 		if (ret != 0)
 			return ret;
diff --git a/src/idle.h b/src/idle.h
index 1a9a71d..25f94f7 100644
--- a/src/idle.h
+++ b/src/idle.h
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2008-2010 The Music Player Daemon Project
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
  * http://www.musicpd.org
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/src/list.c b/src/list.c
index badce82..afc0da3 100644
--- a/src/list.c
+++ b/src/list.c
@@ -1,24 +1,22 @@
-/* music player command (mpc)
- * Copyright (C) 2003-2008 Warren Dukes <warren.dukes at gmail.com>,
-				Eric Wong <normalperson at yhbt.net>,
-				Daniel Brown <danb at cs.utexas.edu>
- * Copyright (C) 2008-2010 Max Kellermann <max at duempel.org>
- * Project homepage: http://musicpd.org
- 
+/*
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
-
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
-
+ *
  * You should have received a copy of the GNU General Public License along
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
+ */
 
 #include "list.h"
 
@@ -239,7 +237,7 @@ void freeList(void * list) {
 
 	tmpNode = ((List *)list)->firstNode;
 
-	if(((List *)list)->nodesArray) free(((List *)list)->nodesArray);
+	free(((List *)list)->nodesArray);
 
 	while(tmpNode!=NULL) {
 		tmpNode2 = tmpNode->nextNode;
diff --git a/src/list.h b/src/list.h
index 6daf173..e3c0d28 100644
--- a/src/list.h
+++ b/src/list.h
@@ -1,24 +1,22 @@
-/* music player command (mpc)
- * Copyright (C) 2003-2008 Warren Dukes <warren.dukes at gmail.com>,
-				Eric Wong <normalperson at yhbt.net>,
-				Daniel Brown <danb at cs.utexas.edu>
- * Copyright (C) 2008-2010 Max Kellermann <max at duempel.org>
- * Project homepage: http://musicpd.org
- 
+/*
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
-
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
-
+ *
  * You should have received a copy of the GNU General Public License along
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
+ */
 
 #ifndef LIST_H
 #define LIST_H
diff --git a/src/main.c b/src/main.c
index 4faa2b5..a3ad346 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,32 +1,33 @@
-/* music player command (mpc)
- * Copyright (C) 2003-2008 Warren Dukes <warren.dukes at gmail.com>,
-				Eric Wong <normalperson at yhbt.net>,
-				Daniel Brown <danb at cs.utexas.edu>
- * Copyright (C) 2008-2010 Max Kellermann <max at duempel.org>
- * Project homepage: http://musicpd.org
-
+/*
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
-
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
-
+ *
  * You should have received a copy of the GNU General Public License along
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
+ */
 
 #include "list.h"
 #include "charset.h"
 #include "password.h"
 #include "util.h"
+#include "args.h"
 #include "status.h"
 #include "command.h"
+#include "queue.h"
 #include "sticker.h"
+#include "tab.h"
 #include "idle.h"
 #include "message.h"
 #include "search.h"
@@ -105,20 +106,16 @@ static struct command {
 #if LIBMPDCLIENT_CHECK_VERSION(2,4,0)
 	{"clearerror",  0,   0,   0,    cmd_clearerror,  "", "Clear the current error"},
 #endif
-#if LIBMPDCLIENT_CHECK_VERSION(2,2,0)
 	{"mixrampdb",   0,   1,   0,    cmd_mixrampdb,   "[<dB>]", "Set and display mixrampdb settings"},
 	{"mixrampdelay",0,   1,   0,    cmd_mixrampdelay,"[<seconds>]", "Set and display mixrampdelay settings"},
-#endif
 	{"update",      0,   -1,  2,    cmd_update,      "[<path>]", "Scan music directory for updates"},
-#if LIBMPDCLIENT_CHECK_VERSION(2,1,0)
 	{"sticker",     2,   -1,  0,    cmd_sticker,     "<uri> <get|set|list|delete|find> [args..]", "Sticker management"},
-#endif
 	{"stats",       0,   -1,  0,    cmd_stats,       "", "Display statistics about MPD"},
 	{"version",     0,   0,   0,    cmd_version,     "", "Report version of MPD"},
 	/* loadtab, lstab, and tab used for completion-scripting only */
-	{"loadtab",     0,   1,   0,    cmd_loadtab,     "<directory>", NULL},
-	{"lstab",       0,   1,   0,    cmd_lstab,       "<directory>", NULL},
-	{"tab",         0,   1,   0,    cmd_tab,         "<path>", NULL},
+	{"loadtab",     1,   1,   0,    cmd_loadtab,     "<directory>", NULL},
+	{"lstab",       1,   1,   0,    cmd_lstab,       "<directory>", NULL},
+	{"tab",         1,   1,   0,    cmd_tab,         "<path>", NULL},
 	/* status was added for pedantic reasons */
 	{"status",      0,   -1,  0,    cmd_status,      "", NULL},
 	{ "idle", 0, -1, 0, cmd_idle, "[events]",
@@ -150,10 +147,9 @@ print_usage(FILE * outfp, char * progname)
 		"mpc version: "VERSION"\n",progname);
 }
 
-static int print_help(char * progname, char * command)
+static int
+print_help(const char *progname, const char *command)
 {
-	int i, max = 0;
-
 	if (command && strcmp(command, "help")) {
 		fprintf(stderr,"unknown command \"%s\"\n",command);
 		print_usage(stderr, progname);
@@ -170,22 +166,22 @@ static int print_help(char * progname, char * command)
 
 	printf("Commands:\n");
 
-	for (i=0; mpc_table[i].command; ++i) {
+	unsigned max = 0;
+	for (unsigned i = 0; mpc_table[i].command != NULL; ++i) {
 		if (mpc_table[i].help) {
-			int tmp = strlen(mpc_table[i].command) +
-					strlen(mpc_table[i].usage);
+			unsigned tmp = strlen(mpc_table[i].command) +
+				strlen(mpc_table[i].usage);
 			max = (tmp > max) ? tmp : max;
 		}
 	}
 
 	printf("  %s %*s  Display status\n",progname,max," ");
 
-	for (i=0; mpc_table[i].command; ++i) {
-		int spaces;
-
+	for (unsigned i = 0; mpc_table[i].command != NULL; ++i) {
 		if (!mpc_table[i].help)
 			continue ;
-		spaces = max-(strlen(mpc_table[i].command)+strlen(mpc_table[i].usage));
+
+		int spaces = max-(strlen(mpc_table[i].command)+strlen(mpc_table[i].usage));
 		spaces += !spaces ? 0 : 1;
 
 		printf("  %s %s %s%*s%s\n",progname,
@@ -200,9 +196,7 @@ static int print_help(char * progname, char * command)
 static struct mpd_connection *
 setup_connection(void)
 {
-	struct mpd_connection *conn;
-
-	conn = mpd_connection_new(options.host, options.port, 0);
+	struct mpd_connection *conn = mpd_connection_new(options.host, options.port, 0);
 	if (conn == NULL) {
 		fputs("Out of memory\n", stderr);
 		exit(EXIT_FAILURE);
@@ -232,7 +226,6 @@ static char **
 check_args(struct command *command, int * argc, char ** argv)
 {
 	char ** array;
-	int i;
 
 	if ((command->pipe == 1 &&
 		(2==*argc || (3==*argc && 0==strcmp(argv[2],STDIN_SYMBOL) )))
@@ -243,7 +236,7 @@ check_args(struct command *command, int * argc, char ** argv)
 	} else {
 		*argc -= 2;
 		array = malloc( (*argc * (sizeof(char *))));
-		for(i=0;i<*argc;++i) {
+		for(int i = 0; i < *argc; ++i) {
 			array[i]=argv[i+2];
 		}
 	}
@@ -259,12 +252,12 @@ check_args(struct command *command, int * argc, char ** argv)
 static int
 run(const struct command *command, int argc, char **array)
 {
-	int ret;
-	struct mpd_connection *conn;
+	struct mpd_connection *conn = setup_connection();
 
-	conn = setup_connection();
+	if (mpd_connection_cmp_server_version(conn, 0, 16, 0) < 0)
+		fprintf(stderr, "warning: MPD 0.16 required\n");
 
-	ret = command->handler(argc, array, conn);
+	int ret = command->handler(argc, array, conn);
 	if (ret != 0 && options.verbosity > V_QUIET) {
 		print_status(conn);
 	}
@@ -275,14 +268,11 @@ run(const struct command *command, int argc, char **array)
 
 int main(int argc, char ** argv)
 {
-	int ret;
-	const char *command_name;
-	struct command *command;
-
 	parse_options(&argc, argv);
 
 	/* parse command and arguments */
 
+	const char *command_name;
 	if (argc >= 2)
 		command_name = argv[1];
 	else {
@@ -294,9 +284,9 @@ int main(int argc, char ** argv)
 		argc = 2;
 	}
 
-	command = find_command(command_name);
+	struct command *command = find_command(command_name);
 	if (command == NULL)
-		return print_help(argv[0], argv[1]);
+		return print_help("mpc", argv[1]);
 
 	argv = check_args(command, &argc, argv);
 
@@ -306,7 +296,7 @@ int main(int argc, char ** argv)
 
 	/* run */
 
-	ret = run(command, argc, argv);
+	int ret = run(command, argc, argv);
 
 	/* cleanup */
 
diff --git a/src/message.c b/src/message.c
index 7558ba6..1db8a5e 100644
--- a/src/message.c
+++ b/src/message.c
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2008-2011 The Music Player Daemon Project
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
  * http://www.musicpd.org
  *
  * This program is free software; you can redistribute it and/or modify
@@ -20,6 +21,7 @@
 #include "message.h"
 #include "util.h"
 #include "charset.h"
+#include "Compiler.h"
 
 #include <mpd/client.h>
 
@@ -32,7 +34,7 @@
 #if LIBMPDCLIENT_CHECK_VERSION(2,5,0)
 
 int
-cmd_channels(mpd_unused int argc, mpd_unused char **argv,
+cmd_channels(gcc_unused int argc, gcc_unused char **argv,
 	     struct mpd_connection *connection)
 {
 	if (!mpd_send_channels(connection))
@@ -52,7 +54,7 @@ cmd_channels(mpd_unused int argc, mpd_unused char **argv,
 }
 
 int
-cmd_sendmessage(mpd_unused int argc, char **argv,
+cmd_sendmessage(gcc_unused int argc, char **argv,
 		struct mpd_connection *connection)
 {
 	const char *text = charset_to_utf8(argv[1]);
@@ -63,7 +65,7 @@ cmd_sendmessage(mpd_unused int argc, char **argv,
 }
 
 int
-cmd_waitmessage(mpd_unused int argc, char **argv,
+cmd_waitmessage(gcc_unused int argc, char **argv,
 		struct mpd_connection *connection)
 {
 	if (!mpd_run_subscribe(connection, argv[0]) ||
@@ -85,7 +87,7 @@ cmd_waitmessage(mpd_unused int argc, char **argv,
 }
 
 int
-cmd_subscribe(mpd_unused int argc, char **argv,
+cmd_subscribe(gcc_unused int argc, char **argv,
 	      struct mpd_connection *connection)
 {
 	if (!mpd_run_subscribe(connection, argv[0]))
diff --git a/src/message.h b/src/message.h
index b67b61a..0c87a1e 100644
--- a/src/message.h
+++ b/src/message.h
@@ -1,24 +1,22 @@
-/* music player command (mpc)
- * Copyright (C) 2003-2008 Warren Dukes <warren.dukes at gmail.com>,
-				Eric Wong <normalperson at yhbt.net>,
-				Daniel Brown <danb at cs.utexas.edu>
- * Copyright (C) 2008-2011 Max Kellermann <max at duempel.org>
- * Project homepage: http://musicpd.org
-
+/*
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
-
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
-
+ *
  * You should have received a copy of the GNU General Public License along
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
+ */
 
 #ifndef MPC_MESSAGE_H
 #define MPC_MESSAGE_H
diff --git a/src/mpc.h b/src/mpc.h
index 86eb3ef..36e0d1e 100644
--- a/src/mpc.h
+++ b/src/mpc.h
@@ -1,24 +1,22 @@
-/* music player command (mpc)
- * Copyright (C) 2003-2008 Warren Dukes <warren.dukes at gmail.com>,
-				Eric Wong <normalperson at yhbt.net>,
-				Daniel Brown <danb at cs.utexas.edu>
- * Copyright (C) 2008-2010 Max Kellermann <max at duempel.org>
- * Project homepage: http://musicpd.org
- 
+/*
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
-
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
-
+ *
  * You should have received a copy of the GNU General Public License along
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
+ */
 
 #ifndef MPC_H
 #define MPC_H
diff --git a/src/options.c b/src/options.c
index 4e43e8c..0be30c1 100644
--- a/src/options.c
+++ b/src/options.c
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2008-2010 The Music Player Daemon Project
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
  * http://www.musicpd.org
  *
  * This program is free software; you can redistribute it and/or modify
@@ -86,9 +87,7 @@ option_error(int error, const char *option, const char *arg)
 static const arg_opt_t *
 lookup_long_option(const char *l, size_t len)
 {
-	unsigned i;
-
-	for (i = 0; i < option_table_size; ++i) {
+	for (unsigned i = 0; i < option_table_size; ++i) {
 		if (strncmp(l, option_table[i].longopt, len) == 0)
 			return &option_table[i];
 	}
@@ -99,9 +98,7 @@ lookup_long_option(const char *l, size_t len)
 static const arg_opt_t *
 lookup_short_option(int s)
 {
-	unsigned i;
-
-	for (i = 0; i < option_table_size; ++i) {
+	for (unsigned i = 0; i < option_table_size; ++i) {
 		if (s == option_table[i].shortopt)
 			return &option_table[i];
 	}
@@ -147,9 +144,7 @@ handle_option(int c, const char *arg)
 void
 print_option_help(void)
 {
-	unsigned i;
-
-	for (i = 0; i < option_table_size; i++) {
+	for (unsigned i = 0; i < option_table_size; i++) {
 		printf("  -%c, ", option_table[i].shortopt);
 		if (option_table[i].argument)
 			printf("--%s=%-*s",
@@ -178,7 +173,6 @@ parse_options(int * argc_p, char ** argv)
 		if (arg[0] == '-' && (arg[1] < '0' || arg[1] > '9')) {
 			if (arg[1] == '-') {
 				/* arg is a long option */
-				char *value;
 				size_t name_len = len - 2;
 
 				/* if arg is "--", there can be no more options */
@@ -195,6 +189,7 @@ parse_options(int * argc_p, char ** argv)
 					option_error(ERROR_MISSING_ARGUMENT, opt->longopt, opt->argument);
 
 				/* retrieve a option argument */
+				char *value;
 				if ((value = strchr(arg + 2, '=')) != NULL) {
 					name_len = value - arg - 2;
 					value++;
diff --git a/src/options.h b/src/options.h
index 4928e3f..9628cf7 100644
--- a/src/options.h
+++ b/src/options.h
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2008-2010 The Music Player Daemon Project
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
  * http://www.musicpd.org
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/src/password.c b/src/password.c
index 23eb414..a4ed341 100644
--- a/src/password.c
+++ b/src/password.c
@@ -1,24 +1,22 @@
-/* music player command (mpc)
- * Copyright (C) 2003-2008 Warren Dukes <warren.dukes at gmail.com>,
-				Eric Wong <normalperson at yhbt.net>,
-				Daniel Brown <danb at cs.utexas.edu>
- * Copyright (C) 2008-2010 Max Kellermann <max at duempel.org>
- * Project homepage: http://musicpd.org
- 
+/*
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
-
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
-
+ *
  * You should have received a copy of the GNU General Public License along
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
+ */
 
 #include "password.h"
 #include "util.h"
diff --git a/src/password.h b/src/password.h
index e729882..8d6df5f 100644
--- a/src/password.h
+++ b/src/password.h
@@ -1,24 +1,22 @@
-/* music player command (mpc)
- * Copyright (C) 2003-2008 Warren Dukes <warren.dukes at gmail.com>,
-				Eric Wong <normalperson at yhbt.net>,
-				Daniel Brown <danb at cs.utexas.edu>
- * Copyright (C) 2008-2010 Max Kellermann <max at duempel.org>
- * Project homepage: http://musicpd.org
- 
+/*
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
-
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
-
+ *
  * You should have received a copy of the GNU General Public License along
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
+ */
 
 #ifndef PASSWORD_H
 #define PASSWORD_H
diff --git a/src/path.c b/src/path.c
index de1e8e9..ab498a3 100644
--- a/src/path.c
+++ b/src/path.c
@@ -1,20 +1,18 @@
-/* music player command (mpc)
- * Copyright (C) 2003-2008 Warren Dukes <warren.dukes at gmail.com>,
-				Eric Wong <normalperson at yhbt.net>,
-				Daniel Brown <danb at cs.utexas.edu>
- * Copyright (C) 2008-2013 Max Kellermann <max at duempel.org>
- * Project homepage: http://musicpd.org
-
+/*
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
-
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
-
+ *
  * You should have received a copy of the GNU General Public License along
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
@@ -53,7 +51,6 @@ path_prepare(struct mpd_connection *conn)
 	return mpd_response_finish(conn) || mpd_connection_clear_error(conn);
 }
 
-mpd_pure
 const char *
 to_relative_path(const char *path)
 {
diff --git a/src/path.h b/src/path.h
index 1360519..6edb9ef 100644
--- a/src/path.h
+++ b/src/path.h
@@ -1,28 +1,28 @@
-/* music player command (mpc)
- * Copyright (C) 2003-2008 Warren Dukes <warren.dukes at gmail.com>,
-				Eric Wong <normalperson at yhbt.net>,
-				Daniel Brown <danb at cs.utexas.edu>
- * Copyright (C) 2008-2013 Max Kellermann <max at duempel.org>
- * Project homepage: http://musicpd.org
-
+/*
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
-
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
-
+ *
  * You should have received a copy of the GNU General Public License along
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
+ */
 
 #ifndef MPC_PATH_H
 #define MPC_PATH_H
 
+#include "Compiler.h"
+
 #include <stdbool.h>
 
 struct mpd_connection;
@@ -35,6 +35,7 @@ path_prepare(struct mpd_connection *conn);
  * That works only if we're connected to MPD via UNIX domain socket
  * and MPD supports the "config" command.
  */
+gcc_pure
 const char *
 to_relative_path(const char *path);
 
diff --git a/src/queue.c b/src/queue.c
new file mode 100644
index 0000000..68f1655
--- /dev/null
+++ b/src/queue.c
@@ -0,0 +1,245 @@
+/* music player command (mpc)
+ * Copyright (C) 2003-2008 Warren Dukes <warren.dukes at gmail.com>,
+				Eric Wong <normalperson at yhbt.net>,
+				Daniel Brown <danb at cs.utexas.edu>
+ * Copyright (C) 2008-2010 Max Kellermann <max at duempel.org>
+ * Project homepage: http://musicpd.org
+
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "queue.h"
+#include "args.h"
+#include "charset.h"
+#include "options.h"
+#include "util.h"
+#include "path.h"
+#include "Compiler.h"
+
+#include <mpd/client.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+SIMPLE_CMD(cmd_clear, mpd_run_clear, 1)
+SIMPLE_CMD(cmd_shuffle, mpd_run_shuffle, 1)
+
+int
+cmd_add(int argc, char **argv, struct mpd_connection *conn)
+{
+	if (contains_absolute_path(argc, argv) && !path_prepare(conn))
+		printErrorAndExit(conn);
+
+	if (!mpd_command_list_begin(conn, false))
+		printErrorAndExit(conn);
+
+	for (int i = 0; i < argc; ++i) {
+		strip_trailing_slash(argv[i]);
+
+		const char *path = argv[i];
+		const char *relative_path = to_relative_path(path);
+		if (relative_path != NULL)
+			path = relative_path;
+
+		if (options.verbosity >= V_VERBOSE)
+			printf("adding: %s\n", path);
+		mpd_send_add(conn, charset_to_utf8(path));
+	}
+
+	if (!mpd_command_list_end(conn))
+		printErrorAndExit(conn);
+
+	if (!mpd_response_finish(conn)) {
+#if LIBMPDCLIENT_CHECK_VERSION(2,4,0)
+		if (mpd_connection_get_error(conn) == MPD_ERROR_SERVER) {
+			/* check which of the arguments has failed */
+			unsigned location =
+				mpd_connection_get_server_error_location(conn);
+			if (location < (unsigned)argc) {
+				/* we've got a valid location from the
+				   server */
+				const char *message =
+					mpd_connection_get_error_message(conn);
+				message = charset_from_utf8(message);
+				fprintf(stderr, "error adding %s: %s\n",
+					argv[location], message);
+				exit(EXIT_FAILURE);
+			}
+		}
+#endif
+
+		printErrorAndExit(conn);
+	}
+
+	return 0;
+}
+
+int
+cmd_crop(gcc_unused int argc, gcc_unused char **argv,
+	 struct mpd_connection *conn)
+{
+	struct mpd_status *status = getStatus(conn);
+	int length = mpd_status_get_queue_length(status) - 1;
+
+	if (length < 0) {
+		mpd_status_free(status);
+		DIE("A playlist longer than 1 song in length is required to crop.\n");
+	} else if (mpd_status_get_state(status) == MPD_STATE_PLAY ||
+		   mpd_status_get_state(status) == MPD_STATE_PAUSE) {
+		if (!mpd_command_list_begin(conn, false))
+			printErrorAndExit(conn);
+
+		for (; length >= 0; --length)
+			if (length != mpd_status_get_song_pos(status))
+				mpd_send_delete(conn, length);
+
+		mpd_status_free(status);
+
+		if (!mpd_command_list_end(conn) || !mpd_response_finish(conn))
+			printErrorAndExit(conn);
+
+		return 0;
+	} else {
+		mpd_status_free(status);
+		DIE("You need to be playing to crop the playlist\n");
+	}
+}
+
+int
+cmd_del(int argc, char **argv, struct mpd_connection *conn)
+{
+	struct mpd_status *status = getStatus(conn);
+
+	const int plLength = mpd_status_get_queue_length(status);
+
+	char *songsToDel = malloc(plLength);
+	memset(songsToDel,0,plLength);
+
+	for (int i = 0; i < argc; ++i) {
+		char *s;
+		if (argv[i][0]=='#')
+			s = &argv[i][1];
+		else
+			s = argv[i];
+
+		char *t;
+		int range[2];
+		range[0] = strtol(s, &t, 10);
+
+		/* If argument is 0 current song and we're not stopped */
+		if (range[0] == 0 && strlen(s) == 1 &&
+		    (mpd_status_get_state(status) == MPD_STATE_PLAY ||
+		     mpd_status_get_state(status) == MPD_STATE_PAUSE))
+			range[0] = mpd_status_get_song_pos(status) + 1;
+
+		if (s==t)
+			DIE("error parsing song numbers from: %s\n", argv[i]);
+		else if (*t=='-') {
+			char *t2;
+			range[1] = strtol(t+1, &t2, 10);
+			if(t + 1 == t2 || *t2!='\0')
+				DIE("error parsing range from: %s\n", argv[i]);
+		} else if (*t == ')' || *t=='\0')
+			range[1] = range[0];
+		else
+			DIE("error parsing song numbers from: %s\n", argv[i]);
+
+		if (range[0] <= 0 || range[1] <= 0) {
+			if (range[0] == range[1])
+				DIE("song number must be positive: %i\n",
+				    range[0]);
+			else
+				DIE("song numbers must be positive: %i to %i\n",
+				    range[0], range[1]);
+		}
+
+		if (range[1] < range[0])
+			DIE("song range must be from low to high: %i to %i\n",range[0],range[1]);
+
+		if (range[1] > plLength)
+			DIE("song number does not exist: %i\n",range[1]);
+
+		for (int j = range[0]; j <= range[1]; j++)
+			songsToDel[j - 1] = 1;
+	}
+
+	if (!mpd_command_list_begin(conn, false))
+		printErrorAndExit(conn);
+
+	int songsDeleted = 0;
+	for (int i = 0; i < plLength; ++i) {
+		if (songsToDel[i]) {
+			mpd_send_delete(conn, i - songsDeleted);
+			++songsDeleted;
+		}
+	}
+
+	mpd_status_free(status);
+	free(songsToDel);
+
+	if (!mpd_command_list_end(conn) || !mpd_response_finish(conn))
+		printErrorAndExit(conn);
+
+	return 0;
+}
+
+int
+cmd_playlist(gcc_unused int argc, gcc_unused char **argv, struct mpd_connection *conn)
+{
+	if (!mpd_send_list_queue_meta(conn))
+		printErrorAndExit(conn);
+
+	struct mpd_song *song;
+	while ((song = mpd_recv_song(conn)) != NULL) {
+		pretty_print_song(song);
+		mpd_song_free(song);
+		printf("\n");
+	}
+
+	my_finishCommand(conn);
+	return 0;
+}
+
+gcc_pure
+static unsigned
+query_queue_length(struct mpd_connection *conn)
+{
+	struct mpd_status *status = getStatus(conn);
+	const unsigned length = mpd_status_get_queue_length(status);
+	mpd_status_free(status);
+	return length;
+}
+
+int cmd_insert (int argc, char ** argv, struct mpd_connection *conn )
+{
+	struct mpd_status *status = getStatus(conn);
+	const unsigned from = mpd_status_get_queue_length(status);
+	const int cur_pos = mpd_status_get_song_pos(status);
+	mpd_status_free(status);
+
+	int ret = cmd_add(argc, argv, conn);
+	if (ret != 0)
+		return ret;
+
+	/* check the new queue length to find out how many songs were
+	   appended  */
+	const unsigned end = query_queue_length(conn);
+	if (end == from)
+		return 0;
+
+	/* move those songs to right after the current one */
+	return mpd_run_move_range(conn, from, end, cur_pos + 1);
+}
diff --git a/src/idle.h b/src/queue.h
similarity index 56%
copy from src/idle.h
copy to src/queue.h
index 1a9a71d..bed4868 100644
--- a/src/idle.h
+++ b/src/queue.h
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2008-2010 The Music Player Daemon Project
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
  * http://www.musicpd.org
  *
  * This program is free software; you can redistribute it and/or modify
@@ -17,15 +18,30 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#ifndef MPC_IDLE_H
-#define MPC_IDLE_H
+#ifndef MPC_QUEUE_H
+#define MPC_QUEUE_H
 
 struct mpd_connection;
 
 int
-cmd_idle(int argc, char **argv, struct mpd_connection *connection);
+cmd_clear(int argc, char **argv, struct mpd_connection *conn);
 
 int
-cmd_idleloop(int argc, char **argv, struct mpd_connection *connection);
+cmd_shuffle(int argc, char **argv, struct mpd_connection *conn);
 
-#endif
+int
+cmd_add(int argc, char **argv, struct mpd_connection *conn);
+
+int
+cmd_crop(int argc, char **argv, struct mpd_connection *conn);
+
+int
+cmd_del(int argc, char **argv, struct mpd_connection *conn);
+
+int
+cmd_playlist(int argc, char **argv, struct mpd_connection *conn);
+
+int
+cmd_insert(int argc, char **argv, struct mpd_connection *conn);
+
+#endif /* COMMAND_H */
diff --git a/src/search.c b/src/search.c
index 1495069..e77f88c 100644
--- a/src/search.c
+++ b/src/search.c
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2008-2010 The Music Player Daemon Project
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
  * http://www.musicpd.org
  *
  * This program is free software; you can redistribute it and/or modify
@@ -27,13 +28,9 @@
 #include <string.h>
 #include <strings.h>
 
-#define DIE(...) do { fprintf(stderr, __VA_ARGS__); return false; } while(0)
-
 enum mpd_tag_type
 get_search_type(const char *name)
 {
-	enum mpd_tag_type type;
-
 	if (strcasecmp(name, "any") == 0)
 		return SEARCH_TAG_ANY;
 
@@ -45,7 +42,7 @@ get_search_type(const char *name)
 		return SEARCH_TAG_BASE;
 #endif
 
-	type = mpd_tag_name_iparse(name);
+	enum mpd_tag_type type = mpd_tag_name_iparse(name);
 	if (type != MPD_TAG_UNKNOWN)
 		return type;
 
@@ -91,11 +88,6 @@ get_constraints(int argc, char **argv, struct constraint **constraints)
 	return numconstraints;
 }
 
-static void my_finishCommand(struct mpd_connection *conn) {
-	if (!mpd_response_finish(conn))
-		printErrorAndExit(conn);
-}
-
 static void
 add_constraint(struct mpd_connection *conn,
 	       const struct constraint *constraint)
@@ -121,17 +113,15 @@ bool
 add_constraints(int argc, char ** argv, struct mpd_connection *conn)
 {
 	struct constraint *constraints;
-	int numconstraints;
-	int i;
 
 	if (argc % 2 != 0)
 		DIE("arguments must be pairs of search types and queries\n");
 
-	numconstraints = get_constraints(argc, argv, &constraints);
+	int numconstraints = get_constraints(argc, argv, &constraints);
 	if (numconstraints < 0)
 		return false;
 
-	for (i = 0; i < numconstraints; i++) {
+	for (int i = 0; i < numconstraints; i++) {
 		add_constraint(conn, &constraints[i]);
 	}
 
@@ -170,9 +160,6 @@ cmd_find(int argc, char **argv, struct mpd_connection *conn)
 int
 cmd_findadd(int argc, char **argv, struct mpd_connection *conn)
 {
-	if (mpd_connection_cmp_server_version(conn, 0, 16, 0) < 0)
-		fprintf(stderr, "warning: MPD 0.16 required for this command\n");
-
 	mpd_search_add_db_songs(conn, true);
 	if (!add_constraints(argc, argv, conn))
 		return -1;
diff --git a/src/search.h b/src/search.h
index b348021..cbb6675 100644
--- a/src/search.h
+++ b/src/search.h
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2008-2010 The Music Player Daemon Project
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
  * http://www.musicpd.org
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/src/status.c b/src/status.c
index 98a393f..18f0a1b 100644
--- a/src/status.c
+++ b/src/status.c
@@ -1,24 +1,22 @@
-/* music player command (mpc)
- * Copyright (C) 2003-2008 Warren Dukes <warren.dukes at gmail.com>,
-				Eric Wong <normalperson at yhbt.net>,
-				Daniel Brown <danb at cs.utexas.edu>
- * Copyright (C) 2008-2010 Max Kellermann <max at duempel.org>
- * Project homepage: http://musicpd.org
-
+/*
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
-
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
-
+ *
  * You should have received a copy of the GNU General Public License along
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
+ */
 
 #include "status.h"
 #include "charset.h"
@@ -34,12 +32,11 @@
 static unsigned
 elapsed_percent(const struct mpd_status *status)
 {
-	unsigned elapsed = mpd_status_get_elapsed_time(status);
 	unsigned total = mpd_status_get_total_time(status);
-
 	if (total == 0)
 		return 0;
 
+	unsigned elapsed = mpd_status_get_elapsed_time(status);
 	if (elapsed >= total)
 		return 100;
 
@@ -49,26 +46,22 @@ elapsed_percent(const struct mpd_status *status)
 void
 print_status(struct mpd_connection *conn)
 {
-	struct mpd_status *status;
-
 	if (!mpd_command_list_begin(conn, true) ||
 	    !mpd_send_status(conn) ||
 	    !mpd_send_current_song(conn) ||
 	    !mpd_command_list_end(conn))
 		printErrorAndExit(conn);
 
-	status = mpd_recv_status(conn);
+	struct mpd_status *status = mpd_recv_status(conn);
 	if (status == NULL)
 		printErrorAndExit(conn);
 
 	if (mpd_status_get_state(status) == MPD_STATE_PLAY ||
 	    mpd_status_get_state(status) == MPD_STATE_PAUSE) {
-		struct mpd_song *song;
-
 		if (!mpd_response_next(conn))
 			printErrorAndExit(conn);
 
-		song = mpd_recv_song(conn);
+		struct mpd_song *song = mpd_recv_song(conn);
 		if (song != NULL) {
 			pretty_print_song(song);
 			printf("\n");
diff --git a/src/status.h b/src/status.h
index 765b51b..21f74f7 100644
--- a/src/status.h
+++ b/src/status.h
@@ -1,24 +1,22 @@
-/* music player command (mpc)
- * Copyright (C) 2003-2008 Warren Dukes <warren.dukes at gmail.com>,
-				Eric Wong <normalperson at yhbt.net>,
-				Daniel Brown <danb at cs.utexas.edu>
- * Copyright (C) 2008-2010 Max Kellermann <max at duempel.org>
- * Project homepage: http://musicpd.org
- 
+/*
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
-
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
-
+ *
  * You should have received a copy of the GNU General Public License along
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
+ */
 
 #ifndef STATUS_H
 #define STATUS_H
diff --git a/src/sticker.c b/src/sticker.c
index b4ffedd..0c2ccef 100644
--- a/src/sticker.c
+++ b/src/sticker.c
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2008-2010 The Music Player Daemon Project
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
  * http://www.musicpd.org
  *
  * This program is free software; you can redistribute it and/or modify
@@ -25,13 +26,6 @@
 #include <string.h>
 #include <stdio.h>
 
-#if LIBMPDCLIENT_CHECK_VERSION(2,1,0)
-
-static void my_finishCommand(struct mpd_connection *conn) {
-	if (!mpd_response_finish(conn))
-		printErrorAndExit(conn);
-}
-
 static void
 recv_print_stickers(struct mpd_connection *connection)
 {
@@ -131,5 +125,3 @@ cmd_sticker(int argc, char **argv, struct mpd_connection *conn)
 
 	return 0;
 }
-
-#endif /* libmpdclient 2.1 */
diff --git a/src/sticker.h b/src/sticker.h
index 428a45d..beb8716 100644
--- a/src/sticker.h
+++ b/src/sticker.h
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2008-2010 The Music Player Daemon Project
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
  * http://www.musicpd.org
  *
  * This program is free software; you can redistribute it and/or modify
diff --git a/src/tab.c b/src/tab.c
new file mode 100644
index 0000000..93ad542
--- /dev/null
+++ b/src/tab.c
@@ -0,0 +1,124 @@
+/*
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "tab.h"
+#include "charset.h"
+#include "util.h"
+#include "Compiler.h"
+
+#include <mpd/client.h>
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+static char *
+tab_base(const char *prefix)
+{
+	const char *slash = strrchr(prefix, '/');
+	if (slash == NULL)
+		return NULL;
+
+	const size_t length = slash - prefix;
+	char *p = malloc(length + 1);
+	memcpy(p, prefix, length);
+	p[length] = '\0';
+	return p;
+}
+
+static void
+tab_send_list(const char *prefix, struct mpd_connection *conn)
+{
+	char *base = tab_base(prefix);
+	if (!mpd_send_list_meta(conn, base))
+		printErrorAndExit(conn);
+	free(base);
+}
+
+int
+cmd_loadtab(gcc_unused int argc, char **argv, struct mpd_connection *conn)
+{
+	assert(argc == 1);
+
+	const char *const prefix = charset_to_utf8(argv[0]);
+	const size_t prefix_length = strlen(prefix);
+
+	tab_send_list(prefix, conn);
+
+	struct mpd_playlist *pl;
+	while ((pl = mpd_recv_playlist(conn)) != NULL) {
+		const char *path = mpd_playlist_get_path(pl);
+		if (memcmp(path, prefix, prefix_length) == 0)
+			printf("%s\n", charset_from_utf8(path));
+
+		mpd_playlist_free(pl);
+	}
+
+	my_finishCommand(conn);
+	return 0;
+}
+
+int
+cmd_lstab(gcc_unused int argc, char **argv, struct mpd_connection *conn)
+{
+	assert(argc == 1);
+
+	const char *const prefix = charset_to_utf8(argv[0]);
+	const size_t prefix_length = strlen(prefix);
+
+	tab_send_list(prefix, conn);
+
+	struct mpd_directory *dir;
+	while ((dir = mpd_recv_directory(conn)) != NULL) {
+		const char *path = mpd_directory_get_path(dir);
+		if (memcmp(path, prefix, prefix_length) == 0)
+			printf("%s\n", charset_from_utf8(path));
+
+		mpd_directory_free(dir);
+	}
+
+	my_finishCommand(conn);
+
+	return 0;
+}
+
+int
+cmd_tab(gcc_unused int argc, char ** argv, struct mpd_connection *conn)
+{
+	assert(argc == 1);
+
+	const char *const prefix = charset_to_utf8(argv[0]);
+	const size_t prefix_length = strlen(prefix);
+
+	tab_send_list(prefix, conn);
+
+	struct mpd_song *song;
+	while ((song = mpd_recv_song(conn)) != NULL) {
+		const char *path = mpd_song_get_uri(song);
+		if (memcmp(path, prefix, prefix_length) == 0)
+			printf("%s\n", charset_from_utf8(path));
+
+		mpd_song_free(song);
+	}
+
+	my_finishCommand(conn);
+	return 0;
+}
diff --git a/src/idle.h b/src/tab.h
similarity index 71%
copy from src/idle.h
copy to src/tab.h
index 1a9a71d..a28dee4 100644
--- a/src/idle.h
+++ b/src/tab.h
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2008-2010 The Music Player Daemon Project
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
  * http://www.musicpd.org
  *
  * This program is free software; you can redistribute it and/or modify
@@ -17,15 +18,18 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#ifndef MPC_IDLE_H
-#define MPC_IDLE_H
+#ifndef MPC_TAB_H
+#define MPC_TAB_H
 
 struct mpd_connection;
 
 int
-cmd_idle(int argc, char **argv, struct mpd_connection *connection);
+cmd_loadtab(int argc, char **argv, struct mpd_connection *conn);
 
 int
-cmd_idleloop(int argc, char **argv, struct mpd_connection *connection);
+cmd_lstab(int argc, char **argv, struct mpd_connection *conn);
+
+int
+cmd_tab(int argc, char **argv, struct mpd_connection *conn);
 
 #endif
diff --git a/src/util.c b/src/util.c
index 3a71c20..305f356 100644
--- a/src/util.c
+++ b/src/util.c
@@ -1,24 +1,22 @@
-/* music player command (mpc)
- * Copyright (C) 2003-2008 Warren Dukes <warren.dukes at gmail.com>,
-				Eric Wong <normalperson at yhbt.net>,
-				Daniel Brown <danb at cs.utexas.edu>
- * Copyright (C) 2008-2010 Max Kellermann <max at duempel.org>
- * Project homepage: http://musicpd.org
- 
+/*
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
-
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
-
+ *
  * You should have received a copy of the GNU General Public License along
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
+ */
 
 #include "util.h"
 #include "charset.h"
@@ -38,11 +36,9 @@
 void
 printErrorAndExit(struct mpd_connection *conn)
 {
-	const char *message;
-
 	assert(mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS);
 
-	message = mpd_connection_get_error_message(conn);
+	const char *message = mpd_connection_get_error_message(conn);
 	if (mpd_connection_get_error(conn) == MPD_ERROR_SERVER)
 		/* messages received from the server are UTF-8; the
 		   rest is either US-ASCII or locale */
@@ -53,149 +49,21 @@ printErrorAndExit(struct mpd_connection *conn)
 	exit(EXIT_FAILURE);
 }
 
-int stdinToArgArray(char *** array)
-{
-	List * list = makeList(NULL);
-	ListNode * node;
-	char buffer[4096];
-	int size;
-	int i;
-	char * sp;
-
-	while(fgets(buffer, sizeof(buffer), stdin)) {
-		if((sp = strchr(buffer,'\n'))) *sp = '\0';
-		insertInListWithoutKey(list,strdup(buffer));
-	}
-
-	size = list->numberOfNodes;
-	*array = malloc((sizeof(char *))*size);
-	i = 0;
-	node = list->firstNode;
-	while(node) {
-		(*array)[i++] = (char *)node->data;
-		node = node->nextNode;
-	}
-	assert(i==size);
-
-	freeList(list);
-
-	return size;
-}
-
-void free_pipe_array (int max, char ** array)
-{
-	int i;
-	for ( i=0 ;i<max; ++i) free(array[i]);
-}
-
-int get_boolean (const char * arg)
-{
-	int i;
-	static const struct _bool_table {
-		const char * on;
-		const char * off;
-	} bool_table [] = {
-		{ "on", "off" },
-		{ "1", "0" },
-		{ "true", "false" },
-		{ "yes", "no" },
-		{ .on = NULL }
-	};
-
-	for (i=0; bool_table[i].on; ++i) {
-		if (! strcasecmp(arg,bool_table[i].on))
-			return 1;
-		else if (! strcasecmp(arg,bool_table[i].off))
-			return 0;
-	}
-	
-	fprintf(stderr,"\"%s\" is not a boolean value: <",arg);
-	
-	for (i=0; bool_table[i].on; ++i) {
-		fprintf(stderr,"%s|%s%s", bool_table[i].on,
-			bool_table[i].off,
-			( bool_table[i+1].off ? "|" : ">\n"));
-	}  
-	return -1;
-}
-
-/* note - return value is success; the parsed int itself is in ret */
-
-int parse_int(const char * str, int * ret)
-{
-        char * test;
-        int temp;
-
-        temp = strtol(str, &test, 10);
-
-        if(*test != '\0')
-                return 0; /* failure */
-
-        *ret = temp;
-        return 1; /* success */
-}
-
-/* note - return value is success; the parsed float itself is in ret */
-
-int parse_float(const char * str, float * ret)
-{
-	char * test;
-	float temp;
-
-	temp = strtof(str, &test);
-
-	if(*test != '\0')
-		return 0; /* failure */
-
-	*ret = temp;
-	return 1; /* success */
-}
-
-/* note - simply strips number out of formatting; does not -1 or +1 or change
- * the number in any other way for that matter */
-int parse_songnum(const char * str, int * ret)
+void
+my_finishCommand(struct mpd_connection *conn)
 {
-        int song;
-        char * endptr;
-
-        if(!str)
-                return 0;
-        if(*str == '#')
-                str++;
-
-        song = strtol(str, &endptr, 10);
-
-        if(str == endptr || (*endptr != ')' && *endptr != '\0') || song < 0)
-                return 0;
-
-        *ret = song;
-
-        return 1;
+	if (!mpd_response_finish(conn))
+		printErrorAndExit(conn);
 }
 
-int parse_int_value_change(const char * str, struct int_value_change * ret)
+struct mpd_status *
+getStatus(struct mpd_connection *conn)
 {
-        int len;
-        int change;
-        int relative = 0;
-
-        len = strlen(str);
-
-        if(len < 1)
-                return 0;
-
-        if(*str == '+')
-                relative = 1;
-        else if(*str == '-')
-                relative = -1;
-
-        if(!parse_int(str, &change))
-                return 0;
-
-        ret->value = change;
-        ret->is_relative = (relative != 0);
+	struct mpd_status *ret = mpd_run_status(conn);
+	if (ret == NULL)
+		printErrorAndExit(conn);
 
-        return 1;
+	return ret;
 }
 
 static char * appendToString(char * dest, const char * src, int len) {
@@ -286,11 +154,8 @@ songToFormatedString(const struct mpd_song *song,
 		     const char *format, const char ** last)
 {
 	char * ret = NULL;
-	const char *p, *end;
-	const char *temp;
-	char name[32];
-	int length;
-	int found = 0;
+	const char *p;
+	bool found = false;
 
 	/* we won't mess up format, we promise... */
 	for (p = format; *p != '\0'; )
@@ -298,10 +163,8 @@ songToFormatedString(const struct mpd_song *song,
 		if (p[0] == '|') {
 			++p;
 			if(!found) {
-				if(ret) {
-					free(ret);
-					ret = NULL;
-				}
+				free(ret);
+				ret = NULL;
 			}
 			else {
 				p = skipFormatting(p);
@@ -311,11 +174,11 @@ songToFormatedString(const struct mpd_song *song,
 		
 		if (p[0] == '&') {
 			++p;
-			if(found == 0) {
+			if(!found) {
 				p = skipFormatting(p);
 			}
 			else {
-				found = 0;
+				found = false;
 			}
 			continue;
 		}
@@ -326,7 +189,7 @@ songToFormatedString(const struct mpd_song *song,
 			if(t != NULL) {
 				ret = appendToString(ret, t, strlen(t));
 				free(t);
-				found = 1;
+				found = true;
 			}
 			continue;
 		}
@@ -334,7 +197,7 @@ songToFormatedString(const struct mpd_song *song,
 		if (p[0] == ']')
 		{
 			if(last) *last = p+1;
-			if(!found && ret) {
+			if (!found) {
 				free(ret);
 				ret = NULL;
 			}
@@ -379,14 +242,13 @@ songToFormatedString(const struct mpd_song *song,
 		/* advance past the esc character */
 
 		/* find the extent of this format specifier (stop at \0, ' ', or esc) */
-		temp = NULL;
-
-		end  = p+1;
+		const char *end = p+1;
 		while(*end >= 'a' && *end <= 'z')
 		{
 			end++;
 		}
-		length = end - p + 1;
+
+		const size_t length = end - p + 1;
 
 		if (*end != '%') {
 			ret = appendToString(ret, p, length - 1);
@@ -394,6 +256,7 @@ songToFormatedString(const struct mpd_song *song,
 			continue;
 		}
 
+		char name[32];
 		if (length > (int)sizeof(name)) {
 			ret = appendToString(ret, p, length);
 			p += length;
@@ -403,10 +266,10 @@ songToFormatedString(const struct mpd_song *song,
 		memcpy(name, p + 1, length - 2);
 		name[length - 2] = 0;
 
-		temp = song_value(song, name);
+		const char *temp = song_value(song, name);
 		if (temp != NULL) {
 			if (*temp != 0)
-				found = 1;
+				found = true;
 			ret = appendToString(ret, temp, strlen(temp));
 		} else
 			ret = appendToString(ret, p, length);
diff --git a/src/util.h b/src/util.h
index 83b5c9c..4f6a5c3 100644
--- a/src/util.h
+++ b/src/util.h
@@ -1,24 +1,22 @@
-/* music player command (mpc)
- * Copyright (C) 2003-2008 Warren Dukes <warren.dukes at gmail.com>,
-				Eric Wong <normalperson at yhbt.net>,
-				Daniel Brown <danb at cs.utexas.edu>
- * Copyright (C) 2008-2010 Max Kellermann <max at duempel.org>
- * Project homepage: http://musicpd.org
- 
+/*
+ * music player command (mpc)
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
-
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
-
+ *
  * You should have received a copy of the GNU General Public License along
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
+ */
 
 #ifndef MPC_UTIL_H
 #define MPC_UTIL_H
@@ -28,22 +26,35 @@
 struct mpd_connection;
 struct mpd_song;
 
-struct int_value_change {
-        int value;
-        bool is_relative;
-};
+#define DIE(...) do { fprintf(stderr, __VA_ARGS__); return -1; } while(0)
+
+#define SIMPLE_CMD(funcname, libmpdclient_funcname, ret) \
+int funcname(gcc_unused int argc, gcc_unused char **argv, \
+	     struct mpd_connection *conn) { \
+	libmpdclient_funcname(conn); \
+	my_finishCommand(conn); \
+	return ret; \
+}
+
+#define SIMPLE_ONEARG_CMD(funcname, libmpdclient_funcname, ret) \
+int funcname (gcc_unused int argc, char **argv, struct mpd_connection *conn) { \
+	if (!libmpdclient_funcname(conn, charset_to_utf8(argv[0]))) \
+		printErrorAndExit(conn); \
+	return ret; \
+}
 
 void
 printErrorAndExit(struct mpd_connection *conn);
 
-void free_pipe_array (int max, char ** array);
-int stdinToArgArray(char *** array);
-int get_boolean (const char * arg);
+/**
+ * Call mpd_response_finish(), and if that fails, call
+ * printErrorAndExit().
+ */
+void
+my_finishCommand(struct mpd_connection *conn);
 
-int parse_int(const char *, int *);
-int parse_float(const char *, float *);
-int parse_songnum(const char *, int *);
-int parse_int_value_change(const char *, struct int_value_change *);
+struct mpd_status *
+getStatus(struct mpd_connection *conn);
 
 void
 pretty_print_song(const struct mpd_song *song);

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mpd/pkg-mpc.git



More information about the Pkg-mpd-commits mailing list