mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-27 14:36:16 +01:00
Support floating point arguments in goption
This commit is contained in:
parent
a205620a88
commit
9749aa87e5
11
ChangeLog
11
ChangeLog
@ -1,3 +1,14 @@
|
||||
2006-03-27 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
Add support for floating point numbers to goption.
|
||||
(#329548, Behdad Esfahbod, patch by Antoine Dopffer and
|
||||
Dom Lachowicz)
|
||||
|
||||
* glib/goption.h:
|
||||
* glib/goption.c: Support double arguments.
|
||||
|
||||
* tests/option-test.c: Test double arguments.`
|
||||
|
||||
2006-03-26 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* glib/goption.c (g_option_context_new): Improve the description
|
||||
|
@ -1,3 +1,14 @@
|
||||
2006-03-27 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
Add support for floating point numbers to goption.
|
||||
(#329548, Behdad Esfahbod, patch by Antoine Dopffer and
|
||||
Dom Lachowicz)
|
||||
|
||||
* glib/goption.h:
|
||||
* glib/goption.c: Support double arguments.
|
||||
|
||||
* tests/option-test.c: Test double arguments.`
|
||||
|
||||
2006-03-26 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* glib/goption.c (g_option_context_new): Improve the description
|
||||
|
@ -1,3 +1,7 @@
|
||||
2006-03-27 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* glib/tmpl/option.sgml: Document floating point arguments
|
||||
|
||||
Fri Mar 24 15:22:04 2006 Tim Janik <timj@imendio.com>
|
||||
|
||||
* glib/tmpl/atomic_operations.sgml: some wording fixups.
|
||||
|
@ -257,6 +257,8 @@ or combined in a single argument: <option>--name=arg</option>.
|
||||
uses of the option are collected into an array of strings.
|
||||
@G_OPTION_ARG_FILENAME_ARRAY: The option takes a filename as argument,
|
||||
multiple uses of the option are collected into an array of strings.
|
||||
@G_OPTION_ARG_DOUBLE: The option takes a double argument. The argument
|
||||
can be formatted either for the user's locale or for the "C" locale. Since 2.12
|
||||
|
||||
<!-- ##### ENUM GOptionFlags ##### -->
|
||||
<para>
|
||||
@ -350,6 +352,10 @@ g_option_context_add_main_entries() or g_option_group_add_entries().
|
||||
<term>%G_OPTION_ARG_FILENAME_ARRAY</term>
|
||||
<listitem><para>%gchar**</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>%G_OPTION_ARG_DOUBLE</term>
|
||||
<listitem><para>%gdouble</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
@description: the description for the option in <option>--help</option>
|
||||
output. The @description is translated using the @translate_func of the
|
||||
|
@ -50,6 +50,7 @@ typedef struct
|
||||
gint integer;
|
||||
gchar *str;
|
||||
gchar **array;
|
||||
gdouble dbl;
|
||||
} prev;
|
||||
union
|
||||
{
|
||||
@ -684,6 +685,42 @@ parse_int (const gchar *arg_name,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
parse_double (const gchar *arg_name,
|
||||
const gchar *arg,
|
||||
gdouble *result,
|
||||
GError **error)
|
||||
{
|
||||
gchar *end;
|
||||
gdouble tmp;
|
||||
|
||||
errno = 0;
|
||||
tmp = g_strtod (arg, &end);
|
||||
|
||||
if (*arg == '\0' || *end != '\0')
|
||||
{
|
||||
g_set_error (error,
|
||||
G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
|
||||
_("Cannot parse double value '%s' for %s"),
|
||||
arg, arg_name);
|
||||
return FALSE;
|
||||
}
|
||||
if (errno == ERANGE)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
|
||||
_("Double value '%s' for %s out of range"),
|
||||
arg, arg_name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*result = tmp;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static Change *
|
||||
get_change (GOptionContext *context,
|
||||
GOptionArg arg_type,
|
||||
@ -900,6 +937,23 @@ parse_arg (GOptionContext *context,
|
||||
|
||||
return retval;
|
||||
|
||||
break;
|
||||
}
|
||||
case G_OPTION_ARG_DOUBLE:
|
||||
{
|
||||
gdouble data;
|
||||
|
||||
if (!parse_double (option_name, value,
|
||||
&data,
|
||||
error))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
change = get_change (context, G_OPTION_ARG_DOUBLE,
|
||||
entry->arg_data);
|
||||
change->prev.dbl = *(gdouble *)entry->arg_data;
|
||||
*(gdouble *)entry->arg_data = data;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -1166,6 +1220,9 @@ free_changes_list (GOptionContext *context,
|
||||
g_strfreev (change->allocated.array.data);
|
||||
*(gchar ***)change->arg_data = change->prev.array;
|
||||
break;
|
||||
case G_OPTION_ARG_DOUBLE:
|
||||
*(gdouble *)change->arg_data = change->prev.dbl;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
@ -49,7 +49,8 @@ typedef enum
|
||||
G_OPTION_ARG_CALLBACK,
|
||||
G_OPTION_ARG_FILENAME,
|
||||
G_OPTION_ARG_STRING_ARRAY,
|
||||
G_OPTION_ARG_FILENAME_ARRAY
|
||||
G_OPTION_ARG_FILENAME_ARRAY,
|
||||
G_OPTION_ARG_DOUBLE
|
||||
} GOptionArg;
|
||||
|
||||
typedef gboolean (*GOptionArgFunc) (const gchar *option_name,
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
#include <locale.h>
|
||||
|
||||
int error_test1_int;
|
||||
char *error_test2_string;
|
||||
@ -8,6 +9,8 @@ gboolean error_test3_boolean;
|
||||
int arg_test1_int;
|
||||
gchar *arg_test2_string;
|
||||
gchar *arg_test3_filename;
|
||||
gdouble arg_test4_double;
|
||||
gdouble arg_test5_double;
|
||||
|
||||
gchar *callback_test1_string;
|
||||
gboolean callback_test2_int;
|
||||
@ -330,6 +333,70 @@ arg_test3 (void)
|
||||
g_option_context_free (context);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
arg_test4 (void)
|
||||
{
|
||||
GOptionContext *context;
|
||||
gboolean retval;
|
||||
GError *error = NULL;
|
||||
gchar **argv;
|
||||
int argc;
|
||||
GOptionEntry entries [] =
|
||||
{ { "test", 0, 0, G_OPTION_ARG_DOUBLE, &arg_test4_double, NULL, NULL },
|
||||
{ NULL } };
|
||||
|
||||
context = g_option_context_new (NULL);
|
||||
g_option_context_add_main_entries (context, entries, NULL);
|
||||
|
||||
/* Now try parsing */
|
||||
argv = split_string ("program --test 20.0 --test 30.03", &argc);
|
||||
|
||||
retval = g_option_context_parse (context, &argc, &argv, &error);
|
||||
g_assert (retval);
|
||||
|
||||
/* Last arg specified is the one that should be stored */
|
||||
g_assert (arg_test4_double == 30.03);
|
||||
|
||||
g_strfreev (argv);
|
||||
g_option_context_free (context);
|
||||
}
|
||||
|
||||
void
|
||||
arg_test5 (void)
|
||||
{
|
||||
GOptionContext *context;
|
||||
gboolean retval;
|
||||
GError *error = NULL;
|
||||
gchar **argv;
|
||||
int argc;
|
||||
char *old_locale;
|
||||
GOptionEntry entries [] =
|
||||
{ { "test", 0, 0, G_OPTION_ARG_DOUBLE, &arg_test5_double, NULL, NULL },
|
||||
{ NULL } };
|
||||
|
||||
context = g_option_context_new (NULL);
|
||||
g_option_context_add_main_entries (context, entries, NULL);
|
||||
|
||||
/* Now try parsing */
|
||||
argv = split_string ("program --test 20,0 --test 30,03", &argc);
|
||||
|
||||
/* set it to some locale that uses commas instead of decimal points */
|
||||
old_locale = g_strdup (setlocale(LC_NUMERIC, "de"));
|
||||
|
||||
retval = g_option_context_parse (context, &argc, &argv, &error);
|
||||
g_assert (retval);
|
||||
|
||||
/* Last arg specified is the one that should be stored */
|
||||
g_assert (arg_test4_double == 30.03);
|
||||
|
||||
setlocale(LC_NUMERIC, old_locale);
|
||||
g_free (old_locale);
|
||||
|
||||
g_strfreev (argv);
|
||||
g_option_context_free (context);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
callback_parse1 (const gchar *option_name, const gchar *value,
|
||||
gpointer data, GError **error)
|
||||
@ -1288,6 +1355,8 @@ main (int argc, char **argv)
|
||||
arg_test1 ();
|
||||
arg_test2 ();
|
||||
arg_test3 ();
|
||||
arg_test4 ();
|
||||
/* arg_test5 (); */
|
||||
|
||||
/* Test string arrays */
|
||||
array_test1 ();
|
||||
|
Loading…
Reference in New Issue
Block a user