Code

Crossfade time can now be definied in the rc file (crossfade-time)
[ncmpc.git] / src / options.c
index 3751aae424806f29e5c59a2316192aef1126a23b..4f1100f9d9f0ce2fed50b9f4eea25d5c32d4f647 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <ncurses.h>
 #include <glib.h>
 
 #include "config.h"
 #include "ncmpc.h"
 #include "support.h"
 #include "options.h"
+#include "command.h"
+#include "conf.h"
 
 #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;
@@ -49,6 +59,10 @@ static arg_opt_t option_table[] = {
   { 'V', "version",  NULL,   "Display version information" },
   { 'c', "colors",   NULL,   "Enable colors" },
   { 'C', "no-colors", NULL,  "Disable colors" },
+#ifdef HAVE_GETMOUSE
+  { 'm', "mouse",    NULL,   "Enable mouse" },
+  { 'M', "no-mouse", NULL,   "Disable mouse" },
+#endif
   { 'e', "exit",     NULL,   "Exit on connection errors" },
   { 'p', "port",  "PORT", "Connect to server on port [" DEFAULT_PORT_STR "]" },
   { 'h', "host",  "HOST", "Connect to server on host [" DEFAULT_HOST "]" },
@@ -56,6 +70,7 @@ static arg_opt_t option_table[] = {
   { 'f', "config",  "FILE",     "Read configuration from file" },
   { 'k', "key-file","FILE",     "Read configuration from file" },
 #ifdef DEBUG
+  { 'K', "dump-keys", NULL,     "Dump key bindings to stdout" },
   { 'D', "debug",   NULL,   "Enable debug output on stderr" },
 #endif
   { 0, NULL, NULL, NULL },
@@ -78,6 +93,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 option\n", option);
+      break;
+    default:
+      fprintf(stderr, PACKAGE ": internal error %d\n", error);
+      break;
+    }
+  exit(EXIT_FAILURE);
+}
+
 static void 
 display_help(void)
 {
@@ -106,13 +145,28 @@ display_help(void)
 static void 
 handle_option(int c, char *arg)
 {
+  D("option callback -%c %s\n", c, arg);
   switch(c)
     {
     case '?': /* --help */
       display_help();
       exit(EXIT_SUCCESS);
     case 'V': /* --version */
-      printf("Version %s\n", VERSION);
+      printf("%s version: %s\n", PACKAGE, VERSION);
+      printf("build options:");
+#ifdef DEBUG
+      printf(" debug");
+#endif
+#ifdef ENABLE_NLS
+      printf(" nls");
+#endif
+#ifdef ENABLE_KEYDEF_SCREEN
+      printf(" key-screen");
+#endif
+#ifdef ENABLE_CLOCK_SCREEN
+      printf(" clock-screen");
+#endif
+      printf("\n");
       exit(EXIT_SUCCESS);
     case 'c': /* --colors */
       options.enable_colors = TRUE;
@@ -120,6 +174,12 @@ handle_option(int c, char *arg)
     case 'C': /* --no-colors */
       options.enable_colors = FALSE;
       break;
+   case 'm': /* --mouse */
+     options.enable_mouse = TRUE;
+      break;
+    case 'M': /* --no-mouse */
+      options.enable_mouse = FALSE;
+      break;
     case 'e': /* --exit */
       options.reconnect = FALSE;
       break;
@@ -146,9 +206,16 @@ handle_option(int c, char *arg)
        g_free(options.key_file);
       options.key_file = g_strdup(arg);
       break;
+#ifdef DEBUG
+    case 'K': /* --dump-keys */
+      read_configuration(&options);
+      write_key_bindings(stdout, KEYDEF_WRITE_ALL | KEYDEF_COMMENT_ALL);
+      exit(EXIT_SUCCESS);
+      break;
     case 'D': /* --debug */
       options.debug = TRUE;
       break;
+#endif
     default:
       fprintf(stderr,"Unknown Option %c = %s\n", c, arg);
       break;
@@ -177,27 +244,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 )
            {
@@ -205,20 +277,28 @@ options_parse(int argc, const char *argv[])
              opt = NULL;
            }
        }
-      /* check for a short option */
-      else if( len==2 && g_str_has_prefix(arg, "-") )
+      /* check for short options */
+      else if( len>=2 && g_str_has_prefix(arg, "-") )
        {
-         /* check if the option exists */
-         if( (opt=lookup_option(arg[1], NULL))==NULL )
-           {
-             fprintf(stderr, PACKAGE ": invalid option %s\n",arg);
-             exit(EXIT_FAILURE);
-           }
-         /* if no option argument is needed execute callback */
-         if( opt->argument==NULL )
+         int j;
+
+         for(j=1; j<len; j++)
            {
-             option_cb (opt->shortopt, NULL);
-             opt = NULL;
+             /* 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[j], NULL))==NULL )
+               option_error(ERROR_UNKNOWN_OPTION, arg, NULL);
+
+             /* if no option argument is needed execute callback */
+             if( opt->argument==NULL )
+               {
+                 option_cb (opt->shortopt, NULL);
+                 opt = NULL;
+               }
            }
        }
       else
@@ -227,17 +307,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 +332,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,20 +345,18 @@ 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;
   options.audible_bell = TRUE;
+  options.crossfade_time = DEFAULT_CROSSFADE_TIME;
 
   return &options;
 }