harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 371d1eacb62d1a09eccad4132f09570d834e0715
parent b9aeea5396e01a4c708de33319284b5930f6b934
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sun, 22 Nov 2020 11:15:42 -0500

parse: trace parsed identifier name

Diffstat:
Mconfigure | 1+
Minclude/identifier.h | 4++++
Asrc/identifier.c | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/parse.c | 10+++++++---
4 files changed, 71 insertions(+), 3 deletions(-)

diff --git a/configure b/configure @@ -4,6 +4,7 @@ eval ". $srcdir/config.sh" harec() { genrules harec \ + src/identifier.c \ src/lex.c \ src/main.c \ src/parse.c \ diff --git a/include/identifier.h b/include/identifier.h @@ -6,4 +6,8 @@ struct identifier { struct identifier *ns; }; +char *identifier_unparse(const struct identifier *ident); +int identifier_unparse_static(const struct identifier *ident, + char *buf, size_t len); + #endif diff --git a/src/identifier.c b/src/identifier.c @@ -0,0 +1,59 @@ +#include <assert.h> +#include <errno.h> +#include <limits.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "identifier.h" + +static int +_asprintf(char **strp, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + int n = vsnprintf(NULL, 0, fmt, ap); + va_end(ap); + + *strp = calloc(n + 1, 1); + if (!*strp) { + errno = ENOMEM; + return -1; + } + + va_start(ap, fmt); + n = vsnprintf(*strp, n + 1, fmt, ap); + va_end(ap); + return n; +} + +char * +identifier_unparse(const struct identifier *ident) +{ + if (ident->ns) { + char *ns = identifier_unparse(ident->ns); + if (!ns) { + return NULL; + } + char *str = NULL; + _asprintf(&str, "%s::%s", ns, ident->name); + free(ns); + return str; + } + return strdup(ident->name); +} + +int +identifier_unparse_static(const struct identifier *ident, char *buf, size_t len) +{ + assert(len < INT_MAX); + if (ident->ns) { + int prefix = identifier_unparse_static(ident->ns, buf, len); + int n = snprintf(&buf[prefix], len - prefix, "::%s", ident->name); + assert(prefix + n < (int)len); + return n; + } + int n = snprintf(buf, len, ident->name); + assert(n < (int)len); + return n; +} diff --git a/src/parse.c b/src/parse.c @@ -60,7 +60,7 @@ parse_identifier(struct parser *par, struct identifier *ident) struct identifier *i = ident; trace("parse", "identifier"); - while (true) { + while (!i->name) { want(par, T_NAME, &tok); i->name = strdup(tok.name); token_finish(&tok); @@ -71,13 +71,17 @@ parse_identifier(struct parser *par, struct identifier *ident) ns = calloc(1, sizeof(struct identifier)); *ns = *i; i->ns = ns; - i = ns; + i->name = NULL; break; default: unlex(par->lex, &tok); - return; + break; } } + + char buf[1024]; + identifier_unparse_static(ident, buf, sizeof(buf)); + trace("parse", "-> %s", buf); } static void