diff options
Diffstat (limited to 'param.h')
-rw-r--r-- | param.h | 163 |
1 files changed, 163 insertions, 0 deletions
@@ -0,0 +1,163 @@ +/* + * This file is part of ltrace. + * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef PARAM_H +#define PARAM_H + +#include "forward.h" + +/* The structure param holds information about a parameter of a + * function. It's used to configure a function prototype. There are + * two flavors of parameters: + * + * - simple types + * - parameter packs + * + * Parameter packs are used to describe various vararg constructs. + * They themselves are parametrized by ltrace expressions. Those will + * typically be references to other arguments, but constants might + * also make sense, and it principle, anything can be used. */ + +enum param_flavor { + PARAM_FLAVOR_TYPE, + PARAM_FLAVOR_PACK, + + /* This is for emitting arguments in two bunches. This is + * where we should stop emitting "left" bunch. All that's + * after this parameter should be emitted in the "right" + * bunch. */ + PARAM_FLAVOR_STOP, +}; + +enum param_pack_flavor { + /* This parameter pack expands to a list of ordinary + * arguments. For example if the last argument is sometimes + * ignored, that would be described by a PARAM_PACK_ARGS + * parameter pack. ioctl or ptrace are two examples that + * would benefit from this. */ + PARAM_PACK_ARGS, + + /* This parameter pack represents a vararg argument. */ + PARAM_PACK_VARARGS, +}; + +enum param_status { + PPCB_ERR = -1, /* An error occurred. */ + PPCB_STOP, /* Stop fetching the arguments. */ + PPCB_CONT, /* Display this argument and keep going. */ +}; + +/* Each parameter enumerator defines its own context object. + * Definitions of these are in respective .c files of each + * enumerator. */ +struct param_enum; + +/* int printf(string, pack(format, arg1)); */ +struct param { + enum param_flavor flavor; + union { + struct { + struct arg_type_info *type; + int own_type; + } type; + struct { + struct expr_node *args; + size_t nargs; + int own_args; + enum param_pack_flavor ppflavor; + + struct param_enum *(*init)(struct value *cb_args, + size_t nargs, + struct value_dict *arguments); + int (*next)(struct param_enum *self, + struct arg_type_info *info, + int *insert_stop); + enum param_status (*stop)(struct param_enum *self, + struct value *value); + void (*done)(struct param_enum *self); + } pack; + } u; +}; + +/* Initialize simple type parameter. TYPE is owned and released by + * PARAM if OWN_TYPE. */ +void param_init_type(struct param *param, + struct arg_type_info *type, int own_type); + +/* Initialize a stop. */ +void param_init_stop(struct param *param); + +/* Initialize parameter pack PARAM. ARGS is an array of expressions + * with parameters. ARGS is owned and released by the pack if + * OWN_ARGS. NARGS is number of ARGS. + * + * When the parameter pack should be expanded, those expressions are + * evaluated and passed to the INIT callback. This has to return a + * non-NULL context object. + * + * The NEXT callback is then called repeatedly, and should initialize + * its INFOP argument to a type of the next parameter in the pack. + * When there are no more parameters in the pack, the NEXT callback + * will set INFOP to a VOID parameter. If the callback sets + * INSERT_STOP to a non-zero value, a stop parameter shall be inserted + * before this actual parameter. + * + * Core then uses the passed-in type to fetch the next argument, which + * is in turn passed to STOP callback. This callback then tells + * ltrace core what to do next: whether there are more arguments, and + * if not, whether this argument should be displayed. + * + * After the enumeration is ended, DONE callback is called. */ +void param_init_pack(struct param *param, enum param_pack_flavor ppflavor, + struct expr_node *args, size_t nargs, int own_args, + struct param_enum *(*init)(struct value *cb_args, + size_t nargs, + struct value_dict *arguments), + int (*next)(struct param_enum *self, + struct arg_type_info *infop, + int *insert_stop), + enum param_status (*stop)(struct param_enum *self, + struct value *value), + void (*done)(struct param_enum *self)); + +/* Start enumerating types in parameter pack. This evaluates the + * parameter the pack arguments and calls the init callback. See the + * documentation of param_init_pack for details. */ +struct param_enum *param_pack_init(struct param *param, + struct value_dict *fargs); + +/* Ask for next type in enumeration. See the documentation of + * param_init_pack for details. */ +int param_pack_next(struct param *param, struct param_enum *self, + struct arg_type_info *infop, int *insert_stop); + +/* Ask whether we should stop enumerating. See the documentation of + * param_init_pack for details. */ +enum param_status param_pack_stop(struct param *param, + struct param_enum *self, struct value *value); + +/* Finish enumerating types in parameter pack. See the documentation + * of param_init_pack for details. */ +void param_pack_done(struct param *param, struct param_enum *self); + +/* Destroy data held by PARAM, but not the PARAM pointer itself. */ +void param_destroy(struct param *param); + +#endif /* PARAM_H */ |