/*
 * showevtinfo.c - show event information
 *
 * Copyright (c) 2010 Google, Inc
 * Contributed by Stephane Eranian <eranian@gmail.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * This file is part of libpfm, a performance monitoring support library for
 * applications on Linux.
 */
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <stdarg.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <regex.h>
#include <perfmon/err.h>

#include <perfmon/pfmlib.h>

#define MAXBUF		1024
#define COMBO_MAX	18

static struct {
	int compact;
	int sort;
	int encode;
	int combo;
	int combo_lim;
	int desc;
	char *csv_sep;
	pfm_event_info_t efilter;
	pfm_event_attr_info_t ufilter;
	pfm_os_t os;
	uint64_t mask;
} options;

typedef struct {
	uint64_t code;
	int idx;
} code_info_t;

static void show_event_info_compact(pfm_event_info_t *info);

static const char *srcs[PFM_ATTR_CTRL_MAX]={
	[PFM_ATTR_CTRL_UNKNOWN] = "???",
	[PFM_ATTR_CTRL_PMU] = "PMU",
	[PFM_ATTR_CTRL_PERF_EVENT] = "perf_event",
};

#ifdef PFMLIB_WINDOWS
int set_env_var(const char *var, const char *value, int ov)
{
	size_t len;
	char *str;
	int ret;

	len = strlen(var) + 1 + strlen(value) + 1;

	str = malloc(len);
	if (!str)
		return PFM_ERR_NOMEM;

	sprintf(str, "%s=%s", var, value);

	ret = putenv(str);

	free(str);

	return ret ? PFM_ERR_INVAL : PFM_SUCCESS;
}
#else
static inline int
set_env_var(const char *var, const char *value, int ov)
{
	return setenv(var, value, ov);
}
#endif

static int
event_has_pname(char *s)
{
	char *p;
	return (p = strchr(s, ':')) && *(p+1) == ':';
}

static int
print_codes(char *buf, int plm, int max_encoding)
{
	uint64_t *codes = NULL;
	int j, ret, count = 0;

	ret = pfm_get_event_encoding(buf, PFM_PLM0|PFM_PLM3, NULL, NULL, &codes, &count);
	if (ret != PFM_SUCCESS) {
		if (ret == PFM_ERR_NOTFOUND)
			errx(1, "encoding failed, try setting env variable LIBPFM_ENCODE_INACTIVE=1");
		return -1;
	}
	for(j = 0; j < max_encoding; j++) {
		if (j < count)
			printf("0x%"PRIx64, codes[j]);
		printf("%s", options.csv_sep);
	}
	free(codes);
	return 0;
}

static int
check_valid(char *buf, int plm)
{
	uint64_t *codes = NULL;
	int ret, count = 0;

	ret = pfm_get_event_encoding(buf, PFM_PLM0|PFM_PLM3, NULL, NULL, &codes, &count);
	if (ret != PFM_SUCCESS)
		return -1;
	free(codes);
	return 0;
}

static int
match_ufilters(pfm_event_attr_info_t *info)
{
	uint32_t ufilter1 = 0;
	uint32_t ufilter2 = 0;

	if (options.ufilter.is_dfl)
		ufilter1 |= 0x1;

	if (info->is_dfl)
		ufilter2 |= 0x1;

	if (options.ufilter.is_precise)
		ufilter1 |= 0x2;

	if (info->is_precise)
		ufilter2 |= 0x2;

	if (!ufilter1)
		return 1;

	/* at least one filter matches */
	return ufilter1 & ufilter2;
}

static int
match_efilters(pfm_event_info_t *info)
{
	pfm_event_attr_info_t ainfo;
	int n = 0;
	int i, ret;

	if (options.efilter.is_precise && !info->is_precise)
		return 0;

	memset(&ainfo, 0, sizeof(ainfo));
	ainfo.size = sizeof(ainfo);

	pfm_for_each_event_attr(i, info) {
		ret = pfm_get_event_attr_info(info->idx, i, options.os, &ainfo);
		if (ret != PFM_SUCCESS)
			continue;
		if (match_ufilters(&ainfo))
			return 1;
                if (ainfo.type == PFM_ATTR_UMASK)
		        n++;
	}
	return n ? 0 : 1;
}

static void
show_event_info_combo(pfm_event_info_t *info)
{
	pfm_event_attr_info_t *ainfo;
	pfm_pmu_info_t pinfo;
	char buf[MAXBUF];
	size_t len;
	int numasks = 0;
	int i, j, ret;
	uint64_t total, m, u;

	memset(&pinfo, 0, sizeof(pinfo));

	pinfo.size = sizeof(pinfo);

	ret = pfm_get_pmu_info(info->pmu, &pinfo);
	if (ret != PFM_SUCCESS)
		errx(1, "cannot get PMU info");

	ainfo = calloc(info->nattrs, sizeof(*ainfo));
	if (!ainfo)
		err(1, "event %s : ", info->name);

	/*
	 * extract attribute information and count number
	 * of umasks
	 *
	 * we cannot just drop non umasks because we need
	 * to keep attributes in order for the enumeration
	 * of 2^n
	 */
	pfm_for_each_event_attr(i, info) {
		ainfo[i].size = sizeof(*ainfo);

		ret = pfm_get_event_attr_info(info->idx, i, options.os, &ainfo[i]);
		if (ret != PFM_SUCCESS)
			errx(1, "cannot get attribute info: %s", pfm_strerror(ret));

		if (ainfo[i].type == PFM_ATTR_UMASK)
			numasks++;
	}
	if (numasks > options.combo_lim) {
		warnx("event %s has too many umasks to print all combinations, dropping to simple enumeration", info->name);
		free(ainfo);
		show_event_info_compact(info);
		return;
	}

	if (numasks) {
		if (info->nattrs > (int)((sizeof(total)<<3))) {
			warnx("too many umasks, cannot show all combinations for event %s", info->name);
			goto end;
		}
		total = 1ULL << info->nattrs;

		for (u = 1; u < total; u++) {
			len = sizeof(buf);
			len -= snprintf(buf, len, "%s::%s", pinfo.name, info->name);
			if (len <= 0) {
				warnx("event name too long%s", info->name);
				goto end;
			}
			for(m = u, j = 0; m; m >>=1, j++) {
				if (m & 0x1ULL) {
					/* we have hit a non umasks attribute, skip */
					if (ainfo[j].type != PFM_ATTR_UMASK)
						break;

					if (len < (1 + strlen(ainfo[j].name))) {
						warnx("umasks combination too long for event %s", buf);
						break;
					}
					strncat(buf, ":", len-1);buf[len-1] = '\0'; len--;
					strncat(buf, ainfo[j].name, len-1);buf[len-1] = '\0';
					len -= strlen(ainfo[j].name);
				}
			}
			/* if found a valid umask combination, check encoding */
			if (m == 0) {
				if (options.encode)
					ret = print_codes(buf, PFM_PLM0|PFM_PLM3, pinfo.max_encoding);
				else
					ret = check_valid(buf, PFM_PLM0|PFM_PLM3);
				if (!ret)
					printf("%s\n", buf);
			}
		}
	} else {
		snprintf(buf, sizeof(buf)-1, "%s::%s", pinfo.name, info->name);
		buf[sizeof(buf)-1] = '\0';

		ret = options.encode ? print_codes(buf, PFM_PLM0|PFM_PLM3, pinfo.max_encoding) : 0;
		if (!ret)
			printf("%s\n", buf);
	}
end:
	free(ainfo);
}

static void
show_event_info_compact(pfm_event_info_t *info)
{
	pfm_event_attr_info_t ainfo;
	pfm_pmu_info_t pinfo;
	char buf[MAXBUF];
	int i, ret, um = 0;

	memset(&ainfo, 0, sizeof(ainfo));
	memset(&pinfo, 0, sizeof(pinfo));

	pinfo.size = sizeof(pinfo);
	ainfo.size = sizeof(ainfo);

	ret = pfm_get_pmu_info(info->pmu, &pinfo);
	if (ret != PFM_SUCCESS)
		errx(1, "cannot get pmu info: %s", pfm_strerror(ret));

	pfm_for_each_event_attr(i, info) {
		ret = pfm_get_event_attr_info(info->idx, i, options.os, &ainfo);
		if (ret != PFM_SUCCESS)
			errx(1, "cannot get attribute info: %s", pfm_strerror(ret));

		if (ainfo.type != PFM_ATTR_UMASK)
			continue;

		if (!match_ufilters(&ainfo))
			continue;

		snprintf(buf, sizeof(buf)-1, "%s::%s:%s", pinfo.name, info->name, ainfo.name);
		buf[sizeof(buf)-1] = '\0';

		ret = 0;
		if (options.encode) {
			ret = print_codes(buf, PFM_PLM0|PFM_PLM3, pinfo.max_encoding);
		}
		if (!ret) {
			printf("%s", buf);
			if (options.desc) {
				printf("%s", options.csv_sep);
				printf("\"%s. %s.\"", info->desc, ainfo.desc);
			}
			putchar('\n');
		}
		um++;
	}
	if (um == 0) {
		if (!match_efilters(info))
			return;

		snprintf(buf, sizeof(buf)-1, "%s::%s", pinfo.name, info->name);
		buf[sizeof(buf)-1] = '\0';
		if (options.encode) {
			ret = print_codes(buf, PFM_PLM0|PFM_PLM3, pinfo.max_encoding);
			if (ret)
				return;
		}
		printf("%s", buf);
		if (options.desc) {
			printf("%s", options.csv_sep);
			printf("\"%s.\"", info->desc);
		}
		putchar('\n');
	}
}

int compare_codes(const void *a, const void *b)
{
	const code_info_t *aa = a;
	const code_info_t *bb = b;
	uint64_t m = options.mask;

	if ((aa->code & m) < (bb->code &m))
		return -1;
	if ((aa->code & m) == (bb->code & m))
		return 0;
	return 1;
}

static void
print_event_flags(pfm_event_info_t *info)
{
	int n = 0;

	if (info->is_precise) {
		printf("[precise] ");
		n++;
	}
	if (!n)
		printf("None");
}

static void
print_attr_flags(pfm_event_attr_info_t *info)
{
	int n = 0;

	if (info->is_dfl) {
		printf("[default] ");
		n++;
	}

	if (info->is_precise) {
		printf("[precise] ");
		n++;
	}

	if (!n)
		printf("None ");
}


static void
show_event_info(pfm_event_info_t *info)
{
	pfm_event_attr_info_t ainfo;
	pfm_pmu_info_t pinfo;
	int mod = 0, um = 0;
	int i, ret;
	const char *src;

	memset(&ainfo, 0, sizeof(ainfo));
	memset(&pinfo, 0, sizeof(pinfo));

	pinfo.size = sizeof(pinfo);
	ainfo.size = sizeof(ainfo);

	if (!match_efilters(info))
		return;
	ret = pfm_get_pmu_info(info->pmu, &pinfo);
	if (ret)
		errx(1, "cannot get pmu info: %s", pfm_strerror(ret));

	printf("#-----------------------------\n"
	       "IDX	 : %d\n"
	       "PMU name : %s (%s)\n"
	       "Name     : %s\n"
	       "Equiv	 : %s\n",
		info->idx,
		pinfo.name,
		pinfo.desc,
		info->name,
		info->equiv ? info->equiv : "None");

	printf("Flags    : ");
	print_event_flags(info);
	putchar('\n');

	printf("Desc     : %s\n", info->desc ? info->desc : "no description available");
	printf("Code     : 0x%"PRIx64"\n", info->code);

	pfm_for_each_event_attr(i, info) {
		ret = pfm_get_event_attr_info(info->idx, i, options.os, &ainfo);
		if (ret != PFM_SUCCESS)
			errx(1, "cannot retrieve event %s attribute info: %s", info->name, pfm_strerror(ret));

		if (ainfo.ctrl >= PFM_ATTR_CTRL_MAX) {
			warnx("event: %s has unsupported attribute source %d", info->name, ainfo.ctrl);
			ainfo.ctrl = PFM_ATTR_CTRL_UNKNOWN;
		}
		src = srcs[ainfo.ctrl];
		switch(ainfo.type) {
		case PFM_ATTR_UMASK:
			if (!match_ufilters(&ainfo))
				continue;

			printf("Umask-%02u : 0x%02"PRIx64" : %s : [%s] : ",
				um,
				ainfo.code,
				src,
				ainfo.name);

			print_attr_flags(&ainfo);

			putchar(':');

			if (ainfo.equiv)
				printf(" Alias to %s", ainfo.equiv);
			else
				printf(" %s", ainfo.desc);

			putchar('\n');
			um++;
			break;
		case PFM_ATTR_MOD_BOOL:
			printf("Modif-%02u : 0x%02"PRIx64" : %s : [%s] : %s (boolean)\n", mod, ainfo.code, src, ainfo.name, ainfo.desc);
			mod++;
			break;
		case PFM_ATTR_MOD_INTEGER:
			printf("Modif-%02u : 0x%02"PRIx64" : %s : [%s] : %s (integer)\n", mod, ainfo.code, src, ainfo.name, ainfo.desc);
			mod++;
			break;
		default:
			printf("Attr-%02u  : 0x%02"PRIx64" : %s : [%s] : %s\n", i, ainfo.code, ainfo.name, src, ainfo.desc);
		}
	}
}


static int
show_info(char *event, regex_t *preg)
{
	pfm_pmu_info_t pinfo;
	pfm_event_info_t info;
	int i, j, ret, match = 0, pname;
	size_t len, l = 0;
	char *fullname = NULL;

	memset(&pinfo, 0, sizeof(pinfo));
	memset(&info, 0, sizeof(info));

	pinfo.size = sizeof(pinfo);
	info.size = sizeof(info);

	pname = event_has_pname(event);

	/*
	 * scan all supported events, incl. those
	 * from undetected PMU models
	 */
	pfm_for_all_pmus(j) {

		ret = pfm_get_pmu_info(j, &pinfo);
		if (ret != PFM_SUCCESS)
			continue;

		/* no pmu prefix, just look for detected PMU models */
		if (!pname && !pinfo.is_present)
			continue;

		for (i = pinfo.first_event; i != -1; i = pfm_get_event_next(i)) {
			ret = pfm_get_event_info(i, options.os, &info);
			if (ret != PFM_SUCCESS)
				errx(1, "cannot get event info: %s", pfm_strerror(ret));

			len = strlen(info.name) + strlen(pinfo.name) + 1 + 2;
			if (len > l) {
				l = len;
				fullname = realloc(fullname, l);
				if (!fullname)
					err(1, "cannot allocate memory");
			}
			sprintf(fullname, "%s::%s", pinfo.name, info.name);

			if (regexec(preg, fullname, 0, NULL, 0) == 0) {
				if (options.compact)
					if (options.combo)
						show_event_info_combo(&info);
					else
						show_event_info_compact(&info);
				else
					show_event_info(&info);
				match++;
			}
		}
	}
	if (fullname)
		free(fullname);

	return match;
}

	static int
show_info_sorted(char *event, regex_t *preg)
{
	pfm_pmu_info_t pinfo;
	pfm_event_info_t info;
	unsigned int j;
	int i, ret, n, match = 0;
	size_t len, l = 0;
	char *fullname = NULL;
	code_info_t *codes;

	memset(&pinfo, 0, sizeof(pinfo));
	memset(&info, 0, sizeof(info));

	pinfo.size = sizeof(pinfo);
	info.size = sizeof(info);

	pfm_for_all_pmus(j) {

		ret = pfm_get_pmu_info(j, &pinfo);
		if (ret != PFM_SUCCESS)
			continue;

		codes = malloc(pinfo.nevents * sizeof(*codes));
		if (!codes)
			err(1, "cannot allocate memory\n");

		/* scans all supported events */
		n = 0;
		for (i = pinfo.first_event; i != -1; i = pfm_get_event_next(i)) {

			ret = pfm_get_event_info(i, options.os, &info);
			if (ret != PFM_SUCCESS)
				errx(1, "cannot get event info: %s", pfm_strerror(ret));

			if (info.pmu != j)
				continue;

			codes[n].idx = info.idx;
			codes[n].code = info.code;
			n++;
		}
		qsort(codes, n, sizeof(*codes), compare_codes);
		for(i=0; i < n; i++) {
			ret = pfm_get_event_info(codes[i].idx, options.os, &info);
			if (ret != PFM_SUCCESS)
				errx(1, "cannot get event info: %s", pfm_strerror(ret));

			len = strlen(info.name) + strlen(pinfo.name) + 1 + 2;
			if (len > l) {
				l = len;
				fullname = realloc(fullname, l);
				if (!fullname)
					err(1, "cannot allocate memory");
			}
			sprintf(fullname, "%s::%s", pinfo.name, info.name);

			if (regexec(preg, fullname, 0, NULL, 0) == 0) {
				if (options.compact)
					show_event_info_compact(&info);
				else
					show_event_info(&info);
				match++;
			}
		}
		free(codes);
	}
	if (fullname)
		free(fullname);

	return match;
}

	static void
usage(void)
{
	printf("showevtinfo [-L] [-E] [-h] [-s] [-m mask]\n"
			"-L\t\tlist one event per line (compact mode)\n"
			"-E\t\tlist one event per line with encoding (compact mode)\n"
			"-M\t\tdisplay all valid unit masks combination (use with -L or -E)\n"
			"-h\t\tget help\n"
			"-s\t\tsort event by PMU and by code based on -m mask\n"
			"-l\t\tmaximum number of umasks to list all combinations (default: %d)\n"
			"-F\t\tshow only events and attributes with certain flags (precise,...)\n"
			"-m mask\t\thexadecimal event code mask, bits to match when sorting\n"
			"-x sep\t\tuse sep as field separator in compact mode\n"
			"-D\t\t\tprint event description in compact mode\n"
			"-O os\t\tshow attributes for the specific operating system\n",
			COMBO_MAX);
}

/*
 * keep: [pmu::]event
 * drop everything else
 */
	static void
drop_event_attributes(char *str)
{
	char *p;

	p = strchr(str, ':');
	if (!p)
		return;

	str = p+1;
	/* keep PMU name */
	if (*str == ':')
		str++;

	/* stop string at 1st attribute */
	p = strchr(str, ':');
	if (p)
		*p = '\0';
}

#define EVENT_FLAGS(n, f, l) { .name = n, .ebit = f, .ubit = l }
struct attr_flags {
	const char *name;
	int ebit; /* bit position in pfm_event_info_t.flags, -1 means ignore */
	int ubit; /*  bit position in pfm_event_attr_info_t.flags, -1 means ignore */
};

static const struct attr_flags  event_flags[]={
	EVENT_FLAGS("precise", 0, 1),
	EVENT_FLAGS("pebs", 0, 1),
	EVENT_FLAGS("default", -1, 0),
	EVENT_FLAGS("dfl", -1, 0),
	EVENT_FLAGS(NULL, 0, 0)
};

static void
parse_filters(char *arg)
{
	const struct attr_flags *attr;
	char *p;

	while (arg) {
		p = strchr(arg, ',');
		if (p)
			*p++ = 0;

		for (attr = event_flags; attr->name; attr++) {
			if (!strcasecmp(attr->name, arg)) {
				switch(attr->ebit) {
				case 0:
					options.efilter.is_precise = 1;
					break;
				case -1:
					break;
				default:
					errx(1, "unknown event flag %d", attr->ebit);
				}
				switch (attr->ubit) {
				case 0:
					options.ufilter.is_dfl = 1;
					break;
				case 1:
					options.ufilter.is_precise = 1;
					break;
				case -1:
					break;
				default:
					errx(1, "unknown umaks flag %d", attr->ubit);
				}
				break;
			}
		}
		arg = p;
	}
}

static const struct {
	char *name;
	pfm_os_t os;
} supported_oses[]={
	{ .name = "none", .os = PFM_OS_NONE },
	{ .name = "raw", .os = PFM_OS_NONE },
	{ .name = "pmu", .os = PFM_OS_NONE },

	{ .name = "perf", .os = PFM_OS_PERF_EVENT},
	{ .name = "perf_ext", .os = PFM_OS_PERF_EVENT_EXT},
	{ .name = NULL, }
};

static const char *pmu_types[]={
	"unknown type",
	"core",
	"uncore",
	"OS generic",
};

static void
setup_os(char *ostr)
{
	int i;

	for (i = 0; supported_oses[i].name; i++) {
		if (!strcmp(supported_oses[i].name, ostr)) {
			options.os = supported_oses[i].os;
			return;
		}
	}
	fprintf(stderr, "unknown OS layer %s, choose from:", ostr);
	for (i = 0; supported_oses[i].name; i++) {
		if (i)
			fputc(',', stderr);
		fprintf(stderr, " %s", supported_oses[i].name);
	}
	fputc('\n', stderr);
	exit(1);
}

int
main(int argc, char **argv)
{
	static char *argv_all[2] = { ".*", NULL };
	pfm_pmu_info_t pinfo;
	char *endptr = NULL;
	char default_sep[2] = "\t";
	char *ostr = NULL;
	char **args;
	int i, match;
	regex_t preg;
	int ret, c;

	memset(&pinfo, 0, sizeof(pinfo));

	pinfo.size = sizeof(pinfo);

	while ((c=getopt(argc, argv,"hELsm:Ml:F:x:DO:")) != -1) {
		switch(c) {
			case 'L':
				options.compact = 1;
				break;
			case 'F':
				parse_filters(optarg);
				break;
			case 'E':
				options.compact = 1;
				options.encode = 1;
				break;
			case 'M':
				options.combo = 1;
				break;
			case 's':
				options.sort = 1;
				break;
			case 'D':
				options.desc = 1;
				break;
			case 'l':
				options.combo_lim = atoi(optarg);
				break;
			case 'x':
				options.csv_sep = optarg;
				break;
			case 'O':
				ostr = optarg;
				break;
			case 'm':
				options.mask = strtoull(optarg, &endptr, 16);
				if (*endptr)
					errx(1, "mask must be in hexadecimal\n");
				break;
			case 'h':
				usage();
				exit(0);
			default:
				errx(1, "unknown option error");
		}
	}
	/* to allow encoding of events from non detected PMU models */
	ret = set_env_var("LIBPFM_ENCODE_INACTIVE", "1", 1);
	if (ret != PFM_SUCCESS)
		errx(1, "cannot force inactive encoding");


	ret = pfm_initialize();
	if (ret != PFM_SUCCESS)
		errx(1, "cannot initialize libpfm: %s", pfm_strerror(ret));

	if (options.mask == 0)
		options.mask = ~0;

	if (optind == argc) {
		args = argv_all;
	} else {
		args = argv + optind;
	}
	if (!options.csv_sep)
		options.csv_sep = default_sep;

	/* avoid combinatorial explosion */
	if (options.combo_lim == 0)
		options.combo_lim = COMBO_MAX;

	if (ostr)
		setup_os(ostr);
	else
		options.os = PFM_OS_NONE;

	if (!options.compact) {
		int total_supported_events = 0;
		int total_available_events = 0;

		printf("Supported PMU models:\n");
		pfm_for_all_pmus(i) {
			ret = pfm_get_pmu_info(i, &pinfo);
			if (ret != PFM_SUCCESS)
				continue;

			printf("\t[%d, %s, \"%s\"]\n", i, pinfo.name,  pinfo.desc);
		}

		printf("Detected PMU models:\n");
		pfm_for_all_pmus(i) {
			ret = pfm_get_pmu_info(i, &pinfo);
			if (ret != PFM_SUCCESS)
				continue;

			if (pinfo.is_present) {
				if (pinfo.type >= PFM_PMU_TYPE_MAX)
					pinfo.type = PFM_PMU_TYPE_UNKNOWN;

				printf("\t[%d, %s, \"%s\", %d events, %d max encoding, %d counters, %s PMU]\n",
				       i,
				       pinfo.name,
				       pinfo.desc,
				       pinfo.nevents,
				       pinfo.max_encoding,
				       pinfo.num_cntrs + pinfo.num_fixed_cntrs,
				       pmu_types[pinfo.type]);

				total_supported_events += pinfo.nevents;
			}
			total_available_events += pinfo.nevents;
		}
		printf("Total events: %d available, %d supported\n", total_available_events, total_supported_events);
	}

	while(*args) {
		/* drop umasks and modifiers */
		drop_event_attributes(*args);
		if (regcomp(&preg, *args, REG_ICASE))
			errx(1, "error in regular expression for event \"%s\"", *argv);

		if (options.sort)
			match = show_info_sorted(*args, &preg);
		else
			match = show_info(*args, &preg);

		if (match == 0)
			errx(1, "event %s not found", *args);

		args++;
	}

	regfree(&preg);

	pfm_terminate();

	return 0;
}
