145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*
245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Value/Parameter type functions
345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *
445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *  Copyright (C) 2001-2007  Peter Johnson
545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *
645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Redistribution and use in source and binary forms, with or without
745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * modification, are permitted provided that the following conditions
845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * are met:
945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 1. Redistributions of source code must retain the above copyright
1045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *    notice, this list of conditions and the following disclaimer.
1145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 2. Redistributions in binary form must reproduce the above copyright
1245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *    notice, this list of conditions and the following disclaimer in the
1345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *    documentation and/or other materials provided with the distribution.
1445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *
1545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
1645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
1945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * POSSIBILITY OF SUCH DAMAGE.
2645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
2745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "util.h"
2845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
2945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "libyasm-stdint.h"
3045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "coretype.h"
3145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "valparam.h"
3245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
3345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "errwarn.h"
3445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "intnum.h"
3545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "expr.h"
3645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "symrec.h"
3745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
3845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "section.h"
3945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
4045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid
4145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_call_directive(const yasm_directive *directive, yasm_object *object,
4245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    yasm_valparamhead *valparams,
4345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    yasm_valparamhead *objext_valparams, unsigned long line)
4445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
4545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_valparam *vp;
4645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
4745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if ((directive->flags & (YASM_DIR_ARG_REQUIRED|YASM_DIR_ID_REQUIRED)) &&
4845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        (!valparams || !yasm_vps_first(valparams))) {
4945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_error_set(YASM_ERROR_SYNTAX,
5045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                       N_("directive `%s' requires an argument"),
5145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                       directive->name);
5245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return;
5345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
5445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (valparams) {
5545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        vp = yasm_vps_first(valparams);
5645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if ((directive->flags & YASM_DIR_ID_REQUIRED) &&
5745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            vp->type != YASM_PARAM_ID) {
5845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_error_set(YASM_ERROR_SYNTAX,
5945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                N_("directive `%s' requires an identifier parameter"),
6045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                directive->name);
6145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return;
6245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
6345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
6445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    directive->handler(object, valparams, objext_valparams, line);
6545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
6645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
6745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_valparam *
6845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_vp_create_id(/*@keep@*/ char *v, /*@keep@*/ char *p, int id_prefix)
6945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
7045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_valparam *r = yasm_xmalloc(sizeof(yasm_valparam));
7145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    r->val = v;
7245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    r->type = YASM_PARAM_ID;
7345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    r->param.id = p;
7445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    r->id_prefix = (char)id_prefix;
7545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return r;
7645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
7745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
7845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_valparam *
7945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_vp_create_string(/*@keep@*/ char *v, /*@keep@*/ char *p)
8045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
8145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_valparam *r = yasm_xmalloc(sizeof(yasm_valparam));
8245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    r->val = v;
8345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    r->type = YASM_PARAM_STRING;
8445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    r->param.str = p;
8545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    r->id_prefix = '\0';
8645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return r;
8745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
8845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
8945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_valparam *
9045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_vp_create_expr(/*@keep@*/ char *v, /*@keep@*/ yasm_expr *p)
9145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
9245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_valparam *r = yasm_xmalloc(sizeof(yasm_valparam));
9345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    r->val = v;
9445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    r->type = YASM_PARAM_EXPR;
9545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    r->param.e = p;
9645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    r->id_prefix = '\0';
9745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return r;
9845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
9945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
10045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*@null@*/ /*@only@*/ yasm_expr *
10145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_vp_expr(const yasm_valparam *vp, yasm_symtab *symtab, unsigned long line)
10245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
10345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (!vp)
10445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return NULL;
10545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    switch (vp->type) {
10645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        case YASM_PARAM_ID:
10745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return yasm_expr_create_ident(yasm_expr_sym(
10845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                yasm_symtab_use(symtab, yasm_vp_id(vp), line)), line);
10945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        case YASM_PARAM_EXPR:
11045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return yasm_expr_copy(vp->param.e);
11145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        default:
11245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return NULL;
11345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
11445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
11545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
11645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*@null@*/ /*@dependent@*/ const char *
11745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_vp_string(const yasm_valparam *vp)
11845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
11945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (!vp)
12045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return NULL;
12145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    switch (vp->type) {
12245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        case YASM_PARAM_ID:
12345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return vp->param.id;
12445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        case YASM_PARAM_STRING:
12545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return vp->param.str;
12645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        default:
12745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return NULL;
12845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
12945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
13045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
13145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*@null@*/ /*@dependent@*/ const char *
13245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_vp_id(const yasm_valparam *vp)
13345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
13445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (!vp)
13545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return NULL;
13645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (vp->type == YASM_PARAM_ID) {
13745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (vp->param.id[0] == vp->id_prefix)
13845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return &vp->param.id[1];
13945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        else
14045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return vp->param.id;
14145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
14245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return NULL;
14345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
14445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
14545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid
14645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_vps_delete(yasm_valparamhead *headp)
14745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
14845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_valparam *cur, *next;
14945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
15045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cur = STAILQ_FIRST(headp);
15145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    while (cur) {
15245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        next = STAILQ_NEXT(cur, link);
15345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (cur->val)
15445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_xfree(cur->val);
15545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        switch (cur->type) {
15645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case YASM_PARAM_ID:
15745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                yasm_xfree(cur->param.id);
15845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
15945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case YASM_PARAM_STRING:
16045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                yasm_xfree(cur->param.str);
16145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
16245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case YASM_PARAM_EXPR:
16345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                yasm_expr_destroy(cur->param.e);
16445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
16545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
16645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_xfree(cur);
16745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        cur = next;
16845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
16945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    STAILQ_INIT(headp);
17045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
17145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
17245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid
17345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_vps_print(const yasm_valparamhead *headp, FILE *f)
17445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
17545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const yasm_valparam *vp;
17645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
17745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if(!headp) {
17845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        fprintf(f, "(none)");
17945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return;
18045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
18145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
18245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_vps_foreach(vp, headp) {
18345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (vp->val)
18445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            fprintf(f, "(\"%s\",", vp->val);
18545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        else
18645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            fprintf(f, "((nil),");
18745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        switch (vp->type) {
18845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case YASM_PARAM_ID:
18945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                fprintf(f, "%s", vp->param.id);
19045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
19145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case YASM_PARAM_STRING:
19245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                fprintf(f, "\"%s\"", vp->param.str);
19345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
19445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case YASM_PARAM_EXPR:
19545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                yasm_expr_print(vp->param.e, f);
19645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
19745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
19845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        fprintf(f, ")");
19945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (yasm_vps_next(vp))
20045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            fprintf(f, ",");
20145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
20245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
20345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
20445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_valparamhead *
20545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_vps_create(void)
20645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
20745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_valparamhead *headp = yasm_xmalloc(sizeof(yasm_valparamhead));
20845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_vps_initialize(headp);
20945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return headp;
21045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
21145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
21245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid
21345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_vps_destroy(yasm_valparamhead *headp)
21445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
21545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_vps_delete(headp);
21645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_xfree(headp);
21745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
21845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
21945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint
22045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_dir_helper(void *obj, yasm_valparam *vp_first, unsigned long line,
22145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                const yasm_dir_help *help, size_t nhelp, void *data,
22245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                int (*helper_valparam) (void *obj, yasm_valparam *vp,
22345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                        unsigned long line, void *data))
22445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
22545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_valparam *vp = vp_first;
22645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    int anymatched = 0;
22745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    int matched;
22845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
22945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (!vp)
23045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return 0;
23145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
23245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    do {
23345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        const char *s;
23445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        size_t i;
23545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
23645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        matched = 0;
23745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (!vp->val && (s = yasm_vp_id(vp))) {
23845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            for (i=0; i<nhelp; i++) {
23945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                if (help[i].needsparam == 0 &&
24045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    yasm__strcasecmp(s, help[i].name) == 0) {
24145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    if (help[i].helper(obj, vp, line,
24245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                       ((char *)data)+help[i].off,
24345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                       help[i].arg) != 0)
24445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        return -1;
24545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    matched = 1;
24645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    anymatched = 1;
24745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    break;
24845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                }
24945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            }
25045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        } else if (vp->val) {
25145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            for (i=0; i<nhelp; i++) {
25245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                if (help[i].needsparam == 1 &&
25345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    yasm__strcasecmp(vp->val, help[i].name) == 0) {
25445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    if (help[i].helper(obj, vp, line,
25545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                       ((char *)data)+help[i].off,
25645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                       help[i].arg) != 0)
25745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        return -1;
25845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    matched = 1;
25945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    anymatched = 1;
26045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    break;
26145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                }
26245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            }
26345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
26445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
26545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (!matched) {
26645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            int final = helper_valparam(obj, vp, line, data);
26745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if (final < 0)
26845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                return -1;
26945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if (final > 0)
27045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                anymatched = 1;
27145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
27245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    } while((vp = yasm_vps_next(vp)));
27345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
27445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return anymatched;
27545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
27645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
27745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint
27845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_dir_helper_flag_or(void *obj, yasm_valparam *vp, unsigned long line,
27945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        void *d, uintptr_t flag)
28045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
28145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned long *flags = (unsigned long *)d;
28245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    *flags |= flag;
28345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
28445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
28545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
28645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint
28745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_dir_helper_flag_and(void *obj, yasm_valparam *vp, unsigned long line,
28845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                         void *d, uintptr_t flag)
28945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
29045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned long *flags = (unsigned long *)d;
29145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    *flags &= ~flag;
29245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
29345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
29445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
29545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint
29645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_dir_helper_flag_set(void *obj, yasm_valparam *vp, unsigned long line,
29745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                         void *d, uintptr_t flag)
29845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
29945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned long *flags = (unsigned long *)d;
30045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    *flags = flag;
30145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
30245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
30345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
30445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint
30545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_dir_helper_expr(void *obj, yasm_valparam *vp, unsigned long line,
30645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                     void *data, uintptr_t arg)
30745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
30845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_object *object = (yasm_object *)obj;
30945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_expr **expr = (yasm_expr **)data;
31045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
31145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (*expr)
31245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_expr_destroy(*expr);
31345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (!(*expr = yasm_vp_expr(vp, object->symtab, line))) {
31445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_error_set(YASM_ERROR_VALUE, N_("argument to `%s' is not an expression"),
31545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                       vp->val);
31645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return -1;
31745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
31845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
31945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
32045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
32145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint
32245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_dir_helper_intn(void *obj, yasm_valparam *vp, unsigned long line,
32345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                     void *data, uintptr_t arg)
32445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
32545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_object *object = (yasm_object *)obj;
32645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /*@only@*/ /*@null@*/ yasm_expr *e;
32745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /*@dependent@*/ /*@null@*/ yasm_intnum *local;
32845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum **intn = (yasm_intnum **)data;
32945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
33045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (*intn)
33145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_intnum_destroy(*intn);
33245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (!(e = yasm_vp_expr(vp, object->symtab, line)) ||
33345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        !(local = yasm_expr_get_intnum(&e, 0))) {
33445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_error_set(YASM_ERROR_NOT_CONSTANT,
33545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                       N_("argument to `%s' is not an integer"),
33645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                       vp->val);
33745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (e)
33845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_expr_destroy(e);
33945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return -1;
34045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
34145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    *intn = yasm_intnum_copy(local);
34245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_expr_destroy(e);
34345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
34445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
34545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
34645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint
34745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_dir_helper_string(void *obj, yasm_valparam *vp, unsigned long line,
34845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                       void *data, uintptr_t arg)
34945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
35045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /*@dependent@*/ /*@null@*/ const char *local;
35145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    char **s = (char **)data;
35245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
35345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (*s)
35445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_xfree(*s);
35545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (!(local = yasm_vp_string(vp))) {
35645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_error_set(YASM_ERROR_VALUE,
35745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                       N_("argument to `%s' is not a string or identifier"),
35845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                       vp->val);
35945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return -1;
36045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
36145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    *s = yasm__xstrdup(local);
36245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
36345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
36445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
36545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint
36645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_dir_helper_valparam_warn(void *obj, yasm_valparam *vp,
36745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                              unsigned long line, void *data)
36845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
36945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const char *s;
37045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
37145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (vp->val) {
37245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_warn_set(YASM_WARN_GENERAL, N_("Unrecognized qualifier `%s'"),
37345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                      vp->val);
37445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return 0;
37545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
37645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
37745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if ((s = yasm_vp_id(vp)))
37845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_warn_set(YASM_WARN_GENERAL, N_("Unrecognized qualifier `%s'"), s);
37945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    else if (vp->type == YASM_PARAM_STRING)
38045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_warn_set(YASM_WARN_GENERAL, N_("Unrecognized string qualifier"));
38145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    else
38245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_warn_set(YASM_WARN_GENERAL, N_("Unrecognized numeric qualifier"));
38345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
38445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
38545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
386