/* This file is part of limb https://lila.oss/limb
* Copyright (C) 2023 Olivier Brunel jjk@jjacky.com */
/* SPDX-License-Identifier: GPL-2.0-only */
#include <ctype.h>
#include <errno.h>
#include <limb/bytestr.h>
#include <limb/copa.h>
int
copa_next(struct copa *ctx)
{
/* not the first line? */
if (ctx->nlen)
/* move to the next line */
ctx->noff += byte_chr(copa_name(ctx), ctx->dlen - ctx->noff, '\n');
/* move past spaces */
while (ctx->noff < ctx->dlen && isspace(ctx->data[ctx->noff]))
++ctx->noff;
/* EOF */
if (ctx->noff == ctx->dlen)
return 0;
/* comments */
if (ctx->data[ctx->noff] == ';' || ctx->data[ctx->noff] == '#')
return (++ctx->nlen, copa_next(ctx));
/* search for end of line */
ctx->nlen = byte_chr(copa_name(ctx), ctx->dlen - ctx->noff, '\n');
/* search for an '=' sign, i.e. a value */
ctx->voff = byte_chr(copa_name(ctx), ctx->nlen, '=');
if (ctx->voff == ctx->nlen) {
/* no value */
ctx->vlen = 0;
/* remove trailing spaces on name */
while (ctx->nlen && isspace(ctx->data[ctx->noff + ctx->nlen - 1]))
--ctx->nlen;
/* section? */
if (ctx->data[ctx->noff] == '[' && ctx->data[ctx->noff + ctx->nlen - 1] == ']') {
++ctx->noff;
ctx->nlen -= 2;
}
/* no section name ("[]") */
if (!ctx->nlen) return (errno = ENODATA, -1);
return 1;
}
/* adjust offsets/lengths */
ctx->vlen = ctx->nlen - ctx->voff - 1;
ctx->nlen = ctx->voff;
ctx->voff += ctx->noff + 1;
/* remove trailing spaces on name */
while (ctx->nlen && isspace(ctx->data[ctx->noff + ctx->nlen - 1]))
--ctx->nlen;
/* nothing before '=' */
if (!ctx->nlen) return (errno = EINVAL, -1);
/* move value past spaces */
while (ctx->vlen && isspace(ctx->data[ctx->voff])) {
++ctx->voff;
--ctx->vlen;
}
/* nothing after '=' */
if (!ctx->vlen) return (errno = ENOMSG, -1);
/* remova trailing spaces on value */
while (ctx->vlen && isspace(ctx->data[ctx->voff + ctx->vlen - 1]))
--ctx->vlen;
return 1;
}