--- /dev/null
+#include <aop.h>
+#include <string.h>
+
+AOP_I_AM_GPL_COMPATIBLE();
+
+static void plugin_join_on_call(struct aop_joinpoint *jp, void *data)
+{
+ const char *advice_name = data;
+ const char *func;
+ const char *called;
+ struct aop_dynval *p;
+
+ func = aop_capture_function_name(jp);
+ if (func == NULL || strcmp(func, "run_test") != 0)
+ return;
+
+ called = aop_capture_called_function_name(jp);
+
+ if (called == NULL || *called != '_') {
+ p = aop_capture_param(jp, 0);
+ aop_insert_advice(jp, advice_name, AOP_INSERT_BEFORE, AOP_STR_CST(called), AOP_DYNVAL(p), AOP_TERM_ARG);
+ }
+}
+
+static unsigned int plugin_pointer()
+{
+ struct aop_pointcut *pc;
+
+ const struct aop_type *intp;
+ const struct aop_type *intpp;
+ const struct aop_type *intppp;
+ const struct aop_type *char_star;
+
+ intp = aop_t_pointer_to(aop_t_signed32());
+ intpp = aop_t_pointer_to(intp);
+ intppp = aop_t_pointer_to(intpp);
+ char_star = aop_t_pointer_to(aop_t_signed8());
+
+ pc = aop_match_function_call();
+ aop_filter_call_pc_by_param(pc, 0, intp);
+ aop_join_on(pc, plugin_join_on_call, "_advice_p");
+
+ pc = aop_match_function_call();
+ aop_filter_call_pc_by_param(pc, 0, intpp);
+ aop_join_on(pc, plugin_join_on_call, "_advice_pp");
+
+ pc = aop_match_function_call();
+ aop_filter_call_pc_by_param(pc, 0, intppp);
+ aop_join_on(pc, plugin_join_on_call, "_advice_ppp");
+
+ pc = aop_match_function_call();
+ aop_filter_call_pc_by_param(pc, 0, char_star);
+ aop_join_on(pc, plugin_join_on_call, "_advice_c_str");
+
+ pc = aop_match_function_call();
+ aop_filter_call_pc_by_param(pc, 0, aop_t_all_pointer());
+ aop_join_on(pc, plugin_join_on_call, "_advice_any_ptr");
+
+ pc = aop_match_function_call();
+ aop_filter_call_pc_by_param(pc, 0, aop_t_pointer_to(aop_t_all_pointer()));
+ aop_join_on(pc, plugin_join_on_call, "_advice_any_ptr_ptr");
+
+ return 0;
+}
+
+AOP_MAIN_PROTO aop_main()
+{
+ aop_register_pass("float", plugin_pointer);
+}
--- /dev/null
+#include <stdio.h>
+
+extern int n;
+extern int *p1;
+extern int **p2;
+extern int ***p3;
+
+static const char *pointer_name(void *ptr)
+{
+ if (ptr == &n)
+ return "&n";
+ else if (ptr == &p1)
+ return "&p1";
+ else if (ptr == &p2)
+ return "&p2";
+ else if (ptr == &p3)
+ return "&p3";
+ else
+ return "other pointer";
+}
+
+void _advice_p(const char *func, int *p)
+{
+ printf("In int * advice (%s): %d\n", func, *p);
+}
+
+void _advice_pp(const char *func, int **p)
+{
+ printf("In int ** advice (%s): %d\n", func, **p);
+}
+
+void _advice_ppp(const char *func, int ***p)
+{
+ printf("In int *** advice (%s): %d\n", func, ***p);
+}
+
+void _advice_c_str(const char *func, const char *str)
+{
+ printf("In str advice (%s): %s\n", func, str);
+}
+
+void _advice_any_ptr(const char *func, void *p)
+{
+ printf("In void * advice (%s): %s\n", func, pointer_name(p));
+}
+
+void _advice_any_ptr_ptr(const char *func, void **p)
+{
+ printf("In void ** advice (%s): %s\n", func, pointer_name(*p));
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE testcase SYSTEM "testcase.dtd">
+<testcase name="Pointer Types">
+ <plugin id="plugin-pointer-types" source="plugin-pointer-types.c" />
+ <run name="Pointer parameter captures" target="pointer-types-target.c" hooks="pointer-types-hooks.c">
+ <using plugin="plugin-pointer-types" />
+ <output>
+ In int * advice (intp): 1337
+ In void * advice (intp): &n
+ int *: 1337
+ In int ** advice (intpp): 1337
+ In void * advice (intpp): &p1
+ In void ** advice (intpp): &n
+ int **: 1337
+ In int *** advice (intppp): 1337
+ In void * advice (intppp): &p2
+ In void ** advice (intppp): &p1
+ int ***: 1337
+ In str advice (c_str): h4x0r
+ In void * advice (c_str): other pointer
+ str: h4x0r
+ </output>
+ </run>
+</testcase>