Support floating point arguments in goption

This commit is contained in:
Matthias Clasen 2006-03-27 06:57:28 +00:00
parent a205620a88
commit 9749aa87e5
7 changed files with 160 additions and 1 deletions

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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 ();
}

View File

@ -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,

View File

@ -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 ();