This source file includes following definitions.
- mc_args_clean_temp_help_strings
- mc_args_add_usage_info
- mc_args_add_extended_info_to_help
- mc_args__convert_help_to_syscharset
- parse_mc_e_argument
- parse_mc_v_argument
- parse_mcedit_arguments
- mc_setup_run_mode
- mc_args_parse
- mc_args_show_info
- mc_setup_by_args
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 #include <config.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30
31 #include "lib/global.h"
32 #include "lib/tty/tty.h"
33 #include "lib/strutil.h"
34 #include "lib/vfs/vfs.h"
35 #include "lib/util.h"
36
37 #include "src/textconf.h"
38
39 #ifdef USE_INTERNAL_EDIT
40 #include "editor/edit.h"
41 #endif
42
43 #include "src/args.h"
44
45
46
47
48
49
50 gboolean mc_args__force_xterm = FALSE;
51
52 gboolean mc_args__nomouse = FALSE;
53
54
55 gboolean mc_args__force_colors = FALSE;
56
57
58 gboolean mc_args__nokeymap = FALSE;
59
60 char *mc_args__last_wd_file = NULL;
61
62
63 char *mc_args__netfs_logfile = NULL;
64
65
66 char *mc_args__keymap_file = NULL;
67
68 void *mc_run_param0 = NULL;
69 char *mc_run_param1 = NULL;
70
71
72
73
74
75
76
77 static gboolean parse_mc_e_argument (const gchar *option_name, const gchar *value, gpointer data,
78 GError **mcerror);
79 static gboolean parse_mc_v_argument (const gchar *option_name, const gchar *value, gpointer data,
80 GError **mcerror);
81
82
83
84
85 static gboolean mc_args__show_version = FALSE;
86
87 static GOptionContext *context;
88
89 #ifdef ENABLE_SUBSHELL
90 static gboolean mc_args__nouse_subshell = FALSE;
91 #endif
92 static gboolean mc_args__show_datadirs = FALSE;
93 static gboolean mc_args__show_datadirs_extended = FALSE;
94 #ifdef ENABLE_CONFIGURE_ARGS
95 static gboolean mc_args__show_configure_opts = FALSE;
96 #endif
97
98 static GOptionGroup *main_group;
99
100 static const GOptionEntry argument_main_table[] = {
101
102 {
103 "version",
104 'V',
105 G_OPTION_FLAG_IN_MAIN,
106 G_OPTION_ARG_NONE,
107 &mc_args__show_version,
108 N_ ("Displays the current version"),
109 NULL,
110 },
111
112
113 {
114 "datadir",
115 'f',
116 G_OPTION_FLAG_IN_MAIN,
117 G_OPTION_ARG_NONE,
118 &mc_args__show_datadirs,
119 N_ ("Print data directory"),
120 NULL,
121 },
122
123
124 {
125 "datadir-info",
126 'F',
127 G_OPTION_FLAG_IN_MAIN,
128 G_OPTION_ARG_NONE,
129 &mc_args__show_datadirs_extended,
130 N_ ("Print extended info about used data directories"),
131 NULL,
132 },
133
134 #ifdef ENABLE_CONFIGURE_ARGS
135
136 {
137 "configure-options",
138 '\0',
139 G_OPTION_FLAG_IN_MAIN,
140 G_OPTION_ARG_NONE,
141 &mc_args__show_configure_opts,
142 N_ ("Print configure options"),
143 NULL,
144 },
145 #endif
146
147 {
148 "printwd",
149 'P',
150 G_OPTION_FLAG_IN_MAIN,
151 G_OPTION_ARG_STRING,
152 &mc_args__last_wd_file,
153 N_ ("Print last working directory to specified file"),
154 N_ ("<file>"),
155 },
156
157 #ifdef ENABLE_SUBSHELL
158 {
159 "subshell",
160 'U',
161 G_OPTION_FLAG_IN_MAIN,
162 G_OPTION_ARG_NONE,
163 &mc_global.tty.use_subshell,
164 N_ ("Enables subshell support (default)"),
165 NULL,
166 },
167
168 {
169 "nosubshell",
170 'u',
171 G_OPTION_FLAG_IN_MAIN,
172 G_OPTION_ARG_NONE,
173 &mc_args__nouse_subshell,
174 N_ ("Disables subshell support"),
175 NULL,
176 },
177 #endif
178
179
180 #ifdef ENABLE_VFS_FTP
181 {
182 "ftplog",
183 'l',
184 G_OPTION_FLAG_IN_MAIN,
185 G_OPTION_ARG_STRING,
186 &mc_args__netfs_logfile,
187 N_ ("Log ftp dialog to specified file"),
188 N_ ("<file>"),
189 },
190 #endif
191
192 {
193
194 "view",
195 'v',
196 G_OPTION_FLAG_IN_MAIN | G_OPTION_FLAG_NO_ARG,
197 G_OPTION_ARG_CALLBACK,
198 (gpointer) parse_mc_v_argument,
199 N_ ("Launches the file viewer on a file"),
200 N_ ("<file>"),
201 },
202
203 {
204
205 "edit",
206 'e',
207 G_OPTION_FLAG_IN_MAIN | G_OPTION_FLAG_NO_ARG,
208 G_OPTION_ARG_CALLBACK,
209 (gpointer) parse_mc_e_argument,
210 N_ ("Edit files"),
211 N_ ("<file> ..."),
212 },
213
214 G_OPTION_ENTRY_NULL,
215 };
216
217 static GOptionGroup *terminal_group;
218 #define ARGS_TERM_OPTIONS 0
219 static const GOptionEntry argument_terminal_table[] = {
220
221 {
222 "xterm",
223 'x',
224 ARGS_TERM_OPTIONS,
225 G_OPTION_ARG_NONE,
226 &mc_args__force_xterm,
227 N_ ("Forces xterm features"),
228 NULL,
229 },
230
231 {
232 "no-x11",
233 'X',
234 ARGS_TERM_OPTIONS,
235 G_OPTION_ARG_NONE,
236 &mc_global.tty.disable_x11,
237 N_ ("Disable X11 support"),
238 NULL,
239 },
240
241 {
242 "oldmouse",
243 'g',
244 ARGS_TERM_OPTIONS,
245 G_OPTION_ARG_NONE,
246 &mc_global.tty.old_mouse,
247 N_ ("Tries to use an old highlight mouse tracking"),
248 NULL,
249 },
250
251 {
252 "nomouse",
253 'd',
254 ARGS_TERM_OPTIONS,
255 G_OPTION_ARG_NONE,
256 &mc_args__nomouse,
257 N_ ("Disable mouse support in text version"),
258 NULL,
259 },
260
261 #ifdef HAVE_SLANG
262 { "termcap", 't', ARGS_TERM_OPTIONS, G_OPTION_ARG_NONE, &SLtt_Try_Termcap,
263 N_ ("Tries to use termcap instead of terminfo"), NULL },
264 #endif
265
266 {
267 "slow",
268 's',
269 ARGS_TERM_OPTIONS,
270 G_OPTION_ARG_NONE,
271 &mc_global.tty.slow_terminal,
272 N_ ("To run on slow terminals"),
273 NULL,
274 },
275
276 {
277 "stickchars",
278 'a',
279 ARGS_TERM_OPTIONS,
280 G_OPTION_ARG_NONE,
281 &mc_global.tty.ugly_line_drawing,
282 N_ ("Use stickchars to draw"),
283 NULL,
284 },
285
286 {
287 "keymap",
288 'K',
289 ARGS_TERM_OPTIONS,
290 G_OPTION_ARG_STRING,
291 &mc_args__keymap_file,
292 N_ ("Load definitions of key bindings from specified file"),
293 N_ ("<file>"),
294 },
295
296 {
297 "nokeymap",
298 '\0',
299 ARGS_TERM_OPTIONS,
300 G_OPTION_ARG_NONE,
301 &mc_args__nokeymap,
302 N_ ("Don't load definitions of key bindings from file, use defaults"),
303 NULL,
304 },
305
306 G_OPTION_ENTRY_NULL,
307 };
308
309 #undef ARGS_TERM_OPTIONS
310
311 static GOptionGroup *color_group;
312 #define ARGS_COLOR_OPTIONS 0
313
314 static const GOptionEntry argument_color_table[] = {
315
316 {
317 "nocolor",
318 'b',
319 ARGS_COLOR_OPTIONS,
320 G_OPTION_ARG_NONE,
321 &mc_global.tty.disable_colors,
322 N_ ("Requests to run in black and white"),
323 NULL,
324 },
325
326 {
327 "color",
328 'c',
329 ARGS_COLOR_OPTIONS,
330 G_OPTION_ARG_NONE,
331 &mc_args__force_colors,
332 N_ ("Request to run in color mode"),
333 NULL,
334 },
335
336 {
337 "skin",
338 'S',
339 ARGS_COLOR_OPTIONS,
340 G_OPTION_ARG_STRING,
341 &mc_global.tty.skin,
342 N_ ("Show mc with specified skin"),
343 N_ ("<string>"),
344 },
345
346 G_OPTION_ENTRY_NULL,
347 };
348
349 #undef ARGS_COLOR_OPTIONS
350
351 static gchar *mc_args__loc__colors_string = NULL;
352 static gchar *mc_args__loc__footer_string = NULL;
353 static gchar *mc_args__loc__header_string = NULL;
354 static gchar *mc_args__loc__usage_string = NULL;
355
356
357
358
359
360 static void
361 mc_args_clean_temp_help_strings (void)
362 {
363 MC_PTR_FREE (mc_args__loc__colors_string);
364 MC_PTR_FREE (mc_args__loc__footer_string);
365 MC_PTR_FREE (mc_args__loc__header_string);
366 MC_PTR_FREE (mc_args__loc__usage_string);
367 }
368
369
370
371 static gchar *
372 mc_args_add_usage_info (void)
373 {
374 gchar *s;
375
376 switch (mc_global.mc_run_mode)
377 {
378 #ifdef USE_INTERNAL_EDIT
379 case MC_RUN_EDITOR:
380 s = g_strdup_printf ("%s\n", _ ("[+lineno] file1[:lineno] [file2[:lineno]...]"));
381 break;
382 #endif
383 case MC_RUN_VIEWER:
384 s = g_strdup_printf ("%s\n", _ ("file"));
385 break;
386 #ifdef USE_DIFF_VIEW
387 case MC_RUN_DIFFVIEWER:
388 s = g_strdup_printf ("%s\n", _ ("file1 file2"));
389 break;
390 #endif
391 case MC_RUN_FULL:
392 default:
393 s = g_strdup_printf ("%s\n", _ ("[this_dir] [other_panel_dir]"));
394 }
395
396 mc_args__loc__usage_string = s;
397
398 return mc_args__loc__usage_string;
399 }
400
401
402
403 static void
404 mc_args_add_extended_info_to_help (void)
405 {
406 mc_args__loc__footer_string =
407 g_strdup_printf (_ ("\n"
408 "Please send any bug reports (including the output of '%s -V')\n"
409 "as tickets at %s\n"),
410 PACKAGE, PACKAGE_BUGREPORT);
411 mc_args__loc__header_string = g_strdup_printf ("%s %s\n", PACKAGE_NAME, mc_global.mc_version);
412
413 g_option_context_set_description (context, mc_args__loc__footer_string);
414 g_option_context_set_summary (context, mc_args__loc__header_string);
415 }
416
417
418
419 static GString *
420 mc_args__convert_help_to_syscharset (const gchar *charset, const gchar *error_message_str,
421 const gchar *help_str)
422 {
423 GString *buffer;
424 GIConv conv;
425 gchar *full_help_str;
426
427 buffer = g_string_new ("");
428 conv = g_iconv_open (charset, "UTF-8");
429 full_help_str = g_strdup_printf ("%s\n\n%s\n", error_message_str, help_str);
430
431 str_convert (conv, full_help_str, buffer);
432
433 g_free (full_help_str);
434 g_iconv_close (conv);
435
436 return buffer;
437 }
438
439
440
441 static gboolean
442 parse_mc_e_argument (const gchar *option_name, const gchar *value, gpointer data, GError **mcerror)
443 {
444 (void) option_name;
445 (void) value;
446 (void) data;
447
448 mc_return_val_if_error (mcerror, FALSE);
449
450 mc_global.mc_run_mode = MC_RUN_EDITOR;
451
452 return TRUE;
453 }
454
455
456
457 static gboolean
458 parse_mc_v_argument (const gchar *option_name, const gchar *value, gpointer data, GError **mcerror)
459 {
460 (void) option_name;
461 (void) value;
462 (void) data;
463
464 mc_return_val_if_error (mcerror, FALSE);
465
466 mc_global.mc_run_mode = MC_RUN_VIEWER;
467
468 return TRUE;
469 }
470
471
472
473 #ifdef USE_INTERNAL_EDIT
474
475
476
477
478
479
480
481
482 static GList *
483 parse_mcedit_arguments (int argc, char **argv)
484 {
485 GList *flist = NULL;
486 int i;
487 long first_line_number = -1;
488
489 for (i = 0; i < argc; i++)
490 {
491 char *tmp;
492 char *end, *p;
493 edit_arg_t *arg;
494
495 tmp = argv[i];
496
497
498
499
500 if (*tmp == '+')
501 {
502 long lineno;
503 char *error;
504
505 lineno = strtol (tmp + 1, &error, 10);
506
507 if (*error == '\0')
508 {
509
510 first_line_number = lineno;
511 continue;
512 }
513
514 }
515
516
517
518
519
520
521
522 end = tmp + strlen (tmp);
523 p = end;
524
525 if (p > tmp && p[-1] == ':')
526 p--;
527 while (p > tmp && g_ascii_isdigit ((gchar) p[-1]))
528 p--;
529
530 if (tmp < p && p < end && p[-1] == ':')
531 {
532 char *fname;
533 vfs_path_t *tmp_vpath, *fname_vpath;
534 struct stat st;
535
536 fname = g_strndup (tmp, p - 1 - tmp);
537 tmp_vpath = vfs_path_from_str (tmp);
538 fname_vpath = vfs_path_from_str (fname);
539
540
541
542
543
544 if (mc_stat (tmp_vpath, &st) == -1 && mc_stat (fname_vpath, &st) != -1)
545 {
546 arg = edit_arg_vpath_new (fname_vpath, atoi (p));
547 vfs_path_free (tmp_vpath, TRUE);
548 }
549 else
550 {
551 arg = edit_arg_vpath_new (tmp_vpath, 0);
552 vfs_path_free (fname_vpath, TRUE);
553 }
554
555 g_free (fname);
556 }
557 else
558 arg = edit_arg_new (tmp, 0);
559
560 flist = g_list_prepend (flist, arg);
561 }
562
563 if (flist == NULL)
564 flist = g_list_prepend (flist, edit_arg_new (NULL, 0));
565 else if (first_line_number != -1)
566 {
567
568 GList *l;
569
570 l = g_list_last (flist);
571 ((edit_arg_t *) l->data)->line_number = first_line_number;
572 }
573
574 return flist;
575 }
576 #endif
577
578
579
580
581
582 void
583 mc_setup_run_mode (char **argv)
584 {
585 const char *base;
586
587 base = x_basename (argv[0]);
588
589 if (strncmp (base, "mcv", 3) == 0 || strcmp (base, "view") == 0)
590 {
591
592 mc_global.mc_run_mode = MC_RUN_VIEWER;
593 }
594 #ifdef USE_INTERNAL_EDIT
595 else if (strncmp (base, "mce", 3) == 0 || strcmp (base, "vi") == 0)
596 {
597
598 mc_global.mc_run_mode = MC_RUN_EDITOR;
599 }
600 #endif
601 #ifdef USE_DIFF_VIEW
602 else if (strncmp (base, "mcd", 3) == 0 || strcmp (base, "diff") == 0)
603 {
604
605 mc_global.mc_run_mode = MC_RUN_DIFFVIEWER;
606 }
607 #endif
608 }
609
610
611
612 gboolean
613 mc_args_parse (int *argc, char ***argv, const char *translation_domain, GError **mcerror)
614 {
615 const gchar *_system_codepage;
616 gboolean ok = TRUE;
617
618 mc_return_val_if_error (mcerror, FALSE);
619
620 _system_codepage = str_detect_termencoding ();
621
622 #ifdef ENABLE_NLS
623 if (!str_isutf8 (_system_codepage))
624 bind_textdomain_codeset ("mc", "UTF-8");
625 #endif
626
627 context = g_option_context_new (mc_args_add_usage_info ());
628
629 g_option_context_set_ignore_unknown_options (context, FALSE);
630
631 mc_args_add_extended_info_to_help ();
632
633 main_group = g_option_group_new ("main", _ ("Main options"), _ ("Main options"), NULL, NULL);
634
635 g_option_group_add_entries (main_group, argument_main_table);
636 g_option_context_set_main_group (context, main_group);
637 g_option_group_set_translation_domain (main_group, translation_domain);
638
639 terminal_group =
640 g_option_group_new ("terminal", _ ("Terminal options"), _ ("Terminal options"), NULL, NULL);
641
642 g_option_group_add_entries (terminal_group, argument_terminal_table);
643 g_option_context_add_group (context, terminal_group);
644 g_option_group_set_translation_domain (terminal_group, translation_domain);
645
646 color_group =
647 g_option_group_new ("color", _ ("Color options"), _ ("Color options"), NULL, NULL);
648
649 g_option_group_add_entries (color_group, argument_color_table);
650 g_option_context_add_group (context, color_group);
651 g_option_group_set_translation_domain (color_group, translation_domain);
652
653 if (!g_option_context_parse (context, argc, argv, mcerror))
654 {
655 if (*mcerror == NULL)
656 mc_propagate_error (mcerror, 0, "%s\n", _ ("Arguments parse error!"));
657 else
658 {
659 gchar *help_str;
660
661 help_str = g_option_context_get_help (context, TRUE, NULL);
662
663 if (str_isutf8 (_system_codepage))
664 mc_replace_error (mcerror, (*mcerror)->code, "%s\n\n%s\n", (*mcerror)->message,
665 help_str);
666 else
667 {
668 GString *full_help_str;
669
670 full_help_str = mc_args__convert_help_to_syscharset (_system_codepage,
671 (*mcerror)->message, help_str);
672 mc_replace_error (mcerror, (*mcerror)->code, "%s", full_help_str->str);
673 g_string_free (full_help_str, TRUE);
674 }
675 g_free (help_str);
676 }
677
678 ok = FALSE;
679 }
680
681 g_option_context_free (context);
682 mc_args_clean_temp_help_strings ();
683
684 #ifdef ENABLE_NLS
685 if (!str_isutf8 (_system_codepage))
686 bind_textdomain_codeset ("mc", _system_codepage);
687 #endif
688
689 return ok;
690 }
691
692
693
694 gboolean
695 mc_args_show_info (void)
696 {
697 if (mc_args__show_version)
698 {
699 show_version ();
700 return FALSE;
701 }
702
703 if (mc_args__show_datadirs)
704 {
705 printf ("%s (%s)\n", mc_global.sysconfig_dir, mc_global.share_data_dir);
706 return FALSE;
707 }
708
709 if (mc_args__show_datadirs_extended)
710 {
711 show_datadirs_extended ();
712 return FALSE;
713 }
714
715 #ifdef ENABLE_CONFIGURE_ARGS
716 if (mc_args__show_configure_opts)
717 {
718 show_configure_options ();
719 return FALSE;
720 }
721 #endif
722
723 return TRUE;
724 }
725
726
727
728 gboolean
729 mc_setup_by_args (int argc, char **argv, GError **mcerror)
730 {
731 char *tmp;
732
733 mc_return_val_if_error (mcerror, FALSE);
734
735 if (mc_args__force_colors)
736 mc_global.tty.disable_colors = FALSE;
737
738 #ifdef ENABLE_SUBSHELL
739 if (mc_args__nouse_subshell)
740 mc_global.tty.use_subshell = FALSE;
741 #endif
742
743 #ifdef ENABLE_VFS_FTP
744 if (mc_args__netfs_logfile != NULL)
745 {
746 vfs_path_t *vpath;
747
748 vpath = vfs_path_from_str ("ftp://");
749 mc_setctl (vpath, VFS_SETCTL_LOGFILE, (void *) mc_args__netfs_logfile);
750 vfs_path_free (vpath, TRUE);
751 }
752 #endif
753
754 tmp = (argc > 0) ? argv[1] : NULL;
755
756 switch (mc_global.mc_run_mode)
757 {
758 case MC_RUN_EDITOR:
759 #ifdef USE_INTERNAL_EDIT
760 mc_run_param0 = parse_mcedit_arguments (argc - 1, &argv[1]);
761 break;
762 #else
763 mc_propagate_error (mcerror, 0, "%s\n", _ ("MC is built without builtin editor."));
764 return FALSE;
765 #endif
766
767 case MC_RUN_VIEWER:
768 if (tmp == NULL)
769 {
770 mc_propagate_error (mcerror, 0, "%s\n", _ ("No arguments given to the viewer."));
771 return FALSE;
772 }
773
774 mc_run_param0 = g_strdup (tmp);
775 break;
776
777 #ifdef USE_DIFF_VIEW
778 case MC_RUN_DIFFVIEWER:
779 if (argc < 3)
780 {
781 mc_propagate_error (mcerror, 0, "%s\n",
782 _ ("Two files are required to invoke the diffviewer."));
783 return FALSE;
784 }
785 MC_FALLTHROUGH;
786 #endif
787
788 case MC_RUN_FULL:
789 default:
790
791
792 if (tmp != NULL)
793 {
794 mc_run_param0 = g_strdup (tmp);
795 tmp = (argc > 1) ? argv[2] : NULL;
796 if (tmp != NULL)
797 mc_run_param1 = g_strdup (tmp);
798 }
799 break;
800 }
801
802 return TRUE;
803 }
804
805