Code

Removed popt code/dependency
[ncmpc.git] / src / options.c
1 /* 
2  * $Id$
3  *
4  * (c) 2004 by Kalle Wallin <kaw@linux.se>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  */
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <glib.h>
26 #include "config.h"
27 #include "ncmpc.h"
28 #include "support.h"
29 #include "options.h"
31 #define MAX_LONGOPT_LENGTH 32
33 typedef struct
34 {
35   int  shortopt;
36   char *longopt;
37   char *argument;
38   char *descrition;
39 } arg_opt_t;
42 typedef void (*option_callback_fn_t)   (int c, char *arg);
45 options_t options;
46  
47 static arg_opt_t option_table[] = {
48   { '?', "help",     NULL,   "Show this help message" },
49   { 'V', "version",  NULL,   "Display version information" },
50   { 'c', "colors",   NULL,   "Enable colors" },
51   { 'C', "no-colors", NULL,  "Disable colors" },
52   { 'e', "exit",     NULL,   "Exit on connection errors" },
53   { 'p', "port",  "PORT", "Connect to server on port [" DEFAULT_PORT_STR "]" },
54   { 'h', "host",  "HOST", "Connect to server on host [" DEFAULT_HOST "]" },
55   { 'P', "password","PASSWORD", "Connect with password" },
56   { 'f', "config",  "FILE",     "Read configuration from file" },
57   { 'k', "key-file","FILE",     "Read configuration from file" },
58 #ifdef DEBUG
59   { 'D', "debug",   NULL,   "Enable debug output on stderr" },
60 #endif
61   { 0, NULL, NULL, NULL },
62 };
64 static arg_opt_t *
65 lookup_option(int s, char *l)
66 {
67   int i;
69   i=0;
70   while( option_table[i].descrition )
71     {
72       if( l && strcmp(l, option_table[i].longopt) == 0 )
73         return &option_table[i];;
74       if( s && s==option_table[i].shortopt )
75         return &option_table[i];;
76       i++;
77     }
78   return NULL;
79 }
81 static void 
82 display_help(void)
83 {
84   int i = 0;
86   printf("Usage: %s [OPTION]...\n", PACKAGE);
87   while( option_table[i].descrition )
88     {
89       char tmp[MAX_LONGOPT_LENGTH];
91       if( option_table[i].argument )
92         g_snprintf(tmp, MAX_LONGOPT_LENGTH, "%s=%s", 
93                    option_table[i].longopt, 
94                    option_table[i].argument);
95       else
96         g_strlcpy(tmp, option_table[i].longopt, 64);
98       printf("  -%c, --%-20s %s\n", 
99              option_table[i].shortopt, 
100              tmp,
101              option_table[i].descrition);
102       i++;
103     }
106 static void 
107 handle_option(int c, char *arg)
109   switch(c)
110     {
111     case '?': /* --help */
112       display_help();
113       exit(EXIT_SUCCESS);
114     case 'V': /* --version */
115       printf("Version %s\n", VERSION);
116       exit(EXIT_SUCCESS);
117     case 'c': /* --colors */
118       options.enable_colors = TRUE;
119       break;
120     case 'C': /* --no-colors */
121       options.enable_colors = FALSE;
122       break;
123     case 'e': /* --exit */
124       options.reconnect = FALSE;
125       break;
126     case 'p': /* --port */
127       options.port = atoi(arg);
128       break;
129     case 'h': /* --host */
130       if( options.host )
131         g_free(options.host);
132       options.host = g_strdup(arg);
133       break;
134     case 'P': /* --password */
135       if( options.password )
136         g_free(options.password);
137       options.password = locale_to_utf8(arg);
138       break;
139     case 'f': /* --config */
140       if( options.config_file )
141         g_free(options.config_file);
142       options.config_file = g_strdup(arg);
143       break;
144     case 'k': /* --key-file */
145       if( options.key_file )
146         g_free(options.key_file);
147       options.key_file = g_strdup(arg);
148       break;
149     case 'D': /* --debug */
150       options.debug = TRUE;
151       break;
152     default:
153       fprintf(stderr,"Unknown Option %c = %s\n", c, arg);
154       break;
155     }
158 options_t *
159 options_get(void)
161   return &options;
164 options_t *
165 options_parse(int argc, const char *argv[])
167   int i;
168   arg_opt_t *opt = NULL;
169   option_callback_fn_t option_cb = handle_option;
171   i=1;
172   while( i<argc )
173     {
174       char *arg = (char *) argv[i];
175       size_t len=strlen(arg);
176       
177       /* check for a long option */
178       if( g_str_has_prefix(arg, "--") )
179         {
180           char *value;
182           /* retreive a option argument */
183           if( (value=g_strrstr(arg+2, "=")) )
184             {
185               *value = '\0';
186               value++;
187             }
188           /* check if the option exists */
189           if( (opt=lookup_option(0, arg+2)) == NULL )
190             {
191               fprintf(stderr, PACKAGE ": invalid option %s\n", arg);
192               exit(EXIT_FAILURE);
193             }
194           /* abort if we got an argument to the option and dont want one */
195           if( value && opt->argument==NULL )
196             {
197               fprintf(stderr, PACKAGE ": invalid option argument %s=%s\n", 
198                       arg, value);
199               exit(EXIT_FAILURE);
200             }
201           /* execute option callback */
202           if( value || opt->argument==NULL )
203             {
204               option_cb (opt->shortopt, value);
205               opt = NULL;
206             }
207         }
208       /* check for a short option */
209       else if( len==2 && g_str_has_prefix(arg, "-") )
210         {
211           /* check if the option exists */
212           if( (opt=lookup_option(arg[1], NULL))==NULL )
213             {
214               fprintf(stderr, PACKAGE ": invalid option %s\n",arg);
215               exit(EXIT_FAILURE);
216             }
217           /* if no option argument is needed execute callback */
218           if( opt->argument==NULL )
219             {
220               option_cb (opt->shortopt, NULL);
221               opt = NULL;
222             }
223         }
224       else
225         {
226           /* is this a option argument? */
227           if( opt && opt->argument)
228             {
229               option_cb (opt->shortopt, arg);
230             }
231           else 
232             {
233               fprintf(stderr, PACKAGE ": bad argument: %s\n", arg);
234               exit(EXIT_FAILURE);
235             }
236           opt = NULL;
237         }
239       i++;
240     }
241   return  &options;
245 options_t *
246 options_init( void )
248   const char *value;
249   char *tmp;
251   memset(&options, 0, sizeof(options_t));
253   if( (value=g_getenv(MPD_HOST_ENV)) )
254     options.host = g_strdup(value);
255   else
256     options.host = g_strdup(DEFAULT_HOST);
257   if( (tmp=g_strstr_len(options.host, strlen(options.host), "@")) )
258     {
259       char *oldhost = options.host;
260       *tmp  = '\0';
261       options.password = locale_to_utf8(oldhost);
262       options.host = g_strdup(tmp+1);
263       g_free(oldhost);
264     }
266   if( (value=g_getenv(MPD_PORT_ENV)) )
267     options.port = atoi(value);
268   else
269     options.port = DEFAULT_PORT;
271   options.list_format = NULL;
272   options.status_format = NULL;
273   options.xterm_title_format = NULL;
275   options.reconnect = TRUE;
276   options.find_wrap = TRUE;
277   options.wide_cursor = TRUE;
278   options.audible_bell = TRUE;
280   return &options;