drgn/libdrgn/lexer.c
Omar Sandoval d1a6350bdd libdrgn: revamp generic vector API
The current generic vector API is pretty minimal and exposes its
internal members as part of the public interface. This has worked well
but prevents us from changing the vector implementation. In particular,
I'd like to have "small vector" variants that can store some entries
directly in the vector structure, use a smaller integer type for the
size and capacity, or both.

So, let's make the generated vector type "private" and add accessor
functions. This is very verbose in some cases, but it'll grant us much
more flexibility. While we're changing every user anyways, let's also
make use of _cleanup_(vector_deinit) where possible.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2023-08-16 14:13:38 -07:00

51 lines
1.1 KiB
C

// Copyright (c) Meta Platforms, Inc. and affiliates.
// SPDX-License-Identifier: LGPL-2.1-or-later
#include "drgn.h"
#include "lexer.h"
DEFINE_VECTOR_FUNCTIONS(drgn_token_vector);
void drgn_lexer_init(struct drgn_lexer *lexer, drgn_lexer_func func,
const char *str)
{
lexer->func = func;
lexer->p = str;
drgn_token_vector_init(&lexer->stack);
}
void drgn_lexer_deinit(struct drgn_lexer *lexer)
{
drgn_token_vector_deinit(&lexer->stack);
}
struct drgn_error *drgn_lexer_pop(struct drgn_lexer *lexer,
struct drgn_token *token)
{
if (drgn_token_vector_empty(&lexer->stack)) {
return lexer->func(lexer, token);
} else {
*token = *drgn_token_vector_pop(&lexer->stack);
return NULL;
}
}
struct drgn_error *drgn_lexer_push(struct drgn_lexer *lexer,
const struct drgn_token *token)
{
if (!drgn_token_vector_append(&lexer->stack, token))
return &drgn_enomem;
return NULL;
}
struct drgn_error *drgn_lexer_peek(struct drgn_lexer *lexer,
struct drgn_token *token)
{
struct drgn_error *err;
err = drgn_lexer_pop(lexer, token);
if (!err)
err = drgn_lexer_push(lexer, token);
return err;
}