100 lines
1.6 KiB
C
100 lines
1.6 KiB
C
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include "rifle/tokbuf.h"
|
|
|
|
#define TOKBUF_GROW_SIZE 4
|
|
|
|
int
|
|
tokbuf_init(struct tokbuf *res)
|
|
{
|
|
if (res == NULL) {
|
|
errno = -EINVAL;
|
|
return -1;
|
|
}
|
|
|
|
memset(res, 0, sizeof(*res));
|
|
res->entry_cap = TOKBUF_GROW_SIZE;
|
|
res->ring = malloc(res->entry_cap * sizeof(struct token));
|
|
if (res->ring == NULL) {
|
|
errno = -ENOMEM;
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
tokbuf_push(struct tokbuf *buf, struct token *tok)
|
|
{
|
|
if (buf == NULL || tok == NULL) {
|
|
errno = -EINVAL;
|
|
return -1;
|
|
}
|
|
|
|
/* Push and grow as needed */
|
|
buf->ring[buf->head++] = *tok;
|
|
if (buf->head >= buf->entry_cap) {
|
|
buf->entry_cap += TOKBUF_GROW_SIZE;
|
|
buf->ring = realloc(
|
|
buf->ring,
|
|
buf->entry_cap * sizeof(struct token)
|
|
);
|
|
}
|
|
|
|
if (buf->ring == NULL) {
|
|
errno = -EINVAL;
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
struct token *
|
|
tokbuf_pop(struct tokbuf *buf)
|
|
{
|
|
if (buf == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
if (buf->tail == buf->head) {
|
|
return NULL;
|
|
}
|
|
|
|
return &buf->ring[buf->tail++];
|
|
}
|
|
|
|
struct token *
|
|
tokbuf_lookbehind(struct tokbuf *buf, off_t n)
|
|
{
|
|
off_t index;
|
|
|
|
if (buf == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
if (n == 0) {
|
|
return &buf->ring[buf->tail - 1];
|
|
}
|
|
|
|
index = (off_t)buf->tail - n - 1;
|
|
if (index < 0) {
|
|
index = buf->head - n;
|
|
}
|
|
|
|
return &buf->ring[index];
|
|
}
|
|
|
|
void
|
|
tokbuf_destroy(struct tokbuf *buf)
|
|
{
|
|
if (buf == NULL) {
|
|
return;
|
|
}
|
|
|
|
free(buf->ring);
|
|
buf->ring = NULL;
|
|
}
|
|
|