struct _glMergeTextPrivate {
- gchar delim;
+ gchar delim;
gboolean line1_has_keys;
enum UnicodeEncoding encoding;
gsize buf_pos;
gsize buf_len;
- FILE *fp;
+ FILE *fp;
GPtrArray *keys;
gint n_fields_max;
};
enum {
- LAST_SIGNAL
+ LAST_SIGNAL
};
enum {
- ARG_0,
- ARG_DELIM,
- ARG_LINE1_HAS_KEYS
+ ARG_0,
+ ARG_DELIM,
+ ARG_LINE1_HAS_KEYS
};
static void gl_merge_text_finalize (GObject *object);
static void gl_merge_text_set_property (GObject *object,
- guint param_id,
- const GValue *value,
- GParamSpec *pspec);
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec);
static void gl_merge_text_get_property (GObject *object,
- guint param_id,
- GValue *value,
- GParamSpec *pspec);
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec);
static gchar *key_from_index (glMergeText *merge_text,
gint i_field);
static void gl_merge_text_close (glMerge *merge);
static glMergeRecord *gl_merge_text_get_record (glMerge *merge);
static void gl_merge_text_copy (glMerge *dst_merge,
- const glMerge *src_merge);
+ const glMerge *src_merge);
static GList *parse_line (glMergeText *merge_text,
- gchar delim);
+ gchar delim);
static void free_fields (GList **fields);
static void
gl_merge_text_class_init (glMergeTextClass *class)
{
- GObjectClass *object_class = G_OBJECT_CLASS (class);
- glMergeClass *merge_class = GL_MERGE_CLASS (class);
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ glMergeClass *merge_class = GL_MERGE_CLASS (class);
- gl_debug (DEBUG_MERGE, "START");
+ gl_debug (DEBUG_MERGE, "START");
- gl_merge_text_parent_class = g_type_class_peek_parent (class);
+ gl_merge_text_parent_class = g_type_class_peek_parent (class);
- object_class->set_property = gl_merge_text_set_property;
- object_class->get_property = gl_merge_text_get_property;
+ object_class->set_property = gl_merge_text_set_property;
+ object_class->get_property = gl_merge_text_get_property;
- g_object_class_install_property
+ g_object_class_install_property
(object_class,
ARG_DELIM,
g_param_spec_char ("delim", NULL, NULL,
- 0, 0x7F, ',',
- (G_PARAM_READABLE | G_PARAM_WRITABLE)));
+ 0, 0x7F, ',',
+ (G_PARAM_READABLE | G_PARAM_WRITABLE)));
- g_object_class_install_property
+ g_object_class_install_property
(object_class,
ARG_LINE1_HAS_KEYS,
g_param_spec_boolean ("line1_has_keys", NULL, NULL,
FALSE,
(G_PARAM_READABLE | G_PARAM_WRITABLE)));
- object_class->finalize = gl_merge_text_finalize;
+ object_class->finalize = gl_merge_text_finalize;
- merge_class->get_key_list = gl_merge_text_get_key_list;
- merge_class->get_primary_key = gl_merge_text_get_primary_key;
- merge_class->open = gl_merge_text_open;
- merge_class->close = gl_merge_text_close;
- merge_class->get_record = gl_merge_text_get_record;
- merge_class->copy = gl_merge_text_copy;
+ merge_class->get_key_list = gl_merge_text_get_key_list;
+ merge_class->get_primary_key = gl_merge_text_get_primary_key;
+ merge_class->open = gl_merge_text_open;
+ merge_class->close = gl_merge_text_close;
+ merge_class->get_record = gl_merge_text_get_record;
+ merge_class->copy = gl_merge_text_copy;
- gl_debug (DEBUG_MERGE, "END");
+ gl_debug (DEBUG_MERGE, "END");
}
static void
gl_merge_text_init (glMergeText *merge_text)
{
- gl_debug (DEBUG_MERGE, "START");
+ gl_debug (DEBUG_MERGE, "START");
- merge_text->priv = g_new0 (glMergeTextPrivate, 1);
+ merge_text->priv = g_new0 (glMergeTextPrivate, 1);
merge_text->priv->keys = g_ptr_array_new ();
- gl_debug (DEBUG_MERGE, "END");
+ gl_debug (DEBUG_MERGE, "END");
}
static void
gl_merge_text_finalize (GObject *object)
{
- glMergeText *merge_text = GL_MERGE_TEXT (object);
+ glMergeText *merge_text = GL_MERGE_TEXT (object);
- gl_debug (DEBUG_MERGE, "START");
+ gl_debug (DEBUG_MERGE, "START");
- g_return_if_fail (object && GL_IS_MERGE_TEXT (object));
+ g_return_if_fail (object && GL_IS_MERGE_TEXT (object));
clear_keys (merge_text);
g_ptr_array_free (merge_text->priv->keys, TRUE);
- g_free (merge_text->priv);
+ g_free (merge_text->priv);
- G_OBJECT_CLASS (gl_merge_text_parent_class)->finalize (object);
+ G_OBJECT_CLASS (gl_merge_text_parent_class)->finalize (object);
- gl_debug (DEBUG_MERGE, "END");
+ gl_debug (DEBUG_MERGE, "END");
}
/*--------------------------------------------------------------------------*/
static void
gl_merge_text_set_property (GObject *object,
- guint param_id,
- const GValue *value,
- GParamSpec *pspec)
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- glMergeText *merge_text;
+ glMergeText *merge_text;
- merge_text = GL_MERGE_TEXT (object);
+ merge_text = GL_MERGE_TEXT (object);
- switch (param_id) {
+ switch (param_id) {
- case ARG_DELIM:
- merge_text->priv->delim = g_value_get_schar (value);
- gl_debug (DEBUG_MERGE, "ARG \"delim\" = \"%c\"",
- merge_text->priv->delim);
- break;
+ case ARG_DELIM:
+ merge_text->priv->delim = g_value_get_schar (value);
+ gl_debug (DEBUG_MERGE, "ARG \"delim\" = \"%c\"",
+ merge_text->priv->delim);
+ break;
case ARG_LINE1_HAS_KEYS:
merge_text->priv->line1_has_keys = g_value_get_boolean (value);
- gl_debug (DEBUG_MERGE, "ARG \"line1_has_keys\" = \"%d\"",
- merge_text->priv->line1_has_keys);
- break;
+ gl_debug (DEBUG_MERGE, "ARG \"line1_has_keys\" = \"%d\"",
+ merge_text->priv->line1_has_keys);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
/*--------------------------------------------------------------------------*/
static void
gl_merge_text_get_property (GObject *object,
- guint param_id,
- GValue *value,
- GParamSpec *pspec)
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- glMergeText *merge_text;
+ glMergeText *merge_text;
- merge_text = GL_MERGE_TEXT (object);
+ merge_text = GL_MERGE_TEXT (object);
- switch (param_id) {
+ switch (param_id) {
- case ARG_DELIM:
- g_value_set_schar (value, merge_text->priv->delim);
- break;
+ case ARG_DELIM:
+ g_value_set_schar (value, merge_text->priv->delim);
+ break;
case ARG_LINE1_HAS_KEYS:
g_value_set_boolean (value, merge_text->priv->line1_has_keys);
static GList *
gl_merge_text_get_key_list (const glMerge *merge)
{
- glMergeText *merge_text;
- gint i_field, n_fields;
- GList *key_list;
-
- gl_debug (DEBUG_MERGE, "BEGIN");
+ glMergeText *merge_text;
+ gint i_field, n_fields;
+ GList *key_list;
+
+ gl_debug (DEBUG_MERGE, "BEGIN");
- merge_text = GL_MERGE_TEXT (merge);
+ merge_text = GL_MERGE_TEXT (merge);
if ( merge_text->priv->line1_has_keys )
{
key_list = g_list_append (key_list, key_from_index(merge_text, i_field));
}
- gl_debug (DEBUG_MERGE, "END");
+ gl_debug (DEBUG_MERGE, "END");
- return key_list;
+ return key_list;
}
static gchar *
gl_merge_text_get_primary_key (const glMerge *merge)
{
- /* For now, let's always assume the first column is the primary key. */
+ /* For now, let's always assume the first column is the primary key. */
return key_from_index (GL_MERGE_TEXT (merge), 0);
}
static void
gl_merge_text_open (glMerge *merge)
{
- glMergeText *merge_text;
- gchar *src;
+ glMergeText *merge_text;
+ gchar *src;
GList *line1_fields;
GList *p;
- merge_text = GL_MERGE_TEXT (merge);
+ merge_text = GL_MERGE_TEXT (merge);
- src = gl_merge_get_src (merge);
+ src = gl_merge_get_src (merge);
- if (src != NULL)
+ if (src != NULL)
{
- if (g_utf8_strlen(src, -1) == 1 && src[0] == '-') {
- merge_text->priv->fp = stdin;
+ if (g_utf8_strlen(src, -1) == 1 && src[0] == '-') {
+ merge_text->priv->fp = stdin;
merge_text->priv->encoding = SYSTEM_ENCODING;
} else {
- if ((merge_text->priv->fp = fopen (src, "r")) != NULL) {
+ if ((merge_text->priv->fp = fopen (src, "r")) != NULL) {
merge_text->priv->encoding = gl_read_encoding(merge_text->priv->fp);
} else {
g_warning("gl_merge_text_open: %s (%s)",
free_fields (&line1_fields);
}
- }
+ }
}
static void
gl_merge_text_close (glMerge *merge)
{
- glMergeText *merge_text;
+ glMergeText *merge_text;
- merge_text = GL_MERGE_TEXT (merge);
+ merge_text = GL_MERGE_TEXT (merge);
- if (merge_text->priv->fp != NULL) {
+ if (merge_text->priv->fp != NULL) {
- fclose (merge_text->priv->fp);
- merge_text->priv->fp = NULL;
+ fclose (merge_text->priv->fp);
+ merge_text->priv->fp = NULL;
- }
+ }
if (merge_text->priv->g_iconverter != 0) {
g_iconv_close(merge_text->priv->g_iconverter);
merge_text->priv->g_iconverter = 0;
static glMergeRecord *
gl_merge_text_get_record (glMerge *merge)
{
- glMergeText *merge_text;
- gchar delim;
- glMergeRecord *record;
- GList *fields, *p;
- gint i_field;
- glMergeField *field;
+ glMergeText *merge_text;
+ gchar delim;
+ glMergeRecord *record;
+ GList *fields, *p;
+ gint i_field;
+ glMergeField *field;
- merge_text = GL_MERGE_TEXT (merge);
+ merge_text = GL_MERGE_TEXT (merge);
- delim = merge_text->priv->delim;
+ delim = merge_text->priv->delim;
- fields = parse_line (merge_text, delim);
- if ( fields == NULL ) {
- return NULL;
- }
+ fields = parse_line (merge_text, delim);
+ if ( fields == NULL ) {
+ return NULL;
+ }
- record = g_new0 (glMergeRecord, 1);
- record->select_flag = TRUE;
- for (p=fields, i_field=0; p != NULL; p=p->next, i_field++) {
+ record = g_new0 (glMergeRecord, 1);
+ record->select_flag = TRUE;
+ for (p=fields, i_field=0; p != NULL; p=p->next, i_field++) {
- field = g_new0 (glMergeField, 1);
+ field = g_new0 (glMergeField, 1);
field->key = key_from_index (merge_text, i_field);
#ifndef CSV_ALWAYS_UTF8
if (merge_text->priv->encoding == SYSTEM_ENCODING) {
field->value = g_strdup (p->data);
}
#else
- field->value = g_strdup (p->data);
+ field->value = g_strdup (p->data);
#endif
- record->field_list = g_list_append (record->field_list, field);
- }
- free_fields (&fields);
+ record->field_list = g_list_append (record->field_list, field);
+ }
+ free_fields (&fields);
if ( i_field > merge_text->priv->n_fields_max )
{
merge_text->priv->n_fields_max = i_field;
}
- return record;
+ return record;
}
/*---------------------------------------------------------------------------*/
static void
gl_merge_text_copy (glMerge *dst_merge,
- const glMerge *src_merge)
+ const glMerge *src_merge)
{
- glMergeText *dst_merge_text;
- glMergeText *src_merge_text;
+ glMergeText *dst_merge_text;
+ glMergeText *src_merge_text;
gint i;
- dst_merge_text = GL_MERGE_TEXT (dst_merge);
- src_merge_text = GL_MERGE_TEXT (src_merge);
+ dst_merge_text = GL_MERGE_TEXT (dst_merge);
+ src_merge_text = GL_MERGE_TEXT (src_merge);
- dst_merge_text->priv->delim = src_merge_text->priv->delim;
- dst_merge_text->priv->line1_has_keys = src_merge_text->priv->line1_has_keys;
+ dst_merge_text->priv->delim = src_merge_text->priv->delim;
+ dst_merge_text->priv->line1_has_keys = src_merge_text->priv->line1_has_keys;
for ( i=0; i < src_merge_text->priv->keys->len; i++ )
{
g_strdup ((gchar *)g_ptr_array_index (src_merge_text->priv->keys, i)));
}
- dst_merge_text->priv->n_fields_max = src_merge_text->priv->n_fields_max;
+ dst_merge_text->priv->n_fields_max = src_merge_text->priv->n_fields_max;
}
/*---------------------------------------------------------------------------*/
static GList *
parse_line (glMergeText* merge_text,
- gchar delim )
+ gchar delim )
{
- GList *list;
- GString *field;
- gint c;
- enum { DELIM,
+ GList *list;
+ GString *field;
+ gint c;
+ enum { DELIM,
QUOTED, QUOTED_QUOTE1, QUOTED_ESCAPED,
SIMPLE, SIMPLE_ESCAPED,
DONE } state;
- if (merge_text->priv->fp == NULL) {
- return NULL;
- }
-
- state = DELIM;
+ if (merge_text->priv->fp == NULL) {
+ return NULL;
+ }
+
+ state = DELIM;
list = NULL;
- field = g_string_new( "" );
- while ( state != DONE ) {
- c=gl_getc (merge_text);
-
- switch (state) {
-
- case DELIM:
- switch (c) {
- case '\n':
- /* last field is empty. */
- list = g_list_append (list, g_strdup (""));
- state = DONE;
- break;
- case '\r':
- /* ignore */
- state = DELIM;
- break;
- case EOF:
+ field = g_string_new( "" );
+ while ( state != DONE ) {
+ c=gl_getc (merge_text);
+
+ switch (state) {
+
+ case DELIM:
+ switch (c) {
+ case '\n':
+ /* last field is empty. */
+ list = g_list_append (list, g_strdup (""));
+ state = DONE;
+ break;
+ case '\r':
+ /* ignore */
+ state = DELIM;
+ break;
+ case EOF:
/* end of file, no more lines. */
- state = DONE;
- break;
- case '"':
+ state = DONE;
+ break;
+ case '"':
/* start a quoted field. */
- state = QUOTED;
- break;
- case '\\':
+ state = QUOTED;
+ break;
+ case '\\':
/* simple field, but 1st character is an escape. */
- state = SIMPLE_ESCAPED;
- break;
- default:
+ state = SIMPLE_ESCAPED;
+ break;
+ default:
if ( c == delim )
{
/* field is empty. */
field = g_string_append_c (field, c);
state = SIMPLE;
}
- break;
- }
- break;
-
- case QUOTED:
- switch (c) {
- case EOF:
- /* File ended mid way through quoted item, truncate field. */
- list = g_list_append (list, g_strdup (field->str));
- state = DONE;
- break;
- case '"':
+ break;
+ }
+ break;
+
+ case QUOTED:
+ switch (c) {
+ case EOF:
+ /* File ended mid way through quoted item, truncate field. */
+ list = g_list_append (list, g_strdup (field->str));
+ state = DONE;
+ break;
+ case '"':
/* Possible end of field, but could be 1st of a pair. */
- state = QUOTED_QUOTE1;
- break;
- case '\\':
+ state = QUOTED_QUOTE1;
+ break;
+ case '\\':
/* Escape next character, or special escape, e.g. \n. */
- state = QUOTED_ESCAPED;
- break;
- default:
+ state = QUOTED_ESCAPED;
+ break;
+ default:
/* Use character literally. */
- field = g_string_append_c (field, c);
- break;
- }
- break;
-
- case QUOTED_QUOTE1:
- switch (c) {
- case '\n':
- case EOF:
- /* line or file ended after quoted item */
- list = g_list_append (list, g_strdup (field->str));
- state = DONE;
- break;
- case '"':
- /* second quote, insert and stay quoted. */
- field = g_string_append_c (field, c);
- state = QUOTED;
- break;
- case '\r':
- /* ignore and go to fallback */
- state = SIMPLE;
- break;
- default:
+ field = g_string_append_c (field, c);
+ break;
+ }
+ break;
+
+ case QUOTED_QUOTE1:
+ switch (c) {
+ case '\n':
+ case EOF:
+ /* line or file ended after quoted item */
+ list = g_list_append (list, g_strdup (field->str));
+ state = DONE;
+ break;
+ case '"':
+ /* second quote, insert and stay quoted. */
+ field = g_string_append_c (field, c);
+ state = QUOTED;
+ break;
+ case '\r':
+ /* ignore and go to fallback */
+ state = SIMPLE;
+ break;
+ default:
if ( c == delim )
{
/* end of field. */
field = g_string_append_c (field, c);
state = SIMPLE;
}
- break;
- }
- break;
-
- case QUOTED_ESCAPED:
- switch (c) {
- case EOF:
- /* File ended mid way through quoted item */
- list = g_list_append (list, g_strdup (field->str));
- state = DONE;
- break;
+ break;
+ }
+ break;
+
+ case QUOTED_ESCAPED:
+ switch (c) {
+ case EOF:
+ /* File ended mid way through quoted item */
+ list = g_list_append (list, g_strdup (field->str));
+ state = DONE;
+ break;
case 'n':
/* Decode "\n" as newline. */
- field = g_string_append_c (field, '\n');
- state = QUOTED;
- break;
+ field = g_string_append_c (field, '\n');
+ state = QUOTED;
+ break;
case 't':
/* Decode "\t" as tab. */
- field = g_string_append_c (field, '\t');
- state = QUOTED;
- break;
- default:
+ field = g_string_append_c (field, '\t');
+ state = QUOTED;
+ break;
+ default:
/* Use character literally. */
- field = g_string_append_c (field, c);
- state = QUOTED;
- break;
- }
- break;
-
- case SIMPLE:
- switch (c) {
- case '\n':
- case EOF:
- /* line or file ended */
- list = g_list_append (list, g_strdup (field->str));
- state = DONE;
- break;
- case '\r':
- /* ignore */
- state = SIMPLE;
- break;
- case '\\':
+ field = g_string_append_c (field, c);
+ state = QUOTED;
+ break;
+ }
+ break;
+
+ case SIMPLE:
+ switch (c) {
+ case '\n':
+ case EOF:
+ /* line or file ended */
+ list = g_list_append (list, g_strdup (field->str));
+ state = DONE;
+ break;
+ case '\r':
+ /* ignore */
+ state = SIMPLE;
+ break;
+ case '\\':
/* Escape next character, or special escape, e.g. \n. */
- state = SIMPLE_ESCAPED;
- break;
- default:
+ state = SIMPLE_ESCAPED;
+ break;
+ default:
if ( c == delim )
{
/* end of field. */
field = g_string_append_c (field, c);
state = SIMPLE;
}
- break;
- }
- break;
-
- case SIMPLE_ESCAPED:
- switch (c) {
- case EOF:
- /* File ended mid way through quoted item */
- list = g_list_append (list, g_strdup (field->str));
- state = DONE;
- break;
+ break;
+ }
+ break;
+
+ case SIMPLE_ESCAPED:
+ switch (c) {
+ case EOF:
+ /* File ended mid way through quoted item */
+ list = g_list_append (list, g_strdup (field->str));
+ state = DONE;
+ break;
case 'n':
/* Decode "\n" as newline. */
- field = g_string_append_c (field, '\n');
- state = SIMPLE;
- break;
+ field = g_string_append_c (field, '\n');
+ state = SIMPLE;
+ break;
case 't':
/* Decode "\t" as tab. */
- field = g_string_append_c (field, '\t');
- state = SIMPLE;
- break;
- default:
+ field = g_string_append_c (field, '\t');
+ state = SIMPLE;
+ break;
+ default:
/* Use character literally. */
- field = g_string_append_c (field, c);
- state = SIMPLE;
- break;
- }
- break;
+ field = g_string_append_c (field, c);
+ state = SIMPLE;
+ break;
+ }
+ break;
- default:
- g_assert_not_reached();
- break;
- }
+ default:
+ g_assert_not_reached();
+ break;
+ }
- }
- g_string_free( field, TRUE );
+ }
+ g_string_free( field, TRUE );
- return list;
+ return list;
}
void
free_fields (GList ** list)
{
- GList *p;
+ GList *p;
- for (p = *list; p != NULL; p = p->next) {
- g_free (p->data);
- p->data = NULL;
- }
+ for ( p = *list; p != NULL; p = p->next )
+ {
+ g_free (p->data);
+ p->data = NULL;
+ }
- g_list_free (*list);
- *list = NULL;
+ g_list_free (*list);
+ *list = NULL;
}