diff -Naur mpc/src/Makefile.am mpc-svn-2004-06-03/src/Makefile.am --- mpc/src/Makefile.am 2004-06-04 03:31:42.704662758 -0500 +++ mpc-svn-2004-06-03/src/Makefile.am 2004-06-04 01:34:29.123206022 -0500 @@ -9,6 +9,7 @@ mpc_headers += util.h mpc_headers += command.h mpc_headers += mpc.h +mpc_headers += options.h mpc_SOURCES = libmpdclient.c mpc_SOURCES += main.c @@ -18,4 +19,5 @@ mpc_SOURCES += status.c mpc_SOURCES += util.c mpc_SOURCES += command.c +mpc_SOURCES += options.c mpc_SOURCES += $(mpc_headers) diff -Naur mpc/src/command.c mpc-svn-2004-06-03/src/command.c --- mpc/src/command.c 2004-06-04 03:31:41.705804980 -0500 +++ mpc-svn-2004-06-03/src/command.c 2004-06-04 03:23:46.528475475 -0500 @@ -1,5 +1,6 @@ /* mpc * (c) 2003-2004 by normalperson and Warren Dukes (shank@mercury.chem.pitt.edu) + * and Daniel Brown (danb@cs.utexas.edu) * This project's homepage is: http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -334,14 +335,11 @@ while((entity = mpd_getNextInfoEntity(conn))) { if(entity->type==MPD_INFO_ENTITY_TYPE_SONG) { mpd_Song * song = entity->info.song; - if(song->artist && song->title) { - printf("#%i) %s - ",1+count, fromUtf8(song->artist)); - printf("%s\n", fromUtf8(song->title)); - } - else if(song->title) { - printf("#%i) %s\n",1+count, fromUtf8(song->title)); - } - else printf("#%i) %s\n",1+count, fromUtf8(song->file)); + + printf("#%i) ", 1+count); + pretty_print_song(song); + printf("\n"); + count++; } mpd_freeInfoEntity(entity); diff -Naur mpc/src/main.c mpc-svn-2004-06-03/src/main.c --- mpc/src/main.c 2004-06-04 03:31:42.552684397 -0500 +++ mpc-svn-2004-06-03/src/main.c 2004-06-04 01:37:38.814305828 -0500 @@ -1,5 +1,6 @@ /* mpc * (c) 2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu) + * Daniel Brown (danb@cs.utexas.edu) * This project's homepage is: http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -24,7 +25,9 @@ #include "status.h" #include "command.h" #include "mpc.h" +#include "options.h" +#include #include #include #include @@ -196,6 +199,8 @@ int ret = 0; setLocaleCharset(); + parse_options(&argc, argv); + if (argc==1) print_status_and_exit (); diff -Naur mpc/src/options.c mpc-svn-2004-06-03/src/options.c --- mpc/src/options.c 1969-12-31 18:00:00.000000000 -0600 +++ mpc-svn-2004-06-03/src/options.c 2004-06-04 01:44:24.806560387 -0500 @@ -0,0 +1,126 @@ +/* mpc + * (c) 2004 by Daniel Brown (danb@cs.utexas.edu) + * This project's homepage is: 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "options.h" + +#include +#include +#include +#include + +/* i like this type/instance naming scheme better than _mpc_table/mpc_table + - danb */ +struct mpc_option mpc_options [] = +{ + { "format", 1, 0, 0 }, + + /* other ideas for options... + { "host", 1, 0, 0 }, + { "port", 1, 0, 0 }, + { "verbose", 0, 0, 0 }, + */ + + {} +}; + +/* why don't all languages have dictionary built-ins...? */ +struct mpc_option * get_option (char option[]) +{ + int i; + + for (i = 0; mpc_options[i].name; ++i) + if (strcmp(option, mpc_options[i].name) == 0) + return &mpc_options[i]; + + return 0; +} + +/* removes the index-th element from arr (*size gets decremented) */ +void remove_index (int index, char ** arr, int * size) +{ + int i; + + /* these would be dumb... */ + assert(arr); + assert(size); + assert(index >= 0); + assert(*size >= 0); + assert(index < *size); + + /* shift everything past index one to the left and decrement the size */ + for (i = index; i < *size - 1; ++i) + arr[i] = arr[i + 1]; + --*size; +} + +/* check and extract options from argv (between argv[0] and the first command + argument, since other locations could be ambiguous) */ +void parse_options (int * argc_p, char ** argv) +{ + int i; + struct mpc_option * option; + + for (i = 1; i < *argc_p; ) + { + /* args with a "--" prefix are options, until we find the "--" option */ + if (strncmp(argv[i], "--", 2) == 0) + { + /* quit parsing on the first "--" */ + if (strcmp(argv[i], "--") == 0) + return; + + /* strip the prefix from our option and try to look it up */ + option = get_option(argv[i] + 2); + if (option) + { + option->set = 1; + + /* do we need to grab a parameter for this option? */ + if (option->has_value) + { + /* are there any arguments left? */ + if (i < *argc_p - 1) + { + /* grab and extract the value */ + option->value = argv[i + 1]; + remove_index(i + 1, argv, argc_p); + } + else + { + fprintf(stderr, "Option %s expects a value\n", + argv[i]); + exit(EXIT_FAILURE); + } + } + } + else + { + fprintf(stderr, "Invalid option: %s\n", argv[i]); + exit(EXIT_FAILURE); + } + + /* remove the i-th element from argv */ + remove_index(i, argv, argc_p); + } + else + { + /* increment iff we don't remove an element of argv */ + ++i; + } + } +} diff -Naur mpc/src/options.h mpc-svn-2004-06-03/src/options.h --- mpc/src/options.h 1969-12-31 18:00:00.000000000 -0600 +++ mpc-svn-2004-06-03/src/options.h 2004-06-04 01:40:48.502344954 -0500 @@ -0,0 +1,37 @@ +/* mpc + * (c) 2004 by Daniel Brown (danb@cs.utexas.edu) + * This project's homepage is: 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef OPTIONS_H +#define OPTIONS_H + +struct mpc_option +{ + const char * name; // long name of the option + int has_value; // whether a value should follow this option + int set; // whether this option is on/off + char * value; // the value of the option (null if ! has_value) +}; + +/* i like this type/instance naming scheme better than _mpc_table/mpc_table + - danb */ +extern struct mpc_option mpc_options []; + +struct mpc_option * get_option (char option[]); +void parse_options (int * argc_p, char ** argv); + +#endif /* OPTIONS_H */ diff -Naur mpc/src/status.c mpc-svn-2004-06-03/src/status.c --- mpc/src/status.c 2004-06-04 03:31:42.271724401 -0500 +++ mpc-svn-2004-06-03/src/status.c 2004-06-04 03:22:48.350762412 -0500 @@ -1,5 +1,6 @@ /* * (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu) + * Daniel Brown (danb@cs.utexas.edu) * This project's homepage is: http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -22,6 +23,7 @@ #include "util.h" #include "mpc.h" +#include #include #include @@ -48,16 +50,8 @@ continue; } - if(song->artist && song->title && - strlen(song->artist) && - strlen(song->title)) { - printf("%s - ",fromUtf8(song->artist)); - printf("%s\n",fromUtf8(song->title)); - } - else if(song->title && strlen(song->title)) { - printf("%s\n",fromUtf8(song->title)); - } - else printf("%s\n",fromUtf8(song->file)); + pretty_print_song(song); + printf("\n"); mpd_freeInfoEntity(entity); diff -Naur mpc/src/util.c mpc-svn-2004-06-03/src/util.c --- mpc/src/util.c 2004-06-04 03:31:41.555826334 -0500 +++ mpc-svn-2004-06-03/src/util.c 2004-06-04 03:29:22.794584860 -0500 @@ -1,5 +1,6 @@ /* mpc * (c) 2003-2004 by normalperson and Warren Dukes (shank@mercury.chem.pitt.edu) + * and Daniel Brown (danb@cs.utexas.edu) * This project's homepage is: http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -21,6 +22,7 @@ #include "charConv.h" #include "list.h" #include "mpc.h" +#include "options.h" #include #include @@ -166,3 +168,92 @@ return 1; } +/* this is a little ugly... */ +void print_formatted_song (mpd_Song * song, const char * format) +{ + char esc = '%'; + char *p, *end; + int length, i; + + /* we won't mess up format, we promise... */ + for (p = (char *)format; *p != '\0'; ) + { + /* pass-through non-escaped portions of the format string */ + if (p[0] != esc) + { + printf("%c", *p); + ++p; + continue; + } + + /* let the escape character escape itself */ + if (p[1] == esc) + { + printf("%c", esc); + ++p; + continue; + } + + /* advance past the esc character */ + ++p; + + /* find the extent of this format specifier (stop at \0, ' ', or esc) */ + for (i = 0; p[i] != ' ' && p[i] != esc && p[i] != '\0'; ++i) + ; + end = p + i; + length = end - p; + + /* does this specifier mean anything to us? (there should be a better + way to do this...) */ + if (strncmp("file", p, length) == 0) + printf("%s", fromUtf8(song->file)); + else if (strncmp("artist", p, length) == 0) + printf("%s", fromUtf8(song->artist ? song->artist : "")); + else if (strncmp("title", p, length) == 0) + printf("%s", fromUtf8(song->title ? song->title : "")); + else if (strncmp("album", p, length) == 0) + printf("%s", fromUtf8(song->album ? song->album : "")); + else if (strncmp("track", p, length) == 0) + printf("%s", fromUtf8(song->track ? song->track : "")); + else if (strncmp("time", p, length) == 0) + { + if (song->time != MPD_SONG_NO_TIME) + printf("%d:%d", song->time / 60, song->time % 60 + 1); + else + printf("%s", ""); + } + else + { + /* just pass-through any unknown specifiers (including esc) */ + /* drop a null char in so printf stops at the end of this specifier, + but put the real character back in (pseudo-const) */ + char c = *end; + *end = '\0'; + printf("%c%s", esc, p); + *end = c; + } + + /* advance past the specifier */ + p += length; + } +} + +void pretty_print_song (mpd_Song * song) +{ + /* was a format string specified? */ + if (get_option("format")->set) + { + print_formatted_song(song, get_option("format")->value); + } + /* just do something pretty */ + else + { + if (song->artist && song->title && strlen(song->artist) && + strlen(song->title)) + printf("%s - %s", fromUtf8(song->artist), fromUtf8(song->title)); + else if (song->title && strlen(song->title)) + printf("%s", fromUtf8(song->title)); + else + printf("%s", fromUtf8(song->file)); + } +} diff -Naur mpc/src/util.h mpc-svn-2004-06-03/src/util.h --- mpc/src/util.h 2004-06-04 03:31:41.982765545 -0500 +++ mpc-svn-2004-06-03/src/util.h 2004-06-04 03:29:19.548047167 -0500 @@ -1,5 +1,6 @@ /* mpc * (c) 2003-2004 by normalperson and Warren Dukes (shank@mercury.chem.pitt.edu) + * and Daniel Brown (danb@cs.utexas.edu) * This project's homepage is: http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -36,5 +37,6 @@ int parse_int(const char *, int *); int parse_songnum(const char *, int *); int parse_int_value_change(const char *, struct int_value_change *); +void pretty_print_song (mpd_Song * song); #endif /* MPC_UTIL_H */