1 /* -*- Mode: C; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3 -*- */
2 
3 /*
4  * GImageView
5  * Copyright (C) 2001 Takuro Ashie
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  *
21  * $Id: argparse.c,v 1.14 2004/09/22 14:26:22 makeinu Exp $
22  */
23 
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 
28 #include "gimageview.h"
29 
30 #include "argparse.h"
31 #include "charset.h"
32 #include "prefs.h"
33 
34 ArgsVal args_val;
35 
36 static struct arg_opt options[] =
37 {
38    /* file load */
39    { "directory", 'd', NULL,    N_("Scan directory at start up")                            },
40    { "recursive", 'R', NULL,    N_("Scan directory recursively (use with \"-d\")")          },
41    { "scan-dot",  'D', NULL,    N_("Read dotfile when scanning directory (use with \"-d\")")},
42    { "ignore-ext",'e', NULL,    N_("Ignore file name extension")                            },
43 
44    /* image window */
45    { "scale",     's', "SCALE", N_("Specify image scale on image window [%]")               },
46    { "buffer",    'b', "ON/OFF",N_("Keep original image on memory or not")                  },
47    { "menubar",   'M', NULL,    N_("Show menu bar on image view window")                    },
48    { "toolbar",   'T', NULL,    N_("Show tool bar on image view window")                    },
49 
50    /*  */
51    { "imagewin",  'I', NULL,    N_("Open empty image window at start up")                   },
52    { "thumbwin",  'w', NULL,    N_("Open thumbnail window at start up")                     },
53 
54    /* default window */
55    { "imageview", 'i', NULL,    N_("Open all images in imageview window")                   },
56    { "thumbview", 't', NULL,    N_("Open all images in thumbnail window")                   },
57    { "slideshow", 'S', NULL,    N_("Open images files in slide show")                       },
58    { "wait",      'W', "TIME",  N_("Interval of slideshow (use with \"-S\") [sec]")         },
59 
60    /* etc */
61    { "version",   'v', NULL,    N_("Print version infomation")                              },
62    { "help",      'h', NULL,    N_("Show this message")                                     },
63    { NULL,         0,  NULL,    NULL,                                                       },
64 };
65 
66 
67 /*
68  *  parse_opt:
69  *
70  *  key    : short option character.
71  *  arg    : arguments.
72  *  Return : state (enum)
73  */
74 static arg_error_t
parse_opt(int key,char * arg)75 parse_opt (int key, char *arg)
76 {
77    int value_bool;
78 
79    if (arg && (!g_strcasecmp (arg, "ON") || !g_strcasecmp (arg, "enable")))
80       value_bool = TRUE;
81    else
82       value_bool = FALSE;
83 
84    switch (key) {
85    case 'I':
86       args_val.open_imagewin = TRUE;
87       break;
88    case 'w':
89       args_val.open_thumbwin = TRUE;
90       break;
91    case 'd':
92       args_val.read_dir = TRUE;
93       break;
94    case 'R':
95       args_val.read_dir_recursive = TRUE;
96       break;
97    case 'D':
98       args_val.read_dot = TRUE;
99       conf.read_dotfile = TRUE;
100       break;
101    case 'e':
102       args_val.ignore_ext = TRUE;
103       conf.detect_filetype_by_ext = FALSE;
104       break;
105    case 's':
106       conf.imgview_scale = atoi(arg);
107       conf.imgview_default_zoom = 0;
108       break;
109    case 'b':
110       conf.imgview_buffer = value_bool;
111       break;
112    case 'M':
113       conf.imgwin_show_menubar = TRUE;
114       break;
115    case 'T':
116       conf.imgwin_show_toolbar = TRUE;
117       break;
118    case 'i':
119       conf.default_file_open_window = IMAGE_VIEW_WINDOW;
120       conf.default_dir_open_window = IMAGE_VIEW_WINDOW;
121       break;
122    case 't':
123       conf.default_file_open_window = THUMBNAIL_WINDOW;
124       conf.default_dir_open_window = THUMBNAIL_WINDOW;
125       break;
126    case 'S':
127       args_val.exec_slideshow = TRUE;
128       break;
129    case 'W':
130       args_val.slideshow_interval = atof(arg);
131       break;
132    case 'v':
133       arg_version ();
134       break;
135    case 'h':
136       return ARG_HELP;
137       break;
138    default:
139    {
140       gchar *tmpstr;
141       tmpstr = charset_internal_to_locale(_("Unknown option: \"-%s\"\n"));
142       fprintf (stderr, tmpstr, arg);
143       g_free (tmpstr);
144       exit (1);
145    }
146    }
147    return 0;
148 }
149 
150 
151 /*
152  *  arg_version:
153  *     @ Print program version info and exit.
154  */
155 void
arg_version(void)156 arg_version (void)
157 {
158    gchar *tmpstr;
159    printf ("%s %s\n", GIMV_PROG_NAME, VERSION);
160    tmpstr = charset_internal_to_locale (
161       _("Copyright (C) 2001 Takuro Ashie\n"
162         "This is free software; see the source for copying conditions.  There is NO\n"
163         "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"));
164    printf (tmpstr);
165    g_free (tmpstr);
166 
167    exit (0);
168 }
169 
170 
171 #define DOC_OFFSET 26
172 
173 /*
174  *  arg_help:
175  *     @ Print help message.
176  *
177  *  argv   : arguments.
178  *  stream : file stream for printing help message.
179  */
180 void
arg_help(char * argv[],FILE * stream)181 arg_help (char *argv[], FILE *stream) {
182    int i, j;
183    char buf[BUF_SIZE], *tmpstr1, *tmpstr2;
184 
185    tmpstr1 = charset_internal_to_locale (
186                 _("Copyright (C) 2001 Takuro Ashie\n\n"
187                   "Usage: %s [OPTION...] [Image Files...]\n\n"));
188    fprintf (stream, tmpstr1, argv[0]);
189    g_free (tmpstr1);
190 
191    for (i = 0; options[i].name; i++) {
192       if (options[i].arg)
193          g_snprintf (buf, BUF_SIZE, "  -%c, --%s=%s",
194                      options[i].key, options[i].name, options[i].arg);
195       else
196          g_snprintf (buf, BUF_SIZE, "  -%c, --%s",
197                      options[i].key, options[i].name);
198       for (j = strlen (buf); j < DOC_OFFSET; j++)
199          strncat (buf, " ", 1);
200       tmpstr1 = charset_internal_to_locale (buf);
201       tmpstr2 = charset_internal_to_locale (_(options[i].doc));
202       fprintf (stream, "%s %s\n", tmpstr1, tmpstr2);
203       g_free (tmpstr1);
204       g_free (tmpstr2);
205    }
206 
207    fprintf (stream, "\n");
208 
209    if (stream == stderr)
210       exit (1);
211    else
212       exit (0);
213 }
214 
215 #undef DOC_OFFSET
216 
217 
218 /*
219  *  parse_long_opt:
220  *     @ Convert long option to short it, and call parse_opt () if success
221  *       converting.
222  *
223  *  argv   : long option string.
224  *  Return : state (enum)
225  */
226 static arg_error_t
parse_long_opt(char * argv)227 parse_long_opt (char *argv) {
228    int i, arglen, optlen;
229    char *argval;
230    arg_error_t retval;
231    gchar *tmpstr;
232 
233    for (i = 0; options[i].name; i++) {
234       arglen = strlen(argv);
235       optlen = strlen(options[i].name);
236 
237       /*
238         if (arglen != optlen)
239         continue;
240       */
241 
242       if (!strncmp (argv, options[i].name, optlen)) {
243          if (options[i].arg == NULL) {
244             retval = parse_opt (options[i].key, NULL);
245             return retval;
246          }
247          if (argv[optlen] == '=') {           /* if arg with value */
248             argval = argv + optlen + 1;
249             if (!*argval) {
250                return ARG_NO_VAL;
251             } else {
252                retval = parse_opt (options[i].key, argval);
253                return retval;
254             }
255          } else                               /* error if no value */
256             return ARG_ERR_PARSE;
257       }
258    }
259 
260    /* error */
261    tmpstr = charset_internal_to_locale (_("Unknown option: \"--%s\"\n"));
262    fprintf (stderr, tmpstr, argv);
263    g_free (tmpstr);
264 
265    exit (1);
266 }
267 
268 
269 /*
270  *  arg_parse:
271  *     @ Command line argument parser.
272  *
273  *  argc      : argument num.
274  *  argv      : arguments.
275  *  remaining : Start element number of remaining argument
276  *              (These arguments are not parsed by this parser).
277  *              The first unknown string will be treated as start of remaining.
278  */
279 void
arg_parse(int argc,char * argv[],int * remaining)280 arg_parse (int argc, char *argv[], int *remaining)
281 {
282    int i, j, k, num;
283    arg_error_t retval = ARG_ERR_UNKNOWN;
284    gchar *tmpstr;
285 
286    args_val_init ();
287 
288    for (i = 1; i < argc; i++) {
289       if (!strncmp (argv[i], "--", 2)) {            /* long option */
290          retval = parse_long_opt (argv[i] + 2);
291       } else if (!strncmp (argv[i], "-", 1)) {      /* short option */
292 
293          num = strlen (argv[i]) - 1;
294 
295          for (j = 1; j <= num; j++) {
296 
297             retval = ARG_ERR_UNKNOWN;
298 
299             for (k = 0; options[k].name; k++) {
300 
301                /* arg with value */
302                if (options[k].key == (int)argv[i][j] && options[k].arg) {
303                   if (j == num && i < argc - 1)
304                      retval = parse_opt ((int)argv[i][j], argv[i+1]);
305                   else
306                      arg_help (argv, stderr);
307                   i++;
308 
309                   /* arg with no value */
310                } else if (options[k].key == (int)argv[i][j]) {
311                   retval = parse_opt ((int)argv[i][j], NULL);
312                }
313             }
314 
315             /* unknown option */
316             if (retval == ARG_ERR_UNKNOWN) {
317                tmpstr = charset_internal_to_locale (_("Unknown option: \"-%c\"\n"));
318                fprintf (stderr, tmpstr, argv[i][j]);
319                g_free (tmpstr);
320                exit (1);
321             }
322          }
323       } else {
324          break;
325       }
326 
327       if (retval == ARG_HELP)
328          arg_help (argv, stdout);
329       else if (retval != ARG_NOERR && retval != ARG_WITH_VAL)
330          arg_help (argv, stderr);
331    }
332    *remaining = i;
333    return;
334 }
335 
336 
337 void
args_val_init(void)338 args_val_init (void)
339 {
340    args_val.read_dir           = conf.startup_read_dir;
341    args_val.read_dir_recursive = conf.scan_dir_recursive;
342    args_val.read_dot           = conf.read_dotfile;
343    args_val.ignore_ext         = !conf.detect_filetype_by_ext;
344    args_val.open_imagewin      = FALSE;
345    args_val.open_thumbwin      = conf.startup_open_thumbwin;
346    args_val.exec_slideshow     = FALSE;
347    args_val.slideshow_interval = conf.slideshow_interval;
348 }
349