configure the scanner the same way GimpConfig did (scanner->user_data is,

2002-05-31  Michael Natterer  <mitch@gimp.org>

	* app/config/gimpscanner.[ch]: configure the scanner the same
	way GimpConfig did (scanner->user_data is, if set, a GError).
	Added gimp_scanner_parse_color(). Added "GError **error" to
	gimp_scanner_new().

	* app/config/gimpconfig.c: use gimp_scanner_new().

	* app/config/gimpconfig-deserialize.c: use gimp_scanner_parse_color().

	* app/core/gimpunits.c
	* app/plug-in/plug-in-rc.c: changed accordingly.

	* app/plug-in/plug-in-rc.c: made the main parse loops consistent
	with the other places using GScanner.
This commit is contained in:
Michael Natterer 2002-05-31 13:58:18 +00:00 committed by Michael Natterer
parent 25b9554bc0
commit c6948e6e95
12 changed files with 433 additions and 364 deletions

View file

@ -1,3 +1,20 @@
2002-05-31 Michael Natterer <mitch@gimp.org>
* app/config/gimpscanner.[ch]: configure the scanner the same
way GimpConfig did (scanner->user_data is, if set, a GError).
Added gimp_scanner_parse_color(). Added "GError **error" to
gimp_scanner_new().
* app/config/gimpconfig.c: use gimp_scanner_new().
* app/config/gimpconfig-deserialize.c: use gimp_scanner_parse_color().
* app/core/gimpunits.c
* app/plug-in/plug-in-rc.c: changed accordingly.
* app/plug-in/plug-in-rc.c: made the main parse loops consistent
with the other places using GScanner.
2002-05-31 Maurits Rijk <lpeek.mrijk@consunet.nl>
* plug-ins/common/checkerboard.c: applied patch from Jeroen Lamain

View file

@ -505,119 +505,19 @@ gimp_config_deserialize_path (GValue *value,
return G_TOKEN_RIGHT_PAREN;
}
enum
{
COLOR_RGB = 1,
COLOR_RGBA,
COLOR_HSV,
COLOR_HSVA
};
static GTokenType
gimp_config_deserialize_color (GValue *value,
GParamSpec *prop_spec,
GScanner *scanner)
{
guint scope_id;
guint old_scope_id;
GTokenType token;
GimpRGB color;
scope_id = g_quark_from_static_string ("gimp_config_deserialize_color");
old_scope_id = g_scanner_set_scope (scanner, scope_id);
if (! gimp_scanner_parse_color (scanner, &color))
return G_TOKEN_NONE;
if (! g_scanner_scope_lookup_symbol (scanner, scope_id, "color-rgb"))
{
g_scanner_scope_add_symbol (scanner, scope_id,
"color-rgb", GINT_TO_POINTER (COLOR_RGB));
g_scanner_scope_add_symbol (scanner, scope_id,
"color-rgba", GINT_TO_POINTER (COLOR_RGBA));
g_scanner_scope_add_symbol (scanner, scope_id,
"color-hsv", GINT_TO_POINTER (COLOR_HSV));
g_scanner_scope_add_symbol (scanner, scope_id,
"color-hsva", GINT_TO_POINTER (COLOR_HSVA));
}
g_value_set_boxed (value, &color);
token = G_TOKEN_LEFT_PAREN;
while (g_scanner_peek_next_token (scanner) == token)
{
token = g_scanner_get_next_token (scanner);
switch (token)
{
case G_TOKEN_LEFT_PAREN:
token = G_TOKEN_SYMBOL;
break;
case G_TOKEN_SYMBOL:
{
gdouble col[4] = { 0.0, 0.0, 0.0, 1.0 };
GimpRGB color;
gint n_channels = 4;
gboolean is_hsv = FALSE;
gint i;
switch (GPOINTER_TO_INT (scanner->value.v_symbol))
{
case COLOR_RGB:
n_channels = 3;
/* fallthrough */
case COLOR_RGBA:
break;
case COLOR_HSV:
n_channels = 3;
/* fallthrough */
case COLOR_HSVA:
is_hsv = TRUE;
break;
}
token = G_TOKEN_FLOAT;
for (i = 0; i < n_channels; i++)
{
if (g_scanner_peek_next_token (scanner) != token)
goto finish;
token = g_scanner_get_next_token (scanner);
col[i] = scanner->value.v_float;
}
if (is_hsv)
{
GimpHSV hsv;
gimp_hsva_set (&hsv, col[0], col[1], col[2], col[3]);
gimp_hsv_clamp (&hsv);
gimp_hsv_to_rgb (&hsv, &color);
}
else
{
gimp_rgba_set (&color, col[0], col[1], col[2], col[3]);
gimp_rgb_clamp (&color);
}
g_value_set_boxed (value, &color);
}
token = G_TOKEN_RIGHT_PAREN;
break;
case G_TOKEN_RIGHT_PAREN:
goto finish;
default: /* do nothing */
break;
}
}
finish:
g_scanner_set_scope (scanner, old_scope_id);
return token;
return G_TOKEN_RIGHT_PAREN;
}
static GTokenType
@ -635,12 +535,9 @@ gimp_config_deserialize_value_array (GValue *value,
array_spec = G_PARAM_SPEC_VALUE_ARRAY (prop_spec);
if (g_scanner_peek_next_token (scanner) != G_TOKEN_INT)
if (! gimp_scanner_parse_int (scanner, &n_values))
return G_TOKEN_INT;
g_scanner_get_next_token (scanner);
n_values = scanner->value.v_int;
array = g_value_array_new (n_values);
for (i = 0; i < n_values; i++)

View file

@ -33,10 +33,13 @@
#include <glib-object.h>
#include "libgimpcolor/gimpcolor.h"
#include "gimpconfig.h"
#include "gimpconfig-serialize.h"
#include "gimpconfig-deserialize.h"
#include "gimpconfig-utils.h"
#include "gimpscanner.h"
#include "libgimp/gimpintl.h"
@ -58,9 +61,6 @@ static gboolean gimp_config_iface_deserialize (GObject *object,
static GObject *gimp_config_iface_duplicate (GObject *object);
static gboolean gimp_config_iface_equal (GObject *a,
GObject *b);
static void gimp_config_scanner_message (GScanner *scanner,
gchar *message,
gboolean is_error);
GType
@ -293,7 +293,6 @@ gimp_config_deserialize (GObject *object,
GError **error)
{
GimpConfigInterface *gimp_config_iface;
gint fd;
GScanner *scanner;
gboolean success;
@ -305,36 +304,14 @@ gimp_config_deserialize (GObject *object,
g_return_val_if_fail (gimp_config_iface != NULL, FALSE);
fd = open (filename, O_RDONLY);
scanner = gimp_scanner_new (filename, error);
if (fd == -1)
{
g_set_error (error,
GIMP_CONFIG_ERROR,
(errno == ENOENT ?
GIMP_CONFIG_ERROR_OPEN_ENOENT : GIMP_CONFIG_ERROR_OPEN),
_("Failed to open file: '%s': %s"),
filename, g_strerror (errno));
return FALSE;
}
scanner = g_scanner_new (NULL);
g_scanner_input_file (scanner, fd);
scanner->user_data = error;
scanner->msg_handler = gimp_config_scanner_message;
scanner->input_name = filename;
scanner->config->cset_identifier_first = ( G_CSET_a_2_z G_CSET_A_2_Z );
scanner->config->cset_identifier_nth = ( G_CSET_a_2_z G_CSET_A_2_Z "-_" );
scanner->config->scan_identifier_1char = TRUE;
if (! scanner)
return FALSE;
success = gimp_config_iface->deserialize (object, scanner, 0, data);
g_scanner_destroy (scanner);
close (fd);
gimp_scanner_destroy (scanner);
if (! success)
g_assert (error == NULL || *error != NULL);
@ -404,22 +381,6 @@ gimp_config_string_indent (GString *string,
g_string_append_len (string, " ", 4);
}
static void
gimp_config_scanner_message (GScanner *scanner,
gchar *message,
gboolean is_error)
{
GError **error = scanner->user_data;
/* we don't expect warnings */
g_return_if_fail (is_error);
g_set_error (error,
GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_PARSE,
_("Error while parsing '%s' in line %d:\n%s"),
scanner->input_name, scanner->line, message);
}
/**
* gimp_config_duplicate:
* @object: a #GObject that implements the #GimpConfigInterface.

View file

@ -22,6 +22,7 @@
#include "config.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#ifdef HAVE_UNISTD_H
@ -35,13 +36,26 @@
#include <io.h>
#endif
#include "libgimpcolor/gimpcolor.h"
#include "gimpconfig.h"
#include "gimpscanner.h"
#include "libgimp/gimpintl.h"
/* local function prototypes */
static void gimp_scanner_message (GScanner *scanner,
gchar *message,
gboolean is_error);
/* public functions */
GScanner *
gimp_scanner_new (const gchar *filename)
gimp_scanner_new (const gchar *filename,
GError **error)
{
gint fd;
GScanner *scanner;
@ -51,15 +65,28 @@ gimp_scanner_new (const gchar *filename)
fd = open (filename, O_RDONLY);
if (fd == -1)
return NULL;
{
g_set_error (error,
GIMP_CONFIG_ERROR,
(errno == ENOENT ?
GIMP_CONFIG_ERROR_OPEN_ENOENT : GIMP_CONFIG_ERROR_OPEN),
_("Failed to open file: '%s': %s"),
filename, g_strerror (errno));
return NULL;
}
scanner = g_scanner_new (NULL);
scanner->config->cset_identifier_first = ( G_CSET_a_2_z );
scanner->config->cset_identifier_nth = ( G_CSET_a_2_z "-_" );
g_scanner_input_file (scanner, fd);
scanner->input_name = g_strdup (filename);
scanner->user_data = error;
scanner->msg_handler = gimp_scanner_message;
scanner->input_name = g_strdup (filename);
scanner->config->cset_identifier_first = ( G_CSET_a_2_z G_CSET_A_2_Z );
scanner->config->cset_identifier_nth = ( G_CSET_a_2_z G_CSET_A_2_Z "-_" );
scanner->config->scan_identifier_1char = TRUE;
return scanner;
}
@ -167,3 +194,139 @@ gimp_scanner_parse_float (GScanner *scanner,
return TRUE;
}
enum
{
COLOR_RGB = 1,
COLOR_RGBA,
COLOR_HSV,
COLOR_HSVA
};
gboolean
gimp_scanner_parse_color (GScanner *scanner,
GimpRGB *dest)
{
guint scope_id;
guint old_scope_id;
GTokenType token;
scope_id = g_quark_from_static_string ("gimp_scanner_parse_color");
old_scope_id = g_scanner_set_scope (scanner, scope_id);
if (! g_scanner_scope_lookup_symbol (scanner, scope_id, "color-rgb"))
{
g_scanner_scope_add_symbol (scanner, scope_id,
"color-rgb", GINT_TO_POINTER (COLOR_RGB));
g_scanner_scope_add_symbol (scanner, scope_id,
"color-rgba", GINT_TO_POINTER (COLOR_RGBA));
g_scanner_scope_add_symbol (scanner, scope_id,
"color-hsv", GINT_TO_POINTER (COLOR_HSV));
g_scanner_scope_add_symbol (scanner, scope_id,
"color-hsva", GINT_TO_POINTER (COLOR_HSVA));
}
token = G_TOKEN_LEFT_PAREN;
while (g_scanner_peek_next_token (scanner) == token)
{
token = g_scanner_get_next_token (scanner);
switch (token)
{
case G_TOKEN_LEFT_PAREN:
token = G_TOKEN_SYMBOL;
break;
case G_TOKEN_SYMBOL:
{
gdouble col[4] = { 0.0, 0.0, 0.0, 1.0 };
GimpRGB color;
gint n_channels = 4;
gboolean is_hsv = FALSE;
gint i;
switch (GPOINTER_TO_INT (scanner->value.v_symbol))
{
case COLOR_RGB:
n_channels = 3;
/* fallthrough */
case COLOR_RGBA:
break;
case COLOR_HSV:
n_channels = 3;
/* fallthrough */
case COLOR_HSVA:
is_hsv = TRUE;
break;
}
token = G_TOKEN_FLOAT;
for (i = 0; i < n_channels; i++)
{
if (! gimp_scanner_parse_float (scanner, &col[i]))
goto finish;
}
if (is_hsv)
{
GimpHSV hsv;
gimp_hsva_set (&hsv, col[0], col[1], col[2], col[3]);
gimp_hsv_clamp (&hsv);
gimp_hsv_to_rgb (&hsv, &color);
}
else
{
gimp_rgba_set (&color, col[0], col[1], col[2], col[3]);
gimp_rgb_clamp (&color);
}
*dest = color;
}
token = G_TOKEN_RIGHT_PAREN;
break;
case G_TOKEN_RIGHT_PAREN:
goto finish;
default: /* do nothing */
break;
}
}
finish:
if (token != G_TOKEN_RIGHT_PAREN)
{
g_scanner_get_next_token (scanner);
g_scanner_unexp_token (scanner, token, NULL, NULL, NULL,
_("fatal parse error"), TRUE);
}
g_scanner_set_scope (scanner, old_scope_id);
return (token == G_TOKEN_RIGHT_PAREN);
}
/* private functions */
static void
gimp_scanner_message (GScanner *scanner,
gchar *message,
gboolean is_error)
{
GError **error = scanner->user_data;
/* we don't expect warnings */
g_return_if_fail (is_error);
g_set_error (error,
GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_PARSE,
_("Error while parsing '%s' in line %d:\n%s"),
scanner->input_name, scanner->line, message);
}

View file

@ -24,21 +24,24 @@
#define __GIMP_SCANNER_H__
GScanner * gimp_scanner_new (const gchar *filename);
void gimp_scanner_destroy (GScanner *scanner);
GScanner * gimp_scanner_new (const gchar *filename,
GError **error);
void gimp_scanner_destroy (GScanner *scanner);
gboolean gimp_scanner_parse_token (GScanner *scanner,
GTokenType token);
gboolean gimp_scanner_parse_identifier (GScanner *scanner,
const gchar *identifier);
gboolean gimp_scanner_parse_string (GScanner *scanner,
gchar **dest);
gboolean gimp_scanner_parse_string_no_validate (GScanner *scanner,
gchar **dest);
gboolean gimp_scanner_parse_int (GScanner *scanner,
gint *dest);
gboolean gimp_scanner_parse_float (GScanner *scanner,
gdouble *dest);
gboolean gimp_scanner_parse_token (GScanner *scanner,
GTokenType token);
gboolean gimp_scanner_parse_identifier (GScanner *scanner,
const gchar *identifier);
gboolean gimp_scanner_parse_string (GScanner *scanner,
gchar **dest);
gboolean gimp_scanner_parse_string_no_validate (GScanner *scanner,
gchar **dest);
gboolean gimp_scanner_parse_int (GScanner *scanner,
gint *dest);
gboolean gimp_scanner_parse_float (GScanner *scanner,
gdouble *dest);
gboolean gimp_scanner_parse_color (GScanner *scanner,
GimpRGB *dest);
#endif /* __GIMP_SCANNER_H__ */

View file

@ -93,11 +93,12 @@ gimp_unitrc_load (Gimp *gimp)
gchar *filename;
GScanner *scanner;
GTokenType token;
GError *error = NULL;
g_return_if_fail (GIMP_IS_GIMP (gimp));
filename = gimp_personal_rc_file ("unitrc");
scanner = gimp_scanner_new (filename);
scanner = gimp_scanner_new (filename, &error);
g_free (filename);
if (! scanner)
@ -156,6 +157,9 @@ gimp_unitrc_load (Gimp *gimp)
g_scanner_unexp_token (scanner, token, NULL, NULL,
scanner->scope_id == 0 ? "unit-info" : NULL,
_("fatal parse error"), TRUE);
g_message (error->message);
g_clear_error (&error);
}
gimp_scanner_destroy (scanner);

View file

@ -93,11 +93,12 @@ gimp_unitrc_load (Gimp *gimp)
gchar *filename;
GScanner *scanner;
GTokenType token;
GError *error = NULL;
g_return_if_fail (GIMP_IS_GIMP (gimp));
filename = gimp_personal_rc_file ("unitrc");
scanner = gimp_scanner_new (filename);
scanner = gimp_scanner_new (filename, &error);
g_free (filename);
if (! scanner)
@ -156,6 +157,9 @@ gimp_unitrc_load (Gimp *gimp)
g_scanner_unexp_token (scanner, token, NULL, NULL,
scanner->scope_id == 0 ? "unit-info" : NULL,
_("fatal parse error"), TRUE);
g_message (error->message);
g_clear_error (&error);
}
gimp_scanner_destroy (scanner);

View file

@ -72,10 +72,11 @@ plug_in_rc_parse (const gchar *filename)
{
GScanner *scanner;
GTokenType token;
GError *error = NULL;
g_return_val_if_fail (filename != NULL, FALSE);
scanner = gimp_scanner_new (filename);
scanner = gimp_scanner_new (filename, &error);
if (! scanner)
return TRUE;
@ -95,11 +96,8 @@ plug_in_rc_parse (const gchar *filename)
token = G_TOKEN_LEFT_PAREN;
do
while (g_scanner_peek_next_token (scanner) == token)
{
if (g_scanner_get_next_token (scanner) != token)
break;
token = g_scanner_get_next_token (scanner);
switch (token)
@ -125,13 +123,15 @@ plug_in_rc_parse (const gchar *filename)
break;
}
}
while (token != G_TOKEN_EOF);
if (token != G_TOKEN_LEFT_PAREN)
{
g_scanner_get_next_token (scanner);
g_scanner_unexp_token (scanner, token, NULL, NULL, NULL,
_("fatal parse error"), TRUE);
g_message (error->message);
g_clear_error (&error);
}
gimp_scanner_destroy (scanner);
@ -161,11 +161,8 @@ plug_in_def_deserialize (GScanner *scanner)
token = G_TOKEN_LEFT_PAREN;
do
while (g_scanner_peek_next_token (scanner) == token)
{
if (g_scanner_peek_next_token (scanner) != token)
break;
token = g_scanner_get_next_token (scanner);
switch (token)
@ -216,7 +213,6 @@ plug_in_def_deserialize (GScanner *scanner)
break;
}
}
while (token != G_TOKEN_EOF);
if (token == G_TOKEN_LEFT_PAREN)
{

View file

@ -505,119 +505,19 @@ gimp_config_deserialize_path (GValue *value,
return G_TOKEN_RIGHT_PAREN;
}
enum
{
COLOR_RGB = 1,
COLOR_RGBA,
COLOR_HSV,
COLOR_HSVA
};
static GTokenType
gimp_config_deserialize_color (GValue *value,
GParamSpec *prop_spec,
GScanner *scanner)
{
guint scope_id;
guint old_scope_id;
GTokenType token;
GimpRGB color;
scope_id = g_quark_from_static_string ("gimp_config_deserialize_color");
old_scope_id = g_scanner_set_scope (scanner, scope_id);
if (! gimp_scanner_parse_color (scanner, &color))
return G_TOKEN_NONE;
if (! g_scanner_scope_lookup_symbol (scanner, scope_id, "color-rgb"))
{
g_scanner_scope_add_symbol (scanner, scope_id,
"color-rgb", GINT_TO_POINTER (COLOR_RGB));
g_scanner_scope_add_symbol (scanner, scope_id,
"color-rgba", GINT_TO_POINTER (COLOR_RGBA));
g_scanner_scope_add_symbol (scanner, scope_id,
"color-hsv", GINT_TO_POINTER (COLOR_HSV));
g_scanner_scope_add_symbol (scanner, scope_id,
"color-hsva", GINT_TO_POINTER (COLOR_HSVA));
}
g_value_set_boxed (value, &color);
token = G_TOKEN_LEFT_PAREN;
while (g_scanner_peek_next_token (scanner) == token)
{
token = g_scanner_get_next_token (scanner);
switch (token)
{
case G_TOKEN_LEFT_PAREN:
token = G_TOKEN_SYMBOL;
break;
case G_TOKEN_SYMBOL:
{
gdouble col[4] = { 0.0, 0.0, 0.0, 1.0 };
GimpRGB color;
gint n_channels = 4;
gboolean is_hsv = FALSE;
gint i;
switch (GPOINTER_TO_INT (scanner->value.v_symbol))
{
case COLOR_RGB:
n_channels = 3;
/* fallthrough */
case COLOR_RGBA:
break;
case COLOR_HSV:
n_channels = 3;
/* fallthrough */
case COLOR_HSVA:
is_hsv = TRUE;
break;
}
token = G_TOKEN_FLOAT;
for (i = 0; i < n_channels; i++)
{
if (g_scanner_peek_next_token (scanner) != token)
goto finish;
token = g_scanner_get_next_token (scanner);
col[i] = scanner->value.v_float;
}
if (is_hsv)
{
GimpHSV hsv;
gimp_hsva_set (&hsv, col[0], col[1], col[2], col[3]);
gimp_hsv_clamp (&hsv);
gimp_hsv_to_rgb (&hsv, &color);
}
else
{
gimp_rgba_set (&color, col[0], col[1], col[2], col[3]);
gimp_rgb_clamp (&color);
}
g_value_set_boxed (value, &color);
}
token = G_TOKEN_RIGHT_PAREN;
break;
case G_TOKEN_RIGHT_PAREN:
goto finish;
default: /* do nothing */
break;
}
}
finish:
g_scanner_set_scope (scanner, old_scope_id);
return token;
return G_TOKEN_RIGHT_PAREN;
}
static GTokenType
@ -635,12 +535,9 @@ gimp_config_deserialize_value_array (GValue *value,
array_spec = G_PARAM_SPEC_VALUE_ARRAY (prop_spec);
if (g_scanner_peek_next_token (scanner) != G_TOKEN_INT)
if (! gimp_scanner_parse_int (scanner, &n_values))
return G_TOKEN_INT;
g_scanner_get_next_token (scanner);
n_values = scanner->value.v_int;
array = g_value_array_new (n_values);
for (i = 0; i < n_values; i++)

View file

@ -33,10 +33,13 @@
#include <glib-object.h>
#include "libgimpcolor/gimpcolor.h"
#include "gimpconfig.h"
#include "gimpconfig-serialize.h"
#include "gimpconfig-deserialize.h"
#include "gimpconfig-utils.h"
#include "gimpscanner.h"
#include "libgimp/gimpintl.h"
@ -58,9 +61,6 @@ static gboolean gimp_config_iface_deserialize (GObject *object,
static GObject *gimp_config_iface_duplicate (GObject *object);
static gboolean gimp_config_iface_equal (GObject *a,
GObject *b);
static void gimp_config_scanner_message (GScanner *scanner,
gchar *message,
gboolean is_error);
GType
@ -293,7 +293,6 @@ gimp_config_deserialize (GObject *object,
GError **error)
{
GimpConfigInterface *gimp_config_iface;
gint fd;
GScanner *scanner;
gboolean success;
@ -305,36 +304,14 @@ gimp_config_deserialize (GObject *object,
g_return_val_if_fail (gimp_config_iface != NULL, FALSE);
fd = open (filename, O_RDONLY);
scanner = gimp_scanner_new (filename, error);
if (fd == -1)
{
g_set_error (error,
GIMP_CONFIG_ERROR,
(errno == ENOENT ?
GIMP_CONFIG_ERROR_OPEN_ENOENT : GIMP_CONFIG_ERROR_OPEN),
_("Failed to open file: '%s': %s"),
filename, g_strerror (errno));
return FALSE;
}
scanner = g_scanner_new (NULL);
g_scanner_input_file (scanner, fd);
scanner->user_data = error;
scanner->msg_handler = gimp_config_scanner_message;
scanner->input_name = filename;
scanner->config->cset_identifier_first = ( G_CSET_a_2_z G_CSET_A_2_Z );
scanner->config->cset_identifier_nth = ( G_CSET_a_2_z G_CSET_A_2_Z "-_" );
scanner->config->scan_identifier_1char = TRUE;
if (! scanner)
return FALSE;
success = gimp_config_iface->deserialize (object, scanner, 0, data);
g_scanner_destroy (scanner);
close (fd);
gimp_scanner_destroy (scanner);
if (! success)
g_assert (error == NULL || *error != NULL);
@ -404,22 +381,6 @@ gimp_config_string_indent (GString *string,
g_string_append_len (string, " ", 4);
}
static void
gimp_config_scanner_message (GScanner *scanner,
gchar *message,
gboolean is_error)
{
GError **error = scanner->user_data;
/* we don't expect warnings */
g_return_if_fail (is_error);
g_set_error (error,
GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_PARSE,
_("Error while parsing '%s' in line %d:\n%s"),
scanner->input_name, scanner->line, message);
}
/**
* gimp_config_duplicate:
* @object: a #GObject that implements the #GimpConfigInterface.

View file

@ -22,6 +22,7 @@
#include "config.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#ifdef HAVE_UNISTD_H
@ -35,13 +36,26 @@
#include <io.h>
#endif
#include "libgimpcolor/gimpcolor.h"
#include "gimpconfig.h"
#include "gimpscanner.h"
#include "libgimp/gimpintl.h"
/* local function prototypes */
static void gimp_scanner_message (GScanner *scanner,
gchar *message,
gboolean is_error);
/* public functions */
GScanner *
gimp_scanner_new (const gchar *filename)
gimp_scanner_new (const gchar *filename,
GError **error)
{
gint fd;
GScanner *scanner;
@ -51,15 +65,28 @@ gimp_scanner_new (const gchar *filename)
fd = open (filename, O_RDONLY);
if (fd == -1)
return NULL;
{
g_set_error (error,
GIMP_CONFIG_ERROR,
(errno == ENOENT ?
GIMP_CONFIG_ERROR_OPEN_ENOENT : GIMP_CONFIG_ERROR_OPEN),
_("Failed to open file: '%s': %s"),
filename, g_strerror (errno));
return NULL;
}
scanner = g_scanner_new (NULL);
scanner->config->cset_identifier_first = ( G_CSET_a_2_z );
scanner->config->cset_identifier_nth = ( G_CSET_a_2_z "-_" );
g_scanner_input_file (scanner, fd);
scanner->input_name = g_strdup (filename);
scanner->user_data = error;
scanner->msg_handler = gimp_scanner_message;
scanner->input_name = g_strdup (filename);
scanner->config->cset_identifier_first = ( G_CSET_a_2_z G_CSET_A_2_Z );
scanner->config->cset_identifier_nth = ( G_CSET_a_2_z G_CSET_A_2_Z "-_" );
scanner->config->scan_identifier_1char = TRUE;
return scanner;
}
@ -167,3 +194,139 @@ gimp_scanner_parse_float (GScanner *scanner,
return TRUE;
}
enum
{
COLOR_RGB = 1,
COLOR_RGBA,
COLOR_HSV,
COLOR_HSVA
};
gboolean
gimp_scanner_parse_color (GScanner *scanner,
GimpRGB *dest)
{
guint scope_id;
guint old_scope_id;
GTokenType token;
scope_id = g_quark_from_static_string ("gimp_scanner_parse_color");
old_scope_id = g_scanner_set_scope (scanner, scope_id);
if (! g_scanner_scope_lookup_symbol (scanner, scope_id, "color-rgb"))
{
g_scanner_scope_add_symbol (scanner, scope_id,
"color-rgb", GINT_TO_POINTER (COLOR_RGB));
g_scanner_scope_add_symbol (scanner, scope_id,
"color-rgba", GINT_TO_POINTER (COLOR_RGBA));
g_scanner_scope_add_symbol (scanner, scope_id,
"color-hsv", GINT_TO_POINTER (COLOR_HSV));
g_scanner_scope_add_symbol (scanner, scope_id,
"color-hsva", GINT_TO_POINTER (COLOR_HSVA));
}
token = G_TOKEN_LEFT_PAREN;
while (g_scanner_peek_next_token (scanner) == token)
{
token = g_scanner_get_next_token (scanner);
switch (token)
{
case G_TOKEN_LEFT_PAREN:
token = G_TOKEN_SYMBOL;
break;
case G_TOKEN_SYMBOL:
{
gdouble col[4] = { 0.0, 0.0, 0.0, 1.0 };
GimpRGB color;
gint n_channels = 4;
gboolean is_hsv = FALSE;
gint i;
switch (GPOINTER_TO_INT (scanner->value.v_symbol))
{
case COLOR_RGB:
n_channels = 3;
/* fallthrough */
case COLOR_RGBA:
break;
case COLOR_HSV:
n_channels = 3;
/* fallthrough */
case COLOR_HSVA:
is_hsv = TRUE;
break;
}
token = G_TOKEN_FLOAT;
for (i = 0; i < n_channels; i++)
{
if (! gimp_scanner_parse_float (scanner, &col[i]))
goto finish;
}
if (is_hsv)
{
GimpHSV hsv;
gimp_hsva_set (&hsv, col[0], col[1], col[2], col[3]);
gimp_hsv_clamp (&hsv);
gimp_hsv_to_rgb (&hsv, &color);
}
else
{
gimp_rgba_set (&color, col[0], col[1], col[2], col[3]);
gimp_rgb_clamp (&color);
}
*dest = color;
}
token = G_TOKEN_RIGHT_PAREN;
break;
case G_TOKEN_RIGHT_PAREN:
goto finish;
default: /* do nothing */
break;
}
}
finish:
if (token != G_TOKEN_RIGHT_PAREN)
{
g_scanner_get_next_token (scanner);
g_scanner_unexp_token (scanner, token, NULL, NULL, NULL,
_("fatal parse error"), TRUE);
}
g_scanner_set_scope (scanner, old_scope_id);
return (token == G_TOKEN_RIGHT_PAREN);
}
/* private functions */
static void
gimp_scanner_message (GScanner *scanner,
gchar *message,
gboolean is_error)
{
GError **error = scanner->user_data;
/* we don't expect warnings */
g_return_if_fail (is_error);
g_set_error (error,
GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_PARSE,
_("Error while parsing '%s' in line %d:\n%s"),
scanner->input_name, scanner->line, message);
}

View file

@ -24,21 +24,24 @@
#define __GIMP_SCANNER_H__
GScanner * gimp_scanner_new (const gchar *filename);
void gimp_scanner_destroy (GScanner *scanner);
GScanner * gimp_scanner_new (const gchar *filename,
GError **error);
void gimp_scanner_destroy (GScanner *scanner);
gboolean gimp_scanner_parse_token (GScanner *scanner,
GTokenType token);
gboolean gimp_scanner_parse_identifier (GScanner *scanner,
const gchar *identifier);
gboolean gimp_scanner_parse_string (GScanner *scanner,
gchar **dest);
gboolean gimp_scanner_parse_string_no_validate (GScanner *scanner,
gchar **dest);
gboolean gimp_scanner_parse_int (GScanner *scanner,
gint *dest);
gboolean gimp_scanner_parse_float (GScanner *scanner,
gdouble *dest);
gboolean gimp_scanner_parse_token (GScanner *scanner,
GTokenType token);
gboolean gimp_scanner_parse_identifier (GScanner *scanner,
const gchar *identifier);
gboolean gimp_scanner_parse_string (GScanner *scanner,
gchar **dest);
gboolean gimp_scanner_parse_string_no_validate (GScanner *scanner,
gchar **dest);
gboolean gimp_scanner_parse_int (GScanner *scanner,
gint *dest);
gboolean gimp_scanner_parse_float (GScanner *scanner,
gdouble *dest);
gboolean gimp_scanner_parse_color (GScanner *scanner,
GimpRGB *dest);
#endif /* __GIMP_SCANNER_H__ */