123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408 |
- /**
- * \file libyasm/valparam.h
- * \brief YASM value/parameter interface.
- *
- * \license
- * 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:
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * - 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.
- * \endlicense
- */
- #ifndef YASM_VALPARAM_H
- #define YASM_VALPARAM_H
- #ifndef YASM_LIB_DECL
- #define YASM_LIB_DECL
- #endif
- /** Value/parameter pair. \internal */
- struct yasm_valparam {
- /*@reldef@*/ STAILQ_ENTRY(yasm_valparam) link; /**< Next pair in list */
- /*@owned@*/ /*@null@*/ char *val; /**< Value */
- /** Parameter type. */
- enum yasm_param_type {
- YASM_PARAM_ID, /**< Identifier */
- YASM_PARAM_STRING, /**< String */
- YASM_PARAM_EXPR /**< Expression */
- } type; /**< Parameter type */
- /** Parameter value. */
- union yasm_param {
- /*@owned@*/ char *id; /**< Identifier */
- /*@owned@*/ char *str; /**< String */
- /*@owned@*/ yasm_expr *e; /**< Expression */
- } param; /**< Parameter */
- /** Prefix character that indicates a raw identifier. When
- * yasm_vp_string() is called on a #YASM_PARAM_ID, all characters are
- * returned. When yasm_vp_id() is called on a #YASM_PARAM_ID, if the
- * identifier begins with this character, this character is stripped
- * from the returned value.
- */
- char id_prefix;
- };
- /** Linked list of value/parameter pairs. \internal */
- /*@reldef@*/ STAILQ_HEAD(yasm_valparamhead, yasm_valparam);
- /** Directive list entry structure. */
- struct yasm_directive {
- /** Directive name. GAS directives should include the ".", NASM
- * directives should just be the raw name (not including the []).
- * NULL entry required to terminate list of directives.
- */
- /*@null@*/ const char *name;
- const char *parser; /**< Parser keyword */
- /** Handler callback function for the directive.
- * \param object object
- * \param valparams value/parameters
- * \param objext_valparams object format-specific value/parameters
- * \param line virtual line (from yasm_linemap)
- */
- void (*handler) (yasm_object *object, yasm_valparamhead *valparams,
- yasm_valparamhead *objext_valparams, unsigned long line);
- /** Flags for pre-handler parameter checking. */
- enum yasm_directive_flags {
- YASM_DIR_ANY = 0, /**< Any valparams accepted */
- YASM_DIR_ARG_REQUIRED = 1, /**< Require at least 1 valparam */
- YASM_DIR_ID_REQUIRED = 2 /**< First valparam must be ID */
- } flags;
- };
- /** Call a directive. Performs any valparam checks asked for by the
- * directive prior to call. Note that for a variety of reasons, a directive
- * can generate an error.
- * \param directive directive
- * \param object object
- * \param valparams value/parameters
- * \param objext_valparams object format-specific value/parameters
- * \param line virtual line (from yasm_linemap)
- */
- YASM_LIB_DECL
- void yasm_call_directive(const yasm_directive *directive, yasm_object *object,
- yasm_valparamhead *valparams,
- yasm_valparamhead *objext_valparams,
- unsigned long line);
- /** Create a new valparam with identifier parameter.
- * \param v value
- * \param p parameter
- * \param id_prefix identifier prefix for raw identifiers
- * \return Newly allocated valparam.
- */
- YASM_LIB_DECL
- yasm_valparam *yasm_vp_create_id(/*@keep@*/ char *v, /*@keep@*/ char *p,
- int id_prefix);
- /** Create a new valparam with string parameter.
- * \param v value
- * \param p parameter
- * \return Newly allocated valparam.
- */
- YASM_LIB_DECL
- yasm_valparam *yasm_vp_create_string(/*@keep@*/ char *v, /*@keep@*/ char *p);
- /** Create a new valparam with expression parameter.
- * \param v value
- * \param p parameter
- * \return Newly allocated valparam.
- */
- YASM_LIB_DECL
- yasm_valparam *yasm_vp_create_expr(/*@keep@*/ char *v,
- /*@keep@*/ yasm_expr *p);
- /** Get a valparam parameter as an expr. If the parameter is an identifier,
- * it's treated as a symbol (yasm_symtab_use() is called to convert it).
- * \param vp valparam
- * \param symtab symbol table
- * \param line virtual line
- * \return Expression, or NULL if vp is NULL or the parameter cannot be
- * converted to an expression.
- */
- YASM_LIB_DECL
- /*@null@*/ /*@only@*/ yasm_expr *yasm_vp_expr
- (const yasm_valparam *vp, yasm_symtab *symtab, unsigned long line);
- /** Get a valparam parameter as a string. If the parameter is an identifier,
- * it's treated as a string.
- * \param vp valparam
- * \return String, or NULL if vp is NULL or the parameter cannot be realized
- * as a string.
- */
- YASM_LIB_DECL
- /*@null@*/ /*@dependent@*/ const char *yasm_vp_string(const yasm_valparam *vp);
- /** Get a valparam parameter as an identifier.
- * \param vp valparam
- * \return Identifier (string), or NULL if vp is NULL or the parameter is not
- * an identifier.
- */
- YASM_LIB_DECL
- /*@null@*/ /*@dependent@*/ const char *yasm_vp_id(const yasm_valparam *vp);
- /** Create a new linked list of valparams.
- * \return Newly allocated valparam list.
- */
- YASM_LIB_DECL
- yasm_valparamhead *yasm_vps_create(void);
- /** Destroy a list of valparams (created with yasm_vps_create).
- * \param headp list of valparams
- */
- YASM_LIB_DECL
- void yasm_vps_destroy(yasm_valparamhead *headp);
- /** Initialize linked list of valparams.
- * \param headp linked list
- */
- void yasm_vps_initialize(/*@out@*/ yasm_valparamhead *headp);
- #ifndef YASM_DOXYGEN
- #define yasm_vps_initialize(headp) STAILQ_INIT(headp)
- #endif
- /** Destroy (free allocated memory for) linked list of valparams (created with
- * yasm_vps_initialize).
- * \warning Deletes val/params.
- * \param headp linked list
- */
- YASM_LIB_DECL
- void yasm_vps_delete(yasm_valparamhead *headp);
- /** Append valparam to tail of linked list.
- * \param headp linked list
- * \param vp valparam
- */
- void yasm_vps_append(yasm_valparamhead *headp, /*@keep@*/ yasm_valparam *vp);
- #ifndef YASM_DOXYGEN
- #define yasm_vps_append(headp, vp) do { \
- if (vp) \
- STAILQ_INSERT_TAIL(headp, vp, link); \
- } while(0)
- #endif
- /** Get first valparam in linked list.
- * \param headp linked list
- * \return First valparam in linked list.
- */
- /*@null@*/ /*@dependent@*/ yasm_valparam *yasm_vps_first
- (yasm_valparamhead *headp);
- #ifndef YASM_DOXYGEN
- #define yasm_vps_first(headp) STAILQ_FIRST(headp)
- #endif
- /** Get next valparam in linked list.
- * \param cur previous valparam in linked list
- * \return Next valparam in linked list.
- */
- /*@null@*/ /*@dependent@*/ yasm_valparam *yasm_vps_next(yasm_valparam *cur);
- #ifndef YASM_DOXYGEN
- #define yasm_vps_next(cur) STAILQ_NEXT(cur, link)
- #endif
- /** Iterate through linked list of valparams.
- * \internal
- * \param iter iterator variable
- * \param headp linked list
- */
- #ifndef YASM_DOXYGEN
- #define yasm_vps_foreach(iter, headp) STAILQ_FOREACH(iter, headp, link)
- #endif
- /** Print linked list of valparams. For debugging purposes.
- * \param f file
- * \param headp linked list
- */
- YASM_LIB_DECL
- void yasm_vps_print(/*@null@*/ const yasm_valparamhead *headp, FILE *f);
- /** Directive valparam parse helper structure. */
- typedef struct yasm_dir_help {
- /** Value portion of val=param (if needsparam=1), or standalone identifier
- * (if needsparam=0).
- */
- const char *name;
- /** 1 if value requires parameter, 0 if it must not have a parameter. */
- int needsparam;
- /** Helper callback function if name and parameter existence match.
- * \param obj obj passed into yasm_dir_helper()
- * \param vp value/parameter
- * \param line line passed into yasm_dir_helper()
- * \param data data passed into yasm_dir_helper() plus
- #yasm_dir_help.off offset
- * \param arg #yasm_dir_help.arg argument
- * \return -1 on error, 0 otherwise.
- */
- int (*helper) (void *obj, yasm_valparam *vp, unsigned long line,
- void *data, uintptr_t arg);
- /** Offset added to data pointer passed into yasm_dir_helper() before
- * data pointer is given to #yasm_dir_help.helper(). This is so that
- * a structure can be passed into yasm_dir_helper() and this can be an
- * offsetof() to point the helper function to a specific structure
- * member.
- */
- size_t off;
- /** Argument to pass in as the arg parameter to #yasm_dir_help.helper().
- */
- uintptr_t arg;
- } yasm_dir_help;
- /** Help parse a list of directive value/parameters. Takes an array of
- * #yasm_dir_help structures and tries to match val=param (or just val)
- * against the passed value/parameters. When no match is found in the
- * array of help structures, calls helper_valparam.
- * \param obj object to be passed to yasm_dir_help.helper() or
- * helper_valparam() callback
- * \param vp_first first value/parameter to examine
- * \param line virtual line number; passed down to helper callback
- * \param help array of #yasm_dir_help structures
- * \param nhelp number of array elements
- * \param data base data pointer; if a match is found,
- * the respective #yasm_dir_help.off is added to this
- * prior to it being passed to the helper callback
- * \param helper_valparam catch-all callback; should return -1 on error,
- * 0 if not matched, 1 if matched.
- * \return -1 on error, 1 if any arguments matched (including via
- * catch-all callback), 0 if no match.
- */
- YASM_LIB_DECL
- 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 *object,
- yasm_valparam *vp,
- unsigned long line,
- void *data));
- /** Standard helper for yasm_dir_helper() that simply sets a flag when called.
- * It does not look at the vp; rather, it uses the value of the arg parameter,
- * and stores an unsigned long value to data.
- * \param obj unused
- * \param vp unused
- * \param line unused
- * \param data pointer to an unsigned long
- * \param arg flag to set
- * \return 0
- */
- YASM_LIB_DECL
- int yasm_dir_helper_flag_set(void *obj, yasm_valparam *vp, unsigned long line,
- void *data, uintptr_t arg);
- /** Standard helper for yasm_dir_helper() that simply ORs a flag when called.
- * It does not look at the vp; rather, it uses the value of the arg parameter,
- * and ORs it with the unsigned long value in data.
- * \param obj unused
- * \param vp unused
- * \param line unused
- * \param data pointer to an unsigned long
- * \param arg flag to OR
- * \return 0
- */
- YASM_LIB_DECL
- int yasm_dir_helper_flag_or(void *obj, yasm_valparam *vp, unsigned long line,
- void *data, uintptr_t arg);
- /** Standard helper for yasm_dir_helper() that simply ANDs a flag when called.
- * It does not look at the vp; rather, it uses the value of the arg parameter,
- * and ANDs its inverse (~) with the unsigned long value in data.
- * \param obj unused
- * \param vp unused
- * \param line unused
- * \param data pointer to an unsigned long
- * \param arg flag to AND
- * \return 0
- */
- YASM_LIB_DECL
- int yasm_dir_helper_flag_and(void *obj, yasm_valparam *vp, unsigned long line,
- void *data, uintptr_t arg);
- /** Standard helper for yasm_dir_helper() that parses an expr parameter.
- * The #yasm_dir_help structure that uses this function should have
- * needsparam=1. The obj parameter to yasm_dir_helper() when this helper
- * is used MUST point to a #yasm_object. In addition, the data parameter
- * that is ultimately passed to this function (e.g. yasm_dir_helper() data
- * parameter plus #yasm_dir_help.off) must point to a #yasm_expr *
- * initialized to NULL.
- * \param obj object; must be #yasm_object
- * \param vp valparam
- * \param line virtual line number
- * \param data pointer to #yasm_expr *
- * \param arg unused argument
- * \return -1 on error, 0 otherwise.
- */
- YASM_LIB_DECL
- int yasm_dir_helper_expr(void *obj, yasm_valparam *vp, unsigned long line,
- void *data, uintptr_t arg);
- /** Standard helper for yasm_dir_helper() that parses an intnum parameter.
- * The #yasm_dir_help structure that uses this function should have
- * needsparam=1. The obj parameter to yasm_dir_helper() when this helper
- * is used MUST point to a #yasm_object. In addition, the data parameter
- * that is ultimately passed to this function (e.g. yasm_dir_helper() data
- * parameter plus #yasm_dir_help.off) must point to a #yasm_intnum *
- * initialized to NULL.
- * \param obj object; must be #yasm_object
- * \param vp valparam
- * \param line virtual line number
- * \param data pointer to #yasm_intnum *
- * \param arg unused argument
- * \return -1 on error, 0 otherwise.
- */
- YASM_LIB_DECL
- int yasm_dir_helper_intn(void *obj, yasm_valparam *vp, unsigned long line,
- void *data, uintptr_t arg);
- /** Standard helper for yasm_dir_helper() that parses an string (or
- * standalone identifier) parameter.
- * The #yasm_dir_help structure that uses this function should have
- * needsparam=1. The data parameter that is ultimately passed to this
- * function (e.g. yasm_dir_helper() data parameter plus #yasm_dir_help.off)
- * must point to a char * initialized to NULL.
- * \param obj unused
- * \param vp valparam
- * \param line unused
- * \param data pointer to char *
- * \param arg unused
- * \return -1 on error, 0 otherwise.
- */
- YASM_LIB_DECL
- int yasm_dir_helper_string(void *obj, yasm_valparam *vp, unsigned long line,
- void *data, uintptr_t arg);
- /** Standard catch-all callback fro yasm_dir_helper(). Generates standard
- * warning for all valparams.
- * \param obj unused
- * \param vp valparam
- * \param line unused
- * \param data unused
- * \return 0
- */
- YASM_LIB_DECL
- int yasm_dir_helper_valparam_warn(void *obj, yasm_valparam *vp,
- unsigned long line, void *data);
- #endif
|