// SPDX-License-Identifier: GPL-2.0+

#include <avm/enh/semi_seq.h>

#include <linux/module.h>

struct seq_file *sseq_create(struct semi_seq *sseq, const char *lvl, char *buf,
			     size_t size)
{
	memset(sseq, 0, sizeof(*sseq));
	memset(buf, 0, size);

	sseq->file.size = size;
	sseq->file.buf = buf;
	sseq->lvl = lvl;

	// We use this as marker in seq_flush
	sseq->file.private = &sseq_create;

	return &sseq->file;
}
EXPORT_SYMBOL(sseq_create);

void sseq_flush(struct seq_file *seq)
{
	char *nl;
	struct semi_seq *sseq;

	// Not a semi seq_file, so simply return
	if (seq->private != &sseq_create)
		return;

	sseq = container_of(seq, struct semi_seq, file);

	for (;;) {
		size_t consumed;

		nl = memchr(seq->buf, '\n', seq->count);
		if (!nl)
			break;

		// Make this a terminated string and print it
		*nl = '\0';
		printk("%s%s\n", sseq->lvl, seq->buf);

		// Move the string forward
		consumed = nl - seq->buf + 1;

		seq->count -= consumed;
		memmove(seq->buf, seq->buf + consumed, seq->count);
	}
}
EXPORT_SYMBOL(sseq_flush);