#include #include #include #include "spho/ctx.h" #include "spho/scope.h" #include "spho/util.h" static void spho_nom_term(struct spho_nom *); static int spho_scope_nom_get_norec(struct spho_scope *, const char *, size_t , struct spho_nom **); int spho_scope_init(struct spho_scope *sc, struct spho_ctx *ctx, struct spho_scope *p) { SLIST_INIT(&sc->subs); SLIST_INIT(&sc->noms); TAILQ_INIT(&sc->tps); sc->ctx = ctx; sc->parent = p; return (0); } void spho_scope_term(struct spho_scope *sc) { SPHO_UTIL_SLIST_DESTROY(&sc->subs, spho_scope, next, spho_scope_term); SPHO_UTIL_SLIST_DESTROY(&sc->noms, spho_nom, next, spho_nom_term); sc->parent = NULL; } struct spho_scope * spho_scope_global(struct spho_ctx *ctx) { SPHO_PRECOND(ctx != NULL); return (&ctx->glob); } struct spho_scope * spho_scope_create(struct spho_scope *sc) { struct spho_scope *sub; if ((sub = malloc(sizeof(struct spho_scope))) == NULL) { SPHO_ERR(sc->ctx, SPHO_ERR_SYS); return (NULL); } if (spho_scope_init(sub, sc->ctx, sc) == -1) { free(sub); return (NULL); } SLIST_INSERT_HEAD(&sc->subs, sub, next); return (sub); } static void spho_nom_term(struct spho_nom *nom) { return; } void spho_scope_destroy(struct spho_scope *sc) { struct spho_scope *p; p = sc->parent; SLIST_REMOVE(&p->subs, sc, spho_scope, next); spho_scope_term(sc); free(sc); } struct spho_nom * spho_scope_nom_add(struct spho_scope *sc, const char *nomstr, size_t sz) { #ifdef SPHO_USE_STRLCPY size_t res; #else ssize_t res; #endif struct spho_nom *nom; nom = NULL; if (spho_scope_nom_get_norec(sc, nomstr, sz, &nom) == -1) return (NULL); if (nom != NULL) { SPHO_SC_ERR(sc, SPHO_ERR_NOM_INUSE); return (NULL); } if ((nom = malloc(sizeof(struct spho_nom))) == NULL) { SPHO_SC_ERR(sc, SPHO_ERR_SYS); return (NULL); } #ifdef SPHO_USE_STRLCPY res = strlcpy(nom->s, nomstr, sizeof(nom->s)); if (res >= sizeof(nom->s)) { SPHO_SC_ERR(sc, SPHO_ERR_TOOBIG); goto err; } #else res = snprintf(nom->s, sizeof(nom->s), "%s", nomstr); if (res < 0) { SPHO_SC_ERR(sc, SPHO_ERR_SYS); goto err; } if (res >= (ssize_t)sizeof(nom->s)) { SPHO_SC_ERR(sc, SPHO_ERR_TOOBIG); goto err; } #endif SLIST_INSERT_HEAD(&sc->noms, nom, next); return (nom); err: free(nom); return (NULL); } int spho_scope_nom_get(struct spho_scope *sc, const char *nomstr, size_t sz, struct spho_nom **out) { struct spho_nom *nom; nom = NULL; if (sz > sizeof(nom->s)) { SPHO_ERR(sc->ctx, SPHO_ERR_TOOBIG); return (-1); } *out = NULL; while (*out == NULL && sc != NULL) { SLIST_FOREACH(nom, &sc->noms, next) { if (strncmp(nom->s, nomstr, sz) == 0) { *out = nom; break; } } sc = sc->parent; } return (0); } int spho_scope_nom_lookup(struct spho_scope *sc, const char *nomstr, size_t sz, struct spho_nom **out) { int ret; if (spho_scope_nom_get(sc, nomstr, sz, out) == -1) return (-1); if (*out == NULL) { SPHO_SC_ERR(sc, SPHO_ERR_NOM_NOTINSCOPE); return (-1); } return (0); } static int spho_scope_nom_get_norec(struct spho_scope *sc, const char *nomstr, size_t sz, struct spho_nom **out) { struct spho_nom *nom; nom = NULL; if (sz > sizeof(nom->s)) { SPHO_ERR(sc->ctx, SPHO_ERR_TOOBIG); return (-1); } *out = NULL; SLIST_FOREACH(nom, &sc->noms, next) { if (strncmp(nom->s, nomstr, sz) == 0) { *out = nom; break; } } return (0); }