[go: up one dir, main page]

File: tilda-cli-options.c

package info (click to toggle)
tilda 2.0.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,708 kB
  • sloc: ansic: 8,286; sh: 4,917; makefile: 169; xml: 54; sed: 16
file content (178 lines) | stat: -rw-r--r-- 7,763 bytes parent folder | download
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#include "tilda-cli-options.h"

#include "config.h"

#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <stdlib.h>

#include "debug.h"

static GQuark tilda_error_quark (void);

G_DEFINE_QUARK(tilda-config-error-quark, tilda_error)

typedef enum {
    TILDA_CONFIG_ERROR_BAD_INPUT, // Error for bad config argument
} TildaConfigError;

static gboolean toggle_option_cb (const gchar *option_name,
                                  const gchar *value,
                                  gpointer user_data,
                                  GError **error);

gboolean tilda_cli_options_parse_options (tilda_cli_options *cli_options,
                                          gint argc,
                                          gchar *argv[],
                                          gchar **config_file)
{
    DEBUG_FUNCTION ("parse_cli");
    DEBUG_ASSERT (argc != 0);
    DEBUG_ASSERT (argv != NULL);
    // *config_file must be non-null only if a configuration file path has been parsed
    DEBUG_ASSERT (*config_file == NULL);

    /* All tilda command-line options */
    GOptionEntry cl_opts[] = {
            { "background-color",   'b', 0, G_OPTION_ARG_STRING,    &(cli_options->background_color),  N_("Set the background color"), NULL },
            { "command",            'c', 0, G_OPTION_ARG_STRING,    &(cli_options->command),           N_("Run a command at startup"), NULL },
            { "hidden",             'h', 0, G_OPTION_ARG_NONE,      &(cli_options->hidden),            N_("Start Tilda hidden"), NULL },
            { "font",               'f', 0, G_OPTION_ARG_STRING,    &(cli_options->font),              N_("Set the font to the following string"), NULL },
            { "config-file",        'g', 0, G_OPTION_ARG_STRING,    config_file,                       N_("Configuration file"), NULL },
            { "lines",              'l', 0, G_OPTION_ARG_INT,       &(cli_options->lines),             N_("Scrollback Lines"), NULL },
            { "scrollbar",          's', 0, G_OPTION_ARG_NONE,      &(cli_options->scrollbar),         N_("Use Scrollbar"), NULL },
            { "version",            'v', 0, G_OPTION_ARG_NONE,      &(cli_options->version),           N_("Print the version, then exit"), NULL },
            { "working-dir",        'w', 0, G_OPTION_ARG_STRING,    &(cli_options->working_dir),       N_("Set Initial Working Directory"), NULL },
            { "x-pos",              'x', 0, G_OPTION_ARG_INT,       &(cli_options->x_pos),             N_("X Position"), NULL },
            { "y-pos",              'y', 0, G_OPTION_ARG_INT,       &(cli_options->y_pos),             N_("Y Position"), NULL },
            { "background-alpha",   't', 0, G_OPTION_ARG_INT,       &(cli_options->back_alpha),        N_("Opaqueness: 0-100%"), NULL },
            { "config",             'C', 0, G_OPTION_ARG_NONE,      &(cli_options->show_config),       N_("Show Configuration Wizard"), NULL },
            G_OPTION_ENTRY_NULL
    };

    GOptionEntry dbus_opts[] = {
            { "dbus", 0, 0, G_OPTION_ARG_NONE,
              &(cli_options->enable_dbus), N_("Enable D-Bus interface for this instance"), NULL },
            { "toggle-window", 'T', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
              toggle_option_cb,  N_("Toggle N-th instance Window visibility and exit"), NULL
            },
            G_OPTION_ENTRY_NULL
    };

    /* Set up the command-line parser */
    GError *error = NULL;
    GOptionContext *context = g_option_context_new (NULL);
    g_option_context_add_main_entries (context, cl_opts, NULL);

    /* Register a separate group for DBus related options. */
    GOptionGroup *group = g_option_group_new ("dbus", "D-Bus Options:", "Show Tilda D-Bus Options", cli_options, NULL);
    g_option_group_add_entries (group, dbus_opts);
    g_option_context_add_group (context, group);

    /* Register default GTK and GDK related option group. */
    g_option_context_add_group (context, gtk_get_option_group (FALSE));

    g_option_context_parse (context, &argc, &argv, &error);
    g_option_context_free (context);

    /* Check for unknown options, and give a nice message if there are some */
    if (error)
    {
        g_printerr (_("Error parsing command-line options. Try \"tilda --help\"\nto see all possible options.\n\nError message: %s\n"),
                    error->message);

        exit (EXIT_FAILURE);
    }

    /* If we need to show the version, show it then exit normally */
    if (cli_options->version)
    {
        g_print ("%s\n\n", PACKAGE_STRING);

        g_print ("Copyright (c) 2012-2020 Sebastian Geiger (lanoxx@gmx.net)\n");
        g_print ("Copyright (c) 2005-2009 Tristan Sloughter (sloutri@iit.edu)\n");
        g_print ("Copyright (c) 2005-2009 Ira W. Snyder (tilda@irasnyder.com)\n\n");

        g_print ("General Information: https://github.com/lanoxx/tilda\n");
        g_print ("Bug Reports: https://github.com/lanoxx/tilda/issues?state=open\n\n");

        g_print ("This program comes with ABSOLUTELY NO WARRANTY.\n");
        g_print ("This is free software, and you are welcome to redistribute it\n");
        g_print ("under certain conditions. See the file COPYING for details.\n");

        exit (EXIT_SUCCESS);
    }

    /* TRUE if we should show the config wizard, FALSE otherwise */
    return cli_options->show_config;
}

tilda_cli_options *tilda_cli_options_new ()
{
    tilda_cli_options *options = g_malloc0(sizeof(tilda_cli_options));
    if (!options)
    {
        g_printerr (_("Error allocating memory for a new tilda_cli_options structure.\n"));
        exit (EXIT_FAILURE);
    }

    // instance id of the windows will be in range from 0 to N,
    // defaults to -1 (unset) if option is not used.
    options->toggle_window = -1;

    return options;
}

/**
 * toggle_option_cb: A GOptionArgFunc which parses the toggle-window option
 * argument. Using this toggle function allows us to assign a default value,
 * if the user just specifies the option without a value. For example, the
 * user may use '-T' instead of '-T 0', in this case we set the default
 * instance_id to 0. Most users will want to use the default unless they
 * are running multiple tilda instances and thus this makes the setup
 * of toggle shortcuts easier.
 */
static gboolean toggle_option_cb (G_GNUC_UNUSED const gchar *option_name,
                                  const gchar *value,
                                  gpointer user_data,
                                  GError **error)
{
    if (!user_data) {
        g_error("Missing user_data pointer in toggle_option_cb function.");
    }

    tilda_cli_options *options = user_data;

    if (!value || !value[0]) {
        options->toggle_window = 0;
        return TRUE;
    }

    char * parseEnd = NULL;

    long instance_id = strtol(value, &parseEnd, 10);

    if (parseEnd != NULL && *parseEnd != '\0') {
        g_set_error(error, tilda_error_quark(), TILDA_CONFIG_ERROR_BAD_INPUT, "Could not parse the toggle argument. The argument must be a valid integer.");
        return FALSE;
    }

    // sanity check for (gint) cast below. In practice, there will
    // only ever be a few instances running, so this value will probably
    // never be higher than 10, but to make the gint cast save, we check
    // against INT_MAX
    if (instance_id > INT_MAX) {
        g_set_error (error, tilda_error_quark(), TILDA_CONFIG_ERROR_BAD_INPUT,
                     "The toggle window option cannot must not be greater than %d, but value was %ld.", INT_MAX, instance_id);
        return FALSE;
    }

    // if the user specified a negative value, then we default to 0.
    if (instance_id < 0) {
        instance_id = 0;
    }

    options->toggle_window = (gint) instance_id;

    return TRUE;
}