]> sigrok.org Git - libsigrok.git/commitdiff
input/csv: add channel list checks for file re-read
authorGerhard Sittig <redacted>
Sun, 28 Oct 2018 07:51:27 +0000 (08:51 +0100)
committerGerhard Sittig <redacted>
Sat, 21 Dec 2019 17:20:04 +0000 (18:20 +0100)
Do for the CSV input module what commit 08f8421a9e82 did for VCD. Check
the channel list for consistency across re-imports of the same file.
This addresses the CSV part of bug #1241.

src/input/csv.c

index 2fa6704dc206d623b1bbb99de065a1395649cb35..2fffc50394fb6b39765f45561160b686f90c8d75 100644 (file)
@@ -167,6 +167,9 @@ struct context {
 
        /* Current line number. */
        size_t line_number;
+
+       /* List of previously created sigrok channels. */
+       GSList *prev_sr_channels;
 };
 
 static void strip_comment(char *buf, const GString *prefix)
@@ -504,6 +507,44 @@ static int init(struct sr_input *in, GHashTable *options)
        return SR_OK;
 }
 
+/*
+ * Check the channel list for consistency across file re-import. See
+ * the VCD input module for more details and motivation.
+ */
+
+static void keep_header_for_reread(const struct sr_input *in)
+{
+       struct context *inc;
+
+       inc = in->priv;
+       g_slist_free_full(inc->prev_sr_channels, sr_channel_free_cb);
+       inc->prev_sr_channels = in->sdi->channels;
+       in->sdi->channels = NULL;
+}
+
+static int check_header_in_reread(const struct sr_input *in)
+{
+       struct context *inc;
+
+       if (!in)
+               return FALSE;
+       inc = in->priv;
+       if (!inc)
+               return FALSE;
+       if (!inc->prev_sr_channels)
+               return TRUE;
+
+       if (sr_channel_lists_differ(inc->prev_sr_channels, in->sdi->channels)) {
+               sr_err("Channel list change not supported for file re-read.");
+               return FALSE;
+       }
+       g_slist_free_full(in->sdi->channels, sr_channel_free_cb);
+       in->sdi->channels = inc->prev_sr_channels;
+       inc->prev_sr_channels = NULL;
+
+       return TRUE;
+}
+
 static const char *delim_set = "\r\n";
 
 static const char *get_line_termination(GString *buf)
@@ -615,6 +656,10 @@ static int initial_parse(const struct sr_input *in, GString *buf)
                sr_channel_new(in->sdi, i, SR_CHANNEL_LOGIC, TRUE, channel_name->str);
        }
        g_string_free(channel_name, TRUE);
+       if (!check_header_in_reread(in)) {
+               ret = SR_ERR_DATA;
+               goto out;
+       }
 
        /*
         * Calculate the minimum buffer size to store the set of samples
@@ -887,6 +932,8 @@ static void cleanup(struct sr_input *in)
 {
        struct context *inc;
 
+       keep_header_for_reread(in);
+
        inc = in->priv;
 
        g_free(inc->termination);