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