145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/**
245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \file libyasm/valparam.h
345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \brief YASM value/parameter interface.
445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *
545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \license
645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *  Copyright (C) 2001-2007  Peter Johnson
745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *
845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Redistribution and use in source and binary forms, with or without
945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * modification, are permitted provided that the following conditions
1045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * are met:
1145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *  - Redistributions of source code must retain the above copyright
1245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *    notice, this list of conditions and the following disclaimer.
1345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *  - Redistributions in binary form must reproduce the above copyright
1445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *    notice, this list of conditions and the following disclaimer in the
1545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *    documentation and/or other materials provided with the distribution.
1645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *
1745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
1845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
2145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * POSSIBILITY OF SUCH DAMAGE.
2845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \endlicense
2945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
3045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#ifndef YASM_VALPARAM_H
3145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define YASM_VALPARAM_H
3245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
3345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#ifndef YASM_LIB_DECL
3445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define YASM_LIB_DECL
3545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#endif
3645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
3745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Value/parameter pair.  \internal */
3845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstruct yasm_valparam {
3945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /*@reldef@*/ STAILQ_ENTRY(yasm_valparam) link;  /**< Next pair in list */
4045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /*@owned@*/ /*@null@*/ char *val;           /**< Value */
4145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
4245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /** Parameter type. */
4345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    enum yasm_param_type {
4445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        YASM_PARAM_ID,                          /**< Identifier */
4545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        YASM_PARAM_STRING,                      /**< String */
4645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        YASM_PARAM_EXPR                         /**< Expression */
4745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    } type;                                     /**< Parameter type */
4845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
4945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /** Parameter value. */
5045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    union yasm_param {
5145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        /*@owned@*/ char *id;                   /**< Identifier */
5245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        /*@owned@*/ char *str;                  /**< String */
5345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        /*@owned@*/ yasm_expr *e;               /**< Expression */
5445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    } param;                                    /**< Parameter */
5545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
5645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /** Prefix character that indicates a raw identifier.  When
5745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * yasm_vp_string() is called on a #YASM_PARAM_ID, all characters are
5845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * returned.  When yasm_vp_id() is called on a #YASM_PARAM_ID, if the
5945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * identifier begins with this character, this character is stripped
6045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * from the returned value.
6145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     */
6245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    char id_prefix;
6345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org};
6445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
6545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Linked list of value/parameter pairs.  \internal */
6645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*@reldef@*/ STAILQ_HEAD(yasm_valparamhead, yasm_valparam);
6745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
6845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Directive list entry structure. */
6945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstruct yasm_directive {
7045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /** Directive name.  GAS directives should include the ".", NASM
7145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * directives should just be the raw name (not including the []).
7245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * NULL entry required to terminate list of directives.
7345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     */
7445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /*@null@*/ const char *name;
7545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
7645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const char *parser;                     /**< Parser keyword */
7745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
7845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /** Handler callback function for the directive.
7945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * \param object            object
8045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * \param valparams         value/parameters
8145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * \param objext_valparams  object format-specific value/parameters
8245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * \param line              virtual line (from yasm_linemap)
8345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     */
8445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    void (*handler) (yasm_object *object, yasm_valparamhead *valparams,
8545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                     yasm_valparamhead *objext_valparams, unsigned long line);
8645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
8745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /** Flags for pre-handler parameter checking. */
8845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    enum yasm_directive_flags {
8945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        YASM_DIR_ANY = 0,           /**< Any valparams accepted */
9045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        YASM_DIR_ARG_REQUIRED = 1,  /**< Require at least 1 valparam */
9145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        YASM_DIR_ID_REQUIRED = 2    /**< First valparam must be ID */
9245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    } flags;
9345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org};
9445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
9545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Call a directive.  Performs any valparam checks asked for by the
9645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * directive prior to call.  Note that for a variety of reasons, a directive
9745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * can generate an error.
9845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param directive             directive
9945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param object                object
10045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param valparams             value/parameters
10145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param objext_valparams      object format-specific value/parameters
10245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param line                  virtual line (from yasm_linemap)
10345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
10445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL
10545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid yasm_call_directive(const yasm_directive *directive, yasm_object *object,
10645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                         yasm_valparamhead *valparams,
10745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                         yasm_valparamhead *objext_valparams,
10845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                         unsigned long line);
10945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
11045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Create a new valparam with identifier parameter.
11145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param v             value
11245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param p             parameter
11345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param id_prefix     identifier prefix for raw identifiers
11445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return Newly allocated valparam.
11545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
11645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL
11745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_valparam *yasm_vp_create_id(/*@keep@*/ char *v, /*@keep@*/ char *p,
11845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                 int id_prefix);
11945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
12045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Create a new valparam with string parameter.
12145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param v     value
12245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param p     parameter
12345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return Newly allocated valparam.
12445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
12545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL
12645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_valparam *yasm_vp_create_string(/*@keep@*/ char *v, /*@keep@*/ char *p);
12745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
12845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Create a new valparam with expression parameter.
12945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param v     value
13045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param p     parameter
13145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return Newly allocated valparam.
13245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
13345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL
13445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_valparam *yasm_vp_create_expr(/*@keep@*/ char *v,
13545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                   /*@keep@*/ yasm_expr *p);
13645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
13745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Get a valparam parameter as an expr.  If the parameter is an identifier,
13845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * it's treated as a symbol (yasm_symtab_use() is called to convert it).
13945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param vp            valparam
14045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param symtab        symbol table
14145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param line          virtual line
14245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return Expression, or NULL if vp is NULL or the parameter cannot be
14345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *         converted to an expression.
14445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
14545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL
14645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*@null@*/ /*@only@*/ yasm_expr *yasm_vp_expr
14745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    (const yasm_valparam *vp, yasm_symtab *symtab, unsigned long line);
14845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
14945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Get a valparam parameter as a string.  If the parameter is an identifier,
15045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * it's treated as a string.
15145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param vp            valparam
15245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return String, or NULL if vp is NULL or the parameter cannot be realized
15345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *         as a string.
15445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
15545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL
15645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*@null@*/ /*@dependent@*/ const char *yasm_vp_string(const yasm_valparam *vp);
15745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
15845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Get a valparam parameter as an identifier.
15945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param vp            valparam
16045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return Identifier (string), or NULL if vp is NULL or the parameter is not
16145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *         an identifier.
16245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
16345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL
16445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*@null@*/ /*@dependent@*/ const char *yasm_vp_id(const yasm_valparam *vp);
16545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
16645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Create a new linked list of valparams.
16745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return Newly allocated valparam list.
16845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
16945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL
17045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_valparamhead *yasm_vps_create(void);
17145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
17245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Destroy a list of valparams (created with yasm_vps_create).
17345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param headp         list of valparams
17445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
17545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL
17645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid yasm_vps_destroy(yasm_valparamhead *headp);
17745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
17845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Initialize linked list of valparams.
17945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param headp linked list
18045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
18145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid yasm_vps_initialize(/*@out@*/ yasm_valparamhead *headp);
18245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#ifndef YASM_DOXYGEN
18345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define yasm_vps_initialize(headp)      STAILQ_INIT(headp)
18445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#endif
18545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
18645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Destroy (free allocated memory for) linked list of valparams (created with
18745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * yasm_vps_initialize).
18845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \warning Deletes val/params.
18945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param headp linked list
19045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
19145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL
19245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid yasm_vps_delete(yasm_valparamhead *headp);
19345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
19445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Append valparam to tail of linked list.
19545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param headp linked list
19645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param vp    valparam
19745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
19845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid yasm_vps_append(yasm_valparamhead *headp, /*@keep@*/ yasm_valparam *vp);
19945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#ifndef YASM_DOXYGEN
20045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define yasm_vps_append(headp, vp)      do {        \
20145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (vp)                                     \
20245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            STAILQ_INSERT_TAIL(headp, vp, link);    \
20345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    } while(0)
20445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#endif
20545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
20645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Get first valparam in linked list.
20745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param headp linked list
20845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return First valparam in linked list.
20945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
21045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*@null@*/ /*@dependent@*/ yasm_valparam *yasm_vps_first
21145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    (yasm_valparamhead *headp);
21245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#ifndef YASM_DOXYGEN
21345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define yasm_vps_first(headp)       STAILQ_FIRST(headp)
21445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#endif
21545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
21645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Get next valparam in linked list.
21745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param cur   previous valparam in linked list
21845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return Next valparam in linked list.
21945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
22045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*@null@*/ /*@dependent@*/ yasm_valparam *yasm_vps_next(yasm_valparam *cur);
22145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#ifndef YASM_DOXYGEN
22245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define yasm_vps_next(cur)          STAILQ_NEXT(cur, link)
22345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#endif
22445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
22545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Iterate through linked list of valparams.
22645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \internal
22745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param iter      iterator variable
22845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param headp     linked list
22945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
23045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#ifndef YASM_DOXYGEN
23145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define yasm_vps_foreach(iter, headp)   STAILQ_FOREACH(iter, headp, link)
23245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#endif
23345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
23445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Print linked list of valparams.  For debugging purposes.
23545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param f     file
23645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param headp linked list
23745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
23845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL
23945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid yasm_vps_print(/*@null@*/ const yasm_valparamhead *headp, FILE *f);
24045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
24145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Directive valparam parse helper structure. */
24245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct yasm_dir_help {
24345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /** Value portion of val=param (if needsparam=1), or standalone identifier
24445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * (if needsparam=0).
24545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     */
24645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const char *name;
24745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
24845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /** 1 if value requires parameter, 0 if it must not have a parameter. */
24945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    int needsparam;
25045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
25145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /** Helper callback function if name and parameter existence match.
25245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * \param obj       obj passed into yasm_dir_helper()
25345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * \param vp        value/parameter
25445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * \param line      line passed into yasm_dir_helper()
25545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * \param data      data passed into yasm_dir_helper() plus
25645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        #yasm_dir_help.off offset
25745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * \param arg       #yasm_dir_help.arg argument
25845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * \return -1 on error, 0 otherwise.
25945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     */
26045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    int (*helper) (void *obj, yasm_valparam *vp, unsigned long line,
26145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                   void *data, uintptr_t arg);
26245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
26345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /** Offset added to data pointer passed into yasm_dir_helper() before
26445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * data pointer is given to #yasm_dir_help.helper().  This is so that
26545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * a structure can be passed into yasm_dir_helper() and this can be an
26645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * offsetof() to point the helper function to a specific structure
26745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     * member.
26845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     */
26945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    size_t off;
27045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
27145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /** Argument to pass in as the arg parameter to #yasm_dir_help.helper().
27245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org     */
27345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    uintptr_t arg;
27445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} yasm_dir_help;
27545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
27645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Help parse a list of directive value/parameters.  Takes an array of
27745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * #yasm_dir_help structures and tries to match val=param (or just val)
27845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * against the passed value/parameters.  When no match is found in the
27945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * array of help structures, calls helper_valparam.
28045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param obj       object to be passed to yasm_dir_help.helper() or
28145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *                  helper_valparam() callback
28245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param vp_first  first value/parameter to examine
28345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param line      virtual line number; passed down to helper callback
28445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param help      array of #yasm_dir_help structures
28545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param nhelp     number of array elements
28645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param data      base data pointer; if a match is found,
28745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *                  the respective #yasm_dir_help.off is added to this
28845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *                  prior to it being passed to the helper callback
28945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param helper_valparam   catch-all callback; should return -1 on error,
29045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *                          0 if not matched, 1 if matched.
29145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return -1 on error, 1 if any arguments matched (including via
29245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *         catch-all callback), 0 if no match.
29345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
29445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL
29545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint yasm_dir_helper(void *obj, yasm_valparam *vp_first, unsigned long line,
29645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    const yasm_dir_help *help, size_t nhelp, void *data,
29745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    int (*helper_valparam) (void *object,
29845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                            yasm_valparam *vp,
29945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                            unsigned long line,
30045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                            void *data));
30145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
30245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Standard helper for yasm_dir_helper() that simply sets a flag when called.
30345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * It does not look at the vp; rather, it uses the value of the arg parameter,
30445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * and stores an unsigned long value to data.
30545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param obj   unused
30645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param vp    unused
30745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param line  unused
30845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param data  pointer to an unsigned long
30945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param arg   flag to set
31045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return 0
31145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
31245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL
31345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint yasm_dir_helper_flag_set(void *obj, yasm_valparam *vp, unsigned long line,
31445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                             void *data, uintptr_t arg);
31545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
31645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Standard helper for yasm_dir_helper() that simply ORs a flag when called.
31745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * It does not look at the vp; rather, it uses the value of the arg parameter,
31845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * and ORs it with the unsigned long value in data.
31945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param obj   unused
32045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param vp    unused
32145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param line  unused
32245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param data  pointer to an unsigned long
32345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param arg   flag to OR
32445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return 0
32545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
32645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL
32745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint yasm_dir_helper_flag_or(void *obj, yasm_valparam *vp, unsigned long line,
32845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                            void *data, uintptr_t arg);
32945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
33045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Standard helper for yasm_dir_helper() that simply ANDs a flag when called.
33145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * It does not look at the vp; rather, it uses the value of the arg parameter,
33245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * and ANDs its inverse (~) with the unsigned long value in data.
33345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param obj   unused
33445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param vp    unused
33545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param line  unused
33645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param data  pointer to an unsigned long
33745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param arg   flag to AND
33845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return 0
33945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
34045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL
34145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint yasm_dir_helper_flag_and(void *obj, yasm_valparam *vp, unsigned long line,
34245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                             void *data, uintptr_t arg);
34345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
34445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Standard helper for yasm_dir_helper() that parses an expr parameter.
34545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * The #yasm_dir_help structure that uses this function should have
34645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * needsparam=1.  The obj parameter to yasm_dir_helper() when this helper
34745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * is used MUST point to a #yasm_object.  In addition, the data parameter
34845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * that is ultimately passed to this function (e.g. yasm_dir_helper() data
34945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * parameter plus #yasm_dir_help.off) must point to a #yasm_expr *
35045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * initialized to NULL.
35145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param obj   object; must be #yasm_object
35245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param vp    valparam
35345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param line  virtual line number
35445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param data  pointer to #yasm_expr *
35545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param arg   unused argument
35645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return -1 on error, 0 otherwise.
35745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
35845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL
35945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint yasm_dir_helper_expr(void *obj, yasm_valparam *vp, unsigned long line,
36045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                         void *data, uintptr_t arg);
36145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
36245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Standard helper for yasm_dir_helper() that parses an intnum parameter.
36345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * The #yasm_dir_help structure that uses this function should have
36445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * needsparam=1.  The obj parameter to yasm_dir_helper() when this helper
36545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * is used MUST point to a #yasm_object.  In addition, the data parameter
36645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * that is ultimately passed to this function (e.g. yasm_dir_helper() data
36745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * parameter plus #yasm_dir_help.off) must point to a #yasm_intnum *
36845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * initialized to NULL.
36945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param obj   object; must be #yasm_object
37045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param vp    valparam
37145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param line  virtual line number
37245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param data  pointer to #yasm_intnum *
37345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param arg   unused argument
37445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return -1 on error, 0 otherwise.
37545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
37645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL
37745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint yasm_dir_helper_intn(void *obj, yasm_valparam *vp, unsigned long line,
37845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                         void *data, uintptr_t arg);
37945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
38045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Standard helper for yasm_dir_helper() that parses an string (or
38145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * standalone identifier) parameter.
38245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * The #yasm_dir_help structure that uses this function should have
38345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * needsparam=1.  The data parameter that is ultimately passed to this
38445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * function (e.g. yasm_dir_helper() data parameter plus #yasm_dir_help.off)
38545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * must point to a char * initialized to NULL.
38645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param obj   unused
38745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param vp    valparam
38845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param line  unused
38945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param data  pointer to char *
39045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param arg   unused
39145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return -1 on error, 0 otherwise.
39245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
39345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL
39445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint yasm_dir_helper_string(void *obj, yasm_valparam *vp, unsigned long line,
39545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                           void *data, uintptr_t arg);
39645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
39745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Standard catch-all callback fro yasm_dir_helper().  Generates standard
39845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * warning for all valparams.
39945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param obj   unused
40045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param vp    valparam
40145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param line  unused
40245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param data  unused
40345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return 0
40445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
40545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL
40645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint yasm_dir_helper_valparam_warn(void *obj, yasm_valparam *vp,
40745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                  unsigned long line, void *data);
40845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#endif
409