+ if (f && !c) {
+ /* User requested "auto-count", must be last format. */
+ if (formats[format_idx + 1]) {
+ sr_err("Auto column count must be last format field.");
+ g_strfreev(formats);
+ return SR_ERR_ARG;
+ }
+ auto_column_count = inc->column_seen_count - column_count;
+ c = auto_column_count;
+ }
+ column_count += c;
+ bit_count += c * b;
+ }
+ sr_dbg("Column format %s -> %zu columns, %zu logic channels.",
+ column_format, column_count, bit_count);
+
+ /* Allocate and fill in "column processing" details. Create channels. */
+ inc->column_want_count = column_count;
+ if (inc->column_seen_count < inc->column_want_count) {
+ sr_err("Insufficient input text width for desired data amount, got %zu but want %zu columns.",
+ inc->column_seen_count, inc->column_want_count);
+ g_strfreev(formats);
+ return SR_ERR_ARG;
+ }
+ inc->column_details = g_malloc0_n(column_count, sizeof(inc->column_details[0]));
+ column_idx = channel_idx = 0;
+ channel_name = g_string_sized_new(64);
+ for (format_idx = 0; format_idx < format_count; format_idx++) {
+ /* Process a format field, which can span multiple columns. */
+ format = formats[format_idx];
+ (void)split_column_format(format, &c, &f, &b);
+ if (f && !c)
+ c = auto_column_count;
+ while (c-- > 0) {
+ /* Fill in a column's processing details. */
+ detail = &inc->column_details[column_idx++];
+ detail->col_nr = column_idx;
+ detail->text_format = f;
+ if (detail->text_format) {
+ detail->channel_offset = channel_idx;
+ detail->channel_count = b;
+ channel_idx += b;
+ }
+ sr_dbg("detail -> col %zu, fmt %s, ch off/cnt %zu/%zu",
+ detail->col_nr, col_format_text[detail->text_format],
+ detail->channel_offset, detail->channel_count);
+ if (!detail->text_format)
+ continue;
+ /*
+ * Create channels with appropriate names. Optionally
+ * use text from a header line (when requested by the
+ * user). In the absence of header text, channels are
+ * assigned rather generic names.
+ *
+ * Manipulation of the column's caption (when a header
+ * line is seen) is acceptable, because this header
+ * line won't get processed another time.
+ */
+ column = column_texts[detail->col_nr - 1];
+ if (inc->use_header && column && *column)
+ caption = sr_scpi_unquote_string(column);
+ else
+ caption = NULL;
+ if (!caption || !*caption)
+ caption = NULL;
+ for (create_idx = 0; create_idx < detail->channel_count; create_idx++) {
+ if (caption && detail->channel_count == 1) {
+ g_string_assign(channel_name, caption);
+ } else if (caption) {
+ g_string_printf(channel_name, "%s[%zu]",
+ caption, create_idx);
+ } else {
+ g_string_printf(channel_name, "%zu",
+ detail->channel_offset + create_idx);
+ }
+ sr_channel_new(in->sdi, detail->channel_offset + create_idx,
+ SR_CHANNEL_LOGIC, TRUE, channel_name->str);
+ }