.. index:: pair: arguments; keyword .. _topic-keyword: Keyword arguments ----------------- Some functions in the MPS interface take :term:`keyword arguments` in order to pass values that might be optional, or are only required in some circumstances. For example, the function :c:func:`mps_arena_create_k` creates any class of :term:`arena`, but :term:`client arenas` require you to specify a base address. These arguments are passed in a keyword argument array, like this:: mps_res_t res; mps_arena_t arena; mps_arg_s args[3]; args[0].key = MPS_KEY_ARENA_SIZE; args[0].val.size = 6553600; args[1].key = MPS_KEY_ARENA_CL_BASE; args[1].val.addr = base_address; args[2].key = MPS_KEY_ARGS_END; res = mps_arena_create_k(&arena, mps_arena_class_cl(), args); Each keyword argument in the array is a structure of type :c:type:`mps_arg_s`. For convenience and robustness, the MPS interface includes macros to help with forming keyword argument lists:: MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, 6553600); MPS_ARGS_ADD(args, MPS_KEY_ARENA_CL_BASE, base_address); res = mps_arena_create_k(&arena, mps_arena_class_cl(), args); } MPS_ARGS_END(args); The argument array must not be ``NULL``, and must end with :c:macro:`MPS_KEY_ARGS_END`. If you don't want to pass any arguments, you can pass :c:macro:`mps_args_none`. When a function that takes keyword arguments returns, the keyword argument array has been *modified* to remove any arguments that have been used. If all arguments have been used, the first element key is now :c:macro:`MPS_KEY_ARGS_END`. .. c:type:: mps_arg_s The type of the structure used to represent a single :term:`keyword argument` to a function. :: typedef struct mps_arg_s { mps_key_t key; union { /* many fields; see table below */ } val; } mps_arg_s; ``key`` identifies the key. It must be one of the values listed in the documentation for the type :c:type:`mps_key_t`. ``val`` is the corresponding value. This union contains many fields: one for each keyword argument type. The table given in the documentation for :c:type:`mps_key_t` below indicates which structure field is used by each keyword. .. note:: If you use the convenience macro :c:macro:`MPS_ARGS_ADD` then you don't need to know the name of the field. .. c:macro:: mps_args_none An array of :c:type:`mps_arg_s` representing the empty list of keyword arguments. Equivalent to:: mps_arg_s mps_args_none[] = {{MPS_KEY_ARGS_END}}; .. c:type:: mps_key_t The type of :term:`keyword argument` keys. Must take one of the following values: ======================================== ========================================================= ========================================================== Keyword Type & field in ``arg.val`` See ======================================== ========================================================= ========================================================== :c:macro:`MPS_KEY_ARGS_END` *none* *see above* :c:macro:`MPS_KEY_ALIGN` :c:type:`mps_align_t` ``align`` :c:func:`mps_class_mvff`, :c:func:`mps_class_mvt` :c:macro:`MPS_KEY_AMS_SUPPORT_AMBIGUOUS` :c:type:`mps_bool_t` ``b`` :c:func:`mps_class_ams` :c:macro:`MPS_KEY_ARENA_CL_BASE` :c:type:`mps_addr_t` ``addr`` :c:func:`mps_arena_class_cl` :c:macro:`MPS_KEY_ARENA_GRAIN_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_arena_class_vm`, :c:func:`mps_arena_class_cl` :c:macro:`MPS_KEY_ARENA_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_arena_class_vm`, :c:func:`mps_arena_class_cl` :c:macro:`MPS_KEY_AWL_FIND_DEPENDENT` ``void *(*)(void *)`` ``addr_method`` :c:func:`mps_class_awl` :c:macro:`MPS_KEY_CHAIN` :c:type:`mps_chain_t` ``chain`` :c:func:`mps_class_amc`, :c:func:`mps_class_amcz`, :c:func:`mps_class_ams`, :c:func:`mps_class_awl`, :c:func:`mps_class_lo` :c:macro:`MPS_KEY_COMMIT_LIMIT` :c:type:`size_t` ``size`` :c:func:`mps_arena_class_vm`, :c:func:`mps_arena_class_cl` :c:macro:`MPS_KEY_EXTEND_BY` :c:type:`size_t` ``size`` :c:func:`mps_class_amc`, :c:func:`mps_class_amcz`, :c:func:`mps_class_mfs`, :c:func:`mps_class_mvff` :c:macro:`MPS_KEY_FMT_ALIGN` :c:type:`mps_align_t` ``align`` :c:func:`mps_fmt_create_k` :c:macro:`MPS_KEY_FMT_CLASS` :c:type:`mps_fmt_class_t` ``fmt_class`` :c:func:`mps_fmt_create_k` :c:macro:`MPS_KEY_FMT_FWD` :c:type:`mps_fmt_fwd_t` ``fmt_fwd`` :c:func:`mps_fmt_create_k` :c:macro:`MPS_KEY_FMT_HEADER_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_fmt_create_k` :c:macro:`MPS_KEY_FMT_ISFWD` :c:type:`mps_fmt_isfwd_t` ``fmt_isfwd`` :c:func:`mps_fmt_create_k` :c:macro:`MPS_KEY_FMT_PAD` :c:type:`mps_fmt_pad_t` ``fmt_pad`` :c:func:`mps_fmt_create_k` :c:macro:`MPS_KEY_FMT_SCAN` :c:type:`mps_fmt_scan_t` ``fmt_scan`` :c:func:`mps_fmt_create_k` :c:macro:`MPS_KEY_FMT_SKIP` :c:type:`mps_fmt_skip_t` ``fmt_skip`` :c:func:`mps_fmt_create_k` :c:macro:`MPS_KEY_FORMAT` :c:type:`mps_fmt_t` ``format`` :c:func:`mps_class_amc`, :c:func:`mps_class_amcz`, :c:func:`mps_class_ams`, :c:func:`mps_class_awl`, :c:func:`mps_class_lo` , :c:func:`mps_class_snc` :c:macro:`MPS_KEY_GEN` ``unsigned`` ``u`` :c:func:`mps_class_ams`, :c:func:`mps_class_awl`, :c:func:`mps_class_lo` :c:macro:`MPS_KEY_INTERIOR` :c:type:`mps_bool_t` ``b`` :c:func:`mps_class_amc`, :c:func:`mps_class_amcz` :c:macro:`MPS_KEY_MEAN_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_class_mvt`, :c:func:`mps_class_mvff` :c:macro:`MPS_KEY_MFS_UNIT_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_class_mfs` :c:macro:`MPS_KEY_MIN_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_class_mvt` :c:macro:`MPS_KEY_MVFF_ARENA_HIGH` :c:type:`mps_bool_t` ``b`` :c:func:`mps_class_mvff` :c:macro:`MPS_KEY_MVFF_FIRST_FIT` :c:type:`mps_bool_t` ``b`` :c:func:`mps_class_mvff` :c:macro:`MPS_KEY_MVFF_SLOT_HIGH` :c:type:`mps_bool_t` ``b`` :c:func:`mps_class_mvff` :c:macro:`MPS_KEY_MVT_FRAG_LIMIT` :c:type:`mps_word_t` ``count`` :c:func:`mps_class_mvt` :c:macro:`MPS_KEY_MVT_RESERVE_DEPTH` :c:type:`mps_word_t` ``count`` :c:func:`mps_class_mvt` :c:macro:`MPS_KEY_PAUSE_TIME` ``double`` ``d`` :c:func:`mps_arena_class_vm`, :c:func:`mps_arena_class_cl` :c:macro:`MPS_KEY_POOL_DEBUG_OPTIONS` :c:type:`mps_pool_debug_option_s` ``*pool_debug_options`` :c:func:`mps_class_ams_debug`, :c:func:`mps_class_mvff_debug` :c:macro:`MPS_KEY_RANK` :c:type:`mps_rank_t` ``rank`` :c:func:`mps_class_ams`, :c:func:`mps_class_awl`, :c:func:`mps_class_snc` :c:macro:`MPS_KEY_SPARE` ``double`` ``d`` :c:func:`mps_arena_class_vm`, :c:func:`mps_class_mvff` :c:macro:`MPS_KEY_SPARE_COMMIT_LIMIT` :c:type:`size_t` ``size`` :c:func:`mps_arena_class_vm` :c:macro:`MPS_KEY_VMW3_TOP_DOWN` :c:type:`mps_bool_t` ``b`` :c:func:`mps_arena_class_vm` ======================================== ========================================================= ========================================================== .. c:macro:: MPS_ARGS_BEGIN(args) Start construction of a list of keyword arguments. This macro must be used like this:: MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, 6553600); MPS_ARGS_ADD(args, MPS_KEY_ARENA_CL_BASE, base_address); res = mps_arena_create_k(&arena, mps_arena_class_cl(), args); } MPS_ARGS_END(args); That is, you must call :c:macro:`MPS_ARGS_ADD` (or :c:macro:`MPS_ARGS_ADD_FIELD`) zero or more times, and then pass the arguments to a function. ``args`` is the name of the array that contains the keyword arguments. The array is stack-allocated, and exists between :c:macro:`MPS_ARGS_BEGIN` and :c:macro:`MPS_ARGS_END`. It is safe to nest blocks created by :c:macro:`MPS_ARGS_BEGIN` and :c:macro:`MPS_ARGS_END`. .. c:macro:: MPS_ARGS_ADD(args, key, value) Add an argument to a list of keyword arguments. This macro must be used only between :c:macro:`MPS_ARGS_BEGIN` and :c:macro:`MPS_ARGS_END`. ``args`` is the name of array that contains the keyword arguments. It must match the argument to the preceding call to :c:macro:`MPS_ARGS_BEGIN`. ``key`` is the keyword identifying this argument. It must be one of the key names starting with ``MPS_KEY_`` that are listed in the table in the documentation for :c:type:`mps_key_t`. ``value`` is the value for this argument. .. c:macro:: MPS_ARGS_ADD_FIELD(args, key, field, value) Add an argument to a list of keyword arguments. This macro must be used only between :c:macro:`MPS_ARGS_BEGIN` and :c:macro:`MPS_ARGS_END`. ``args`` is the name of array that contains the keyword arguments. It must match the argument to the preceding call to :c:macro:`MPS_ARGS_BEGIN`. ``key`` is the keyword identifying this argument. ``field`` is the name of the field in the ``val`` union in the structure :c:type:`mps_args_s`. ``value`` is the value for this argument. .. note:: You should prefer to use :c:macro:`MPS_ARGS_ADD`, because then you don't need to look up the name of the field. .. c:macro:: MPS_ARGS_END(args) Finish using a list of keyword arguments whose construction was started by :c:macro:`MPS_ARGS_BEGIN`. ``args`` is the name of array that contains the keyword arguments. It must match the argument to the preceding call to :c:macro:`MPS_ARGS_BEGIN`.