aboutsummaryrefslogtreecommitdiffstats
path: root/src/options.c
diff options
context:
space:
mode:
authorKalle Wallin <kaw@linux.se>2004-07-02 10:30:01 +0000
committerKalle Wallin <kaw@linux.se>2004-07-02 10:30:01 +0000
commit2bdcaa623f479686a08bcfe6285db633e9fa4a4e (patch)
tree95e068dc47d0013609f11dd81bbb71581e0a99c2 /src/options.c
parent7bf87192828e33fbdad2dd2a82474acaffc1bdf1 (diff)
downloadmpd-2bdcaa623f479686a08bcfe6285db633e9fa4a4e.tar.gz
mpd-2bdcaa623f479686a08bcfe6285db633e9fa4a4e.tar.xz
mpd-2bdcaa623f479686a08bcfe6285db633e9fa4a4e.zip
improved error handling in the argv parser
git-svn-id: https://svn.musicpd.org/ncmpc/trunk@1762 09075e82-0dd4-0310-85a5-a0d7c8717e4f
Diffstat (limited to '')
-rw-r--r--src/options.c91
1 files changed, 65 insertions, 26 deletions
diff --git a/src/options.c b/src/options.c
index 3751aae42..314a0e98c 100644
--- a/src/options.c
+++ b/src/options.c
@@ -30,6 +30,13 @@
#define MAX_LONGOPT_LENGTH 32
+#define ERROR_UNKNOWN_OPTION 0x01
+#define ERROR_BAD_ARGUMENT 0x02
+#define ERROR_GOT_ARGUMENT 0x03
+#define ERROR_MISSING_ARGUMENT 0x04
+
+
+
typedef struct
{
int shortopt;
@@ -78,6 +85,30 @@ lookup_option(int s, char *l)
return NULL;
}
+static void
+option_error(int error, char *option, char *arg)
+{
+ switch(error)
+ {
+ case ERROR_UNKNOWN_OPTION:
+ fprintf(stderr, PACKAGE ": invalid option %s\n", option);
+ break;
+ case ERROR_BAD_ARGUMENT:
+ fprintf(stderr, PACKAGE ": bad argument: %s\n", option);
+ break;
+ case ERROR_GOT_ARGUMENT:
+ fprintf(stderr, PACKAGE ": invalid option %s=%s\n", option, arg);
+ break;
+ case ERROR_MISSING_ARGUMENT:
+ fprintf(stderr, PACKAGE ": missing value for %s\n", option);
+ break;
+ default:
+ fprintf(stderr, PACKAGE ": internal error %d\n", error);
+ break;
+ }
+ exit(EXIT_FAILURE);
+}
+
static void
display_help(void)
{
@@ -106,6 +137,7 @@ display_help(void)
static void
handle_option(int c, char *arg)
{
+ D("option callback -%c %s\n", c, arg);
switch(c)
{
case '?': /* --help */
@@ -177,27 +209,32 @@ options_parse(int argc, const char *argv[])
/* check for a long option */
if( g_str_has_prefix(arg, "--") )
{
- char *value;
+ char *name, *value;
+
+ /* make shure we got an argument for the previous option */
+ if( opt && opt->argument )
+ option_error(ERROR_MISSING_ARGUMENT, opt->longopt, opt->argument);
/* retreive a option argument */
if( (value=g_strrstr(arg+2, "=")) )
{
*value = '\0';
+ name = g_strdup(arg);
+ *value = '=';
value++;
}
+ else
+ name = g_strdup(arg);
+
/* check if the option exists */
- if( (opt=lookup_option(0, arg+2)) == NULL )
- {
- fprintf(stderr, PACKAGE ": invalid option %s\n", arg);
- exit(EXIT_FAILURE);
- }
+ if( (opt=lookup_option(0, name+2)) == NULL )
+ option_error(ERROR_UNKNOWN_OPTION, name, NULL);
+ g_free(name);
+
/* abort if we got an argument to the option and dont want one */
if( value && opt->argument==NULL )
- {
- fprintf(stderr, PACKAGE ": invalid option argument %s=%s\n",
- arg, value);
- exit(EXIT_FAILURE);
- }
+ option_error(ERROR_GOT_ARGUMENT, arg, value);
+
/* execute option callback */
if( value || opt->argument==NULL )
{
@@ -208,12 +245,14 @@ options_parse(int argc, const char *argv[])
/* check for a short option */
else if( len==2 && g_str_has_prefix(arg, "-") )
{
+ /* make shure we got an argument for the previous option */
+ if( opt && opt->argument )
+ option_error(ERROR_MISSING_ARGUMENT, opt->longopt, opt->argument);
+
/* check if the option exists */
if( (opt=lookup_option(arg[1], NULL))==NULL )
- {
- fprintf(stderr, PACKAGE ": invalid option %s\n",arg);
- exit(EXIT_FAILURE);
- }
+ option_error(ERROR_UNKNOWN_OPTION, arg, NULL);
+
/* if no option argument is needed execute callback */
if( opt->argument==NULL )
{
@@ -227,17 +266,19 @@ options_parse(int argc, const char *argv[])
if( opt && opt->argument)
{
option_cb (opt->shortopt, arg);
+ opt = NULL;
}
else
- {
- fprintf(stderr, PACKAGE ": bad argument: %s\n", arg);
- exit(EXIT_FAILURE);
- }
- opt = NULL;
+ option_error(ERROR_BAD_ARGUMENT, arg, NULL);
}
-
i++;
}
+
+ if( opt && opt->argument==NULL)
+ option_cb (opt->shortopt, NULL);
+ else if( opt && opt->argument )
+ option_error(ERROR_MISSING_ARGUMENT, opt->longopt, opt->argument);
+
return &options;
}
@@ -250,6 +291,7 @@ options_init( void )
memset(&options, 0, sizeof(options_t));
+ /* get initial values for host and password from MPD_HOST (enviroment) */
if( (value=g_getenv(MPD_HOST_ENV)) )
options.host = g_strdup(value);
else
@@ -262,16 +304,13 @@ options_init( void )
options.host = g_strdup(tmp+1);
g_free(oldhost);
}
-
+ /* get initial values for port from MPD_PORT (enviroment) */
if( (value=g_getenv(MPD_PORT_ENV)) )
options.port = atoi(value);
else
options.port = DEFAULT_PORT;
- options.list_format = NULL;
- options.status_format = NULL;
- options.xterm_title_format = NULL;
-
+ /* default option values */
options.reconnect = TRUE;
options.find_wrap = TRUE;
options.wide_cursor = TRUE;