Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 93ec4ce7 authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo
Browse files

perf tools: Asprintf like functions to format integer filter expression

  char *asprintf_expr_in_ints(const char *var, size_t nints, int *ints);
  char *asprintf_expr_not_in_ints(const char *var, size_t nints, int *ints);

Example of output formatted with those functions:

  # ./tp_filter 6 12 2015
  asprintf_expr_in_ints:     id == 6 || id == 12 || id == 2015
  asprintf_expr_not_in_ints: id != 6 && id != 12 && id != 2015
  #

It'll be used with, for instance, perf_evsel__set_filter_in_ints(), that
will be used in turn to ask the kernel to filter out all raw_syscalls:*
except for the ones specified by the user via:

 $ perf trace -e some,list,of,syscalls

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: David Ahern <dsahern@gmail.com>
Cc: Don Zickus <dzickus@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-jt07vfp6bd8y50c05j1t7hrn@git.kernel.org


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent d2d61ed5
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -357,3 +357,42 @@ void *memdup(const void *src, size_t len)

	return p;
}

char *asprintf_expr_inout_ints(const char *var, bool in, size_t nints, int *ints)
{
	/*
	 * FIXME: replace this with an expression using log10() when we
	 * find a suitable implementation, maybe the one in the dvb drivers...
	 *
	 * "%s == %d || " = log10(MAXINT) * 2 + 8 chars for the operators
	 */
	size_t size = nints * 28 + 1; /* \0 */
	size_t i, printed = 0;
	char *expr = malloc(size);

	if (expr) {
		const char *or_and = "||", *eq_neq = "==";
		char *e = expr;

		if (!in) {
			or_and = "&&";
			eq_neq = "!=";
		}

		for (i = 0; i < nints; ++i) {
			if (printed == size)
				goto out_err_overflow;

			if (i > 0)
				printed += snprintf(e + printed, size - printed, " %s ", or_and);
			printed += scnprintf(e + printed, size - printed,
					     "%s %s %d", var, eq_neq, ints[i]);
		}
	}

	return expr;

out_err_overflow:
	free(expr);
	return NULL;
}
+12 −0
Original line number Diff line number Diff line
@@ -339,4 +339,16 @@ int gzip_decompress_to_file(const char *input, int output_fd);
int lzma_decompress_to_file(const char *input, int output_fd);
#endif

char *asprintf_expr_inout_ints(const char *var, bool in, size_t nints, int *ints);

static inline char *asprintf_expr_in_ints(const char *var, size_t nints, int *ints)
{
	return asprintf_expr_inout_ints(var, true, nints, ints);
}

static inline char *asprintf_expr_not_in_ints(const char *var, size_t nints, int *ints)
{
	return asprintf_expr_inout_ints(var, false, nints, ints);
}

#endif /* GIT_COMPAT_UTIL_H */