This source file includes following definitions.
- mc_args_clean_temp_help_strings
- mc_args_new_color_group
- 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 #ifdef HAVE_SLANG
287 { "resetsoft", 'k', ARGS_TERM_OPTIONS, G_OPTION_ARG_NONE, &reset_hp_softkeys,
288 N_ ("Resets soft keys on HP terminals"), NULL },
289 #endif
290
291 {
292 "keymap",
293 'K',
294 ARGS_TERM_OPTIONS,
295 G_OPTION_ARG_STRING,
296 &mc_args__keymap_file,
297 N_ ("Load definitions of key bindings from specified file"),
298 N_ ("<file>"),
299 },
300
301 {
302 "nokeymap",
303 '\0',
304 ARGS_TERM_OPTIONS,
305 G_OPTION_ARG_NONE,
306 &mc_args__nokeymap,
307 N_ ("Don't load definitions of key bindings from file, use defaults"),
308 NULL,
309 },
310
311 G_OPTION_ENTRY_NULL,
312 };
313
314 #undef ARGS_TERM_OPTIONS
315
316 static GOptionGroup *color_group;
317 #define ARGS_COLOR_OPTIONS 0
318
319 static const GOptionEntry argument_color_table[] = {
320
321 {
322 "nocolor",
323 'b',
324 ARGS_COLOR_OPTIONS,
325 G_OPTION_ARG_NONE,
326 &mc_global.tty.disable_colors,
327 N_ ("Requests to run in black and white"),
328 NULL,
329 },
330
331 {
332 "color",
333 'c',
334 ARGS_COLOR_OPTIONS,
335 G_OPTION_ARG_NONE,
336 &mc_args__force_colors,
337 N_ ("Request to run in color mode"),
338 NULL,
339 },
340
341 {
342 "colors",
343 'C',
344 ARGS_COLOR_OPTIONS,
345 G_OPTION_ARG_STRING,
346 &mc_global.tty.command_line_colors,
347 N_ ("Specifies a color configuration"),
348 N_ ("<string>"),
349 },
350
351 {
352 "skin",
353 'S',
354 ARGS_COLOR_OPTIONS,
355 G_OPTION_ARG_STRING,
356 &mc_global.tty.skin,
357 N_ ("Show mc with specified skin"),
358 N_ ("<string>"),
359 },
360
361 G_OPTION_ENTRY_NULL,
362 };
363
364 #undef ARGS_COLOR_OPTIONS
365
366 static gchar *mc_args__loc__colors_string = NULL;
367 static gchar *mc_args__loc__footer_string = NULL;
368 static gchar *mc_args__loc__header_string = NULL;
369 static gchar *mc_args__loc__usage_string = NULL;
370
371
372
373
374
375 static void
376 mc_args_clean_temp_help_strings (void)
377 {
378 MC_PTR_FREE (mc_args__loc__colors_string);
379 MC_PTR_FREE (mc_args__loc__footer_string);
380 MC_PTR_FREE (mc_args__loc__header_string);
381 MC_PTR_FREE (mc_args__loc__usage_string);
382 }
383
384
385
386 static GOptionGroup *
387 mc_args_new_color_group (void)
388 {
389
390 mc_args__loc__colors_string = g_strdup_printf (
391 "%s\n%s",
392
393 _ ("--colors KEYWORD={FORE},{BACK},{ATTR}:KEYWORD2=...\n\n"
394 "{FORE}, {BACK} and {ATTR} can be omitted, and the default will be used\n"
395 "\n Keywords:\n"
396 " Global: errors, disabled, reverse, gauge, header\n"
397 " input, inputmark, inputunchanged, commandlinemark\n"
398 " bbarhotkey, bbarbutton, statusbar\n"
399 " File display: normal, selected, marked, markselect\n"
400 " Dialog boxes: dnormal, dfocus, dhotnormal, dhotfocus, errdhotnormal,\n"
401 " errdhotfocus\n"
402 " Menus: menunormal, menuhot, menusel, menuhotsel, menuinactive\n"
403 " Popup menus: pmenunormal, pmenusel, pmenutitle\n"
404 " Editor: editnormal, editbold, editmarked, editwhitespace, editnonprintable,\n"
405 " editlinestate, editbg, editframe, editframeactive\n"
406 " editframedrag\n"
407 " Viewer: viewnormal,viewbold, viewunderline, viewselected\n"
408 " Help: helpnormal, helpitalic, helpbold, helplink, helpslink\n"),
409
410 _ ("Standard Colors:\n"
411 " black, gray, red, brightred, green, brightgreen, brown,\n"
412 " yellow, blue, brightblue, magenta, brightmagenta, cyan,\n"
413 " brightcyan, lightgray and white\n\n"
414 "Extended colors, when 256 colors are available:\n"
415 " color16 to color255, or rgb000 to rgb555 and gray0 to gray23\n\n"
416 "Attributes:\n"
417 " bold, italic, underline, reverse, blink; append more with '+'\n"));
418
419 return g_option_group_new ("color", mc_args__loc__colors_string, _ ("Color options"), NULL,
420 NULL);
421 }
422
423
424
425 static gchar *
426 mc_args_add_usage_info (void)
427 {
428 gchar *s;
429
430 switch (mc_global.mc_run_mode)
431 {
432 #ifdef USE_INTERNAL_EDIT
433 case MC_RUN_EDITOR:
434 s = g_strdup_printf ("%s\n", _ ("[+lineno] file1[:lineno] [file2[:lineno]...]"));
435 break;
436 #endif
437 case MC_RUN_VIEWER:
438 s = g_strdup_printf ("%s\n", _ ("file"));
439 break;
440 #ifdef USE_DIFF_VIEW
441 case MC_RUN_DIFFVIEWER:
442 s = g_strdup_printf ("%s\n", _ ("file1 file2"));
443 break;
444 #endif
445 case MC_RUN_FULL:
446 default:
447 s = g_strdup_printf ("%s\n", _ ("[this_dir] [other_panel_dir]"));
448 }
449
450 mc_args__loc__usage_string = s;
451
452 return mc_args__loc__usage_string;
453 }
454
455
456
457 static void
458 mc_args_add_extended_info_to_help (void)
459 {
460 mc_args__loc__footer_string =
461 g_strdup_printf (_ ("\n"
462 "Please send any bug reports (including the output of 'mc -V')\n"
463 "as tickets at %s\n"),
464 PACKAGE_BUGREPORT);
465 mc_args__loc__header_string = g_strdup_printf (PACKAGE_NAME " %s\n", mc_global.mc_version);
466
467 g_option_context_set_description (context, mc_args__loc__footer_string);
468 g_option_context_set_summary (context, mc_args__loc__header_string);
469 }
470
471
472
473 static GString *
474 mc_args__convert_help_to_syscharset (const gchar *charset, const gchar *error_message_str,
475 const gchar *help_str)
476 {
477 GString *buffer;
478 GIConv conv;
479 gchar *full_help_str;
480
481 buffer = g_string_new ("");
482 conv = g_iconv_open (charset, "UTF-8");
483 full_help_str = g_strdup_printf ("%s\n\n%s\n", error_message_str, help_str);
484
485 str_convert (conv, full_help_str, buffer);
486
487 g_free (full_help_str);
488 g_iconv_close (conv);
489
490 return buffer;
491 }
492
493
494
495 static gboolean
496 parse_mc_e_argument (const gchar *option_name, const gchar *value, gpointer data, GError **mcerror)
497 {
498 (void) option_name;
499 (void) value;
500 (void) data;
501
502 mc_return_val_if_error (mcerror, FALSE);
503
504 mc_global.mc_run_mode = MC_RUN_EDITOR;
505
506 return TRUE;
507 }
508
509
510
511 static gboolean
512 parse_mc_v_argument (const gchar *option_name, const gchar *value, gpointer data, GError **mcerror)
513 {
514 (void) option_name;
515 (void) value;
516 (void) data;
517
518 mc_return_val_if_error (mcerror, FALSE);
519
520 mc_global.mc_run_mode = MC_RUN_VIEWER;
521
522 return TRUE;
523 }
524
525
526
527 #ifdef USE_INTERNAL_EDIT
528
529
530
531
532
533
534
535
536 static GList *
537 parse_mcedit_arguments (int argc, char **argv)
538 {
539 GList *flist = NULL;
540 int i;
541 long first_line_number = -1;
542
543 for (i = 0; i < argc; i++)
544 {
545 char *tmp;
546 char *end, *p;
547 edit_arg_t *arg;
548
549 tmp = argv[i];
550
551
552
553
554 if (*tmp == '+')
555 {
556 long lineno;
557 char *error;
558
559 lineno = strtol (tmp + 1, &error, 10);
560
561 if (*error == '\0')
562 {
563
564 first_line_number = lineno;
565 continue;
566 }
567
568 }
569
570
571
572
573
574
575
576 end = tmp + strlen (tmp);
577 p = end;
578
579 if (p > tmp && p[-1] == ':')
580 p--;
581 while (p > tmp && g_ascii_isdigit ((gchar) p[-1]))
582 p--;
583
584 if (tmp < p && p < end && p[-1] == ':')
585 {
586 char *fname;
587 vfs_path_t *tmp_vpath, *fname_vpath;
588 struct stat st;
589
590 fname = g_strndup (tmp, p - 1 - tmp);
591 tmp_vpath = vfs_path_from_str (tmp);
592 fname_vpath = vfs_path_from_str (fname);
593
594
595
596
597
598 if (mc_stat (tmp_vpath, &st) == -1 && mc_stat (fname_vpath, &st) != -1)
599 {
600 arg = edit_arg_vpath_new (fname_vpath, atoi (p));
601 vfs_path_free (tmp_vpath, TRUE);
602 }
603 else
604 {
605 arg = edit_arg_vpath_new (tmp_vpath, 0);
606 vfs_path_free (fname_vpath, TRUE);
607 }
608
609 g_free (fname);
610 }
611 else
612 arg = edit_arg_new (tmp, 0);
613
614 flist = g_list_prepend (flist, arg);
615 }
616
617 if (flist == NULL)
618 flist = g_list_prepend (flist, edit_arg_new (NULL, 0));
619 else if (first_line_number != -1)
620 {
621
622 GList *l;
623
624 l = g_list_last (flist);
625 ((edit_arg_t *) l->data)->line_number = first_line_number;
626 }
627
628 return flist;
629 }
630 #endif
631
632
633
634
635
636 void
637 mc_setup_run_mode (char **argv)
638 {
639 const char *base;
640
641 base = x_basename (argv[0]);
642
643 if (strncmp (base, "mcv", 3) == 0 || strcmp (base, "view") == 0)
644 {
645
646 mc_global.mc_run_mode = MC_RUN_VIEWER;
647 }
648 #ifdef USE_INTERNAL_EDIT
649 else if (strncmp (base, "mce", 3) == 0 || strcmp (base, "vi") == 0)
650 {
651
652 mc_global.mc_run_mode = MC_RUN_EDITOR;
653 }
654 #endif
655 #ifdef USE_DIFF_VIEW
656 else if (strncmp (base, "mcd", 3) == 0 || strcmp (base, "diff") == 0)
657 {
658
659 mc_global.mc_run_mode = MC_RUN_DIFFVIEWER;
660 }
661 #endif
662 }
663
664
665
666 gboolean
667 mc_args_parse (int *argc, char ***argv, const char *translation_domain, GError **mcerror)
668 {
669 const gchar *_system_codepage;
670 gboolean ok = TRUE;
671
672 mc_return_val_if_error (mcerror, FALSE);
673
674 _system_codepage = str_detect_termencoding ();
675
676 #ifdef ENABLE_NLS
677 if (!str_isutf8 (_system_codepage))
678 bind_textdomain_codeset ("mc", "UTF-8");
679 #endif
680
681 context = g_option_context_new (mc_args_add_usage_info ());
682
683 g_option_context_set_ignore_unknown_options (context, FALSE);
684
685 mc_args_add_extended_info_to_help ();
686
687 main_group = g_option_group_new ("main", _ ("Main options"), _ ("Main options"), NULL, NULL);
688
689 g_option_group_add_entries (main_group, argument_main_table);
690 g_option_context_set_main_group (context, main_group);
691 g_option_group_set_translation_domain (main_group, translation_domain);
692
693 terminal_group =
694 g_option_group_new ("terminal", _ ("Terminal options"), _ ("Terminal options"), NULL, NULL);
695
696 g_option_group_add_entries (terminal_group, argument_terminal_table);
697 g_option_context_add_group (context, terminal_group);
698 g_option_group_set_translation_domain (terminal_group, translation_domain);
699
700 color_group = mc_args_new_color_group ();
701
702 g_option_group_add_entries (color_group, argument_color_table);
703 g_option_context_add_group (context, color_group);
704 g_option_group_set_translation_domain (color_group, translation_domain);
705
706 if (!g_option_context_parse (context, argc, argv, mcerror))
707 {
708 if (*mcerror == NULL)
709 mc_propagate_error (mcerror, 0, "%s\n", _ ("Arguments parse error!"));
710 else
711 {
712 gchar *help_str;
713
714 help_str = g_option_context_get_help (context, TRUE, NULL);
715
716 if (str_isutf8 (_system_codepage))
717 mc_replace_error (mcerror, (*mcerror)->code, "%s\n\n%s\n", (*mcerror)->message,
718 help_str);
719 else
720 {
721 GString *full_help_str;
722
723 full_help_str = mc_args__convert_help_to_syscharset (_system_codepage,
724 (*mcerror)->message, help_str);
725 mc_replace_error (mcerror, (*mcerror)->code, "%s", full_help_str->str);
726 g_string_free (full_help_str, TRUE);
727 }
728 g_free (help_str);
729 }
730
731 ok = FALSE;
732 }
733
734 g_option_context_free (context);
735 mc_args_clean_temp_help_strings ();
736
737 #ifdef ENABLE_NLS
738 if (!str_isutf8 (_system_codepage))
739 bind_textdomain_codeset ("mc", _system_codepage);
740 #endif
741
742 return ok;
743 }
744
745
746
747 gboolean
748 mc_args_show_info (void)
749 {
750 if (mc_args__show_version)
751 {
752 show_version ();
753 return FALSE;
754 }
755
756 if (mc_args__show_datadirs)
757 {
758 printf ("%s (%s)\n", mc_global.sysconfig_dir, mc_global.share_data_dir);
759 return FALSE;
760 }
761
762 if (mc_args__show_datadirs_extended)
763 {
764 show_datadirs_extended ();
765 return FALSE;
766 }
767
768 #ifdef ENABLE_CONFIGURE_ARGS
769 if (mc_args__show_configure_opts)
770 {
771 show_configure_options ();
772 return FALSE;
773 }
774 #endif
775
776 return TRUE;
777 }
778
779
780
781 gboolean
782 mc_setup_by_args (int argc, char **argv, GError **mcerror)
783 {
784 char *tmp;
785
786 mc_return_val_if_error (mcerror, FALSE);
787
788 if (mc_args__force_colors)
789 mc_global.tty.disable_colors = FALSE;
790
791 #ifdef ENABLE_SUBSHELL
792 if (mc_args__nouse_subshell)
793 mc_global.tty.use_subshell = FALSE;
794 #endif
795
796 #ifdef ENABLE_VFS_FTP
797 if (mc_args__netfs_logfile != NULL)
798 {
799 vfs_path_t *vpath;
800
801 vpath = vfs_path_from_str ("ftp://");
802 mc_setctl (vpath, VFS_SETCTL_LOGFILE, (void *) mc_args__netfs_logfile);
803 vfs_path_free (vpath, TRUE);
804 }
805 #endif
806
807 tmp = (argc > 0) ? argv[1] : NULL;
808
809 switch (mc_global.mc_run_mode)
810 {
811 case MC_RUN_EDITOR:
812 #ifdef USE_INTERNAL_EDIT
813 mc_run_param0 = parse_mcedit_arguments (argc - 1, &argv[1]);
814 break;
815 #else
816 mc_propagate_error (mcerror, 0, "%s\n", _ ("MC is built without builtin editor."));
817 return FALSE;
818 #endif
819
820 case MC_RUN_VIEWER:
821 if (tmp == NULL)
822 {
823 mc_propagate_error (mcerror, 0, "%s\n", _ ("No arguments given to the viewer."));
824 return FALSE;
825 }
826
827 mc_run_param0 = g_strdup (tmp);
828 break;
829
830 #ifdef USE_DIFF_VIEW
831 case MC_RUN_DIFFVIEWER:
832 if (argc < 3)
833 {
834 mc_propagate_error (mcerror, 0, "%s\n",
835 _ ("Two files are required to invoke the diffviewer."));
836 return FALSE;
837 }
838 MC_FALLTHROUGH;
839 #endif
840
841 case MC_RUN_FULL:
842 default:
843
844
845 if (tmp != NULL)
846 {
847 mc_run_param0 = g_strdup (tmp);
848 tmp = (argc > 1) ? argv[2] : NULL;
849 if (tmp != NULL)
850 mc_run_param1 = g_strdup (tmp);
851 }
852 break;
853 }
854
855 return TRUE;
856 }
857
858