aboutsummaryrefslogtreecommitdiff
path: root/param.h
diff options
context:
space:
mode:
authorPetr Machata <pmachata@redhat.com>2012-01-06 18:40:38 +0100
committerPetr Machata <pmachata@redhat.com>2012-08-29 19:02:06 +0200
commit865303f5abd934aff8e054ff8d8117e9cd36dda3 (patch)
tree0e625934ae54bb583c8029cab0fd25d83270882e /param.h
parentd7b2292789462475ead5986c2dea25a0b8623f7d (diff)
downloadltrace-865303f5abd934aff8e054ff8d8117e9cd36dda3.tar.gz
Add module param.c/param.h
- this allows support of parameter packs, which in particular enables re-introducing of "format" and others in a more systematic manner
Diffstat (limited to 'param.h')
-rw-r--r--param.h150
1 files changed, 150 insertions, 0 deletions
diff --git a/param.h b/param.h
new file mode 100644
index 0000000..5882689
--- /dev/null
+++ b/param.h
@@ -0,0 +1,150 @@
+/*
+ * 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_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;
+
+ 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,
+ 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 */