123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385 |
- /*
- * Value/Parameter type functions
- *
- * Copyright (C) 2001-2007 Peter Johnson
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
- #include "util.h"
- #include "libyasm-stdint.h"
- #include "coretype.h"
- #include "valparam.h"
- #include "errwarn.h"
- #include "intnum.h"
- #include "expr.h"
- #include "symrec.h"
- #include "section.h"
- void
- yasm_call_directive(const yasm_directive *directive, yasm_object *object,
- yasm_valparamhead *valparams,
- yasm_valparamhead *objext_valparams, unsigned long line)
- {
- yasm_valparam *vp;
- if ((directive->flags & (YASM_DIR_ARG_REQUIRED|YASM_DIR_ID_REQUIRED)) &&
- (!valparams || !yasm_vps_first(valparams))) {
- yasm_error_set(YASM_ERROR_SYNTAX,
- N_("directive `%s' requires an argument"),
- directive->name);
- return;
- }
- if (valparams) {
- vp = yasm_vps_first(valparams);
- if ((directive->flags & YASM_DIR_ID_REQUIRED) &&
- vp->type != YASM_PARAM_ID) {
- yasm_error_set(YASM_ERROR_SYNTAX,
- N_("directive `%s' requires an identifier parameter"),
- directive->name);
- return;
- }
- }
- directive->handler(object, valparams, objext_valparams, line);
- }
- yasm_valparam *
- yasm_vp_create_id(/*@keep@*/ char *v, /*@keep@*/ char *p, int id_prefix)
- {
- yasm_valparam *r = yasm_xmalloc(sizeof(yasm_valparam));
- r->val = v;
- r->type = YASM_PARAM_ID;
- r->param.id = p;
- r->id_prefix = (char)id_prefix;
- return r;
- }
- yasm_valparam *
- yasm_vp_create_string(/*@keep@*/ char *v, /*@keep@*/ char *p)
- {
- yasm_valparam *r = yasm_xmalloc(sizeof(yasm_valparam));
- r->val = v;
- r->type = YASM_PARAM_STRING;
- r->param.str = p;
- r->id_prefix = '\0';
- return r;
- }
- yasm_valparam *
- yasm_vp_create_expr(/*@keep@*/ char *v, /*@keep@*/ yasm_expr *p)
- {
- yasm_valparam *r = yasm_xmalloc(sizeof(yasm_valparam));
- r->val = v;
- r->type = YASM_PARAM_EXPR;
- r->param.e = p;
- r->id_prefix = '\0';
- return r;
- }
- /*@null@*/ /*@only@*/ yasm_expr *
- yasm_vp_expr(const yasm_valparam *vp, yasm_symtab *symtab, unsigned long line)
- {
- if (!vp)
- return NULL;
- switch (vp->type) {
- case YASM_PARAM_ID:
- return yasm_expr_create_ident(yasm_expr_sym(
- yasm_symtab_use(symtab, yasm_vp_id(vp), line)), line);
- case YASM_PARAM_EXPR:
- return yasm_expr_copy(vp->param.e);
- default:
- return NULL;
- }
- }
- /*@null@*/ /*@dependent@*/ const char *
- yasm_vp_string(const yasm_valparam *vp)
- {
- if (!vp)
- return NULL;
- switch (vp->type) {
- case YASM_PARAM_ID:
- return vp->param.id;
- case YASM_PARAM_STRING:
- return vp->param.str;
- default:
- return NULL;
- }
- }
- /*@null@*/ /*@dependent@*/ const char *
- yasm_vp_id(const yasm_valparam *vp)
- {
- if (!vp)
- return NULL;
- if (vp->type == YASM_PARAM_ID) {
- if (vp->param.id[0] == vp->id_prefix)
- return &vp->param.id[1];
- else
- return vp->param.id;
- }
- return NULL;
- }
- void
- yasm_vps_delete(yasm_valparamhead *headp)
- {
- yasm_valparam *cur, *next;
- cur = STAILQ_FIRST(headp);
- while (cur) {
- next = STAILQ_NEXT(cur, link);
- if (cur->val)
- yasm_xfree(cur->val);
- switch (cur->type) {
- case YASM_PARAM_ID:
- yasm_xfree(cur->param.id);
- break;
- case YASM_PARAM_STRING:
- yasm_xfree(cur->param.str);
- break;
- case YASM_PARAM_EXPR:
- yasm_expr_destroy(cur->param.e);
- break;
- }
- yasm_xfree(cur);
- cur = next;
- }
- STAILQ_INIT(headp);
- }
- void
- yasm_vps_print(const yasm_valparamhead *headp, FILE *f)
- {
- const yasm_valparam *vp;
- if(!headp) {
- fprintf(f, "(none)");
- return;
- }
- yasm_vps_foreach(vp, headp) {
- if (vp->val)
- fprintf(f, "(\"%s\",", vp->val);
- else
- fprintf(f, "((nil),");
- switch (vp->type) {
- case YASM_PARAM_ID:
- fprintf(f, "%s", vp->param.id);
- break;
- case YASM_PARAM_STRING:
- fprintf(f, "\"%s\"", vp->param.str);
- break;
- case YASM_PARAM_EXPR:
- yasm_expr_print(vp->param.e, f);
- break;
- }
- fprintf(f, ")");
- if (yasm_vps_next(vp))
- fprintf(f, ",");
- }
- }
- yasm_valparamhead *
- yasm_vps_create(void)
- {
- yasm_valparamhead *headp = yasm_xmalloc(sizeof(yasm_valparamhead));
- yasm_vps_initialize(headp);
- return headp;
- }
- void
- yasm_vps_destroy(yasm_valparamhead *headp)
- {
- yasm_vps_delete(headp);
- yasm_xfree(headp);
- }
- int
- yasm_dir_helper(void *obj, yasm_valparam *vp_first, unsigned long line,
- const yasm_dir_help *help, size_t nhelp, void *data,
- int (*helper_valparam) (void *obj, yasm_valparam *vp,
- unsigned long line, void *data))
- {
- yasm_valparam *vp = vp_first;
- int anymatched = 0;
- int matched;
- if (!vp)
- return 0;
- do {
- const char *s;
- size_t i;
- matched = 0;
- if (!vp->val && (s = yasm_vp_id(vp))) {
- for (i=0; i<nhelp; i++) {
- if (help[i].needsparam == 0 &&
- yasm__strcasecmp(s, help[i].name) == 0) {
- if (help[i].helper(obj, vp, line,
- ((char *)data)+help[i].off,
- help[i].arg) != 0)
- return -1;
- matched = 1;
- anymatched = 1;
- break;
- }
- }
- } else if (vp->val) {
- for (i=0; i<nhelp; i++) {
- if (help[i].needsparam == 1 &&
- yasm__strcasecmp(vp->val, help[i].name) == 0) {
- if (help[i].helper(obj, vp, line,
- ((char *)data)+help[i].off,
- help[i].arg) != 0)
- return -1;
- matched = 1;
- anymatched = 1;
- break;
- }
- }
- }
- if (!matched) {
- int final = helper_valparam(obj, vp, line, data);
- if (final < 0)
- return -1;
- if (final > 0)
- anymatched = 1;
- }
- } while((vp = yasm_vps_next(vp)));
- return anymatched;
- }
- int
- yasm_dir_helper_flag_or(void *obj, yasm_valparam *vp, unsigned long line,
- void *d, uintptr_t flag)
- {
- unsigned long *flags = (unsigned long *)d;
- *flags |= flag;
- return 0;
- }
- int
- yasm_dir_helper_flag_and(void *obj, yasm_valparam *vp, unsigned long line,
- void *d, uintptr_t flag)
- {
- unsigned long *flags = (unsigned long *)d;
- *flags &= ~flag;
- return 0;
- }
- int
- yasm_dir_helper_flag_set(void *obj, yasm_valparam *vp, unsigned long line,
- void *d, uintptr_t flag)
- {
- unsigned long *flags = (unsigned long *)d;
- *flags = flag;
- return 0;
- }
- int
- yasm_dir_helper_expr(void *obj, yasm_valparam *vp, unsigned long line,
- void *data, uintptr_t arg)
- {
- yasm_object *object = (yasm_object *)obj;
- yasm_expr **expr = (yasm_expr **)data;
- if (*expr)
- yasm_expr_destroy(*expr);
- if (!(*expr = yasm_vp_expr(vp, object->symtab, line))) {
- yasm_error_set(YASM_ERROR_VALUE, N_("argument to `%s' is not an expression"),
- vp->val);
- return -1;
- }
- return 0;
- }
- int
- yasm_dir_helper_intn(void *obj, yasm_valparam *vp, unsigned long line,
- void *data, uintptr_t arg)
- {
- yasm_object *object = (yasm_object *)obj;
- /*@only@*/ /*@null@*/ yasm_expr *e;
- /*@dependent@*/ /*@null@*/ yasm_intnum *local;
- yasm_intnum **intn = (yasm_intnum **)data;
- if (*intn)
- yasm_intnum_destroy(*intn);
- if (!(e = yasm_vp_expr(vp, object->symtab, line)) ||
- !(local = yasm_expr_get_intnum(&e, 0))) {
- yasm_error_set(YASM_ERROR_NOT_CONSTANT,
- N_("argument to `%s' is not an integer"),
- vp->val);
- if (e)
- yasm_expr_destroy(e);
- return -1;
- }
- *intn = yasm_intnum_copy(local);
- yasm_expr_destroy(e);
- return 0;
- }
- int
- yasm_dir_helper_string(void *obj, yasm_valparam *vp, unsigned long line,
- void *data, uintptr_t arg)
- {
- /*@dependent@*/ /*@null@*/ const char *local;
- char **s = (char **)data;
- if (*s)
- yasm_xfree(*s);
- if (!(local = yasm_vp_string(vp))) {
- yasm_error_set(YASM_ERROR_VALUE,
- N_("argument to `%s' is not a string or identifier"),
- vp->val);
- return -1;
- }
- *s = yasm__xstrdup(local);
- return 0;
- }
- int
- yasm_dir_helper_valparam_warn(void *obj, yasm_valparam *vp,
- unsigned long line, void *data)
- {
- const char *s;
- if (vp->val) {
- yasm_warn_set(YASM_WARN_GENERAL, N_("Unrecognized qualifier `%s'"),
- vp->val);
- return 0;
- }
- if ((s = yasm_vp_id(vp)))
- yasm_warn_set(YASM_WARN_GENERAL, N_("Unrecognized qualifier `%s'"), s);
- else if (vp->type == YASM_PARAM_STRING)
- yasm_warn_set(YASM_WARN_GENERAL, N_("Unrecognized string qualifier"));
- else
- yasm_warn_set(YASM_WARN_GENERAL, N_("Unrecognized numeric qualifier"));
- return 0;
- }
|