// SPDX-License-Identifier: LGPL-2.1
/*
 * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
 *
 *
 *  The parts for function graph printing was taken and modified from the
 *  Linux Kernel that were written by
 *    - Copyright (C) 2009  Frederic Weisbecker,
 *  Frederic Weisbecker gave his permission to relicense the code to
 *  the Lesser General Public License.
 */
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <ctype.h>
#include <errno.h>
#include <stdint.h>
#include <limits.h>
#include <linux/time64.h>

#include <netinet/in.h>
#include "event-parse.h"

#include "event-parse-local.h"
#include "event-utils.h"
#include "trace-seq.h"

static const char *input_buf;
static unsigned long long input_buf_ptr;
static unsigned long long input_buf_siz;

static int is_flag_field;
static int is_symbolic_field;

static int show_warning = 1;

#define do_warning(fmt, ...)				\
	do {						\
		if (show_warning)			\
			warning(fmt, ##__VA_ARGS__);	\
	} while (0)

#define do_warning_event(event, fmt, ...)			\
	do {							\
		if (!show_warning)				\
			continue;				\
								\
		if (event)					\
			warning("[%s:%s] " fmt, event->system,	\
				event->name, ##__VA_ARGS__);	\
		else						\
			warning(fmt, ##__VA_ARGS__);		\
	} while (0)

/**
 * init_input_buf - init buffer for parsing
 * @buf: buffer to parse
 * @size: the size of the buffer
 *
 * Initializes the internal buffer that tep_read_token() will parse.
 */
__hidden void init_input_buf(const char *buf, unsigned long long size)
{
	input_buf = buf;
	input_buf_siz = size;
	input_buf_ptr = 0;
}

__hidden const char *get_input_buf(void)
{
	return input_buf;
}

__hidden unsigned long long get_input_buf_ptr(void)
{
	return input_buf_ptr;
}

struct event_handler {
	struct event_handler		*next;
	int				id;
	const char			*sys_name;
	const char			*event_name;
	tep_event_handler_func		func;
	void				*context;
};

struct func_params {
	struct func_params	*next;
	enum tep_func_arg_type	type;
};

struct tep_function_handler {
	struct tep_function_handler	*next;
	enum tep_func_arg_type		ret_type;
	char				*name;
	tep_func_handler		func;
	struct func_params		*params;
	int				nr_args;
};

static unsigned long long
process_defined_func(struct trace_seq *s, void *data, int size,
		     struct tep_event *event, struct tep_print_arg *arg);

static void free_func_handle(struct tep_function_handler *func);

void breakpoint(void)
{
	static int x;
	x++;
}

static struct tep_print_arg *alloc_arg(void)
{
	return calloc(1, sizeof(struct tep_print_arg));
}

struct tep_cmdline {
	char *comm;
	int pid;
};

static int cmdline_cmp(const void *a, const void *b)
{
	const struct tep_cmdline *ca = a;
	const struct tep_cmdline *cb = b;

	if (ca->pid < cb->pid)
		return -1;
	if (ca->pid > cb->pid)
		return 1;

	return 0;
}

/* Looking for where to place the key */
static int cmdline_slot_cmp(const void *a, const void *b)
{
	const struct tep_cmdline *ca = a;
	const struct tep_cmdline *cb = b;
	const struct tep_cmdline *cb1 = cb + 1;

	if (ca->pid < cb->pid)
		return -1;

	if (ca->pid > cb->pid) {
		if (ca->pid <= cb1->pid)
			return 0;
		return 1;
	}

	return 0;
}

struct cmdline_list {
	struct cmdline_list	*next;
	char			*comm;
	int			pid;
};

static int cmdline_init(struct tep_handle *tep)
{
	struct cmdline_list *cmdlist = tep->cmdlist;
	struct cmdline_list *item;
	struct tep_cmdline *cmdlines;
	int i;

	cmdlines = malloc(sizeof(*cmdlines) * tep->cmdline_count);
	if (!cmdlines)
		return -1;

	i = 0;
	while (cmdlist) {
		cmdlines[i].pid = cmdlist->pid;
		cmdlines[i].comm = cmdlist->comm;
		i++;
		item = cmdlist;
		cmdlist = cmdlist->next;
		free(item);
	}

	qsort(cmdlines, tep->cmdline_count, sizeof(*cmdlines), cmdline_cmp);

	tep->cmdlines = cmdlines;
	tep->cmdlist = NULL;

	return 0;
}

static const char *find_cmdline(struct tep_handle *tep, int pid)
{
	const struct tep_cmdline *comm;
	struct tep_cmdline key;

	if (!pid)
		return "<idle>";

	if (!tep->cmdlines && cmdline_init(tep))
		return "<not enough memory for cmdlines!>";

	key.pid = pid;

	comm = bsearch(&key, tep->cmdlines, tep->cmdline_count,
		       sizeof(*tep->cmdlines), cmdline_cmp);

	if (comm)
		return comm->comm;
	return "<...>";
}

/**
 * tep_is_pid_registered - return if a pid has a cmdline registered
 * @tep: a handle to the trace event parser context
 * @pid: The pid to check if it has a cmdline registered with.
 *
 * Returns true if the pid has a cmdline mapped to it
 * false otherwise.
 */
bool tep_is_pid_registered(struct tep_handle *tep, int pid)
{
	const struct tep_cmdline *comm;
	struct tep_cmdline key;

	if (!pid)
		return true;

	if (!tep->cmdlines && cmdline_init(tep))
		return false;

	key.pid = pid;

	comm = bsearch(&key, tep->cmdlines, tep->cmdline_count,
		       sizeof(*tep->cmdlines), cmdline_cmp);

	if (comm)
		return true;
	return false;
}

/*
 * If the command lines have been converted to an array, then
 * we must add this pid. This is much slower than when cmdlines
 * are added before the array is initialized.
 */
static int add_new_comm(struct tep_handle *tep,
			const char *comm, int pid, bool override)
{
	struct tep_cmdline *cmdlines = tep->cmdlines;
	struct tep_cmdline *cmdline;
	struct tep_cmdline key;
	char *new_comm;
	int cnt;

	if (!pid)
		return 0;

	/* avoid duplicates */
	key.pid = pid;

	cmdline = bsearch(&key, tep->cmdlines, tep->cmdline_count,
			  sizeof(*tep->cmdlines), cmdline_cmp);
	if (cmdline) {
		if (!override) {
			errno = EEXIST;
			return -1;
		}
		new_comm = strdup(comm);
		if (!new_comm) {
			errno = ENOMEM;
			return -1;
		}
		free(cmdline->comm);
		cmdline->comm = new_comm;

		return 0;
	}

	cmdlines = realloc(cmdlines, sizeof(*cmdlines) * (tep->cmdline_count + 1));
	if (!cmdlines) {
		errno = ENOMEM;
		return -1;
	}
	tep->cmdlines = cmdlines;

	key.comm = strdup(comm);
	if (!key.comm) {
		errno = ENOMEM;
		return -1;
	}

	if (!tep->cmdline_count) {
		/* no entries yet */
		tep->cmdlines[0] = key;
		tep->cmdline_count++;
		return 0;
	}

	/* Now find where we want to store the new cmdline */
	cmdline = bsearch(&key, tep->cmdlines, tep->cmdline_count - 1,
			  sizeof(*tep->cmdlines), cmdline_slot_cmp);

	cnt = tep->cmdline_count;
	if (cmdline) {
		/* cmdline points to the one before the spot we want */
		cmdline++;
		cnt -= cmdline - tep->cmdlines;

	} else {
		/* The new entry is either before or after the list */
		if (key.pid > tep->cmdlines[tep->cmdline_count - 1].pid) {
			tep->cmdlines[tep->cmdline_count++] = key;
			return 0;
		}
		cmdline = &tep->cmdlines[0];
	}
	memmove(cmdline + 1, cmdline, (cnt * sizeof(*cmdline)));
	*cmdline = key;

	tep->cmdline_count++;

	return 0;
}

static int _tep_register_comm(struct tep_handle *tep,
			      const char *comm, int pid, bool override)
{
	struct cmdline_list *item;

	if (tep->cmdlines)
		return add_new_comm(tep, comm, pid, override);

	item = malloc(sizeof(*item));
	if (!item)
		return -1;

	if (comm)
		item->comm = strdup(comm);
	else
		item->comm = strdup("<...>");
	if (!item->comm) {
		free(item);
		return -1;
	}
	item->pid = pid;
	item->next = tep->cmdlist;

	tep->cmdlist = item;
	tep->cmdline_count++;

	return 0;
}

/**
 * tep_register_comm - register a pid / comm mapping
 * @tep: a handle to the trace event parser context
 * @comm: the command line to register
 * @pid: the pid to map the command line to
 *
 * This adds a mapping to search for command line names with
 * a given pid. The comm is duplicated. If a command with the same pid
 * already exist, -1 is returned and errno is set to EEXIST
 */
int tep_register_comm(struct tep_handle *tep, const char *comm, int pid)
{
	return _tep_register_comm(tep, comm, pid, false);
}

/**
 * tep_override_comm - register a pid / comm mapping
 * @tep: a handle to the trace event parser context
 * @comm: the command line to register
 * @pid: the pid to map the command line to
 *
 * This adds a mapping to search for command line names with
 * a given pid. The comm is duplicated. If a command with the same pid
 * already exist, the command string is udapted with the new one
 */
int tep_override_comm(struct tep_handle *tep, const char *comm, int pid)
{
	if (!tep->cmdlines && cmdline_init(tep)) {
		errno = ENOMEM;
		return -1;
	}
	return _tep_register_comm(tep, comm, pid, true);
}

struct func_map {
	unsigned long long		addr;
	char				*func;
	char				*mod;
};

struct func_list {
	struct func_list	*next;
	unsigned long long	addr;
	char			*func;
	char			*mod;
};

static int func_cmp(const void *a, const void *b)
{
	const struct func_map *fa = a;
	const struct func_map *fb = b;

	if (fa->addr < fb->addr)
		return -1;
	if (fa->addr > fb->addr)
		return 1;

	return 0;
}

/*
 * We are searching for a record in between, not an exact
 * match.
 */
static int func_bcmp(const void *a, const void *b)
{
	const struct func_map *fa = a;
	const struct func_map *fb = b;

	if ((fa->addr == fb->addr) ||

	    (fa->addr > fb->addr &&
	     fa->addr < (fb+1)->addr))
		return 0;

	if (fa->addr < fb->addr)
		return -1;

	return 1;
}

static int func_map_init(struct tep_handle *tep)
{
	struct func_list *funclist;
	struct func_list *item;
	struct func_map *func_map;
	int i;

	func_map = malloc(sizeof(*func_map) * (tep->func_count + 1));
	if (!func_map)
		return -1;

	funclist = tep->funclist;

	i = 0;
	while (funclist) {
		func_map[i].func = funclist->func;
		func_map[i].addr = funclist->addr;
		func_map[i].mod = funclist->mod;
		i++;
		item = funclist;
		funclist = funclist->next;
		free(item);
	}

	qsort(func_map, tep->func_count, sizeof(*func_map), func_cmp);

	/*
	 * Add a special record at the end.
	 */
	func_map[tep->func_count].func = NULL;
	func_map[tep->func_count].addr = 0;
	func_map[tep->func_count].mod = NULL;

	tep->func_map = func_map;
	tep->funclist = NULL;

	return 0;
}

static struct func_map *
__find_func(struct tep_handle *tep, unsigned long long addr)
{
	struct func_map *func;
	struct func_map key;

	if (!tep->func_map)
		func_map_init(tep);

	key.addr = addr;

	func = bsearch(&key, tep->func_map, tep->func_count,
		       sizeof(*tep->func_map), func_bcmp);

	return func;
}

struct func_resolver {
	tep_func_resolver_t	*func;
	void			*priv;
	struct func_map		map;
};

/**
 * tep_set_function_resolver - set an alternative function resolver
 * @tep: a handle to the trace event parser context
 * @resolver: function to be used
 * @priv: resolver function private state.
 *
 * Some tools may have already a way to resolve kernel functions, allow them to
 * keep using it instead of duplicating all the entries inside tep->funclist.
 */
int tep_set_function_resolver(struct tep_handle *tep,
			      tep_func_resolver_t *func, void *priv)
{
	struct func_resolver *resolver = malloc(sizeof(*resolver));

	if (resolver == NULL)
		return -1;

	resolver->func = func;
	resolver->priv = priv;

	free(tep->func_resolver);
	tep->func_resolver = resolver;

	return 0;
}

/**
 * tep_reset_function_resolver - reset alternative function resolver
 * @tep: a handle to the trace event parser context
 *
 * Stop using whatever alternative resolver was set, use the default
 * one instead.
 */
void tep_reset_function_resolver(struct tep_handle *tep)
{
	free(tep->func_resolver);
	tep->func_resolver = NULL;
}

static struct func_map *
find_func(struct tep_handle *tep, unsigned long long addr)
{
	struct func_map *map;

	if (!tep->func_resolver)
		return __find_func(tep, addr);

	map = &tep->func_resolver->map;
	map->mod  = NULL;
	map->addr = addr;
	map->func = tep->func_resolver->func(tep->func_resolver->priv,
					     &map->addr, &map->mod);
	if (map->func == NULL)
		return NULL;

	return map;
}

/**
 * tep_find_function - find a function by a given address
 * @tep: a handle to the trace event parser context
 * @addr: the address to find the function with
 *
 * Returns a pointer to the function stored that has the given
 * address. Note, the address does not have to be exact, it
 * will select the function that would contain the address.
 */
const char *tep_find_function(struct tep_handle *tep, unsigned long long addr)
{
	struct func_map *map;

	map = find_func(tep, addr);
	if (!map)
		return NULL;

	return map->func;
}

/**
 * tep_find_function_address - find a function address by a given address
 * @tep: a handle to the trace event parser context
 * @addr: the address to find the function with
 *
 * Returns the address the function starts at. This can be used in
 * conjunction with tep_find_function to print both the function
 * name and the function offset.
 */
unsigned long long
tep_find_function_address(struct tep_handle *tep, unsigned long long addr)
{
	struct func_map *map;

	map = find_func(tep, addr);
	if (!map)
		return 0;

	return map->addr;
}

/**
 * tep_register_function - register a function with a given address
 * @tep: a handle to the trace event parser context
 * @function: the function name to register
 * @addr: the address the function starts at
 * @mod: the kernel module the function may be in (NULL for none)
 *
 * This registers a function name with an address and module.
 * The @func passed in is duplicated.
 */
int tep_register_function(struct tep_handle *tep, char *func,
			  unsigned long long addr, char *mod)
{
	struct func_list *item = malloc(sizeof(*item));

	if (!item)
		return -1;

	item->next = tep->funclist;
	item->func = strdup(func);
	if (!item->func)
		goto out_free;

	if (mod) {
		item->mod = strdup(mod);
		if (!item->mod)
			goto out_free_func;
	} else
		item->mod = NULL;
	item->addr = addr;

	tep->funclist = item;
	tep->func_count++;

	return 0;

out_free_func:
	free(item->func);
	item->func = NULL;
out_free:
	free(item);
	errno = ENOMEM;
	return -1;
}

/**
 * tep_print_funcs - print out the stored functions
 * @tep: a handle to the trace event parser context
 *
 * This prints out the stored functions.
 */
void tep_print_funcs(struct tep_handle *tep)
{
	int i;

	if (!tep->func_map)
		func_map_init(tep);

	for (i = 0; i < (int)tep->func_count; i++) {
		printf("%016llx %s",
		       tep->func_map[i].addr,
		       tep->func_map[i].func);
		if (tep->func_map[i].mod)
			printf(" [%s]\n", tep->func_map[i].mod);
		else
			printf("\n");
	}
}

struct printk_map {
	unsigned long long		addr;
	char				*printk;
};

struct printk_list {
	struct printk_list	*next;
	unsigned long long	addr;
	char			*printk;
};

static int printk_cmp(const void *a, const void *b)
{
	const struct printk_map *pa = a;
	const struct printk_map *pb = b;

	if (pa->addr < pb->addr)
		return -1;
	if (pa->addr > pb->addr)
		return 1;

	return 0;
}

static int printk_map_init(struct tep_handle *tep)
{
	struct printk_list *printklist;
	struct printk_list *item;
	struct printk_map *printk_map;
	int i;

	printk_map = malloc(sizeof(*printk_map) * (tep->printk_count + 1));
	if (!printk_map)
		return -1;

	printklist = tep->printklist;

	i = 0;
	while (printklist) {
		printk_map[i].printk = printklist->printk;
		printk_map[i].addr = printklist->addr;
		i++;
		item = printklist;
		printklist = printklist->next;
		free(item);
	}

	qsort(printk_map, tep->printk_count, sizeof(*printk_map), printk_cmp);

	tep->printk_map = printk_map;
	tep->printklist = NULL;

	return 0;
}

static struct printk_map *
find_printk(struct tep_handle *tep, unsigned long long addr)
{
	struct printk_map *printk;
	struct printk_map key;

	if (!tep->printk_map && printk_map_init(tep))
		return NULL;

	key.addr = addr;

	printk = bsearch(&key, tep->printk_map, tep->printk_count,
			 sizeof(*tep->printk_map), printk_cmp);

	return printk;
}

/**
 * tep_register_print_string - register a string by its address
 * @tep: a handle to the trace event parser context
 * @fmt: the string format to register
 * @addr: the address the string was located at
 *
 * This registers a string by the address it was stored in the kernel.
 * The @fmt passed in is duplicated.
 */
int tep_register_print_string(struct tep_handle *tep, const char *fmt,
			      unsigned long long addr)
{
	struct printk_list *item = malloc(sizeof(*item));
	char *p;

	if (!item)
		return -1;

	item->next = tep->printklist;
	item->addr = addr;

	/* Strip off quotes and '\n' from the end */
	if (fmt[0] == '"')
		fmt++;
	item->printk = strdup(fmt);
	if (!item->printk)
		goto out_free;

	p = item->printk + strlen(item->printk) - 1;
	if (*p == '"')
		*p = 0;

	p -= 2;
	if (strcmp(p, "\\n") == 0)
		*p = 0;

	tep->printklist = item;
	tep->printk_count++;

	return 0;

out_free:
	free(item);
	errno = ENOMEM;
	return -1;
}

/**
 * tep_print_printk - print out the stored strings
 * @tep: a handle to the trace event parser context
 *
 * This prints the string formats that were stored.
 */
void tep_print_printk(struct tep_handle *tep)
{
	int i;

	if (!tep->printk_map)
		printk_map_init(tep);

	for (i = 0; i < (int)tep->printk_count; i++) {
		printf("%016llx %s\n",
		       tep->printk_map[i].addr,
		       tep->printk_map[i].printk);
	}
}

static struct tep_event *alloc_event(void)
{
	return calloc(1, sizeof(struct tep_event));
}

static int add_event(struct tep_handle *tep, struct tep_event *event)
{
	int i;
	struct tep_event **events = realloc(tep->events, sizeof(event) *
					    (tep->nr_events + 1));
	if (!events)
		return -1;

	tep->events = events;

	for (i = 0; i < tep->nr_events; i++) {
		if (tep->events[i]->id > event->id)
			break;
	}
	if (i < tep->nr_events)
		memmove(&tep->events[i + 1],
			&tep->events[i],
			sizeof(event) * (tep->nr_events - i));

	tep->events[i] = event;
	tep->nr_events++;

	event->tep = tep;

	return 0;
}

static int event_item_type(enum tep_event_type type)
{
	switch (type) {
	case TEP_EVENT_ITEM ... TEP_EVENT_SQUOTE:
		return 1;
	case TEP_EVENT_ERROR ... TEP_EVENT_DELIM:
	default:
		return 0;
	}
}

static void free_flag_sym(struct tep_print_flag_sym *fsym)
{
	struct tep_print_flag_sym *next;

	while (fsym) {
		next = fsym->next;
		free(fsym->value);
		free(fsym->str);
		free(fsym);
		fsym = next;
	}
}

static void free_arg(struct tep_print_arg *arg)
{
	struct tep_print_arg *farg;

	if (!arg)
		return;

	switch (arg->type) {
	case TEP_PRINT_ATOM:
		free(arg->atom.atom);
		break;
	case TEP_PRINT_FIELD:
		free(arg->field.name);
		break;
	case TEP_PRINT_FLAGS:
		free_arg(arg->flags.field);
		free(arg->flags.delim);
		free_flag_sym(arg->flags.flags);
		break;
	case TEP_PRINT_SYMBOL:
		free_arg(arg->symbol.field);
		free_flag_sym(arg->symbol.symbols);
		break;
	case TEP_PRINT_HEX:
	case TEP_PRINT_HEX_STR:
		free_arg(arg->hex.field);
		free_arg(arg->hex.size);
		break;
	case TEP_PRINT_INT_ARRAY:
		free_arg(arg->int_array.field);
		free_arg(arg->int_array.count);
		free_arg(arg->int_array.el_size);
		break;
	case TEP_PRINT_TYPE:
		free(arg->typecast.type);
		free_arg(arg->typecast.item);
		break;
	case TEP_PRINT_STRING:
	case TEP_PRINT_BSTRING:
		free(arg->string.string);
		break;
	case TEP_PRINT_BITMASK:
		free(arg->bitmask.bitmask);
		break;
	case TEP_PRINT_DYNAMIC_ARRAY:
	case TEP_PRINT_DYNAMIC_ARRAY_LEN:
		free(arg->dynarray.index);
		break;
	case TEP_PRINT_OP:
		free(arg->op.op);
		free_arg(arg->op.left);
		free_arg(arg->op.right);
		break;
	case TEP_PRINT_FUNC:
		while (arg->func.args) {
			farg = arg->func.args;
			arg->func.args = farg->next;
			free_arg(farg);
		}
		break;

	case TEP_PRINT_NULL:
	default:
		break;
	}

	free(arg);
}

static enum tep_event_type get_type(int ch)
{
	if (ch == '\n')
		return TEP_EVENT_NEWLINE;
	if (isspace(ch))
		return TEP_EVENT_SPACE;
	if (isalnum(ch) || ch == '_')
		return TEP_EVENT_ITEM;
	if (ch == '\'')
		return TEP_EVENT_SQUOTE;
	if (ch == '"')
		return TEP_EVENT_DQUOTE;
	if (!isprint(ch))
		return TEP_EVENT_NONE;
	if (ch == '(' || ch == ')' || ch == ',')
		return TEP_EVENT_DELIM;

	return TEP_EVENT_OP;
}

static int __read_char(void)
{
	if (input_buf_ptr >= input_buf_siz)
		return -1;

	return input_buf[input_buf_ptr++];
}

/**
 * peek_char - peek at the next character that will be read
 *
 * Returns the next character read, or -1 if end of buffer.
 */
__hidden int peek_char(void)
{
	if (input_buf_ptr >= input_buf_siz)
		return -1;

	return input_buf[input_buf_ptr];
}

static int extend_token(char **tok, char *buf, int size)
{
	char *newtok = realloc(*tok, size);

	if (!newtok) {
		free(*tok);
		*tok = NULL;
		return -1;
	}

	if (!*tok)
		strcpy(newtok, buf);
	else
		strcat(newtok, buf);
	*tok = newtok;

	return 0;
}

static enum tep_event_type force_token(const char *str, char **tok);

static enum tep_event_type __read_token(char **tok)
{
	char buf[BUFSIZ];
	int ch, last_ch, quote_ch, next_ch;
	int i = 0;
	int tok_size = 0;
	enum tep_event_type type;

	*tok = NULL;


	ch = __read_char();
	if (ch < 0)
		return TEP_EVENT_NONE;

	type = get_type(ch);
	if (type == TEP_EVENT_NONE)
		return type;

	buf[i++] = ch;

	switch (type) {
	case TEP_EVENT_NEWLINE:
	case TEP_EVENT_DELIM:
		if (asprintf(tok, "%c", ch) < 0)
			return TEP_EVENT_ERROR;

		return type;

	case TEP_EVENT_OP:
		switch (ch) {
		case '-':
			next_ch = peek_char();
			if (next_ch == '>') {
				buf[i++] = __read_char();
				break;
			}
			/* fall through */
		case '+':
		case '|':
		case '&':
		case '>':
		case '<':
			last_ch = ch;
			ch = peek_char();
			if (ch != last_ch)
				goto test_equal;
			buf[i++] = __read_char();
			switch (last_ch) {
			case '>':
			case '<':
				goto test_equal;
			default:
				break;
			}
			break;
		case '!':
		case '=':
			goto test_equal;
		default: /* what should we do instead? */
			break;
		}
		buf[i] = 0;
		*tok = strdup(buf);
		return type;

 test_equal:
		ch = peek_char();
		if (ch == '=')
			buf[i++] = __read_char();
		goto out;

	case TEP_EVENT_DQUOTE:
	case TEP_EVENT_SQUOTE:
		/* don't keep quotes */
		i--;
		quote_ch = ch;
		last_ch = 0;
 concat:
		do {
			if (i == (BUFSIZ - 1)) {
				buf[i] = 0;
				tok_size += BUFSIZ;

				if (extend_token(tok, buf, tok_size) < 0)
					return TEP_EVENT_NONE;
				i = 0;
			}
			last_ch = ch;
			ch = __read_char();
			buf[i++] = ch;
			/* the '\' '\' will cancel itself */
			if (ch == '\\' && last_ch == '\\')
				last_ch = 0;
		} while (ch != quote_ch || last_ch == '\\');
		/* remove the last quote */
		i--;

		/*
		 * For strings (double quotes) check the next token.
		 * If it is another string, concatinate the two.
		 */
		if (type == TEP_EVENT_DQUOTE) {
			unsigned long long save_input_buf_ptr = input_buf_ptr;

			do {
				ch = __read_char();
			} while (isspace(ch));
			if (ch == '"')
				goto concat;
			input_buf_ptr = save_input_buf_ptr;
		}

		goto out;

	case TEP_EVENT_ERROR ... TEP_EVENT_SPACE:
	case TEP_EVENT_ITEM:
	default:
		break;
	}

	while (get_type(peek_char()) == type) {
		if (i == (BUFSIZ - 1)) {
			buf[i] = 0;
			tok_size += BUFSIZ;

			if (extend_token(tok, buf, tok_size) < 0)
				return TEP_EVENT_NONE;
			i = 0;
		}
		ch = __read_char();
		buf[i++] = ch;
	}

 out:
	buf[i] = 0;
	if (extend_token(tok, buf, tok_size + i + 1) < 0)
		return TEP_EVENT_NONE;

	if (type == TEP_EVENT_ITEM) {
		/*
		 * Older versions of the kernel has a bug that
		 * creates invalid symbols and will break the mac80211
		 * parsing. This is a work around to that bug.
		 *
		 * See Linux kernel commit:
		 *  811cb50baf63461ce0bdb234927046131fc7fa8b
		 */
		if (strcmp(*tok, "LOCAL_PR_FMT") == 0) {
			free(*tok);
			*tok = NULL;
			return force_token("\"%s\" ", tok);
		} else if (strcmp(*tok, "STA_PR_FMT") == 0) {
			free(*tok);
			*tok = NULL;
			return force_token("\" sta:%pM\" ", tok);
		} else if (strcmp(*tok, "VIF_PR_FMT") == 0) {
			free(*tok);
			*tok = NULL;
			return force_token("\" vif:%p(%d)\" ", tok);
		}
	}

	return type;
}

static enum tep_event_type force_token(const char *str, char **tok)
{
	const char *save_input_buf;
	unsigned long long save_input_buf_ptr;
	unsigned long long save_input_buf_siz;
	enum tep_event_type type;
	
	/* save off the current input pointers */
	save_input_buf = input_buf;
	save_input_buf_ptr = input_buf_ptr;
	save_input_buf_siz = input_buf_siz;

	init_input_buf(str, strlen(str));

	type = __read_token(tok);

	/* reset back to original token */
	input_buf = save_input_buf;
	input_buf_ptr = save_input_buf_ptr;
	input_buf_siz = save_input_buf_siz;

	return type;
}

/**
 * free_token - free a token returned by tep_read_token
 * @token: the token to free
 */
__hidden void free_token(char *tok)
{
	if (tok)
		free(tok);
}

/**
 * read_token - access to utilities to use the tep parser
 * @tok: The token to return
 *
 * This will parse tokens from the string given by
 * tep_init_data().
 *
 * Returns the token type.
 */
__hidden enum tep_event_type read_token(char **tok)
{
	enum tep_event_type type;

	for (;;) {
		type = __read_token(tok);
		if (type != TEP_EVENT_SPACE)
			return type;

		free_token(*tok);
	}

	/* not reached */
	*tok = NULL;
	return TEP_EVENT_NONE;
}

/* no newline */
static enum tep_event_type read_token_item(char **tok)
{
	enum tep_event_type type;

	for (;;) {
		type = __read_token(tok);
		if (type != TEP_EVENT_SPACE && type != TEP_EVENT_NEWLINE)
			return type;
		free_token(*tok);
		*tok = NULL;
	}

	/* not reached */
	*tok = NULL;
	return TEP_EVENT_NONE;
}

static int test_type(enum tep_event_type type, enum tep_event_type expect)
{
	if (type != expect) {
		do_warning("Error: expected type %d but read %d",
		    expect, type);
		return -1;
	}
	return 0;
}

static int test_type_token(enum tep_event_type type, const char *token,
		    enum tep_event_type expect, const char *expect_tok)
{
	if (type != expect) {
		do_warning("Error: expected type %d but read %d",
		    expect, type);
		return -1;
	}

	if (strcmp(token, expect_tok) != 0) {
		do_warning("Error: expected '%s' but read '%s'",
		    expect_tok, token);
		return -1;
	}
	return 0;
}

static int __read_expect_type(enum tep_event_type expect, char **tok, int newline_ok)
{
	enum tep_event_type type;

	if (newline_ok)
		type = read_token(tok);
	else
		type = read_token_item(tok);
	return test_type(type, expect);
}

static int read_expect_type(enum tep_event_type expect, char **tok)
{
	return __read_expect_type(expect, tok, 1);
}

static int __read_expected(enum tep_event_type expect, const char *str,
			   int newline_ok)
{
	enum tep_event_type type;
	char *token;
	int ret;

	if (newline_ok)
		type = read_token(&token);
	else
		type = read_token_item(&token);

	ret = test_type_token(type, token, expect, str);

	free_token(token);

	return ret;
}

static int read_expected(enum tep_event_type expect, const char *str)
{
	return __read_expected(expect, str, 1);
}

static int read_expected_item(enum tep_event_type expect, const char *str)
{
	return __read_expected(expect, str, 0);
}

static char *event_read_name(void)
{
	char *token;

	if (read_expected(TEP_EVENT_ITEM, "name") < 0)
		return NULL;

	if (read_expected(TEP_EVENT_OP, ":") < 0)
		return NULL;

	if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
		goto fail;

	return token;

 fail:
	free_token(token);
	return NULL;
}

static int event_read_id(void)
{
	char *token;
	int id;

	if (read_expected_item(TEP_EVENT_ITEM, "ID") < 0)
		return -1;

	if (read_expected(TEP_EVENT_OP, ":") < 0)
		return -1;

	if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
		goto fail;

	id = strtoul(token, NULL, 0);
	free_token(token);
	return id;

 fail:
	free_token(token);
	return -1;
}

static int field_is_string(struct tep_format_field *field)
{
	if ((field->flags & TEP_FIELD_IS_ARRAY) &&
	    (strstr(field->type, "char") || strstr(field->type, "u8") ||
	     strstr(field->type, "s8")))
		return 1;

	return 0;
}

static int field_is_dynamic(struct tep_format_field *field)
{
	if (strncmp(field->type, "__data_loc", 10) == 0)
		return 1;

	return 0;
}

static int field_is_long(struct tep_format_field *field)
{
	/* includes long long */
	if (strstr(field->type, "long"))
		return 1;

	return 0;
}

static unsigned int type_size(const char *name)
{
	/* This covers all TEP_FIELD_IS_STRING types. */
	static struct {
		const char *type;
		unsigned int size;
	} table[] = {
		{ "u8",   1 },
		{ "u16",  2 },
		{ "u32",  4 },
		{ "u64",  8 },
		{ "s8",   1 },
		{ "s16",  2 },
		{ "s32",  4 },
		{ "s64",  8 },
		{ "char", 1 },
		{ },
	};
	int i;

	for (i = 0; table[i].type; i++) {
		if (!strcmp(table[i].type, name))
			return table[i].size;
	}

	return 0;
}

static int append(char **buf, const char *delim, const char *str)
{
	char *new_buf;

	new_buf = realloc(*buf, strlen(*buf) + strlen(delim) + strlen(str) + 1);
	if (!new_buf)
		return -1;
	strcat(new_buf, delim);
	strcat(new_buf, str);
	*buf = new_buf;
	return 0;
}

static int event_read_fields(struct tep_event *event, struct tep_format_field **fields)
{
	struct tep_format_field *field = NULL;
	enum tep_event_type type;
	char *token;
	char *last_token;
	char *delim = " ";
	int count = 0;
	int ret;

	do {
		unsigned int size_dynamic = 0;

		type = read_token(&token);
		if (type == TEP_EVENT_NEWLINE) {
			free_token(token);
			return count;
		}

		count++;

		if (test_type_token(type, token, TEP_EVENT_ITEM, "field"))
			goto fail;
		free_token(token);

		type = read_token(&token);
		/*
		 * The ftrace fields may still use the "special" name.
		 * Just ignore it.
		 */
		if (event->flags & TEP_EVENT_FL_ISFTRACE &&
		    type == TEP_EVENT_ITEM && strcmp(token, "special") == 0) {
			free_token(token);
			type = read_token(&token);
		}

		if (test_type_token(type, token, TEP_EVENT_OP, ":") < 0)
			goto fail;

		free_token(token);
		if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
			goto fail;

		last_token = token;

		field = calloc(1, sizeof(*field));
		if (!field)
			goto fail;

		field->event = event;

		/* read the rest of the type */
		for (;;) {
			type = read_token(&token);
			if (type == TEP_EVENT_ITEM ||
			    (type == TEP_EVENT_OP && strcmp(token, "*") == 0) ||
			    /*
			     * Some of the ftrace fields are broken and have
			     * an illegal "." in them.
			     */
			    (event->flags & TEP_EVENT_FL_ISFTRACE &&
			     type == TEP_EVENT_OP && strcmp(token, ".") == 0)) {

				if (strcmp(token, "*") == 0)
					field->flags |= TEP_FIELD_IS_POINTER;

				if (field->type) {
					ret = append(&field->type, delim, last_token);
					free(last_token);
					if (ret < 0)
						goto fail;
				} else
					field->type = last_token;
				last_token = token;
				delim = " ";
				continue;
			}

			/* Handle __attribute__((user)) */
			if ((type == TEP_EVENT_DELIM) &&
			    strcmp("__attribute__", last_token) == 0 &&
			    token[0] == '(') {
				int depth = 1;
				int ret;

				ret = append(&field->type, " ", last_token);
				ret |= append(&field->type, "", "(");
				if (ret < 0)
					goto fail;

				delim = " ";
				while ((type = read_token(&token)) != TEP_EVENT_NONE) {
					if (type == TEP_EVENT_DELIM) {
						if (token[0] == '(')
							depth++;
						else if (token[0] == ')')
							depth--;
						if (!depth)
							break;
						ret = append(&field->type, "", token);
						delim = "";
					} else {
						ret = append(&field->type, delim, token);
						delim = " ";
					}
					if (ret < 0)
						goto fail;
					free(last_token);
					last_token = token;
				}
				continue;
			}
			break;
		}

		if (!field->type) {
			do_warning_event(event, "%s: no type found", __func__);
			goto fail;
		}
		field->name = field->alias = last_token;

		if (test_type(type, TEP_EVENT_OP))
			goto fail;

		if (strcmp(token, "[") == 0) {
			enum tep_event_type last_type = type;
			char *brackets = token;

			field->flags |= TEP_FIELD_IS_ARRAY;

			type = read_token(&token);

			if (type == TEP_EVENT_ITEM)
				field->arraylen = strtoul(token, NULL, 0);
			else
				field->arraylen = 0;

		        while (strcmp(token, "]") != 0) {
				const char *delim;

				if (last_type == TEP_EVENT_ITEM &&
				    type == TEP_EVENT_ITEM)
					delim = " ";
				else
					delim = "";

				last_type = type;

				ret = append(&brackets, delim, token);
				if (ret < 0) {
					free(brackets);
					goto fail;
				}
				/* We only care about the last token */
				field->arraylen = strtoul(token, NULL, 0);
				free_token(token);
				type = read_token(&token);
				if (type == TEP_EVENT_NONE) {
					free(brackets);
					do_warning_event(event, "failed to find token");
					goto fail;
				}
			}

			free_token(token);

			ret = append(&brackets, "", "]");
			if (ret < 0) {
				free(brackets);
				goto fail;
			}

			/* add brackets to type */

			type = read_token(&token);
			/*
			 * If the next token is not an OP, then it is of
			 * the format: type [] item;
			 */
			if (type == TEP_EVENT_ITEM) {
				ret = append(&field->type, " ", field->name);
				if (ret < 0) {
					free(brackets);
					goto fail;
				}
				ret = append(&field->type, "", brackets);

				size_dynamic = type_size(field->name);
				free_token(field->name);
				field->name = field->alias = token;
				type = read_token(&token);
			} else {
				ret = append(&field->type, "", brackets);
				if (ret < 0) {
					free(brackets);
					goto fail;
				}
			}
			free(brackets);
		}

		if (field_is_string(field))
			field->flags |= TEP_FIELD_IS_STRING;
		if (field_is_dynamic(field))
			field->flags |= TEP_FIELD_IS_DYNAMIC;
		if (field_is_long(field))
			field->flags |= TEP_FIELD_IS_LONG;

		if (test_type_token(type, token,  TEP_EVENT_OP, ";"))
			goto fail;
		free_token(token);

		if (read_expected(TEP_EVENT_ITEM, "offset") < 0)
			goto fail_expect;

		if (read_expected(TEP_EVENT_OP, ":") < 0)
			goto fail_expect;

		if (read_expect_type(TEP_EVENT_ITEM, &token))
			goto fail;
		field->offset = strtoul(token, NULL, 0);
		free_token(token);

		if (read_expected(TEP_EVENT_OP, ";") < 0)
			goto fail_expect;

		if (read_expected(TEP_EVENT_ITEM, "size") < 0)
			goto fail_expect;

		if (read_expected(TEP_EVENT_OP, ":") < 0)
			goto fail_expect;

		if (read_expect_type(TEP_EVENT_ITEM, &token))
			goto fail;
		field->size = strtoul(token, NULL, 0);
		free_token(token);

		if (read_expected(TEP_EVENT_OP, ";") < 0)
			goto fail_expect;

		type = read_token(&token);
		if (type != TEP_EVENT_NEWLINE) {
			/* newer versions of the kernel have a "signed" type */
			if (test_type_token(type, token, TEP_EVENT_ITEM, "signed"))
				goto fail;

			free_token(token);

			if (read_expected(TEP_EVENT_OP, ":") < 0)
				goto fail_expect;

			if (read_expect_type(TEP_EVENT_ITEM, &token))
				goto fail;

			if (strtoul(token, NULL, 0))
				field->flags |= TEP_FIELD_IS_SIGNED;

			free_token(token);
			if (read_expected(TEP_EVENT_OP, ";") < 0)
				goto fail_expect;

			if (read_expect_type(TEP_EVENT_NEWLINE, &token))
				goto fail;
		}

		free_token(token);

		if (field->flags & TEP_FIELD_IS_ARRAY) {
			if (field->arraylen)
				field->elementsize = field->size / field->arraylen;
			else if (field->flags & TEP_FIELD_IS_DYNAMIC)
				field->elementsize = size_dynamic;
			else if (field->flags & TEP_FIELD_IS_STRING)
				field->elementsize = 1;
			else if (field->flags & TEP_FIELD_IS_LONG)
				field->elementsize = event->tep ?
						     event->tep->long_size :
						     sizeof(long);
		} else
			field->elementsize = field->size;

		*fields = field;
		fields = &field->next;

	} while (1);

	return 0;

fail:
	free_token(token);
fail_expect:
	if (field) {
		free(field->type);
		free(field->name);
		free(field);
	}
	return -1;
}

static int event_read_format(struct tep_event *event)
{
	char *token;
	int ret;

	if (read_expected_item(TEP_EVENT_ITEM, "format") < 0)
		return -1;

	if (read_expected(TEP_EVENT_OP, ":") < 0)
		return -1;

	if (read_expect_type(TEP_EVENT_NEWLINE, &token))
		goto fail;
	free_token(token);

	ret = event_read_fields(event, &event->format.common_fields);
	if (ret < 0)
		return ret;
	event->format.nr_common = ret;

	ret = event_read_fields(event, &event->format.fields);
	if (ret < 0)
		return ret;
	event->format.nr_fields = ret;

	return 0;

 fail:
	free_token(token);
	return -1;
}

static enum tep_event_type
process_arg_token(struct tep_event *event, struct tep_print_arg *arg,
		  char **tok, enum tep_event_type type);

static enum tep_event_type
process_arg(struct tep_event *event, struct tep_print_arg *arg, char **tok)
{
	enum tep_event_type type;
	char *token;

	type = read_token(&token);
	*tok = token;

	return process_arg_token(event, arg, tok, type);
}

static enum tep_event_type
process_op(struct tep_event *event, struct tep_print_arg *arg, char **tok);

/*
 * For __print_symbolic() and __print_flags, we need to completely
 * evaluate the first argument, which defines what to print next.
 */
static enum tep_event_type
process_field_arg(struct tep_event *event, struct tep_print_arg *arg, char **tok)
{
	enum tep_event_type type;

	type = process_arg(event, arg, tok);

	while (type == TEP_EVENT_OP) {
		type = process_op(event, arg, tok);
	}

	return type;
}

static enum tep_event_type
process_cond(struct tep_event *event, struct tep_print_arg *top, char **tok)
{
	struct tep_print_arg *arg, *left, *right;
	enum tep_event_type type;
	char *token = NULL;

	arg = alloc_arg();
	left = alloc_arg();
	right = alloc_arg();

	if (!arg || !left || !right) {
		do_warning_event(event, "%s: not enough memory!", __func__);
		/* arg will be freed at out_free */
		free_arg(left);
		free_arg(right);
		goto out_free;
	}

	arg->type = TEP_PRINT_OP;
	arg->op.left = left;
	arg->op.right = right;

	*tok = NULL;
	type = process_arg(event, left, &token);

 again:
	if (type == TEP_EVENT_ERROR)
		goto out_free;

	/* Handle other operations in the arguments */
	if (type == TEP_EVENT_OP && strcmp(token, ":") != 0) {
		type = process_op(event, left, &token);
		goto again;
	}

	if (test_type_token(type, token, TEP_EVENT_OP, ":"))
		goto out_free;

	arg->op.op = token;

	type = process_arg(event, right, &token);

	top->op.right = arg;

	*tok = token;
	return type;

out_free:
	/* Top may point to itself */
	top->op.right = NULL;
	free_token(token);
	free_arg(arg);
	return TEP_EVENT_ERROR;
}

static enum tep_event_type
process_array(struct tep_event *event, struct tep_print_arg *top, char **tok)
{
	struct tep_print_arg *arg;
	enum tep_event_type type;
	char *token = NULL;

	arg = alloc_arg();
	if (!arg) {
		do_warning_event(event, "%s: not enough memory!", __func__);
		/* '*tok' is set to top->op.op.  No need to free. */
		*tok = NULL;
		return TEP_EVENT_ERROR;
	}

	*tok = NULL;
	type = process_arg(event, arg, &token);
	if (test_type_token(type, token, TEP_EVENT_OP, "]"))
		goto out_free;

	top->op.right = arg;

	free_token(token);
	type = read_token_item(&token);
	*tok = token;

	return type;

out_free:
	free_token(token);
	free_arg(arg);
	return TEP_EVENT_ERROR;
}

static int get_op_prio(char *op)
{
	if (!op[1]) {
		switch (op[0]) {
		case '~':
		case '!':
			return 4;
		case '*':
		case '/':
		case '%':
			return 6;
		case '+':
		case '-':
			return 7;
			/* '>>' and '<<' are 8 */
		case '<':
		case '>':
			return 9;
			/* '==' and '!=' are 10 */
		case '&':
			return 11;
		case '^':
			return 12;
		case '|':
			return 13;
		case '?':
			return 16;
		default:
			do_warning("unknown op '%c'", op[0]);
			return -1;
		}
	} else {
		if (strcmp(op, "++") == 0 ||
		    strcmp(op, "--") == 0) {
			return 3;
		} else if (strcmp(op, ">>") == 0 ||
			   strcmp(op, "<<") == 0) {
			return 8;
		} else if (strcmp(op, ">=") == 0 ||
			   strcmp(op, "<=") == 0) {
			return 9;
		} else if (strcmp(op, "==") == 0 ||
			   strcmp(op, "!=") == 0) {
			return 10;
		} else if (strcmp(op, "&&") == 0) {
			return 14;
		} else if (strcmp(op, "||") == 0) {
			return 15;
		} else {
			do_warning("unknown op '%s'", op);
			return -1;
		}
	}
}

static int set_op_prio(struct tep_print_arg *arg)
{

	/* single ops are the greatest */
	if (!arg->op.left || arg->op.left->type == TEP_PRINT_NULL)
		arg->op.prio = 0;
	else
		arg->op.prio = get_op_prio(arg->op.op);

	return arg->op.prio;
}

/* Note, *tok does not get freed, but will most likely be saved */
static enum tep_event_type
process_op(struct tep_event *event, struct tep_print_arg *arg, char **tok)
{
	struct tep_print_arg *left, *right = NULL;
	enum tep_event_type type;
	char *token;

	/* the op is passed in via tok */
	token = *tok;

	if (arg->type == TEP_PRINT_OP && !arg->op.left) {
		/* handle single op */
		if (token[1]) {
			do_warning_event(event, "bad op token %s", token);
			goto out_free;
		}
		switch (token[0]) {
		case '~':
		case '!':
		case '+':
		case '-':
			break;
		default:
			do_warning_event(event, "bad op token %s", token);
			goto out_free;

		}

		/* make an empty left */
		left = alloc_arg();
		if (!left)
			goto out_warn_free;

		left->type = TEP_PRINT_NULL;
		arg->op.left = left;

		right = alloc_arg();
		if (!right)
			goto out_warn_free;

		arg->op.right = right;

		/* do not free the token, it belongs to an op */
		*tok = NULL;
		type = process_arg(event, right, tok);

	} else if (strcmp(token, "?") == 0) {

		left = alloc_arg();
		if (!left)
			goto out_warn_free;

		/* copy the top arg to the left */
		*left = *arg;

		arg->type = TEP_PRINT_OP;
		arg->op.op = token;
		arg->op.left = left;
		arg->op.prio = 0;

		/* it will set arg->op.right */
		type = process_cond(event, arg, tok);

	} else if (strcmp(token, ">>") == 0 ||
		   strcmp(token, "<<") == 0 ||
		   strcmp(token, "&") == 0 ||
		   strcmp(token, "|") == 0 ||
		   strcmp(token, "&&") == 0 ||
		   strcmp(token, "||") == 0 ||
		   strcmp(token, "-") == 0 ||
		   strcmp(token, "+") == 0 ||
		   strcmp(token, "*") == 0 ||
		   strcmp(token, "^") == 0 ||
		   strcmp(token, "/") == 0 ||
		   strcmp(token, "%") == 0 ||
		   strcmp(token, "<") == 0 ||
		   strcmp(token, ">") == 0 ||
		   strcmp(token, "<=") == 0 ||
		   strcmp(token, ">=") == 0 ||
		   strcmp(token, "==") == 0 ||
		   strcmp(token, "!=") == 0) {

		left = alloc_arg();
		if (!left)
			goto out_warn_free;

		/* copy the top arg to the left */
		*left = *arg;

		arg->type = TEP_PRINT_OP;
		arg->op.op = token;
		arg->op.left = left;
		arg->op.right = NULL;

		if (set_op_prio(arg) == -1) {
			event->flags |= TEP_EVENT_FL_FAILED;
			/* arg->op.op (= token) will be freed at out_free */
			arg->op.op = NULL;
			goto out_free;
		}

		type = read_token_item(&token);
		*tok = token;

		/* could just be a type pointer */
		if ((strcmp(arg->op.op, "*") == 0) &&
		    type == TEP_EVENT_DELIM && (strcmp(token, ")") == 0)) {
			int ret;

			if (left->type != TEP_PRINT_ATOM) {
				do_warning_event(event, "bad pointer type");
				goto out_free;
			}
			ret = append(&left->atom.atom, " ", "*");
			if (ret < 0)
				goto out_warn_free;

			free(arg->op.op);
			*arg = *left;
			free(left);

			return type;
		}

		right = alloc_arg();
		if (!right)
			goto out_warn_free;

		type = process_arg_token(event, right, tok, type);
		if (type == TEP_EVENT_ERROR) {
			free_arg(right);
			/* token was freed in process_arg_token() via *tok */
			token = NULL;
			goto out_free;
		}

		if (right->type == TEP_PRINT_OP &&
		    get_op_prio(arg->op.op) < get_op_prio(right->op.op)) {
			struct tep_print_arg tmp;

			/* rotate ops according to the priority */
			arg->op.right = right->op.left;

			tmp = *arg;
			*arg = *right;
			*right = tmp;

			arg->op.left = right;
		} else {
			arg->op.right = right;
		}

	} else if (strcmp(token, "[") == 0) {

		left = alloc_arg();
		if (!left)
			goto out_warn_free;

		*left = *arg;

		arg->type = TEP_PRINT_OP;
		arg->op.op = token;
		arg->op.left = left;

		arg->op.prio = 0;

		/* it will set arg->op.right */
		type = process_array(event, arg, tok);

	} else {
		do_warning_event(event, "unknown op '%s'", token);
		event->flags |= TEP_EVENT_FL_FAILED;
		/* the arg is now the left side */
		goto out_free;
	}

	if (type == TEP_EVENT_OP && strcmp(*tok, ":") != 0) {
		int prio;

		/* higher prios need to be closer to the root */
		prio = get_op_prio(*tok);

		if (prio > arg->op.prio)
			return process_op(event, arg, tok);

		return process_op(event, right, tok);
	}

	return type;

out_warn_free:
	do_warning_event(event, "%s: not enough memory!", __func__);
out_free:
	free_token(token);
	*tok = NULL;
	return TEP_EVENT_ERROR;
}

static enum tep_event_type
process_entry(struct tep_event *event __maybe_unused, struct tep_print_arg *arg,
	      char **tok)
{
	enum tep_event_type type;
	char *field;
	char *token;

	if (read_expected(TEP_EVENT_OP, "->") < 0)
		goto out_err;

	if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
		goto out_free;
	field = token;

	arg->type = TEP_PRINT_FIELD;
	arg->field.name = field;

	if (is_flag_field) {
		arg->field.field = tep_find_any_field(event, arg->field.name);
		arg->field.field->flags |= TEP_FIELD_IS_FLAG;
		is_flag_field = 0;
	} else if (is_symbolic_field) {
		arg->field.field = tep_find_any_field(event, arg->field.name);
		arg->field.field->flags |= TEP_FIELD_IS_SYMBOLIC;
		is_symbolic_field = 0;
	}

	type = read_token(&token);
	*tok = token;

	return type;

 out_free:
	free_token(token);
 out_err:
	*tok = NULL;
	return TEP_EVENT_ERROR;
}

static int alloc_and_process_delim(struct tep_event *event, char *next_token,
				   struct tep_print_arg **print_arg)
{
	struct tep_print_arg *field;
	enum tep_event_type type;
	char *token;
	int ret = 0;

	field = alloc_arg();
	if (!field) {
		do_warning_event(event, "%s: not enough memory!", __func__);
		errno = ENOMEM;
		return -1;
	}

	type = process_arg(event, field, &token);

	if (test_type_token(type, token, TEP_EVENT_DELIM, next_token)) {
		errno = EINVAL;
		ret = -1;
		free_arg(field);
		goto out_free_token;
	}

	*print_arg = field;

out_free_token:
	free_token(token);

	return ret;
}

static char *arg_eval (struct tep_print_arg *arg);

static unsigned long long
eval_type_str(unsigned long long val, const char *type, int pointer)
{
	int sign = 0;
	char *ref;
	int len;

	len = strlen(type);

	if (pointer) {

		if (type[len-1] != '*') {
			do_warning("pointer expected with non pointer type");
			return val;
		}

		ref = malloc(len);
		if (!ref) {
			do_warning("%s: not enough memory!", __func__);
			return val;
		}
		memcpy(ref, type, len);

		/* chop off the " *" */
		ref[len - 2] = 0;

		val = eval_type_str(val, ref, 0);
		free(ref);
		return val;
	}

	/* check if this is a pointer */
	if (type[len - 1] == '*')
		return val;

	/* Try to figure out the arg size*/
	if (strncmp(type, "struct", 6) == 0)
		/* all bets off */
		return val;

	if (strcmp(type, "u8") == 0)
		return val & 0xff;

	if (strcmp(type, "u16") == 0)
		return val & 0xffff;

	if (strcmp(type, "u32") == 0)
		return val & 0xffffffff;

	if (strcmp(type, "u64") == 0 ||
	    strcmp(type, "s64") == 0)
		return val;

	if (strcmp(type, "s8") == 0)
		return (unsigned long long)(char)val & 0xff;

	if (strcmp(type, "s16") == 0)
		return (unsigned long long)(short)val & 0xffff;

	if (strcmp(type, "s32") == 0)
		return (unsigned long long)(int)val & 0xffffffff;

	if (strncmp(type, "unsigned ", 9) == 0) {
		sign = 0;
		type += 9;
	}

	if (strcmp(type, "char") == 0) {
		if (sign)
			return (unsigned long long)(char)val & 0xff;
		else
			return val & 0xff;
	}

	if (strcmp(type, "short") == 0) {
		if (sign)
			return (unsigned long long)(short)val & 0xffff;
		else
			return val & 0xffff;
	}

	if (strcmp(type, "int") == 0) {
		if (sign)
			return (unsigned long long)(int)val & 0xffffffff;
		else
			return val & 0xffffffff;
	}

	return val;
}

/*
 * Try to figure out the type.
 */
static unsigned long long
eval_type(unsigned long long val, struct tep_print_arg *arg, int pointer)
{
	if (arg->type != TEP_PRINT_TYPE) {
		do_warning("expected type argument");
		return 0;
	}

	return eval_type_str(val, arg->typecast.type, pointer);
}

static int arg_num_eval(struct tep_print_arg *arg, long long *val)
{
	long long left, right;
	int ret = 1;

	switch (arg->type) {
	case TEP_PRINT_ATOM:
		*val = strtoll(arg->atom.atom, NULL, 0);
		break;
	case TEP_PRINT_TYPE:
		ret = arg_num_eval(arg->typecast.item, val);
		if (!ret)
			break;
		*val = eval_type(*val, arg, 0);
		break;
	case TEP_PRINT_OP:
		switch (arg->op.op[0]) {
		case '|':
			ret = arg_num_eval(arg->op.left, &left);
			if (!ret)
				break;
			ret = arg_num_eval(arg->op.right, &right);
			if (!ret)
				break;
			if (arg->op.op[1])
				*val = left || right;
			else
				*val = left | right;
			break;
		case '&':
			ret = arg_num_eval(arg->op.left, &left);
			if (!ret)
				break;
			ret = arg_num_eval(arg->op.right, &right);
			if (!ret)
				break;
			if (arg->op.op[1])
				*val = left && right;
			else
				*val = left & right;
			break;
		case '<':
			ret = arg_num_eval(arg->op.left, &left);
			if (!ret)
				break;
			ret = arg_num_eval(arg->op.right, &right);
			if (!ret)
				break;
			switch (arg->op.op[1]) {
			case 0:
				*val = left < right;
				break;
			case '<':
				*val = left << right;
				break;
			case '=':
				*val = left <= right;
				break;
			default:
				do_warning("unknown op '%s'", arg->op.op);
				ret = 0;
			}
			break;
		case '>':
			ret = arg_num_eval(arg->op.left, &left);
			if (!ret)
				break;
			ret = arg_num_eval(arg->op.right, &right);
			if (!ret)
				break;
			switch (arg->op.op[1]) {
			case 0:
				*val = left > right;
				break;
			case '>':
				*val = left >> right;
				break;
			case '=':
				*val = left >= right;
				break;
			default:
				do_warning("unknown op '%s'", arg->op.op);
				ret = 0;
			}
			break;
		case '=':
			ret = arg_num_eval(arg->op.left, &left);
			if (!ret)
				break;
			ret = arg_num_eval(arg->op.right, &right);
			if (!ret)
				break;

			if (arg->op.op[1] != '=') {
				do_warning("unknown op '%s'", arg->op.op);
				ret = 0;
			} else
				*val = left == right;
			break;
		case '!':
			ret = arg_num_eval(arg->op.left, &left);
			if (!ret)
				break;
			ret = arg_num_eval(arg->op.right, &right);
			if (!ret)
				break;

			switch (arg->op.op[1]) {
			case '=':
				*val = left != right;
				break;
			default:
				do_warning("unknown op '%s'", arg->op.op);
				ret = 0;
			}
			break;
		case '-':
			/* check for negative */
			if (arg->op.left->type == TEP_PRINT_NULL)
				left = 0;
			else
				ret = arg_num_eval(arg->op.left, &left);
			if (!ret)
				break;
			ret = arg_num_eval(arg->op.right, &right);
			if (!ret)
				break;
			*val = left - right;
			break;
		case '+':
			if (arg->op.left->type == TEP_PRINT_NULL)
				left = 0;
			else
				ret = arg_num_eval(arg->op.left, &left);
			if (!ret)
				break;
			ret = arg_num_eval(arg->op.right, &right);
			if (!ret)
				break;
			*val = left + right;
			break;
		case '~':
			ret = arg_num_eval(arg->op.right, &right);
			if (!ret)
				break;
			*val = ~right;
			break;
		default:
			do_warning("unknown op '%s'", arg->op.op);
			ret = 0;
		}
		break;

	case TEP_PRINT_NULL:
	case TEP_PRINT_FIELD ... TEP_PRINT_SYMBOL:
	case TEP_PRINT_STRING:
	case TEP_PRINT_BSTRING:
	case TEP_PRINT_BITMASK:
	default:
		do_warning("invalid eval type %d", arg->type);
		ret = 0;

	}
	return ret;
}

static char *arg_eval (struct tep_print_arg *arg)
{
	long long val;
	static char buf[24];

	switch (arg->type) {
	case TEP_PRINT_ATOM:
		return arg->atom.atom;
	case TEP_PRINT_TYPE:
		return arg_eval(arg->typecast.item);
	case TEP_PRINT_OP:
		if (!arg_num_eval(arg, &val))
			break;
		sprintf(buf, "%lld", val);
		return buf;

	case TEP_PRINT_NULL:
	case TEP_PRINT_FIELD ... TEP_PRINT_SYMBOL:
	case TEP_PRINT_STRING:
	case TEP_PRINT_BSTRING:
	case TEP_PRINT_BITMASK:
	default:
		do_warning("invalid eval type %d", arg->type);
		break;
	}

	return NULL;
}

static enum tep_event_type
process_fields(struct tep_event *event, struct tep_print_flag_sym **list, char **tok)
{
	enum tep_event_type type;
	struct tep_print_arg *arg = NULL;
	struct tep_print_flag_sym *field;
	char *token = *tok;
	char *value;

	do {
		free_token(token);
		type = read_token_item(&token);
		if (test_type_token(type, token, TEP_EVENT_OP, "{"))
			break;

		arg = alloc_arg();
		if (!arg)
			goto out_free;

		free_token(token);
		type = process_arg(event, arg, &token);

		if (type == TEP_EVENT_OP)
			type = process_op(event, arg, &token);

		if (type == TEP_EVENT_ERROR)
			goto out_free;

		if (test_type_token(type, token, TEP_EVENT_DELIM, ","))
			goto out_free;

		field = calloc(1, sizeof(*field));
		if (!field)
			goto out_free;

		value = arg_eval(arg);
		if (value == NULL)
			goto out_free_field;
		field->value = strdup(value);
		if (field->value == NULL)
			goto out_free_field;

		free_arg(arg);
		arg = alloc_arg();
		if (!arg)
			goto out_free;

		free_token(token);
		type = process_arg(event, arg, &token);
		if (test_type_token(type, token, TEP_EVENT_OP, "}"))
			goto out_free_field;

		value = arg_eval(arg);
		if (value == NULL)
			goto out_free_field;
		field->str = strdup(value);
		if (field->str == NULL)
			goto out_free_field;
		free_arg(arg);
		arg = NULL;

		*list = field;
		list = &field->next;

		free_token(token);
		type = read_token_item(&token);
	} while (type == TEP_EVENT_DELIM && strcmp(token, ",") == 0);

	*tok = token;
	return type;

out_free_field:
	free_flag_sym(field);
out_free:
	free_arg(arg);
	free_token(token);
	*tok = NULL;

	return TEP_EVENT_ERROR;
}

static enum tep_event_type
process_flags(struct tep_event *event, struct tep_print_arg *arg, char **tok)
{
	struct tep_print_arg *field;
	enum tep_event_type type;
	char *token = NULL;

	memset(arg, 0, sizeof(*arg));
	arg->type = TEP_PRINT_FLAGS;

	field = alloc_arg();
	if (!field) {
		do_warning_event(event, "%s: not enough memory!", __func__);
		goto out_free;
	}

	type = process_field_arg(event, field, &token);

	/* Handle operations in the first argument */
	while (type == TEP_EVENT_OP)
		type = process_op(event, field, &token);

	if (test_type_token(type, token, TEP_EVENT_DELIM, ","))
		goto out_free_field;
	free_token(token);

	arg->flags.field = field;

	type = read_token_item(&token);
	if (event_item_type(type)) {
		arg->flags.delim = token;
		type = read_token_item(&token);
	}

	if (test_type_token(type, token, TEP_EVENT_DELIM, ","))
		goto out_free;

	type = process_fields(event, &arg->flags.flags, &token);
	if (test_type_token(type, token, TEP_EVENT_DELIM, ")"))
		goto out_free;

	free_token(token);
	type = read_token_item(tok);
	return type;

out_free_field:
	free_arg(field);
out_free:
	free_token(token);
	*tok = NULL;
	return TEP_EVENT_ERROR;
}

static enum tep_event_type
process_symbols(struct tep_event *event, struct tep_print_arg *arg, char **tok)
{
	struct tep_print_arg *field;
	enum tep_event_type type;
	char *token = NULL;

	memset(arg, 0, sizeof(*arg));
	arg->type = TEP_PRINT_SYMBOL;

	field = alloc_arg();
	if (!field) {
		do_warning_event(event, "%s: not enough memory!", __func__);
		goto out_free;
	}

	type = process_field_arg(event, field, &token);

	if (test_type_token(type, token, TEP_EVENT_DELIM, ","))
		goto out_free_field;

	arg->symbol.field = field;

	type = process_fields(event, &arg->symbol.symbols, &token);
	if (test_type_token(type, token, TEP_EVENT_DELIM, ")"))
		goto out_free;

	free_token(token);
	type = read_token_item(tok);
	return type;

out_free_field:
	free_arg(field);
out_free:
	free_token(token);
	*tok = NULL;
	return TEP_EVENT_ERROR;
}

static enum tep_event_type
process_hex_common(struct tep_event *event, struct tep_print_arg *arg,
		   char **tok, enum tep_print_arg_type type)
{
	memset(arg, 0, sizeof(*arg));
	arg->type = type;

	if (alloc_and_process_delim(event, ",", &arg->hex.field))
		goto out;

	if (alloc_and_process_delim(event, ")", &arg->hex.size))
		goto free_field;

	return read_token_item(tok);

free_field:
	free_arg(arg->hex.field);
	arg->hex.field = NULL;
out:
	*tok = NULL;
	return TEP_EVENT_ERROR;
}

static enum tep_event_type
process_hex(struct tep_event *event, struct tep_print_arg *arg, char **tok)
{
	return process_hex_common(event, arg, tok, TEP_PRINT_HEX);
}

static enum tep_event_type
process_hex_str(struct tep_event *event, struct tep_print_arg *arg,
		char **tok)
{
	return process_hex_common(event, arg, tok, TEP_PRINT_HEX_STR);
}

static enum tep_event_type
process_int_array(struct tep_event *event, struct tep_print_arg *arg, char **tok)
{
	memset(arg, 0, sizeof(*arg));
	arg->type = TEP_PRINT_INT_ARRAY;

	if (alloc_and_process_delim(event, ",", &arg->int_array.field))
		goto out;

	if (alloc_and_process_delim(event, ",", &arg->int_array.count))
		goto free_field;

	if (alloc_and_process_delim(event, ")", &arg->int_array.el_size))
		goto free_size;

	return read_token_item(tok);

free_size:
	free_arg(arg->int_array.count);
	arg->int_array.count = NULL;
free_field:
	free_arg(arg->int_array.field);
	arg->int_array.field = NULL;
out:
	*tok = NULL;
	return TEP_EVENT_ERROR;
}

static enum tep_event_type
process_dynamic_array(struct tep_event *event, struct tep_print_arg *arg, char **tok)
{
	struct tep_format_field *field;
	enum tep_event_type type;
	char *token;

	memset(arg, 0, sizeof(*arg));
	arg->type = TEP_PRINT_DYNAMIC_ARRAY;

	/*
	 * The item within the parenthesis is another field that holds
	 * the index into where the array starts.
	 */
	type = read_token(&token);
	*tok = token;
	if (type != TEP_EVENT_ITEM)
		goto out_free;

	/* Find the field */

	field = tep_find_field(event, token);
	if (!field)
		goto out_free;

	arg->dynarray.field = field;
	arg->dynarray.index = 0;

	if (read_expected(TEP_EVENT_DELIM, ")") < 0)
		goto out_free;

	free_token(token);
	type = read_token_item(&token);
	*tok = token;
	if (type != TEP_EVENT_OP || strcmp(token, "[") != 0)
		return type;

	free_token(token);
	arg = alloc_arg();
	if (!arg) {
		do_warning_event(event, "%s: not enough memory!", __func__);
		*tok = NULL;
		return TEP_EVENT_ERROR;
	}

	type = process_arg(event, arg, &token);
	if (type == TEP_EVENT_ERROR)
		goto out_free_arg;

	if (!test_type_token(type, token, TEP_EVENT_OP, "]"))
		goto out_free_arg;

	free_token(token);
	type = read_token_item(tok);
	return type;

 out_free_arg:
	free_arg(arg);
 out_free:
	free_token(token);
	*tok = NULL;
	return TEP_EVENT_ERROR;
}

static enum tep_event_type
process_dynamic_array_len(struct tep_event *event, struct tep_print_arg *arg,
			  char **tok)
{
	struct tep_format_field *field;
	enum tep_event_type type;
	char *token;

	if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
		goto out_free;

	arg->type = TEP_PRINT_DYNAMIC_ARRAY_LEN;

	/* Find the field */
	field = tep_find_field(event, token);
	if (!field)
		goto out_free;

	arg->dynarray.field = field;
	arg->dynarray.index = 0;

	if (read_expected(TEP_EVENT_DELIM, ")") < 0)
		goto out_err;

	free_token(token);
	type = read_token(&token);
	*tok = token;

	return type;

 out_free:
	free_token(token);
 out_err:
	*tok = NULL;
	return TEP_EVENT_ERROR;
}

static enum tep_event_type
process_paren(struct tep_event *event, struct tep_print_arg *arg, char **tok)
{
	struct tep_print_arg *item_arg;
	enum tep_event_type type;
	char *token;

	type = process_arg(event, arg, &token);

	if (type == TEP_EVENT_ERROR)
		goto out_free;

	if (type == TEP_EVENT_OP)
		type = process_op(event, arg, &token);

	if (type == TEP_EVENT_ERROR)
		goto out_free;

	if (test_type_token(type, token, TEP_EVENT_DELIM, ")"))
		goto out_free;

	free_token(token);
	type = read_token_item(&token);

	/*
	 * If the next token is an item or another open paren, then
	 * this was a typecast.
	 */
	if (event_item_type(type) ||
	    (type == TEP_EVENT_DELIM && strcmp(token, "(") == 0)) {

		/* make this a typecast and contine */

		/* prevous must be an atom */
		if (arg->type != TEP_PRINT_ATOM) {
			do_warning_event(event, "previous needed to be TEP_PRINT_ATOM");
			goto out_free;
		}

		item_arg = alloc_arg();
		if (!item_arg) {
			do_warning_event(event, "%s: not enough memory!",
					 __func__);
			goto out_free;
		}

		arg->type = TEP_PRINT_TYPE;
		arg->typecast.type = arg->atom.atom;
		arg->typecast.item = item_arg;
		type = process_arg_token(event, item_arg, &token, type);

	}

	*tok = token;
	return type;

 out_free:
	free_token(token);
	*tok = NULL;
	return TEP_EVENT_ERROR;
}


static enum tep_event_type
process_str(struct tep_event *event __maybe_unused, struct tep_print_arg *arg,
	    char **tok)
{
	enum tep_event_type type;
	char *token;

	if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
		goto out_free;

	arg->type = TEP_PRINT_STRING;
	arg->string.string = token;
	arg->string.offset = -1;

	if (read_expected(TEP_EVENT_DELIM, ")") < 0)
		goto out_err;

	type = read_token(&token);
	*tok = token;

	return type;

 out_free:
	free_token(token);
 out_err:
	*tok = NULL;
	return TEP_EVENT_ERROR;
}

static enum tep_event_type
process_bitmask(struct tep_event *event __maybe_unused, struct tep_print_arg *arg,
		char **tok)
{
	enum tep_event_type type;
	char *token;

	if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
		goto out_free;

	arg->type = TEP_PRINT_BITMASK;
	arg->bitmask.bitmask = token;
	arg->bitmask.offset = -1;

	if (read_expected(TEP_EVENT_DELIM, ")") < 0)
		goto out_err;

	type = read_token(&token);
	*tok = token;

	return type;

 out_free:
	free_token(token);
 out_err:
	*tok = NULL;
	return TEP_EVENT_ERROR;
}

static struct tep_function_handler *
find_func_handler(struct tep_handle *tep, char *func_name)
{
	struct tep_function_handler *func;

	if (!tep)
		return NULL;

	for (func = tep->func_handlers; func; func = func->next) {
		if (strcmp(func->name, func_name) == 0)
			break;
	}

	return func;
}

static void remove_func_handler(struct tep_handle *tep, char *func_name)
{
	struct tep_function_handler *func;
	struct tep_function_handler **next;

	next = &tep->func_handlers;
	while ((func = *next)) {
		if (strcmp(func->name, func_name) == 0) {
			*next = func->next;
			free_func_handle(func);
			break;
		}
		next = &func->next;
	}
}

static enum tep_event_type
process_func_handler(struct tep_event *event, struct tep_function_handler *func,
		     struct tep_print_arg *arg, char **tok)
{
	struct tep_print_arg **next_arg;
	struct tep_print_arg *farg;
	enum tep_event_type type;
	char *token;
	int i;

	arg->type = TEP_PRINT_FUNC;
	arg->func.func = func;

	*tok = NULL;

	next_arg = &(arg->func.args);
	for (i = 0; i < func->nr_args; i++) {
		farg = alloc_arg();
		if (!farg) {
			do_warning_event(event, "%s: not enough memory!",
					 __func__);
			return TEP_EVENT_ERROR;
		}

		type = process_arg(event, farg, &token);
		if (i < (func->nr_args - 1)) {
			if (type != TEP_EVENT_DELIM || strcmp(token, ",") != 0) {
				do_warning_event(event,
					"Error: function '%s()' expects %d arguments but event %s only uses %d",
					func->name, func->nr_args,
					event->name, i + 1);
				goto err;
			}
		} else {
			if (type != TEP_EVENT_DELIM || strcmp(token, ")") != 0) {
				do_warning_event(event,
					"Error: function '%s()' only expects %d arguments but event %s has more",
					func->name, func->nr_args, event->name);
				goto err;
			}
		}

		*next_arg = farg;
		next_arg = &(farg->next);
		free_token(token);
	}

	type = read_token(&token);
	*tok = token;

	return type;

err:
	free_arg(farg);
	free_token(token);
	return TEP_EVENT_ERROR;
}

static enum tep_event_type
process_builtin_expect(struct tep_event *event, struct tep_print_arg *arg, char **tok)
{
	enum tep_event_type type;
	char *token = NULL;

	/* Handle __builtin_expect( cond, #) */
	type = process_arg(event, arg, &token);

	if (type != TEP_EVENT_DELIM || token[0] != ',')
		goto out_free;

	free_token(token);

	/* We don't care what the second parameter is of the __builtin_expect() */
	if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
		goto out_free;

	if (read_expected(TEP_EVENT_DELIM, ")") < 0)
		goto out_free;

	free_token(token);
	type = read_token_item(tok);
	return type;

out_free:
	free_token(token);
	*tok = NULL;
	return TEP_EVENT_ERROR;
}

static enum tep_event_type
process_function(struct tep_event *event, struct tep_print_arg *arg,
		 char *token, char **tok)
{
	struct tep_function_handler *func;

	if (strcmp(token, "__print_flags") == 0) {
		free_token(token);
		is_flag_field = 1;
		return process_flags(event, arg, tok);
	}
	if (strcmp(token, "__print_symbolic") == 0) {
		free_token(token);
		is_symbolic_field = 1;
		return process_symbols(event, arg, tok);
	}
	if (strcmp(token, "__print_hex") == 0) {
		free_token(token);
		return process_hex(event, arg, tok);
	}
	if (strcmp(token, "__print_hex_str") == 0) {
		free_token(token);
		return process_hex_str(event, arg, tok);
	}
	if (strcmp(token, "__print_array") == 0) {
		free_token(token);
		return process_int_array(event, arg, tok);
	}
	if (strcmp(token, "__get_str") == 0) {
		free_token(token);
		return process_str(event, arg, tok);
	}
	if (strcmp(token, "__get_bitmask") == 0) {
		free_token(token);
		return process_bitmask(event, arg, tok);
	}
	if (strcmp(token, "__get_dynamic_array") == 0) {
		free_token(token);
		return process_dynamic_array(event, arg, tok);
	}
	if (strcmp(token, "__get_dynamic_array_len") == 0) {
		free_token(token);
		return process_dynamic_array_len(event, arg, tok);
	}
	if (strcmp(token, "__builtin_expect") == 0) {
		free_token(token);
		return process_builtin_expect(event, arg, tok);
	}

	func = find_func_handler(event->tep, token);
	if (func) {
		free_token(token);
		return process_func_handler(event, func, arg, tok);
	}

	do_warning_event(event, "function %s not defined", token);
	free_token(token);
	return TEP_EVENT_ERROR;
}

static enum tep_event_type
process_arg_token(struct tep_event *event, struct tep_print_arg *arg,
		  char **tok, enum tep_event_type type)
{
	char *token;
	char *atom;

	token = *tok;

	switch (type) {
	case TEP_EVENT_ITEM:
		if (strcmp(token, "REC") == 0) {
			free_token(token);
			type = process_entry(event, arg, &token);
			break;
		}
		atom = token;
		/* test the next token */
		type = read_token_item(&token);

		/*
		 * If the next token is a parenthesis, then this
		 * is a function.
		 */
		if (type == TEP_EVENT_DELIM && strcmp(token, "(") == 0) {
			free_token(token);
			token = NULL;
			/* this will free atom. */
			type = process_function(event, arg, atom, &token);
			break;
		}
		/* atoms can be more than one token long */
		while (type == TEP_EVENT_ITEM) {
			int ret;

			ret = append(&atom, " ", token);
			if (ret < 0) {
				free(atom);
				*tok = NULL;
				free_token(token);
				return TEP_EVENT_ERROR;
			}
			free_token(token);
			type = read_token_item(&token);
		}

		arg->type = TEP_PRINT_ATOM;
		arg->atom.atom = atom;
		break;

	case TEP_EVENT_DQUOTE:
	case TEP_EVENT_SQUOTE:
		arg->type = TEP_PRINT_ATOM;
		arg->atom.atom = token;
		type = read_token_item(&token);
		break;
	case TEP_EVENT_DELIM:
		if (strcmp(token, "(") == 0) {
			free_token(token);
			type = process_paren(event, arg, &token);
			break;
		}
	case TEP_EVENT_OP:
		/* handle single ops */
		arg->type = TEP_PRINT_OP;
		arg->op.op = token;
		arg->op.left = NULL;
		type = process_op(event, arg, &token);

		/* On error, the op is freed */
		if (type == TEP_EVENT_ERROR)
			arg->op.op = NULL;

		/* return error type if errored */
		break;

	case TEP_EVENT_ERROR ... TEP_EVENT_NEWLINE:
	default:
		do_warning_event(event, "unexpected type %d", type);
		return TEP_EVENT_ERROR;
	}
	*tok = token;

	return type;
}

static int event_read_print_args(struct tep_event *event, struct tep_print_arg **list)
{
	enum tep_event_type type = TEP_EVENT_ERROR;
	struct tep_print_arg *arg;
	char *token;
	int args = 0;

	do {
		if (type == TEP_EVENT_NEWLINE) {
			type = read_token_item(&token);
			continue;
		}

		arg = alloc_arg();
		if (!arg) {
			do_warning_event(event, "%s: not enough memory!",
					 __func__);
			return -1;
		}

		type = process_arg(event, arg, &token);

		if (type == TEP_EVENT_ERROR) {
			free_token(token);
			free_arg(arg);
			return -1;
		}

		*list = arg;
		args++;

		if (type == TEP_EVENT_OP) {
			type = process_op(event, arg, &token);
			free_token(token);
			if (type == TEP_EVENT_ERROR) {
				*list = NULL;
				free_arg(arg);
				return -1;
			}
			list = &arg->next;
			continue;
		}

		if (type == TEP_EVENT_DELIM && strcmp(token, ",") == 0) {
			free_token(token);
			*list = arg;
			list = &arg->next;
			continue;
		}
		break;
	} while (type != TEP_EVENT_NONE);

	if (type != TEP_EVENT_NONE && type != TEP_EVENT_ERROR)
		free_token(token);

	return args;
}

static int event_read_print(struct tep_event *event)
{
	enum tep_event_type type;
	char *token;
	int ret;

	if (read_expected_item(TEP_EVENT_ITEM, "print") < 0)
		return -1;

	if (read_expected(TEP_EVENT_ITEM, "fmt") < 0)
		return -1;

	if (read_expected(TEP_EVENT_OP, ":") < 0)
		return -1;

	if (read_expect_type(TEP_EVENT_DQUOTE, &token) < 0)
		goto fail;

 concat:
	event->print_fmt.format = token;
	event->print_fmt.args = NULL;

	/* ok to have no arg */
	type = read_token_item(&token);

	if (type == TEP_EVENT_NONE)
		return 0;

	/* Handle concatenation of print lines */
	if (type == TEP_EVENT_DQUOTE) {
		char *cat;

		if (asprintf(&cat, "%s%s", event->print_fmt.format, token) < 0)
			goto fail;
		free_token(token);
		free_token(event->print_fmt.format);
		event->print_fmt.format = NULL;
		token = cat;
		goto concat;
	}
			     
	if (test_type_token(type, token, TEP_EVENT_DELIM, ","))
		goto fail;

	free_token(token);

	ret = event_read_print_args(event, &event->print_fmt.args);
	if (ret < 0)
		return -1;

	return ret;

 fail:
	free_token(token);
	return -1;
}

/**
 * tep_find_common_field - return a common field by event
 * @event: handle for the event
 * @name: the name of the common field to return
 *
 * Returns a common field from the event by the given @name.
 * This only searches the common fields and not all field.
 */
struct tep_format_field *
tep_find_common_field(struct tep_event *event, const char *name)
{
	struct tep_format_field *format;

	for (format = event->format.common_fields;
	     format; format = format->next) {
		if (strcmp(format->name, name) == 0)
			break;
	}

	return format;
}

/**
 * tep_find_field - find a non-common field
 * @event: handle for the event
 * @name: the name of the non-common field
 *
 * Returns a non-common field by the given @name.
 * This does not search common fields.
 */
struct tep_format_field *
tep_find_field(struct tep_event *event, const char *name)
{
	struct tep_format_field *format;

	for (format = event->format.fields;
	     format; format = format->next) {
		if (strcmp(format->name, name) == 0)
			break;
	}

	return format;
}

/**
 * tep_find_any_field - find any field by name
 * @event: handle for the event
 * @name: the name of the field
 *
 * Returns a field by the given @name.
 * This searches the common field names first, then
 * the non-common ones if a common one was not found.
 */
struct tep_format_field *
tep_find_any_field(struct tep_event *event, const char *name)
{
	struct tep_format_field *format;

	format = tep_find_common_field(event, name);
	if (format)
		return format;
	return tep_find_field(event, name);
}

/**
 * tep_read_number - read a number from data
 * @tep: a handle to the trace event parser context
 * @ptr: the raw data
 * @size: the size of the data that holds the number
 *
 * Returns the number (converted to host) from the
 * raw data.
 */
unsigned long long tep_read_number(struct tep_handle *tep,
				   const void *ptr, int size)
{
	unsigned long long val;

	switch (size) {
	case 1:
		return *(unsigned char *)ptr;
	case 2:
		return data2host2(tep, *(unsigned short *)ptr);
	case 4:
		return data2host4(tep, *(unsigned int *)ptr);
	case 8:
		memcpy(&val, (ptr), sizeof(unsigned long long));
		return data2host8(tep, val);
	default:
		/* BUG! */
		return 0;
	}
}

/**
 * tep_read_number_field - read a number from data
 * @field: a handle to the field
 * @data: the raw data to read
 * @value: the value to place the number in
 *
 * Reads raw data according to a field offset and size,
 * and translates it into @value.
 *
 * Returns 0 on success, -1 otherwise.
 */
int tep_read_number_field(struct tep_format_field *field, const void *data,
			  unsigned long long *value)
{
	if (!field)
		return -1;
	switch (field->size) {
	case 1:
	case 2:
	case 4:
	case 8:
		*value = tep_read_number(field->event->tep,
					 data + field->offset, field->size);
		return 0;
	default:
		return -1;
	}
}

static int get_common_info(struct tep_handle *tep,
			   const char *type, int *offset, int *size)
{
	struct tep_event *event;
	struct tep_format_field *field;

	/*
	 * All events should have the same common elements.
	 * Pick any event to find where the type is;
	 */
	if (!tep->events) {
		do_warning("no event_list!");
		return -1;
	}

	event = tep->events[0];
	field = tep_find_common_field(event, type);
	if (!field)
		return -1;

	*offset = field->offset;
	*size = field->size;

	return 0;
}

static int __parse_common(struct tep_handle *tep, void *data,
			  int *size, int *offset, const char *name)
{
	int ret;

	if (!*size) {
		ret = get_common_info(tep, name, offset, size);
		if (ret < 0)
			return ret;
	}
	return tep_read_number(tep, data + *offset, *size);
}

static int trace_parse_common_type(struct tep_handle *tep, void *data)
{
	return __parse_common(tep, data,
			      &tep->type_size, &tep->type_offset,
			      "common_type");
}

static int parse_common_pid(struct tep_handle *tep, void *data)
{
	return __parse_common(tep, data,
			      &tep->pid_size, &tep->pid_offset,
			      "common_pid");
}

static int parse_common_pc(struct tep_handle *tep, void *data)
{
	return __parse_common(tep, data,
			      &tep->pc_size, &tep->pc_offset,
			      "common_preempt_count");
}

static int parse_common_flags(struct tep_handle *tep, void *data)
{
	return __parse_common(tep, data,
			      &tep->flags_size, &tep->flags_offset,
			      "common_flags");
}

static int parse_common_lock_depth(struct tep_handle *tep, void *data)
{
	return __parse_common(tep, data,
			      &tep->ld_size, &tep->ld_offset,
			      "common_lock_depth");
}

static int parse_common_migrate_disable(struct tep_handle *tep, void *data)
{
	return __parse_common(tep, data,
			      &tep->ld_size, &tep->ld_offset,
			      "common_migrate_disable");
}

static int events_id_cmp(const void *a, const void *b);

/**
 * tep_find_event - find an event by given id
 * @tep: a handle to the trace event parser context
 * @id: the id of the event
 *
 * Returns an event that has a given @id.
 */
struct tep_event *tep_find_event(struct tep_handle *tep, int id)
{
	struct tep_event **eventptr;
	struct tep_event key;
	struct tep_event *pkey = &key;

	/* Check cache first */
	if (tep->last_event && tep->last_event->id == id)
		return tep->last_event;

	key.id = id;

	eventptr = bsearch(&pkey, tep->events, tep->nr_events,
			   sizeof(*tep->events), events_id_cmp);

	if (eventptr) {
		tep->last_event = *eventptr;
		return *eventptr;
	}

	return NULL;
}

/**
 * tep_find_event_by_name - find an event by given name
 * @tep: a handle to the trace event parser context
 * @sys: the system name to search for
 * @name: the name of the event to search for
 *
 * This returns an event with a given @name and under the system
 * @sys. If @sys is NULL the first event with @name is returned.
 */
struct tep_event *
tep_find_event_by_name(struct tep_handle *tep,
		       const char *sys, const char *name)
{
	struct tep_event *event = NULL;
	int i;

	if (tep->last_event &&
	    strcmp(tep->last_event->name, name) == 0 &&
	    (!sys || strcmp(tep->last_event->system, sys) == 0))
		return tep->last_event;

	for (i = 0; i < tep->nr_events; i++) {
		event = tep->events[i];
		if (strcmp(event->name, name) == 0) {
			if (!sys)
				break;
			if (strcmp(event->system, sys) == 0)
				break;
		}
	}
	if (i == tep->nr_events)
		event = NULL;

	tep->last_event = event;
	return event;
}

static unsigned long long
eval_num_arg(void *data, int size, struct tep_event *event, struct tep_print_arg *arg)
{
	struct tep_handle *tep = event->tep;
	unsigned long long val = 0;
	unsigned long long left, right;
	struct tep_print_arg *typearg = NULL;
	struct tep_print_arg *larg;
	unsigned long offset;
	unsigned int field_size;

	switch (arg->type) {
	case TEP_PRINT_NULL:
		/* ?? */
		return 0;
	case TEP_PRINT_ATOM:
		return strtoull(arg->atom.atom, NULL, 0);
	case TEP_PRINT_FIELD:
		if (!arg->field.field) {
			arg->field.field = tep_find_any_field(event, arg->field.name);
			if (!arg->field.field)
				goto out_warning_field;
			
		}
		/* must be a number */
		val = tep_read_number(tep, data + arg->field.field->offset,
				      arg->field.field->size);
		break;
	case TEP_PRINT_FLAGS:
	case TEP_PRINT_SYMBOL:
	case TEP_PRINT_INT_ARRAY:
	case TEP_PRINT_HEX:
	case TEP_PRINT_HEX_STR:
		break;
	case TEP_PRINT_TYPE:
		val = eval_num_arg(data, size, event, arg->typecast.item);
		return eval_type(val, arg, 0);
	case TEP_PRINT_STRING:
	case TEP_PRINT_BSTRING:
	case TEP_PRINT_BITMASK:
		return 0;
	case TEP_PRINT_FUNC: {
		struct trace_seq s;
		trace_seq_init(&s);
		val = process_defined_func(&s, data, size, event, arg);
		trace_seq_destroy(&s);
		return val;
	}
	case TEP_PRINT_OP:
		if (strcmp(arg->op.op, "[") == 0) {
			/*
			 * Arrays are special, since we don't want
			 * to read the arg as is.
			 */
			right = eval_num_arg(data, size, event, arg->op.right);

			/* handle typecasts */
			larg = arg->op.left;
			while (larg->type == TEP_PRINT_TYPE) {
				if (!typearg)
					typearg = larg;
				larg = larg->typecast.item;
			}

			/* Default to long size */
			field_size = tep->long_size;

			switch (larg->type) {
			case TEP_PRINT_DYNAMIC_ARRAY:
				offset = tep_read_number(tep,
						   data + larg->dynarray.field->offset,
						   larg->dynarray.field->size);
				if (larg->dynarray.field->elementsize)
					field_size = larg->dynarray.field->elementsize;
				/*
				 * The actual length of the dynamic array is stored
				 * in the top half of the field, and the offset
				 * is in the bottom half of the 32 bit field.
				 */
				offset &= 0xffff;
				offset += right;
				break;
			case TEP_PRINT_FIELD:
				if (!larg->field.field) {
					larg->field.field =
						tep_find_any_field(event, larg->field.name);
					if (!larg->field.field) {
						arg = larg;
						goto out_warning_field;
					}
				}
				field_size = larg->field.field->elementsize;
				offset = larg->field.field->offset +
					right * larg->field.field->elementsize;
				break;
			default:
				goto default_op; /* oops, all bets off */
			}
			val = tep_read_number(tep,
					      data + offset, field_size);
			if (typearg)
				val = eval_type(val, typearg, 1);
			break;
		} else if (strcmp(arg->op.op, "?") == 0) {
			left = eval_num_arg(data, size, event, arg->op.left);
			arg = arg->op.right;
			if (left)
				val = eval_num_arg(data, size, event, arg->op.left);
			else
				val = eval_num_arg(data, size, event, arg->op.right);
			break;
		}
 default_op:
		left = eval_num_arg(data, size, event, arg->op.left);
		right = eval_num_arg(data, size, event, arg->op.right);
		switch (arg->op.op[0]) {
		case '!':
			switch (arg->op.op[1]) {
			case 0:
				val = !right;
				break;
			case '=':
				val = left != right;
				break;
			default:
				goto out_warning_op;
			}
			break;
		case '~':
			val = ~right;
			break;
		case '|':
			if (arg->op.op[1])
				val = left || right;
			else
				val = left | right;
			break;
		case '&':
			if (arg->op.op[1])
				val = left && right;
			else
				val = left & right;
			break;
		case '<':
			switch (arg->op.op[1]) {
			case 0:
				val = left < right;
				break;
			case '<':
				val = left << right;
				break;
			case '=':
				val = left <= right;
				break;
			default:
				goto out_warning_op;
			}
			break;
		case '>':
			switch (arg->op.op[1]) {
			case 0:
				val = left > right;
				break;
			case '>':
				val = left >> right;
				break;
			case '=':
				val = left >= right;
				break;
			default:
				goto out_warning_op;
			}
			break;
		case '=':
			if (arg->op.op[1] != '=')
				goto out_warning_op;

			val = left == right;
			break;
		case '-':
			val = left - right;
			break;
		case '+':
			val = left + right;
			break;
		case '/':
			val = left / right;
			break;
		case '%':
			val = left % right;
			break;
		case '*':
			val = left * right;
			break;
		default:
			goto out_warning_op;
		}
		break;
	case TEP_PRINT_DYNAMIC_ARRAY_LEN:
		offset = tep_read_number(tep,
					 data + arg->dynarray.field->offset,
					 arg->dynarray.field->size);
		/*
		 * The total allocated length of the dynamic array is
		 * stored in the top half of the field, and the offset
		 * is in the bottom half of the 32 bit field.
		 */
		val = (unsigned long long)(offset >> 16);
		break;
	case TEP_PRINT_DYNAMIC_ARRAY:
		/* Without [], we pass the address to the dynamic data */
		offset = tep_read_number(tep,
					 data + arg->dynarray.field->offset,
					 arg->dynarray.field->size);
		/*
		 * The total allocated length of the dynamic array is
		 * stored in the top half of the field, and the offset
		 * is in the bottom half of the 32 bit field.
		 */
		offset &= 0xffff;
		val = (unsigned long long)((unsigned long)data + offset);
		break;
	default: /* not sure what to do there */
		return 0;
	}
	return val;

out_warning_op:
	do_warning_event(event, "%s: unknown op '%s'", __func__, arg->op.op);
	return 0;

out_warning_field:
	do_warning_event(event, "%s: field %s not found",
			 __func__, arg->field.name);
	return 0;
}

struct flag {
	const char *name;
	unsigned long long value;
};

static const struct flag flags[] = {
	{ "HI_SOFTIRQ", 0 },
	{ "TIMER_SOFTIRQ", 1 },
	{ "NET_TX_SOFTIRQ", 2 },
	{ "NET_RX_SOFTIRQ", 3 },
	{ "BLOCK_SOFTIRQ", 4 },
	{ "IRQ_POLL_SOFTIRQ", 5 },
	{ "TASKLET_SOFTIRQ", 6 },
	{ "SCHED_SOFTIRQ", 7 },
	{ "HRTIMER_SOFTIRQ", 8 },
	{ "RCU_SOFTIRQ", 9 },

	{ "HRTIMER_NORESTART", 0 },
	{ "HRTIMER_RESTART", 1 },
};

static long long eval_flag(const char *flag)
{
	int i;

	/*
	 * Some flags in the format files do not get converted.
	 * If the flag is not numeric, see if it is something that
	 * we already know about.
	 */
	if (isdigit(flag[0]))
		return strtoull(flag, NULL, 0);

	for (i = 0; i < (int)(sizeof(flags)/sizeof(flags[0])); i++)
		if (strcmp(flags[i].name, flag) == 0)
			return flags[i].value;

	return -1LL;
}

static void print_str_to_seq(struct trace_seq *s, const char *format,
			     int len_arg, const char *str)
{
	if (len_arg >= 0)
		trace_seq_printf(s, format, len_arg, str);
	else
		trace_seq_printf(s, format, str);
}

static void print_bitmask_to_seq(struct tep_handle *tep,
				 struct trace_seq *s, const char *format,
				 int len_arg, const void *data, int size)
{
	int nr_bits = size * 8;
	int str_size = (nr_bits + 3) / 4;
	int len = 0;
	char buf[3];
	char *str;
	int index;
	int i;

	/*
	 * The kernel likes to put in commas every 32 bits, we
	 * can do the same.
	 */
	str_size += (nr_bits - 1) / 32;

	str = malloc(str_size + 1);
	if (!str) {
		do_warning("%s: not enough memory!", __func__);
		return;
	}
	str[str_size] = 0;

	/* Start out with -2 for the two chars per byte */
	for (i = str_size - 2; i >= 0; i -= 2) {
		/*
		 * data points to a bit mask of size bytes.
		 * In the kernel, this is an array of long words, thus
		 * endianness is very important.
		 */
		if (tep->file_bigendian)
			index = size - (len + 1);
		else
			index = len;

		snprintf(buf, 3, "%02x", *((unsigned char *)data + index));
		memcpy(str + i, buf, 2);
		len++;
		if (!(len & 3) && i > 0) {
			i--;
			str[i] = ',';
		}
	}

	if (len_arg >= 0)
		trace_seq_printf(s, format, len_arg, str);
	else
		trace_seq_printf(s, format, str);

	free(str);
}

static void print_str_arg(struct trace_seq *s, void *data, int size,
			  struct tep_event *event, const char *format,
			  int len_arg, struct tep_print_arg *arg)
{
	struct tep_handle *tep = event->tep;
	struct tep_print_flag_sym *flag;
	struct tep_format_field *field;
	struct printk_map *printk;
	long long val, fval;
	unsigned long long addr;
	char *str;
	unsigned char *hex;
	int print;
	int i, len;

	switch (arg->type) {
	case TEP_PRINT_NULL:
		/* ?? */
		return;
	case TEP_PRINT_ATOM:
		print_str_to_seq(s, format, len_arg, arg->atom.atom);
		return;
	case TEP_PRINT_FIELD:
		field = arg->field.field;
		if (!field) {
			field = tep_find_any_field(event, arg->field.name);
			if (!field) {
				str = arg->field.name;
				goto out_warning_field;
			}
			arg->field.field = field;
		}
		/* Zero sized fields, mean the rest of the data */
		len = field->size ? : size - field->offset;

		/*
		 * Some events pass in pointers. If this is not an array
		 * and the size is the same as long_size, assume that it
		 * is a pointer.
		 */
		if (!(field->flags & TEP_FIELD_IS_ARRAY) &&
		    field->size == tep->long_size) {

			/* Handle heterogeneous recording and processing
			 * architectures
			 *
			 * CASE I:
			 * Traces recorded on 32-bit devices (32-bit
			 * addressing) and processed on 64-bit devices:
			 * In this case, only 32 bits should be read.
			 *
			 * CASE II:
			 * Traces recorded on 64 bit devices and processed
			 * on 32-bit devices:
			 * In this case, 64 bits must be read.
			 */
			addr = (tep->long_size == 8) ?
				*(unsigned long long *)(data + field->offset) :
				(unsigned long long)*(unsigned int *)(data + field->offset);

			/* Check if it matches a print format */
			printk = find_printk(tep, addr);
			if (printk)
				trace_seq_puts(s, printk->printk);
			else
				trace_seq_printf(s, "%llx", addr);
			break;
		}
		str = malloc(len + 1);
		if (!str) {
			do_warning_event(event, "%s: not enough memory!",
					 __func__);
			return;
		}
		memcpy(str, data + field->offset, len);
		str[len] = 0;
		print_str_to_seq(s, format, len_arg, str);
		free(str);
		break;
	case TEP_PRINT_FLAGS:
		val = eval_num_arg(data, size, event, arg->flags.field);
		print = 0;
		for (flag = arg->flags.flags; flag; flag = flag->next) {
			fval = eval_flag(flag->value);
			if (!val && fval < 0) {
				print_str_to_seq(s, format, len_arg, flag->str);
				break;
			}
			if (fval > 0 && (val & fval) == fval) {
				if (print && arg->flags.delim)
					trace_seq_puts(s, arg->flags.delim);
				print_str_to_seq(s, format, len_arg, flag->str);
				print = 1;
				val &= ~fval;
			}
		}
		if (val) {
			if (print && arg->flags.delim)
				trace_seq_puts(s, arg->flags.delim);
			trace_seq_printf(s, "0x%llx", val);
		}
		break;
	case TEP_PRINT_SYMBOL:
		val = eval_num_arg(data, size, event, arg->symbol.field);
		for (flag = arg->symbol.symbols; flag; flag = flag->next) {
			fval = eval_flag(flag->value);
			if (val == fval) {
				print_str_to_seq(s, format, len_arg, flag->str);
				break;
			}
		}
		if (!flag)
			trace_seq_printf(s, "0x%llx", val);
		break;
	case TEP_PRINT_HEX:
	case TEP_PRINT_HEX_STR:
		if (arg->hex.field->type == TEP_PRINT_DYNAMIC_ARRAY) {
			unsigned long offset;
			offset = tep_read_number(tep,
				data + arg->hex.field->dynarray.field->offset,
				arg->hex.field->dynarray.field->size);
			hex = data + (offset & 0xffff);
		} else {
			field = arg->hex.field->field.field;
			if (!field) {
				str = arg->hex.field->field.name;
				field = tep_find_any_field(event, str);
				if (!field)
					goto out_warning_field;
				arg->hex.field->field.field = field;
			}
			hex = data + field->offset;
		}
		len = eval_num_arg(data, size, event, arg->hex.size);
		for (i = 0; i < len; i++) {
			if (i && arg->type == TEP_PRINT_HEX)
				trace_seq_putc(s, ' ');
			trace_seq_printf(s, "%02x", hex[i]);
		}
		break;

	case TEP_PRINT_INT_ARRAY: {
		void *num;
		int el_size;

		if (arg->int_array.field->type == TEP_PRINT_DYNAMIC_ARRAY) {
			unsigned long offset;
			struct tep_format_field *field =
				arg->int_array.field->dynarray.field;
			offset = tep_read_number(tep,
						 data + field->offset,
						 field->size);
			num = data + (offset & 0xffff);
		} else {
			field = arg->int_array.field->field.field;
			if (!field) {
				str = arg->int_array.field->field.name;
				field = tep_find_any_field(event, str);
				if (!field)
					goto out_warning_field;
				arg->int_array.field->field.field = field;
			}
			num = data + field->offset;
		}
		len = eval_num_arg(data, size, event, arg->int_array.count);
		el_size = eval_num_arg(data, size, event,
				       arg->int_array.el_size);
		for (i = 0; i < len; i++) {
			if (i)
				trace_seq_putc(s, ' ');

			if (el_size == 1) {
				trace_seq_printf(s, "%u", *(uint8_t *)num);
			} else if (el_size == 2) {
				trace_seq_printf(s, "%u", *(uint16_t *)num);
			} else if (el_size == 4) {
				trace_seq_printf(s, "%u", *(uint32_t *)num);
			} else if (el_size == 8) {
				trace_seq_printf(s, "%"PRIu64, *(uint64_t *)num);
			} else {
				trace_seq_printf(s, "BAD SIZE:%d 0x%x",
						 el_size, *(uint8_t *)num);
				el_size = 1;
			}

			num += el_size;
		}
		break;
	}
	case TEP_PRINT_TYPE:
		break;
	case TEP_PRINT_STRING: {
		int str_offset;

		if (arg->string.offset == -1) {
			struct tep_format_field *f;

			f = tep_find_any_field(event, arg->string.string);
			arg->string.offset = f->offset;
		}
		str_offset = data2host4(tep, *(unsigned int *)(data + arg->string.offset));
		str_offset &= 0xffff;
		print_str_to_seq(s, format, len_arg, ((char *)data) + str_offset);
		break;
	}
	case TEP_PRINT_BSTRING:
		print_str_to_seq(s, format, len_arg, arg->string.string);
		break;
	case TEP_PRINT_BITMASK: {
		int bitmask_offset;
		int bitmask_size;

		if (arg->bitmask.offset == -1) {
			struct tep_format_field *f;

			f = tep_find_any_field(event, arg->bitmask.bitmask);
			arg->bitmask.offset = f->offset;
		}
		bitmask_offset = data2host4(tep, *(unsigned int *)(data + arg->bitmask.offset));
		bitmask_size = bitmask_offset >> 16;
		bitmask_offset &= 0xffff;
		print_bitmask_to_seq(tep, s, format, len_arg,
				     data + bitmask_offset, bitmask_size);
		break;
	}
	case TEP_PRINT_OP:
		/*
		 * The only op for string should be ? :
		 */
		if (arg->op.op[0] != '?')
			return;
		val = eval_num_arg(data, size, event, arg->op.left);
		if (val)
			print_str_arg(s, data, size, event,
				      format, len_arg, arg->op.right->op.left);
		else
			print_str_arg(s, data, size, event,
				      format, len_arg, arg->op.right->op.right);
		break;
	case TEP_PRINT_FUNC:
		process_defined_func(s, data, size, event, arg);
		break;
	default:
		/* well... */
		break;
	}

	return;

out_warning_field:
	do_warning_event(event, "%s: field %s not found",
			 __func__, arg->field.name);
}

static unsigned long long
process_defined_func(struct trace_seq *s, void *data, int size,
		     struct tep_event *event, struct tep_print_arg *arg)
{
	struct tep_function_handler *func_handle = arg->func.func;
	struct func_params *param;
	unsigned long long *args;
	unsigned long long ret;
	struct tep_print_arg *farg;
	struct trace_seq str;
	struct save_str {
		struct save_str *next;
		char *str;
	} *strings = NULL, *string;
	int i;

	if (!func_handle->nr_args) {
		ret = (*func_handle->func)(s, NULL);
		goto out;
	}

	farg = arg->func.args;
	param = func_handle->params;

	ret = ULLONG_MAX;
	args = malloc(sizeof(*args) * func_handle->nr_args);
	if (!args)
		goto out;

	for (i = 0; i < func_handle->nr_args; i++) {
		switch (param->type) {
		case TEP_FUNC_ARG_INT:
		case TEP_FUNC_ARG_LONG:
		case TEP_FUNC_ARG_PTR:
			args[i] = eval_num_arg(data, size, event, farg);
			break;
		case TEP_FUNC_ARG_STRING:
			trace_seq_init(&str);
			print_str_arg(&str, data, size, event, "%s", -1, farg);
			trace_seq_terminate(&str);
			string = malloc(sizeof(*string));
			if (!string) {
				do_warning_event(event, "%s(%d): malloc str",
						 __func__, __LINE__);
				goto out_free;
			}
			string->next = strings;
			string->str = strdup(str.buffer);
			if (!string->str) {
				free(string);
				do_warning_event(event, "%s(%d): malloc str",
						 __func__, __LINE__);
				goto out_free;
			}
			args[i] = (uintptr_t)string->str;
			strings = string;
			trace_seq_destroy(&str);
			break;
		default:
			/*
			 * Something went totally wrong, this is not
			 * an input error, something in this code broke.
			 */
			do_warning_event(event, "Unexpected end of arguments\n");
			goto out_free;
		}
		farg = farg->next;
		param = param->next;
	}

	ret = (*func_handle->func)(s, args);
out_free:
	free(args);
	while (strings) {
		string = strings;
		strings = string->next;
		free(string->str);
		free(string);
	}

 out:
	/* TBD : handle return type here */
	return ret;
}

static void free_args(struct tep_print_arg *args)
{
	struct tep_print_arg *next;

	while (args) {
		next = args->next;

		free_arg(args);
		args = next;
	}
}

static struct tep_print_arg *make_bprint_args(char *fmt, void *data, int size, struct tep_event *event)
{
	struct tep_handle *tep = event->tep;
	struct tep_format_field *field, *ip_field;
	struct tep_print_arg *args, *arg, **next;
	unsigned long long ip, val;
	char *ptr;
	void *bptr;
	int vsize = 0;

	field = tep->bprint_buf_field;
	ip_field = tep->bprint_ip_field;

	if (!field) {
		field = tep_find_field(event, "buf");
		if (!field) {
			do_warning_event(event, "can't find buffer field for binary printk");
			return NULL;
		}
		ip_field = tep_find_field(event, "ip");
		if (!ip_field) {
			do_warning_event(event, "can't find ip field for binary printk");
			return NULL;
		}
		tep->bprint_buf_field = field;
		tep->bprint_ip_field = ip_field;
	}

	ip = tep_read_number(tep, data + ip_field->offset, ip_field->size);

	/*
	 * The first arg is the IP pointer.
	 */
	args = alloc_arg();
	if (!args) {
		do_warning_event(event, "%s(%d): not enough memory!",
				 __func__, __LINE__);
		return NULL;
	}
	arg = args;
	arg->next = NULL;
	next = &arg->next;

	arg->type = TEP_PRINT_ATOM;
		
	if (asprintf(&arg->atom.atom, "%lld", ip) < 0)
		goto out_free;

	/* skip the first "%ps: " */
	for (ptr = fmt + 5, bptr = data + field->offset;
	     bptr < data + size && *ptr; ptr++) {
		int ls = 0;

		if (*ptr == '%') {
 process_again:
			ptr++;
			switch (*ptr) {
			case '%':
				break;
			case 'l':
				ls++;
				goto process_again;
			case 'L':
				ls = 2;
				goto process_again;
			case '0' ... '9':
				goto process_again;
			case '.':
				goto process_again;
			case 'z':
			case 'Z':
				ls = 1;
				goto process_again;
			case 'p':
				ls = 1;
				if (isalnum(ptr[1])) {
					ptr++;
					/* Check for special pointers */
					switch (*ptr) {
					case 's':
					case 'S':
					case 'x':
						break;
					case 'f':
					case 'F':
						/*
						 * Pre-5.5 kernels use %pf and
						 * %pF for printing symbols
						 * while kernels since 5.5 use
						 * %pfw for fwnodes. So check
						 * %p[fF] isn't followed by 'w'.
						 */
						if (ptr[1] != 'w')
							break;
						/* fall through */
					default:
						/*
						 * Older kernels do not process
						 * dereferenced pointers.
						 * Only process if the pointer
						 * value is a printable.
						 */
						if (isprint(*(char *)bptr))
							goto process_string;
					}
				}
				/* fall through */
			case 'd':
			case 'u':
			case 'i':
			case 'x':
			case 'X':
			case 'o':
				switch (ls) {
				case 0:
					vsize = 4;
					break;
				case 1:
					vsize = tep->long_size;
					break;
				case 2:
					vsize = 8;
					break;
				default:
					vsize = ls; /* ? */
					break;
				}
			/* fall through */
			case '*':
				if (*ptr == '*')
					vsize = 4;

				/* the pointers are always 4 bytes aligned */
				bptr = (void *)(((unsigned long)bptr + 3) &
						~3);
				val = tep_read_number(tep, bptr, vsize);
				bptr += vsize;
				arg = alloc_arg();
				if (!arg) {
					do_warning_event(event, "%s(%d): not enough memory!",
						   __func__, __LINE__);
					goto out_free;
				}
				arg->next = NULL;
				arg->type = TEP_PRINT_ATOM;
				if (asprintf(&arg->atom.atom, "%lld", val) < 0) {
					free(arg);
					goto out_free;
				}
				*next = arg;
				next = &arg->next;
				/*
				 * The '*' case means that an arg is used as the length.
				 * We need to continue to figure out for what.
				 */
				if (*ptr == '*')
					goto process_again;

				break;
			case 's':
 process_string:
				arg = alloc_arg();
				if (!arg) {
					do_warning_event(event, "%s(%d): not enough memory!",
						   __func__, __LINE__);
					goto out_free;
				}
				arg->next = NULL;
				arg->type = TEP_PRINT_BSTRING;
				arg->string.string = strdup(bptr);
				if (!arg->string.string)
					goto out_free;
				bptr += strlen(bptr) + 1;
				*next = arg;
				next = &arg->next;
			default:
				break;
			}
		}
	}

	return args;

out_free:
	free_args(args);
	return NULL;
}

static char *
get_bprint_format(void *data, int size __maybe_unused,
		  struct tep_event *event)
{
	struct tep_handle *tep = event->tep;
	unsigned long long addr;
	struct tep_format_field *field;
	struct printk_map *printk;
	char *format;

	field = tep->bprint_fmt_field;

	if (!field) {
		field = tep_find_field(event, "fmt");
		if (!field) {
			do_warning_event(event, "can't find format field for binary printk");
			return NULL;
		}
		tep->bprint_fmt_field = field;
	}

	addr = tep_read_number(tep, data + field->offset, field->size);

	printk = find_printk(tep, addr);
	if (!printk) {
		if (asprintf(&format, "%%ps: (NO FORMAT FOUND at %llx)\n", addr) < 0)
			return NULL;
		return format;
	}

	if (asprintf(&format, "%s: %s", "%ps", printk->printk) < 0)
		return NULL;

	return format;
}

static int print_mac_arg(struct trace_seq *s, const char *format,
			 void *data, int size, struct tep_event *event,
			 struct tep_print_arg *arg)
{
	const char *fmt = "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x";
	bool reverse = false;
	unsigned char *buf;
	int ret = 0;

	if (arg->type == TEP_PRINT_FUNC) {
		process_defined_func(s, data, size, event, arg);
		return 0;
	}

	if (arg->type != TEP_PRINT_FIELD) {
		trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d",
				 arg->type);
		return 0;
	}

	if (format[0] == 'm') {
		fmt = "%.2x%.2x%.2x%.2x%.2x%.2x";
	} else if (format[0] == 'M' && format[1] == 'F') {
		fmt = "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x";
		ret++;
	}
	if (format[1] == 'R') {
		reverse = true;
		ret++;
	}

	if (!arg->field.field) {
		arg->field.field =
			tep_find_any_field(event, arg->field.name);
		if (!arg->field.field) {
			do_warning_event(event, "%s: field %s not found",
					 __func__, arg->field.name);
			return ret;
		}
	}
	if (arg->field.field->size != 6) {
		trace_seq_printf(s, "INVALIDMAC");
		return ret;
	}

	buf = data + arg->field.field->offset;
	if (reverse)
		trace_seq_printf(s, fmt, buf[5], buf[4], buf[3], buf[2], buf[1], buf[0]);
	else
		trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);

	return ret;
}

static int parse_ip4_print_args(struct tep_handle *tep,
				const char *ptr, bool *reverse)
{
	int ret = 0;

	*reverse = false;

	/* hnbl */
	switch (*ptr) {
	case 'h':
		if (tep->file_bigendian)
			*reverse = false;
		else
			*reverse = true;
		ret++;
		break;
	case 'l':
		*reverse = true;
		ret++;
		break;
	case 'n':
	case 'b':
		ret++;
		/* fall through */
	default:
		*reverse = false;
		break;
	}

	return ret;
}

static void print_ip4_addr(struct trace_seq *s, char i, bool reverse, unsigned char *buf)
{
	const char *fmt;

	if (i == 'i')
		fmt = "%03d.%03d.%03d.%03d";
	else
		fmt = "%d.%d.%d.%d";

	if (reverse)
		trace_seq_printf(s, fmt, buf[3], buf[2], buf[1], buf[0]);
	else
		trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3]);

}

static inline bool ipv6_addr_v4mapped(const struct in6_addr *a)
{
	return ((unsigned long)(a->s6_addr32[0] | a->s6_addr32[1]) |
		(unsigned long)(a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0UL;
}

static inline bool ipv6_addr_is_isatap(const struct in6_addr *addr)
{
	return (addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE);
}

static void print_ip6c_addr(struct trace_seq *s, unsigned char *addr)
{
	int i, j, range;
	unsigned char zerolength[8];
	int longest = 1;
	int colonpos = -1;
	uint16_t word;
	uint8_t hi, lo;
	bool needcolon = false;
	bool useIPv4;
	struct in6_addr in6;

	memcpy(&in6, addr, sizeof(struct in6_addr));

	useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6);

	memset(zerolength, 0, sizeof(zerolength));

	if (useIPv4)
		range = 6;
	else
		range = 8;

	/* find position of longest 0 run */
	for (i = 0; i < range; i++) {
		for (j = i; j < range; j++) {
			if (in6.s6_addr16[j] != 0)
				break;
			zerolength[i]++;
		}
	}
	for (i = 0; i < range; i++) {
		if (zerolength[i] > longest) {
			longest = zerolength[i];
			colonpos = i;
		}
	}
	if (longest == 1)		/* don't compress a single 0 */
		colonpos = -1;

	/* emit address */
	for (i = 0; i < range; i++) {
		if (i == colonpos) {
			if (needcolon || i == 0)
				trace_seq_printf(s, ":");
			trace_seq_printf(s, ":");
			needcolon = false;
			i += longest - 1;
			continue;
		}
		if (needcolon) {
			trace_seq_printf(s, ":");
			needcolon = false;
		}
		/* hex u16 without leading 0s */
		word = ntohs(in6.s6_addr16[i]);
		hi = word >> 8;
		lo = word & 0xff;
		if (hi)
			trace_seq_printf(s, "%x%02x", hi, lo);
		else
			trace_seq_printf(s, "%x", lo);

		needcolon = true;
	}

	if (useIPv4) {
		if (needcolon)
			trace_seq_printf(s, ":");
		print_ip4_addr(s, 'I', false, &in6.s6_addr[12]);
	}

	return;
}

static void print_ip6_addr(struct trace_seq *s, char i, unsigned char *buf)
{
	int j;

	for (j = 0; j < 16; j += 2) {
		trace_seq_printf(s, "%02x%02x", buf[j], buf[j+1]);
		if (i == 'I' && j < 14)
			trace_seq_printf(s, ":");
	}
}

/*
 * %pi4   print an IPv4 address with leading zeros
 * %pI4   print an IPv4 address without leading zeros
 * %pi6   print an IPv6 address without colons
 * %pI6   print an IPv6 address with colons
 * %pI6c  print an IPv6 address in compressed form with colons
 * %pISpc print an IP address based on sockaddr; p adds port.
 */
static int print_ipv4_arg(struct trace_seq *s, const char *ptr, char i,
			  void *data, int size, struct tep_event *event,
			  struct tep_print_arg *arg)
{
	bool reverse = false;
	unsigned char *buf;
	int ret;

	ret = parse_ip4_print_args(event->tep, ptr, &reverse);

	if (arg->type == TEP_PRINT_FUNC) {
		process_defined_func(s, data, size, event, arg);
		return ret;
	}

	if (arg->type != TEP_PRINT_FIELD) {
		trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type);
		return ret;
	}

	if (!arg->field.field) {
		arg->field.field =
			tep_find_any_field(event, arg->field.name);
		if (!arg->field.field) {
			do_warning("%s: field %s not found",
				   __func__, arg->field.name);
			return ret;
		}
	}

	buf = data + arg->field.field->offset;

	if (arg->field.field->size != 4) {
		trace_seq_printf(s, "INVALIDIPv4");
		return ret;
	}

	print_ip4_addr(s, i, reverse, buf);
	return ret;

}

static int print_ipv6_arg(struct trace_seq *s, const char *ptr, char i,
			  void *data, int size, struct tep_event *event,
			  struct tep_print_arg *arg)
{
	char have_c = 0;
	unsigned char *buf;
	int rc = 0;

	/* pI6c */
	if (i == 'I' && *ptr == 'c') {
		have_c = 1;
		ptr++;
		rc++;
	}

	if (arg->type == TEP_PRINT_FUNC) {
		process_defined_func(s, data, size, event, arg);
		return rc;
	}

	if (arg->type != TEP_PRINT_FIELD) {
		trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type);
		return rc;
	}

	if (!arg->field.field) {
		arg->field.field =
			tep_find_any_field(event, arg->field.name);
		if (!arg->field.field) {
			do_warning("%s: field %s not found",
				   __func__, arg->field.name);
			return rc;
		}
	}

	buf = data + arg->field.field->offset;

	if (arg->field.field->size != 16) {
		trace_seq_printf(s, "INVALIDIPv6");
		return rc;
	}

	if (have_c)
		print_ip6c_addr(s, buf);
	else
		print_ip6_addr(s, i, buf);

	return rc;
}

static int print_ipsa_arg(struct trace_seq *s, const char *ptr, char i,
			  void *data, int size, struct tep_event *event,
			  struct tep_print_arg *arg)
{
	char have_c = 0, have_p = 0;
	unsigned char *buf;
	struct sockaddr_storage *sa;
	bool reverse = false;
	int rc = 0;
	int ret;

	/* pISpc */
	if (i == 'I') {
		if (*ptr == 'p') {
			have_p = 1;
			ptr++;
			rc++;
		}
		if (*ptr == 'c') {
			have_c = 1;
			ptr++;
			rc++;
		}
	}
	ret = parse_ip4_print_args(event->tep, ptr, &reverse);
	ptr += ret;
	rc += ret;

	if (arg->type == TEP_PRINT_FUNC) {
		process_defined_func(s, data, size, event, arg);
		return rc;
	}

	if (arg->type != TEP_PRINT_FIELD) {
		trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type);
		return rc;
	}

	if (!arg->field.field) {
		arg->field.field =
			tep_find_any_field(event, arg->field.name);
		if (!arg->field.field) {
			do_warning("%s: field %s not found",
				   __func__, arg->field.name);
			return rc;
		}
	}

	sa = (struct sockaddr_storage *) (data + arg->field.field->offset);

	if (sa->ss_family == AF_INET) {
		struct sockaddr_in *sa4 = (struct sockaddr_in *) sa;

		if (arg->field.field->size < sizeof(struct sockaddr_in)) {
			trace_seq_printf(s, "INVALIDIPv4");
			return rc;
		}

		print_ip4_addr(s, i, reverse, (unsigned char *) &sa4->sin_addr);
		if (have_p)
			trace_seq_printf(s, ":%d", ntohs(sa4->sin_port));


	} else if (sa->ss_family == AF_INET6) {
		struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) sa;

		if (arg->field.field->size < sizeof(struct sockaddr_in6)) {
			trace_seq_printf(s, "INVALIDIPv6");
			return rc;
		}

		if (have_p)
			trace_seq_printf(s, "[");

		buf = (unsigned char *) &sa6->sin6_addr;
		if (have_c)
			print_ip6c_addr(s, buf);
		else
			print_ip6_addr(s, i, buf);

		if (have_p)
			trace_seq_printf(s, "]:%d", ntohs(sa6->sin6_port));
	}

	return rc;
}

static int print_ip_arg(struct trace_seq *s, const char *ptr,
			void *data, int size, struct tep_event *event,
			struct tep_print_arg *arg)
{
	char i = *ptr;  /* 'i' or 'I' */
	int rc = 1;

	/* IP version */
	ptr++;

	switch (*ptr) {
	case '4':
		rc += print_ipv4_arg(s, ptr + 1, i, data, size, event, arg);
		break;
	case '6':
		rc += print_ipv6_arg(s, ptr + 1, i, data, size, event, arg);
		break;
	case 'S':
		rc += print_ipsa_arg(s, ptr + 1, i, data, size, event, arg);
		break;
	default:
		return 0;
	}

	return rc;
}

static const int guid_index[16] = {3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15};
static const int uuid_index[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};

static int print_uuid_arg(struct trace_seq *s, const char *ptr,
			void *data, int size, struct tep_event *event,
			struct tep_print_arg *arg)
{
	const int *index = uuid_index;
	char *format = "%02x";
	int ret = 0;
	char *buf;
	int i;

	switch (*(ptr + 1)) {
	case 'L':
		format = "%02X";
		/* fall through */
	case 'l':
		index = guid_index;
		ret++;
		break;
	case 'B':
		format = "%02X";
		/* fall through */
	case 'b':
		ret++;
		break;
	}

	if (arg->type == TEP_PRINT_FUNC) {
		process_defined_func(s, data, size, event, arg);
		return ret;
	}

	if (arg->type != TEP_PRINT_FIELD) {
		trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type);
		return ret;
	}

	if (!arg->field.field) {
		arg->field.field =
			tep_find_any_field(event, arg->field.name);
		if (!arg->field.field) {
			do_warning("%s: field %s not found",
				   __func__, arg->field.name);
			return ret;
		}
	}

	if (arg->field.field->size != 16) {
		trace_seq_printf(s, "INVALIDUUID");
		return ret;
	}

	buf = data + arg->field.field->offset;

	for (i = 0; i < 16; i++) {
		trace_seq_printf(s, format, buf[index[i]] & 0xff);
		switch (i) {
		case 3:
		case 5:
		case 7:
		case 9:
			trace_seq_printf(s, "-");
			break;
		}
	}

	return ret;
}

static int print_raw_buff_arg(struct trace_seq *s, const char *ptr,
			      void *data, int size, struct tep_event *event,
			      struct tep_print_arg *arg, int print_len)
{
	int plen = print_len;
	char *delim = " ";
	int ret = 0;
	char *buf;
	int i;
	unsigned long offset;
	int arr_len;

	switch (*(ptr + 1)) {
	case 'C':
		delim = ":";
		ret++;
		break;
	case 'D':
		delim = "-";
		ret++;
		break;
	case 'N':
		delim = "";
		ret++;
		break;
	}

	if (arg->type == TEP_PRINT_FUNC) {
		process_defined_func(s, data, size, event, arg);
		return ret;
	}

	if (arg->type != TEP_PRINT_DYNAMIC_ARRAY) {
		trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type);
		return ret;
	}

	offset = tep_read_number(event->tep,
				 data + arg->dynarray.field->offset,
				 arg->dynarray.field->size);
	arr_len = (unsigned long long)(offset >> 16);
	buf = data + (offset & 0xffff);

	if (arr_len < plen)
		plen = arr_len;

	if (plen < 1)
		return ret;

	trace_seq_printf(s, "%02x", buf[0] & 0xff);
	for (i = 1; i < plen; i++)
		trace_seq_printf(s, "%s%02x", delim, buf[i] & 0xff);

	return ret;
}

static int is_printable_array(char *p, unsigned int len)
{
	unsigned int i;

	for (i = 0; i < len && p[i]; i++)
		if (!isprint(p[i]) && !isspace(p[i]))
		    return 0;
	return 1;
}

void tep_print_field(struct trace_seq *s, void *data,
		     struct tep_format_field *field)
{
	unsigned long long val;
	unsigned int offset, len, i;
	struct tep_handle *tep = field->event->tep;

	if (field->flags & TEP_FIELD_IS_ARRAY) {
		offset = field->offset;
		len = field->size;
		if (field->flags & TEP_FIELD_IS_DYNAMIC) {
			val = tep_read_number(tep, data + offset, len);
			offset = val;
			len = offset >> 16;
			offset &= 0xffff;
		}
		if (field->flags & TEP_FIELD_IS_STRING &&
		    is_printable_array(data + offset, len)) {
			trace_seq_printf(s, "%s", (char *)data + offset);
		} else {
			trace_seq_puts(s, "ARRAY[");
			for (i = 0; i < len; i++) {
				if (i)
					trace_seq_puts(s, ", ");
				trace_seq_printf(s, "%02x",
						 *((unsigned char *)data + offset + i));
			}
			trace_seq_putc(s, ']');
			field->flags &= ~TEP_FIELD_IS_STRING;
		}
	} else {
		val = tep_read_number(tep, data + field->offset,
				      field->size);
		if (field->flags & TEP_FIELD_IS_POINTER) {
			trace_seq_printf(s, "0x%llx", val);
		} else if (field->flags & TEP_FIELD_IS_SIGNED) {
			switch (field->size) {
			case 4:
				/*
				 * If field is long then print it in hex.
				 * A long usually stores pointers.
				 */
				if (field->flags & TEP_FIELD_IS_LONG)
					trace_seq_printf(s, "0x%x", (int)val);
				else
					trace_seq_printf(s, "%d", (int)val);
				break;
			case 2:
				trace_seq_printf(s, "%2d", (short)val);
				break;
			case 1:
				trace_seq_printf(s, "%1d", (char)val);
				break;
			default:
				trace_seq_printf(s, "%lld", val);
			}
		} else {
			if (field->flags & TEP_FIELD_IS_LONG)
				trace_seq_printf(s, "0x%llx", val);
			else
				trace_seq_printf(s, "%llu", val);
		}
	}
}

void tep_print_fields(struct trace_seq *s, void *data,
		      int size __maybe_unused, struct tep_event *event)
{
	struct tep_format_field *field;

	field = event->format.fields;
	while (field) {
		trace_seq_printf(s, " %s=", field->name);
		tep_print_field(s, data, field);
		field = field->next;
	}
}

static int print_function(struct trace_seq *s, const char *format,
			  void *data, int size, struct tep_event *event,
			  struct tep_print_arg *arg)
{
	struct func_map *func;
	unsigned long long val;

	val = eval_num_arg(data, size, event, arg);
	func = find_func(event->tep, val);
	if (func) {
		trace_seq_puts(s, func->func);
		if (*format == 'F' || *format == 'S')
			trace_seq_printf(s, "+0x%llx", val - func->addr);
	} else {
		if (event->tep->long_size == 4)
			trace_seq_printf(s, "0x%lx", (long)val);
		else
			trace_seq_printf(s, "0x%llx", (long long)val);
	}

	return 0;
}

static int print_arg_pointer(struct trace_seq *s, const char *format, int plen,
			     void *data, int size,
			     struct tep_event *event, struct tep_print_arg *arg)
{
	unsigned long long val;
	int ret = 1;

	if (arg->type == TEP_PRINT_BSTRING) {
		trace_seq_puts(s, arg->string.string);
		return 0;
	}
	while (*format) {
		if (*format == 'p') {
			format++;
			break;
		}
		format++;
	}

	switch (*format) {
	case 'F':
	case 'f':
	case 'S':
	case 's':
		ret += print_function(s, format, data, size, event, arg);
		break;
	case 'M':
	case 'm':
		ret += print_mac_arg(s, format, data, size, event, arg);
		break;
	case 'I':
	case 'i':
		ret += print_ip_arg(s, format, data, size, event, arg);
		break;
	case 'U':
		ret += print_uuid_arg(s, format, data, size, event, arg);
		break;
	case 'h':
		ret += print_raw_buff_arg(s, format, data, size, event, arg, plen);
		break;
	default:
		ret = 0;
		val = eval_num_arg(data, size, event, arg);
		trace_seq_printf(s, "%p", (void *)(intptr_t)val);
		break;
	}

	return ret;

}

static int print_arg_number(struct trace_seq *s, const char *format, int plen,
			    void *data, int size, int ls,
			    struct tep_event *event, struct tep_print_arg *arg)
{
	unsigned long long val;

	val = eval_num_arg(data, size, event, arg);

	switch (ls) {
	case -2:
		if (plen >= 0)
			trace_seq_printf(s, format, plen, (char)val);
		else
			trace_seq_printf(s, format, (char)val);
		break;
	case -1:
		if (plen >= 0)
			trace_seq_printf(s, format, plen, (short)val);
		else
			trace_seq_printf(s, format, (short)val);
		break;
	case 0:
		if (plen >= 0)
			trace_seq_printf(s, format, plen, (int)val);
		else
			trace_seq_printf(s, format, (int)val);
		break;
	case 1:
		if (plen >= 0)
			trace_seq_printf(s, format, plen, (long)val);
		else
			trace_seq_printf(s, format, (long)val);
		break;
	case 2:
		if (plen >= 0)
			trace_seq_printf(s, format, plen, (long long)val);
		else
			trace_seq_printf(s, format, (long long)val);
		break;
	default:
		do_warning_event(event, "bad count (%d)", ls);
		event->flags |= TEP_EVENT_FL_FAILED;
	}
	return 0;
}


static void print_arg_string(struct trace_seq *s, const char *format, int plen,
			     void *data, int size,
			     struct tep_event *event, struct tep_print_arg *arg)
{
	struct trace_seq p;

	/* Use helper trace_seq */
	trace_seq_init(&p);
	print_str_arg(&p, data, size, event,
		      format, plen, arg);
	trace_seq_terminate(&p);
	trace_seq_puts(s, p.buffer);
	trace_seq_destroy(&p);
}

static int parse_arg_format_pointer(const char *format)
{
	int ret = 0;
	int index;
	int loop;

	switch (*format) {
	case 'F':
	case 'S':
	case 'f':
	case 's':
		ret++;
		break;
	case 'M':
	case 'm':
		/* [mM]R , [mM]F */
		switch (format[1]) {
		case 'R':
		case 'F':
			ret++;
			break;
		}
		ret++;
		break;
	case 'I':
	case 'i':
		index = 2;
		loop = 1;
		switch (format[1]) {
		case 'S':
			/*[S][pfs]*/
			while (loop) {
				switch (format[index]) {
				case 'p':
				case 'f':
				case 's':
					ret++;
					index++;
					break;
				default:
					loop = 0;
					break;
				}
			}
			/* fall through */
		case '4':
			/* [4S][hnbl] */
			switch (format[index]) {
			case 'h':
			case 'n':
			case 'l':
			case 'b':
				ret++;
				index++;
				break;
			}
			if (format[1] == '4') {
				ret++;
				break;
			}
			/* fall through */
		case '6':
			/* [6S]c */
			if (format[index] == 'c')
				ret++;
			ret++;
			break;
		}
		ret++;
		break;
	case 'U':
		switch (format[1]) {
		case 'L':
		case 'l':
		case 'B':
		case 'b':
			ret++;
			break;
		}
		ret++;
		break;
	case 'h':
		switch (format[1]) {
		case 'C':
		case 'D':
		case 'N':
			ret++;
			break;
		}
		ret++;
		break;
	default:
		break;
	}

	return ret;
}

static void free_parse_args(struct tep_print_parse *arg)
{
	struct tep_print_parse *del;

	while (arg) {
		del = arg;
		arg = del->next;
		free(del->format);
		free(del);
	}
}

static int parse_arg_add(struct tep_print_parse **parse, char *format,
			 enum tep_print_parse_type type,
			 struct tep_print_arg *arg,
			 struct tep_print_arg *len_as_arg,
			 int ls)
{
	struct tep_print_parse *parg = NULL;

	parg = calloc(1, sizeof(*parg));
	if (!parg)
		goto error;
	parg->format = strdup(format);
	if (!parg->format)
		goto error;
	parg->type = type;
	parg->arg = arg;
	parg->len_as_arg = len_as_arg;
	parg->ls = ls;
	*parse = parg;
	return 0;
error:
	if (parg) {
		free(parg->format);
		free(parg);
	}
	return -1;
}

static int parse_arg_format(struct tep_print_parse **parse,
			    struct tep_event *event,
			    const char *format, struct tep_print_arg **arg)
{
	struct tep_print_arg *len_arg = NULL;
	char print_format[32];
	const char *start = format;
	int ret = 0;
	int ls = 0;
	int res;
	int len;

	format++;
	ret++;
	for (; *format; format++) {
		switch (*format) {
		case '#':
			/* FIXME: need to handle properly */
			break;
		case 'h':
			ls--;
			break;
		case 'l':
			ls++;
			break;
		case 'L':
			ls = 2;
			break;
		case '.':
		case 'z':
		case 'Z':
		case '0' ... '9':
		case '-':
			break;
		case '*':
			/* The argument is the length. */
			if (!*arg) {
				do_warning_event(event, "no argument match");
				event->flags |= TEP_EVENT_FL_FAILED;
				goto out_failed;
			}
			if (len_arg) {
				do_warning_event(event, "argument already matched");
				event->flags |= TEP_EVENT_FL_FAILED;
				goto out_failed;
			}
			len_arg = *arg;
			*arg = (*arg)->next;
			break;
		case 'p':
			if (!*arg) {
				do_warning_event(event, "no argument match");
				event->flags |= TEP_EVENT_FL_FAILED;
				goto out_failed;
			}
			res = parse_arg_format_pointer(format + 1);
			if (res > 0) {
				format += res;
				ret += res;
			}
			len = ((unsigned long)format + 1) -
				(unsigned long)start;
			/* should never happen */
			if (len > 31) {
				do_warning_event(event, "bad format!");
				event->flags |= TEP_EVENT_FL_FAILED;
				len = 31;
			}
			memcpy(print_format, start, len);
			print_format[len] = 0;

			parse_arg_add(parse, print_format,
				      PRINT_FMT_ARG_POINTER, *arg, len_arg, ls);
			*arg = (*arg)->next;
			ret++;
			return ret;
		case 'd':
		case 'u':
		case 'i':
		case 'x':
		case 'X':
		case 'o':
			if (!*arg) {
				do_warning_event(event, "no argument match");
				event->flags |= TEP_EVENT_FL_FAILED;
				goto out_failed;
			}

			len = ((unsigned long)format + 1) -
				(unsigned long)start;

			/* should never happen */
			if (len > 30) {
				do_warning_event(event, "bad format!");
				event->flags |= TEP_EVENT_FL_FAILED;
				len = 31;
			}
			memcpy(print_format, start, len);
			print_format[len] = 0;

			if (event->tep->long_size == 8 && ls == 1 &&
			    sizeof(long) != 8) {
				char *p;

				/* make %l into %ll */
				if (ls == 1 && (p = strchr(print_format, 'l')))
					memmove(p+1, p, strlen(p)+1);
				ls = 2;
			}
			if (ls < -2 || ls > 2) {
				do_warning_event(event, "bad count (%d)", ls);
				event->flags |= TEP_EVENT_FL_FAILED;
			}
			parse_arg_add(parse, print_format,
				      PRINT_FMT_ARG_DIGIT, *arg, len_arg, ls);
			*arg = (*arg)->next;
			ret++;
			return ret;
		case 's':
			if (!*arg) {
				do_warning_event(event, "no matching argument");
				event->flags |= TEP_EVENT_FL_FAILED;
				goto out_failed;
			}

			len = ((unsigned long)format + 1) -
				(unsigned long)start;

			/* should never happen */
			if (len > 31) {
				do_warning_event(event, "bad format!");
				event->flags |= TEP_EVENT_FL_FAILED;
				len = 31;
			}

			memcpy(print_format, start, len);
			print_format[len] = 0;

			parse_arg_add(parse, print_format,
					PRINT_FMT_ARG_STRING, *arg, len_arg, 0);
			*arg = (*arg)->next;
			ret++;
			return ret;
		default:
			snprintf(print_format, 32, ">%c<", *format);
			parse_arg_add(parse, print_format,
					PRINT_FMT_STRING, NULL, NULL, 0);
			ret++;
			return ret;
		}
		ret++;
	}

out_failed:
	return ret;

}

static int parse_arg_string(struct tep_print_parse **parse, const char *format)
{
	struct trace_seq s;
	int ret = 0;

	trace_seq_init(&s);
	for (; *format; format++) {
		if (*format == '\\') {
			format++;
			ret++;
			switch (*format) {
			case 'n':
				trace_seq_putc(&s, '\n');
				break;
			case 't':
				trace_seq_putc(&s, '\t');
				break;
			case 'r':
				trace_seq_putc(&s, '\r');
				break;
			case '\\':
				trace_seq_putc(&s, '\\');
				break;
			default:
				trace_seq_putc(&s, *format);
				break;
			}
		} else if (*format == '%') {
			if (*(format + 1) == '%') {
				trace_seq_putc(&s, '%');
				format++;
				ret++;
			} else
				break;
		} else
			trace_seq_putc(&s, *format);

		ret++;
	}
	trace_seq_terminate(&s);
	parse_arg_add(parse, s.buffer, PRINT_FMT_STRING, NULL, NULL, 0);
	trace_seq_destroy(&s);

	return ret;
}

static struct tep_print_parse *
parse_args(struct tep_event *event, const char *format, struct tep_print_arg *arg)
{
	struct tep_print_parse *parse_ret = NULL;
	struct tep_print_parse **parse = NULL;
	int ret;
	int len;

	len = strlen(format);
	while (*format) {
		if (!parse_ret)
			parse = &parse_ret;
		if (*format == '%' && *(format + 1) != '%')
			ret = parse_arg_format(parse, event, format, &arg);
		else
			ret = parse_arg_string(parse, format);
		if (*parse)
			parse = &((*parse)->next);

		len -= ret;
		if (len > 0)
			format += ret;
		else
			break;
	}
	return parse_ret;
}

static void print_event_cache(struct tep_print_parse *parse, struct trace_seq *s,
			      void *data, int size, struct tep_event *event)
{
	int len_arg;

	while (parse) {
		if (parse->len_as_arg)
			len_arg = eval_num_arg(data, size, event, parse->len_as_arg);
		switch (parse->type) {
		case PRINT_FMT_ARG_DIGIT:
			print_arg_number(s, parse->format,
					parse->len_as_arg ? len_arg : -1, data,
					 size, parse->ls, event, parse->arg);
			break;
		case PRINT_FMT_ARG_POINTER:
			print_arg_pointer(s, parse->format,
					  parse->len_as_arg ? len_arg : 1,
					  data, size, event, parse->arg);
			break;
		case PRINT_FMT_ARG_STRING:
			print_arg_string(s, parse->format,
					 parse->len_as_arg ? len_arg : -1,
					 data, size, event, parse->arg);
			break;
		case PRINT_FMT_STRING:
		default:
			trace_seq_printf(s, "%s", parse->format);
			break;
		}
		parse = parse->next;
	}
}

static void pretty_print(struct trace_seq *s, void *data, int size, struct tep_event *event)
{
	struct tep_print_parse *parse = event->print_fmt.print_cache;
	struct tep_print_arg *args = NULL;
	char *bprint_fmt = NULL;

	if (event->flags & TEP_EVENT_FL_FAILED) {
		trace_seq_printf(s, "[FAILED TO PARSE]");
		tep_print_fields(s, data, size, event);
		return;
	}

	if (event->flags & TEP_EVENT_FL_ISBPRINT) {
		bprint_fmt = get_bprint_format(data, size, event);
		args = make_bprint_args(bprint_fmt, data, size, event);
		parse = parse_args(event, bprint_fmt, args);
	}

	print_event_cache(parse, s, data, size, event);

	if (event->flags & TEP_EVENT_FL_ISBPRINT) {
		free_parse_args(parse);
		free_args(args);
		free(bprint_fmt);
	}
}

/*
 * This parses out the Latency format (interrupts disabled,
 * need rescheduling, in hard/soft interrupt, preempt count
 * and lock depth) and places it into the trace_seq.
 */
static void data_latency_format(struct tep_handle *tep, struct trace_seq *s,
				char *format, struct tep_record *record)
{
	static int check_lock_depth = 1;
	static int check_migrate_disable = 1;
	static int lock_depth_exists;
	static int migrate_disable_exists;
	unsigned int lat_flags;
	struct trace_seq sq;
	unsigned int pc;
	int lock_depth = 0;
	int migrate_disable = 0;
	int hardirq;
	int softirq;
	void *data = record->data;

	trace_seq_init(&sq);
	lat_flags = parse_common_flags(tep, data);
	pc = parse_common_pc(tep, data);
	/* lock_depth may not always exist */
	if (lock_depth_exists)
		lock_depth = parse_common_lock_depth(tep, data);
	else if (check_lock_depth) {
		lock_depth = parse_common_lock_depth(tep, data);
		if (lock_depth < 0)
			check_lock_depth = 0;
		else
			lock_depth_exists = 1;
	}

	/* migrate_disable may not always exist */
	if (migrate_disable_exists)
		migrate_disable = parse_common_migrate_disable(tep, data);
	else if (check_migrate_disable) {
		migrate_disable = parse_common_migrate_disable(tep, data);
		if (migrate_disable < 0)
			check_migrate_disable = 0;
		else
			migrate_disable_exists = 1;
	}

	hardirq = lat_flags & TRACE_FLAG_HARDIRQ;
	softirq = lat_flags & TRACE_FLAG_SOFTIRQ;

	trace_seq_printf(&sq, "%c%c%c",
	       (lat_flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
	       (lat_flags & TRACE_FLAG_IRQS_NOSUPPORT) ?
	       'X' : '.',
	       (lat_flags & TRACE_FLAG_NEED_RESCHED) ?
	       'N' : '.',
	       (hardirq && softirq) ? 'H' :
	       hardirq ? 'h' : softirq ? 's' : '.');

	if (pc)
		trace_seq_printf(&sq, "%x", pc);
	else
		trace_seq_printf(&sq, ".");

	if (migrate_disable_exists) {
		if (migrate_disable < 0)
			trace_seq_printf(&sq, ".");
		else
			trace_seq_printf(&sq, "%d", migrate_disable);
	}

	if (lock_depth_exists) {
		if (lock_depth < 0)
			trace_seq_printf(&sq, ".");
		else
			trace_seq_printf(&sq, "%d", lock_depth);
	}

	if (sq.state == TRACE_SEQ__MEM_ALLOC_FAILED) {
		s->state = TRACE_SEQ__MEM_ALLOC_FAILED;
		return;
	}

	trace_seq_terminate(&sq);
	trace_seq_puts(s, sq.buffer);
	trace_seq_destroy(&sq);
	trace_seq_terminate(s);
}

/**
 * tep_data_type - parse out the given event type
 * @tep: a handle to the trace event parser context
 * @rec: the record to read from
 *
 * This returns the event id from the @rec.
 */
int tep_data_type(struct tep_handle *tep, struct tep_record *rec)
{
	return trace_parse_common_type(tep, rec->data);
}

/**
 * tep_data_pid - parse the PID from record
 * @tep: a handle to the trace event parser context
 * @rec: the record to parse
 *
 * This returns the PID from a record.
 */
int tep_data_pid(struct tep_handle *tep, struct tep_record *rec)
{
	return parse_common_pid(tep, rec->data);
}

/**
 * tep_data_preempt_count - parse the preempt count from the record
 * @tep: a handle to the trace event parser context
 * @rec: the record to parse
 *
 * This returns the preempt count from a record.
 */
int tep_data_preempt_count(struct tep_handle *tep, struct tep_record *rec)
{
	return parse_common_pc(tep, rec->data);
}

/**
 * tep_data_flags - parse the latency flags from the record
 * @tep: a handle to the trace event parser context
 * @rec: the record to parse
 *
 * This returns the latency flags from a record.
 *
 *  Use trace_flag_type enum for the flags (see event-parse.h).
 */
int tep_data_flags(struct tep_handle *tep, struct tep_record *rec)
{
	return parse_common_flags(tep, rec->data);
}

/**
 * tep_data_comm_from_pid - return the command line from PID
 * @tep: a handle to the trace event parser context
 * @pid: the PID of the task to search for
 *
 * This returns a pointer to the command line that has the given
 * @pid.
 */
const char *tep_data_comm_from_pid(struct tep_handle *tep, int pid)
{
	const char *comm;

	comm = find_cmdline(tep, pid);
	return comm;
}

static struct tep_cmdline *
pid_from_cmdlist(struct tep_handle *tep, const char *comm, struct tep_cmdline *next)
{
	struct cmdline_list *cmdlist = (struct cmdline_list *)next;

	if (cmdlist)
		cmdlist = cmdlist->next;
	else
		cmdlist = tep->cmdlist;

	while (cmdlist && strcmp(cmdlist->comm, comm) != 0)
		cmdlist = cmdlist->next;

	return (struct tep_cmdline *)cmdlist;
}

/**
 * tep_data_pid_from_comm - return the pid from a given comm
 * @tep: a handle to the trace event parser context
 * @comm: the cmdline to find the pid from
 * @next: the cmdline structure to find the next comm
 *
 * This returns the cmdline structure that holds a pid for a given
 * comm, or NULL if none found. As there may be more than one pid for
 * a given comm, the result of this call can be passed back into
 * a recurring call in the @next parameter, and then it will find the
 * next pid.
 * Also, it does a linear search, so it may be slow.
 */
struct tep_cmdline *tep_data_pid_from_comm(struct tep_handle *tep, const char *comm,
					   struct tep_cmdline *next)
{
	struct tep_cmdline *cmdline;

	/*
	 * If the cmdlines have not been converted yet, then use
	 * the list.
	 */
	if (!tep->cmdlines)
		return pid_from_cmdlist(tep, comm, next);

	if (next) {
		/*
		 * The next pointer could have been still from
		 * a previous call before cmdlines were created
		 */
		if (next < tep->cmdlines ||
		    next >= tep->cmdlines + tep->cmdline_count)
			next = NULL;
		else
			cmdline  = next++;
	}

	if (!next)
		cmdline = tep->cmdlines;

	while (cmdline < tep->cmdlines + tep->cmdline_count) {
		if (strcmp(cmdline->comm, comm) == 0)
			return cmdline;
		cmdline++;
	}
	return NULL;
}

/**
 * tep_cmdline_pid - return the pid associated to a given cmdline
 * @tep: a handle to the trace event parser context
 * @cmdline: The cmdline structure to get the pid from
 *
 * Returns the pid for a give cmdline. If @cmdline is NULL, then
 * -1 is returned.
 */
int tep_cmdline_pid(struct tep_handle *tep, struct tep_cmdline *cmdline)
{
	struct cmdline_list *cmdlist = (struct cmdline_list *)cmdline;

	if (!cmdline)
		return -1;

	/*
	 * If cmdlines have not been created yet, or cmdline is
	 * not part of the array, then treat it as a cmdlist instead.
	 */
	if (!tep->cmdlines ||
	    cmdline < tep->cmdlines ||
	    cmdline >= tep->cmdlines + tep->cmdline_count)
		return cmdlist->pid;

	return cmdline->pid;
}

/*
 * This parses the raw @data using the given @event information and
 * writes the print format into the trace_seq.
 */
static void print_event_info(struct trace_seq *s, char *format, bool raw,
			     struct tep_event *event, struct tep_record *record)
{
	int print_pretty = 1;

	if (raw || (event->flags & TEP_EVENT_FL_PRINTRAW))
		tep_print_fields(s, record->data, record->size, event);
	else {

		if (event->handler && !(event->flags & TEP_EVENT_FL_NOHANDLE))
			print_pretty = event->handler(s, record, event,
						      event->context);

		if (print_pretty)
			pretty_print(s, record->data, record->size, event);
	}

	trace_seq_terminate(s);
}

/**
 * tep_find_event_by_record - return the event from a given record
 * @tep: a handle to the trace event parser context
 * @record: The record to get the event from
 *
 * Returns the associated event for a given record, or NULL if non is
 * is found.
 */
struct tep_event *
tep_find_event_by_record(struct tep_handle *tep, struct tep_record *record)
{
	int type;

	if (record->size < 0) {
		do_warning("ug! negative record size %d", record->size);
		return NULL;
	}

	type = trace_parse_common_type(tep, record->data);

	return tep_find_event(tep, type);
}

/*
 * Writes the timestamp of the record into @s. Time divisor and precision can be
 * specified as part of printf @format string. Example:
 *	"%3.1000d" - divide the time by 1000 and print the first 3 digits
 *	before the dot. Thus, the timestamp "123456000" will be printed as
 *	"123.456"
 */
static void print_event_time(struct tep_handle *tep, struct trace_seq *s,
				 char *format, struct tep_event *event,
				 struct tep_record *record)
{
	unsigned long long time;
	char *divstr;
	int prec = 0, pr;
	int div = 0;
	int p10 = 1;

	if (isdigit(*(format + 1)))
		prec = atoi(format + 1);
	divstr = strchr(format, '.');
	if (divstr && isdigit(*(divstr + 1)))
		div = atoi(divstr + 1);
	time = record->ts;
	if (div) {
		time += div / 2;
		time /= div;
	}
	pr = prec;
	while (pr--)
		p10 *= 10;

	if (p10 > 1 && p10 < time)
		trace_seq_printf(s, "%5llu.%0*llu", time / p10, prec, time % p10);
	else
		trace_seq_printf(s, "%12llu", time);
}

struct print_event_type {
	enum {
		EVENT_TYPE_INT = 1,
		EVENT_TYPE_STRING,
		EVENT_TYPE_UNKNOWN,
	} type;
	char format[32];
};

static void print_string(struct tep_handle *tep, struct trace_seq *s,
			 struct tep_record *record, struct tep_event *event,
			 const char *arg, struct print_event_type *type)
{
	const char *comm;
	int pid;

	if (strncmp(arg, TEP_PRINT_LATENCY, strlen(TEP_PRINT_LATENCY)) == 0) {
		data_latency_format(tep, s, type->format, record);
	} else if (strncmp(arg, TEP_PRINT_COMM, strlen(TEP_PRINT_COMM)) == 0) {
		pid = parse_common_pid(tep, record->data);
		comm = find_cmdline(tep, pid);
		trace_seq_printf(s, type->format, comm);
	} else if (strncmp(arg, TEP_PRINT_INFO_RAW, strlen(TEP_PRINT_INFO_RAW)) == 0) {
		print_event_info(s, type->format, true, event, record);
	} else if (strncmp(arg, TEP_PRINT_INFO, strlen(TEP_PRINT_INFO)) == 0) {
		print_event_info(s, type->format, false, event, record);
	} else if  (strncmp(arg, TEP_PRINT_NAME, strlen(TEP_PRINT_NAME)) == 0) {
		trace_seq_printf(s, type->format, event->name);
	} else {
		trace_seq_printf(s, "[UNKNOWN TEP TYPE %s]", arg);
	}

}

static void print_int(struct tep_handle *tep, struct trace_seq *s,
		      struct tep_record *record, struct tep_event *event,
		      int arg, struct print_event_type *type)
{
	int param;

	switch (arg) {
	case TEP_PRINT_CPU:
		param = record->cpu;
		break;
	case TEP_PRINT_PID:
		param = parse_common_pid(tep, record->data);
		break;
	case TEP_PRINT_TIME:
		return print_event_time(tep, s, type->format, event, record);
	default:
		return;
	}
	trace_seq_printf(s, type->format, param);
}

static int tep_print_event_param_type(char *format,
				      struct print_event_type *type)
{
	char *str = format + 1;
	int i = 1;

	type->type = EVENT_TYPE_UNKNOWN;
	while (*str) {
		switch (*str) {
		case 'd':
		case 'u':
		case 'i':
		case 'x':
		case 'X':
		case 'o':
			type->type = EVENT_TYPE_INT;
			break;
		case 's':
			type->type = EVENT_TYPE_STRING;
			break;
		}
		str++;
		i++;
		if (type->type != EVENT_TYPE_UNKNOWN)
			break;
	}
	memset(type->format, 0, 32);
	memcpy(type->format, format, i < 32 ? i : 31);
	return i;
}

/**
 * tep_print_event - Write various event information
 * @tep: a handle to the trace event parser context
 * @s: the trace_seq to write to
 * @record: The record to get the event from
 * @format: a printf format string. Supported event fileds:
 *	TEP_PRINT_PID, "%d" - event PID
 *	TEP_PRINT_CPU, "%d" - event CPU
 *	TEP_PRINT_COMM, "%s" - event command string
 *	TEP_PRINT_NAME, "%s" - event name
 *	TEP_PRINT_LATENCY, "%s" - event latency
 *	TEP_PRINT_TIME, %d - event time stamp. A divisor and precision
 *			can be specified as part of this format string:
 *			"%precision.divisord". Example:
 *			"%3.1000d" - divide the time by 1000 and print the first
 *			3 digits before the dot. Thus, the time stamp
 *			"123456000" will be printed as "123.456"
 *	TEP_PRINT_INFO, "%s" - event information. If any width is specified in
 *			the format string, the event information will be printed
 *			in raw format.
 * Writes the specified event information into @s.
 */
void tep_print_event(struct tep_handle *tep, struct trace_seq *s,
		     struct tep_record *record, const char *fmt, ...)
{
	struct print_event_type type;
	char *format = strdup(fmt);
	char *current = format;
	char *str = format;
	int offset;
	va_list args;
	struct tep_event *event;

	if (!format)
		return;

	event = tep_find_event_by_record(tep, record);
	va_start(args, fmt);
	while (*current) {
		current = strchr(str, '%');
		if (!current) {
			trace_seq_puts(s, str);
			break;
		}
		memset(&type, 0, sizeof(type));
		offset = tep_print_event_param_type(current, &type);
		*current = '\0';
		trace_seq_puts(s, str);
		current += offset;
		switch (type.type) {
		case EVENT_TYPE_STRING:
			print_string(tep, s, record, event,
				     va_arg(args, char*), &type);
			break;
		case EVENT_TYPE_INT:
			print_int(tep, s, record, event,
				  va_arg(args, int), &type);
			break;
		case EVENT_TYPE_UNKNOWN:
		default:
			trace_seq_printf(s, "[UNKNOWN TYPE]");
			break;
		}
		str = current;

	}
	va_end(args);
	free(format);
}

static int events_id_cmp(const void *a, const void *b)
{
	struct tep_event * const * ea = a;
	struct tep_event * const * eb = b;

	if ((*ea)->id < (*eb)->id)
		return -1;

	if ((*ea)->id > (*eb)->id)
		return 1;

	return 0;
}

static int events_name_cmp(const void *a, const void *b)
{
	struct tep_event * const * ea = a;
	struct tep_event * const * eb = b;
	int res;

	res = strcmp((*ea)->name, (*eb)->name);
	if (res)
		return res;

	res = strcmp((*ea)->system, (*eb)->system);
	if (res)
		return res;

	return events_id_cmp(a, b);
}

static int events_system_cmp(const void *a, const void *b)
{
	struct tep_event * const * ea = a;
	struct tep_event * const * eb = b;
	int res;

	res = strcmp((*ea)->system, (*eb)->system);
	if (res)
		return res;

	res = strcmp((*ea)->name, (*eb)->name);
	if (res)
		return res;

	return events_id_cmp(a, b);
}

static struct tep_event **list_events_copy(struct tep_handle *tep)
{
	struct tep_event **events;

	if (!tep)
		return NULL;

	events = malloc(sizeof(*events) * (tep->nr_events + 1));
	if (!events)
		return NULL;

	memcpy(events, tep->events, sizeof(*events) * tep->nr_events);
	events[tep->nr_events] = NULL;
	return events;
}

static void list_events_sort(struct tep_event **events, int nr_events,
			     enum tep_event_sort_type sort_type)
{
	int (*sort)(const void *a, const void *b);

	switch (sort_type) {
	case TEP_EVENT_SORT_ID:
		sort = events_id_cmp;
		break;
	case TEP_EVENT_SORT_NAME:
		sort = events_name_cmp;
		break;
	case TEP_EVENT_SORT_SYSTEM:
		sort = events_system_cmp;
		break;
	default:
		sort = NULL;
	}

	if (sort)
		qsort(events, nr_events, sizeof(*events), sort);
}

/**
 * tep_list_events - Get events, sorted by given criteria.
 * @tep: a handle to the tep context
 * @sort_type: desired sort order of the events in the array
 *
 * Returns an array of pointers to all events, sorted by the given
 * @sort_type criteria. The last element of the array is NULL. The returned
 * memory must not be freed, it is managed by the library.
 * The function is not thread safe.
 */
struct tep_event **tep_list_events(struct tep_handle *tep,
				   enum tep_event_sort_type sort_type)
{
	struct tep_event **events;

	if (!tep)
		return NULL;

	events = tep->sort_events;
	if (events && tep->last_type == sort_type)
		return events;

	if (!events) {
		events = list_events_copy(tep);
		if (!events)
			return NULL;

		tep->sort_events = events;

		/* the internal events are sorted by id */
		if (sort_type == TEP_EVENT_SORT_ID) {
			tep->last_type = sort_type;
			return events;
		}
	}

	list_events_sort(events, tep->nr_events, sort_type);
	tep->last_type = sort_type;

	return events;
}


/**
 * tep_list_events_copy - Thread safe version of tep_list_events()
 * @tep: a handle to the tep context
 * @sort_type: desired sort order of the events in the array
 *
 * Returns an array of pointers to all events, sorted by the given
 * @sort_type criteria. The last element of the array is NULL. The returned
 * array is newly allocated inside the function and must be freed by the caller
 */
struct tep_event **tep_list_events_copy(struct tep_handle *tep,
					enum tep_event_sort_type sort_type)
{
	struct tep_event **events;

	if (!tep)
		return NULL;

	events = list_events_copy(tep);
	if (!events)
		return NULL;

	/* the internal events are sorted by id */
	if (sort_type == TEP_EVENT_SORT_ID)
		return events;

	list_events_sort(events, tep->nr_events, sort_type);

	return events;
}

static struct tep_format_field **
get_event_fields(const char *type, const char *name,
		 int count, struct tep_format_field *list)
{
	struct tep_format_field **fields;
	struct tep_format_field *field;
	int i = 0;

	fields = malloc(sizeof(*fields) * (count + 1));
	if (!fields)
		return NULL;

	for (field = list; field; field = field->next) {
		fields[i++] = field;
		if (i == count + 1) {
			do_warning("event %s has more %s fields than specified",
				name, type);
			i--;
			break;
		}
	}

	if (i != count)
		do_warning("event %s has less %s fields than specified",
			name, type);

	fields[i] = NULL;

	return fields;
}

/**
 * tep_event_common_fields - return a list of common fields for an event
 * @event: the event to return the common fields of.
 *
 * Returns an allocated array of fields. The last item in the array is NULL.
 * The array must be freed with free().
 */
struct tep_format_field **tep_event_common_fields(struct tep_event *event)
{
	return get_event_fields("common", event->name,
				event->format.nr_common,
				event->format.common_fields);
}

/**
 * tep_event_fields - return a list of event specific fields for an event
 * @event: the event to return the fields of.
 *
 * Returns an allocated array of fields. The last item in the array is NULL.
 * The array must be freed with free().
 */
struct tep_format_field **tep_event_fields(struct tep_event *event)
{
	return get_event_fields("event", event->name,
				event->format.nr_fields,
				event->format.fields);
}

static void print_fields(struct trace_seq *s, struct tep_print_flag_sym *field)
{
	trace_seq_printf(s, "{ %s, %s }", field->value, field->str);
	if (field->next) {
		trace_seq_puts(s, ", ");
		print_fields(s, field->next);
	}
}

/* for debugging */
static void print_args(struct tep_print_arg *args)
{
	int print_paren = 1;
	struct trace_seq s;

	switch (args->type) {
	case TEP_PRINT_NULL:
		printf("null");
		break;
	case TEP_PRINT_ATOM:
		printf("%s", args->atom.atom);
		break;
	case TEP_PRINT_FIELD:
		printf("REC->%s", args->field.name);
		break;
	case TEP_PRINT_FLAGS:
		printf("__print_flags(");
		print_args(args->flags.field);
		printf(", %s, ", args->flags.delim);
		trace_seq_init(&s);
		print_fields(&s, args->flags.flags);
		trace_seq_do_printf(&s);
		trace_seq_destroy(&s);
		printf(")");
		break;
	case TEP_PRINT_SYMBOL:
		printf("__print_symbolic(");
		print_args(args->symbol.field);
		printf(", ");
		trace_seq_init(&s);
		print_fields(&s, args->symbol.symbols);
		trace_seq_do_printf(&s);
		trace_seq_destroy(&s);
		printf(")");
		break;
	case TEP_PRINT_HEX:
		printf("__print_hex(");
		print_args(args->hex.field);
		printf(", ");
		print_args(args->hex.size);
		printf(")");
		break;
	case TEP_PRINT_HEX_STR:
		printf("__print_hex_str(");
		print_args(args->hex.field);
		printf(", ");
		print_args(args->hex.size);
		printf(")");
		break;
	case TEP_PRINT_INT_ARRAY:
		printf("__print_array(");
		print_args(args->int_array.field);
		printf(", ");
		print_args(args->int_array.count);
		printf(", ");
		print_args(args->int_array.el_size);
		printf(")");
		break;
	case TEP_PRINT_STRING:
	case TEP_PRINT_BSTRING:
		printf("__get_str(%s)", args->string.string);
		break;
	case TEP_PRINT_BITMASK:
		printf("__get_bitmask(%s)", args->bitmask.bitmask);
		break;
	case TEP_PRINT_TYPE:
		printf("(%s)", args->typecast.type);
		print_args(args->typecast.item);
		break;
	case TEP_PRINT_OP:
		if (strcmp(args->op.op, ":") == 0)
			print_paren = 0;
		if (print_paren)
			printf("(");
		print_args(args->op.left);
		printf(" %s ", args->op.op);
		print_args(args->op.right);
		if (print_paren)
			printf(")");
		break;
	default:
		/* we should warn... */
		return;
	}
	if (args->next) {
		printf("\n");
		print_args(args->next);
	}
}

static void parse_header_field(const char *field,
			       int *offset, int *size, int mandatory)
{
	unsigned long long save_input_buf_ptr;
	unsigned long long save_input_buf_siz;
	char *token;
	int type;

	save_input_buf_ptr = input_buf_ptr;
	save_input_buf_siz = input_buf_siz;

	if (read_expected(TEP_EVENT_ITEM, "field") < 0)
		return;
	if (read_expected(TEP_EVENT_OP, ":") < 0)
		return;

	/* type */
	if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
		goto fail;
	free_token(token);

	/*
	 * If this is not a mandatory field, then test it first.
	 */
	if (mandatory) {
		if (read_expected(TEP_EVENT_ITEM, field) < 0)
			return;
	} else {
		if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
			goto fail;
		if (strcmp(token, field) != 0)
			goto discard;
		free_token(token);
	}

	if (read_expected(TEP_EVENT_OP, ";") < 0)
		return;
	if (read_expected(TEP_EVENT_ITEM, "offset") < 0)
		return;
	if (read_expected(TEP_EVENT_OP, ":") < 0)
		return;
	if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
		goto fail;
	*offset = atoi(token);
	free_token(token);
	if (read_expected(TEP_EVENT_OP, ";") < 0)
		return;
	if (read_expected(TEP_EVENT_ITEM, "size") < 0)
		return;
	if (read_expected(TEP_EVENT_OP, ":") < 0)
		return;
	if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
		goto fail;
	*size = atoi(token);
	free_token(token);
	if (read_expected(TEP_EVENT_OP, ";") < 0)
		return;
	type = read_token(&token);
	if (type != TEP_EVENT_NEWLINE) {
		/* newer versions of the kernel have a "signed" type */
		if (type != TEP_EVENT_ITEM)
			goto fail;

		if (strcmp(token, "signed") != 0)
			goto fail;

		free_token(token);

		if (read_expected(TEP_EVENT_OP, ":") < 0)
			return;

		if (read_expect_type(TEP_EVENT_ITEM, &token))
			goto fail;

		free_token(token);
		if (read_expected(TEP_EVENT_OP, ";") < 0)
			return;

		if (read_expect_type(TEP_EVENT_NEWLINE, &token))
			goto fail;
	}
 fail:
	free_token(token);
	return;

 discard:
	input_buf_ptr = save_input_buf_ptr;
	input_buf_siz = save_input_buf_siz;
	*offset = 0;
	*size = 0;
	free_token(token);
}

/**
 * tep_parse_header_page - parse the data stored in the header page
 * @tep: a handle to the trace event parser context
 * @buf: the buffer storing the header page format string
 * @size: the size of @buf
 * @long_size: the long size to use if there is no header
 *
 * This parses the header page format for information on the
 * ring buffer used. The @buf should be copied from
 *
 * /sys/kernel/debug/tracing/events/header_page
 */
int tep_parse_header_page(struct tep_handle *tep, char *buf, unsigned long size,
			  int long_size)
{
	int ignore;

	if (!size) {
		/*
		 * Old kernels did not have header page info.
		 * Sorry but we just use what we find here in user space.
		 */
		tep->header_page_ts_size = sizeof(long long);
		tep->header_page_size_size = long_size;
		tep->header_page_data_offset = sizeof(long long) + long_size;
		tep->old_format = 1;
		return -1;
	}
	init_input_buf(buf, size);

	parse_header_field("timestamp", &tep->header_page_ts_offset,
			   &tep->header_page_ts_size, 1);
	parse_header_field("commit", &tep->header_page_size_offset,
			   &tep->header_page_size_size, 1);
	parse_header_field("overwrite", &tep->header_page_overwrite,
			   &ignore, 0);
	parse_header_field("data", &tep->header_page_data_offset,
			   &tep->header_page_data_size, 1);

	return 0;
}

static int event_matches(struct tep_event *event,
			 int id, const char *sys_name,
			 const char *event_name)
{
	if (id >= 0 && id != event->id)
		return 0;

	if (event_name && (strcmp(event_name, event->name) != 0))
		return 0;

	if (sys_name && (strcmp(sys_name, event->system) != 0))
		return 0;

	return 1;
}

static void free_handler(struct event_handler *handle)
{
	free((void *)handle->sys_name);
	free((void *)handle->event_name);
	free(handle);
}

static int find_event_handle(struct tep_handle *tep, struct tep_event *event)
{
	struct event_handler *handle, **next;

	for (next = &tep->handlers; *next;
	     next = &(*next)->next) {
		handle = *next;
		if (event_matches(event, handle->id,
				  handle->sys_name,
				  handle->event_name))
			break;
	}

	if (!(*next))
		return 0;

	pr_stat("overriding event (%d) %s:%s with new print handler",
		event->id, event->system, event->name);

	event->handler = handle->func;
	event->context = handle->context;

	*next = handle->next;
	free_handler(handle);

	return 1;
}

/**
 * parse_format - parse the event format
 * @buf: the buffer storing the event format string
 * @size: the size of @buf
 * @sys: the system the event belongs to
 *
 * This parses the event format and creates an event structure
 * to quickly parse raw data for a given event.
 *
 * These files currently come from:
 *
 * /sys/kernel/debug/tracing/events/.../.../format
 */
static enum tep_errno parse_format(struct tep_event **eventp,
				   struct tep_handle *tep, const char *buf,
				   unsigned long size, const char *sys)
{
	struct tep_event *event;
	int ret;

	init_input_buf(buf, size);

	*eventp = event = alloc_event();
	if (!event)
		return TEP_ERRNO__MEM_ALLOC_FAILED;

	event->name = event_read_name();
	if (!event->name) {
		/* Bad event? */
		ret = TEP_ERRNO__MEM_ALLOC_FAILED;
		goto event_alloc_failed;
	}

	if (strcmp(sys, "ftrace") == 0) {
		event->flags |= TEP_EVENT_FL_ISFTRACE;

		if (strcmp(event->name, "bprint") == 0)
			event->flags |= TEP_EVENT_FL_ISBPRINT;
	}
		
	event->id = event_read_id();
	if (event->id < 0) {
		ret = TEP_ERRNO__READ_ID_FAILED;
		/*
		 * This isn't an allocation error actually.
		 * But as the ID is critical, just bail out.
		 */
		goto event_alloc_failed;
	}

	event->system = strdup(sys);
	if (!event->system) {
		ret = TEP_ERRNO__MEM_ALLOC_FAILED;
		goto event_alloc_failed;
	}

	/* Add tep to event so that it can be referenced */
	event->tep = tep;

	ret = event_read_format(event);
	if (ret < 0) {
		ret = TEP_ERRNO__READ_FORMAT_FAILED;
		goto event_parse_failed;
	}

	/*
	 * If the event has an override, don't print warnings if the event
	 * print format fails to parse.
	 */
	if (tep && find_event_handle(tep, event))
		show_warning = 0;

	ret = event_read_print(event);
	show_warning = 1;

	if (ret < 0) {
		ret = TEP_ERRNO__READ_PRINT_FAILED;
		goto event_parse_failed;
	}

	if (!ret && (event->flags & TEP_EVENT_FL_ISFTRACE)) {
		struct tep_format_field *field;
		struct tep_print_arg *arg, **list;

		/* old ftrace had no args */
		list = &event->print_fmt.args;
		for (field = event->format.fields; field; field = field->next) {
			arg = alloc_arg();
			if (!arg) {
				event->flags |= TEP_EVENT_FL_FAILED;
				return TEP_ERRNO__OLD_FTRACE_ARG_FAILED;
			}
			arg->type = TEP_PRINT_FIELD;
			arg->field.name = strdup(field->name);
			if (!arg->field.name) {
				event->flags |= TEP_EVENT_FL_FAILED;
				free_arg(arg);
				return TEP_ERRNO__OLD_FTRACE_ARG_FAILED;
			}
			arg->field.field = field;
			*list = arg;
			list = &arg->next;
		}
	}

	if (!(event->flags & TEP_EVENT_FL_ISBPRINT))
		event->print_fmt.print_cache = parse_args(event,
							  event->print_fmt.format,
							  event->print_fmt.args);

	return 0;

 event_parse_failed:
	event->flags |= TEP_EVENT_FL_FAILED;
	return ret;

 event_alloc_failed:
	free(event->system);
	free(event->name);
	free(event);
	*eventp = NULL;
	return ret;
}

static enum tep_errno
__parse_event(struct tep_handle *tep,
	      struct tep_event **eventp,
	      const char *buf, unsigned long size,
	      const char *sys)
{
	int ret = parse_format(eventp, tep, buf, size, sys);
	struct tep_event *event = *eventp;

	if (event == NULL)
		return ret;

	if (tep && add_event(tep, event)) {
		ret = TEP_ERRNO__MEM_ALLOC_FAILED;
		goto event_add_failed;
	}

#define PRINT_ARGS 0
	if (PRINT_ARGS && event->print_fmt.args)
		print_args(event->print_fmt.args);

	return 0;

event_add_failed:
	free_tep_event(event);
	return ret;
}

/**
 * tep_parse_format - parse the event format
 * @tep: a handle to the trace event parser context
 * @eventp: returned format
 * @buf: the buffer storing the event format string
 * @size: the size of @buf
 * @sys: the system the event belongs to
 *
 * This parses the event format and creates an event structure
 * to quickly parse raw data for a given event.
 *
 * These files currently come from:
 *
 * /sys/kernel/debug/tracing/events/.../.../format
 */
enum tep_errno tep_parse_format(struct tep_handle *tep,
				struct tep_event **eventp,
				const char *buf,
				unsigned long size, const char *sys)
{
	return __parse_event(tep, eventp, buf, size, sys);
}

/**
 * tep_parse_event - parse the event format
 * @tep: a handle to the trace event parser context
 * @buf: the buffer storing the event format string
 * @size: the size of @buf
 * @sys: the system the event belongs to
 *
 * This parses the event format and creates an event structure
 * to quickly parse raw data for a given event.
 *
 * These files currently come from:
 *
 * /sys/kernel/debug/tracing/events/.../.../format
 */
enum tep_errno tep_parse_event(struct tep_handle *tep, const char *buf,
			       unsigned long size, const char *sys)
{
	struct tep_event *event = NULL;
	return __parse_event(tep, &event, buf, size, sys);
}

int get_field_val(struct trace_seq *s, struct tep_format_field *field,
		  const char *name, struct tep_record *record,
		  unsigned long long *val, int err)
{
	if (!field) {
		if (err)
			trace_seq_printf(s, "<CANT FIND FIELD %s>", name);
		return -1;
	}

	if (tep_read_number_field(field, record->data, val)) {
		if (err)
			trace_seq_printf(s, " %s=INVALID", name);
		return -1;
	}

	return 0;
}

/**
 * tep_get_field_raw - return the raw pointer into the data field
 * @s: The seq to print to on error
 * @event: the event that the field is for
 * @name: The name of the field
 * @record: The record with the field name.
 * @len: place to store the field length.
 * @err: print default error if failed.
 *
 * Returns a pointer into record->data of the field and places
 * the length of the field in @len.
 *
 * On failure, it returns NULL.
 */
void *tep_get_field_raw(struct trace_seq *s, struct tep_event *event,
			const char *name, struct tep_record *record,
			int *len, int err)
{
	struct tep_format_field *field;
	void *data = record->data;
	unsigned offset;
	int dummy;

	if (!event)
		return NULL;

	field = tep_find_field(event, name);

	if (!field) {
		if (err)
			trace_seq_printf(s, "<CANT FIND FIELD %s>", name);
		return NULL;
	}

	/* Allow @len to be NULL */
	if (!len)
		len = &dummy;

	offset = field->offset;
	if (field->flags & TEP_FIELD_IS_DYNAMIC) {
		offset = tep_read_number(event->tep,
					 data + offset, field->size);
		*len = offset >> 16;
		offset &= 0xffff;
	} else
		*len = field->size;

	return data + offset;
}

/**
 * tep_get_field_val - find a field and return its value
 * @s: The seq to print to on error
 * @event: the event that the field is for
 * @name: The name of the field
 * @record: The record with the field name.
 * @val: place to store the value of the field.
 * @err: print default error if failed.
 *
 * Returns 0 on success -1 on field not found.
 */
int tep_get_field_val(struct trace_seq *s, struct tep_event *event,
		      const char *name, struct tep_record *record,
		      unsigned long long *val, int err)
{
	struct tep_format_field *field;

	if (!event)
		return -1;

	field = tep_find_field(event, name);

	return get_field_val(s, field, name, record, val, err);
}

/**
 * tep_get_common_field_val - find a common field and return its value
 * @s: The seq to print to on error
 * @event: the event that the field is for
 * @name: The name of the field
 * @record: The record with the field name.
 * @val: place to store the value of the field.
 * @err: print default error if failed.
 *
 * Returns 0 on success -1 on field not found.
 */
int tep_get_common_field_val(struct trace_seq *s, struct tep_event *event,
			     const char *name, struct tep_record *record,
			     unsigned long long *val, int err)
{
	struct tep_format_field *field;

	if (!event)
		return -1;

	field = tep_find_common_field(event, name);

	return get_field_val(s, field, name, record, val, err);
}

/**
 * tep_get_any_field_val - find a any field and return its value
 * @s: The seq to print to on error
 * @event: the event that the field is for
 * @name: The name of the field
 * @record: The record with the field name.
 * @val: place to store the value of the field.
 * @err: print default error if failed.
 *
 * Returns 0 on success -1 on field not found.
 */
int tep_get_any_field_val(struct trace_seq *s, struct tep_event *event,
			  const char *name, struct tep_record *record,
			  unsigned long long *val, int err)
{
	struct tep_format_field *field;

	if (!event)
		return -1;

	field = tep_find_any_field(event, name);

	return get_field_val(s, field, name, record, val, err);
}

/**
 * tep_print_num_field - print a field and a format
 * @s: The seq to print to
 * @fmt: The printf format to print the field with.
 * @event: the event that the field is for
 * @name: The name of the field
 * @record: The record with the field name.
 * @err: print default error if failed.
 *
 * Returns positive value on success, negative in case of an error,
 * or 0 if buffer is full.
 */
int tep_print_num_field(struct trace_seq *s, const char *fmt,
			struct tep_event *event, const char *name,
			struct tep_record *record, int err)
{
	struct tep_format_field *field = tep_find_field(event, name);
	unsigned long long val;

	if (!field)
		goto failed;

	if (tep_read_number_field(field, record->data, &val))
		goto failed;

	return trace_seq_printf(s, fmt, val);

 failed:
	if (err)
		trace_seq_printf(s, "CAN'T FIND FIELD \"%s\"", name);
	return -1;
}

/**
 * tep_print_func_field - print a field and a format for function pointers
 * @s: The seq to print to
 * @fmt: The printf format to print the field with.
 * @event: the event that the field is for
 * @name: The name of the field
 * @record: The record with the field name.
 * @err: print default error if failed.
 *
 * Returns positive value on success, negative in case of an error,
 * or 0 if buffer is full.
 */
int tep_print_func_field(struct trace_seq *s, const char *fmt,
			 struct tep_event *event, const char *name,
			 struct tep_record *record, int err)
{
	struct tep_format_field *field = tep_find_field(event, name);
	struct tep_handle *tep = event->tep;
	unsigned long long val;
	struct func_map *func;
	char tmp[128];

	if (!field)
		goto failed;

	if (tep_read_number_field(field, record->data, &val))
		goto failed;

	func = find_func(tep, val);

	if (func)
		snprintf(tmp, 128, "%s/0x%llx", func->func, func->addr - val);
	else
		sprintf(tmp, "0x%08llx", val);

	return trace_seq_printf(s, fmt, tmp);

 failed:
	if (err)
		trace_seq_printf(s, "CAN'T FIND FIELD \"%s\"", name);
	return -1;
}

static void free_func_handle(struct tep_function_handler *func)
{
	struct func_params *params;

	free(func->name);

	while (func->params) {
		params = func->params;
		func->params = params->next;
		free(params);
	}

	free(func);
}

/**
 * tep_register_print_function - register a helper function
 * @tep: a handle to the trace event parser context
 * @func: the function to process the helper function
 * @ret_type: the return type of the helper function
 * @name: the name of the helper function
 * @parameters: A list of enum tep_func_arg_type
 *
 * Some events may have helper functions in the print format arguments.
 * This allows a plugin to dynamically create a way to process one
 * of these functions.
 *
 * The @parameters is a variable list of tep_func_arg_type enums that
 * must end with TEP_FUNC_ARG_VOID.
 */
int tep_register_print_function(struct tep_handle *tep,
				tep_func_handler func,
				enum tep_func_arg_type ret_type,
				char *name, ...)
{
	struct tep_function_handler *func_handle;
	struct func_params **next_param;
	struct func_params *param;
	enum tep_func_arg_type type;
	va_list ap;
	int ret;

	func_handle = find_func_handler(tep, name);
	if (func_handle) {
		/*
		 * This is most like caused by the users own
		 * plugins updating the function. This overrides the
		 * system defaults.
		 */
		pr_stat("override of function helper '%s'", name);
		remove_func_handler(tep, name);
	}

	func_handle = calloc(1, sizeof(*func_handle));
	if (!func_handle) {
		do_warning("Failed to allocate function handler");
		return TEP_ERRNO__MEM_ALLOC_FAILED;
	}

	func_handle->ret_type = ret_type;
	func_handle->name = strdup(name);
	func_handle->func = func;
	if (!func_handle->name) {
		do_warning("Failed to allocate function name");
		free(func_handle);
		return TEP_ERRNO__MEM_ALLOC_FAILED;
	}

	next_param = &(func_handle->params);
	va_start(ap, name);
	for (;;) {
		type = va_arg(ap, enum tep_func_arg_type);
		if (type == TEP_FUNC_ARG_VOID)
			break;

		if (type >= TEP_FUNC_ARG_MAX_TYPES) {
			do_warning("Invalid argument type %d", type);
			ret = TEP_ERRNO__INVALID_ARG_TYPE;
			goto out_free;
		}

		param = malloc(sizeof(*param));
		if (!param) {
			do_warning("Failed to allocate function param");
			ret = TEP_ERRNO__MEM_ALLOC_FAILED;
			goto out_free;
		}
		param->type = type;
		param->next = NULL;

		*next_param = param;
		next_param = &(param->next);

		func_handle->nr_args++;
	}
	va_end(ap);

	func_handle->next = tep->func_handlers;
	tep->func_handlers = func_handle;

	return 0;
 out_free:
	va_end(ap);
	free_func_handle(func_handle);
	return ret;
}

/**
 * tep_unregister_print_function - unregister a helper function
 * @tep: a handle to the trace event parser context
 * @func: the function to process the helper function
 * @name: the name of the helper function
 *
 * This function removes existing print handler for function @name.
 *
 * Returns 0 if the handler was removed successully, -1 otherwise.
 */
int tep_unregister_print_function(struct tep_handle *tep,
				  tep_func_handler func, char *name)
{
	struct tep_function_handler *func_handle;

	func_handle = find_func_handler(tep, name);
	if (func_handle && func_handle->func == func) {
		remove_func_handler(tep, name);
		return 0;
	}
	return -1;
}

static struct tep_event *search_event(struct tep_handle *tep, int id,
				      const char *sys_name,
				      const char *event_name)
{
	struct tep_event *event;

	if (id >= 0) {
		/* search by id */
		event = tep_find_event(tep, id);
		if (!event)
			return NULL;
		if (event_name && (strcmp(event_name, event->name) != 0))
			return NULL;
		if (sys_name && (strcmp(sys_name, event->system) != 0))
			return NULL;
	} else {
		event = tep_find_event_by_name(tep, sys_name, event_name);
		if (!event)
			return NULL;
	}
	return event;
}

/**
 * tep_register_event_handler - register a way to parse an event
 * @tep: a handle to the trace event parser context
 * @id: the id of the event to register
 * @sys_name: the system name the event belongs to
 * @event_name: the name of the event
 * @func: the function to call to parse the event information
 * @context: the data to be passed to @func
 *
 * This function allows a developer to override the parsing of
 * a given event. If for some reason the default print format
 * is not sufficient, this function will register a function
 * for an event to be used to parse the data instead.
 *
 * If @id is >= 0, then it is used to find the event.
 * else @sys_name and @event_name are used.
 *
 * Returns:
 *  TEP_REGISTER_SUCCESS_OVERWRITE if an existing handler is overwritten
 *  TEP_REGISTER_SUCCESS if a new handler is registered successfully
 *  negative TEP_ERRNO_... in case of an error
 *
 */
int tep_register_event_handler(struct tep_handle *tep, int id,
			       const char *sys_name, const char *event_name,
			       tep_event_handler_func func, void *context)
{
	struct tep_event *event;
	struct event_handler *handle;

	event = search_event(tep, id, sys_name, event_name);
	if (event == NULL)
		goto not_found;

	pr_stat("overriding event (%d) %s:%s with new print handler",
		event->id, event->system, event->name);

	event->handler = func;
	event->context = context;
	return TEP_REGISTER_SUCCESS_OVERWRITE;

 not_found:
	/* Save for later use. */
	handle = calloc(1, sizeof(*handle));
	if (!handle) {
		do_warning("Failed to allocate event handler");
		return TEP_ERRNO__MEM_ALLOC_FAILED;
	}

	handle->id = id;
	if (event_name)
		handle->event_name = strdup(event_name);
	if (sys_name)
		handle->sys_name = strdup(sys_name);

	if ((event_name && !handle->event_name) ||
	    (sys_name && !handle->sys_name)) {
		do_warning("Failed to allocate event/sys name");
		free((void *)handle->event_name);
		free((void *)handle->sys_name);
		free(handle);
		return TEP_ERRNO__MEM_ALLOC_FAILED;
	}

	handle->func = func;
	handle->next = tep->handlers;
	tep->handlers = handle;
	handle->context = context;

	return TEP_REGISTER_SUCCESS;
}

static int handle_matches(struct event_handler *handler, int id,
			  const char *sys_name, const char *event_name,
			  tep_event_handler_func func, void *context)
{
	if (id >= 0 && id != handler->id)
		return 0;

	if (event_name && (strcmp(event_name, handler->event_name) != 0))
		return 0;

	if (sys_name && (strcmp(sys_name, handler->sys_name) != 0))
		return 0;

	if (func != handler->func || context != handler->context)
		return 0;

	return 1;
}

/**
 * tep_unregister_event_handler - unregister an existing event handler
 * @tep: a handle to the trace event parser context
 * @id: the id of the event to unregister
 * @sys_name: the system name the handler belongs to
 * @event_name: the name of the event handler
 * @func: the function to call to parse the event information
 * @context: the data to be passed to @func
 *
 * This function removes existing event handler (parser).
 *
 * If @id is >= 0, then it is used to find the event.
 * else @sys_name and @event_name are used.
 *
 * Returns 0 if handler was removed successfully, -1 if event was not found.
 */
int tep_unregister_event_handler(struct tep_handle *tep, int id,
				 const char *sys_name, const char *event_name,
				 tep_event_handler_func func, void *context)
{
	struct tep_event *event;
	struct event_handler *handle;
	struct event_handler **next;

	event = search_event(tep, id, sys_name, event_name);
	if (event == NULL)
		goto not_found;

	if (event->handler == func && event->context == context) {
		pr_stat("removing override handler for event (%d) %s:%s. Going back to default handler.",
			event->id, event->system, event->name);

		event->handler = NULL;
		event->context = NULL;
		return 0;
	}

not_found:
	for (next = &tep->handlers; *next; next = &(*next)->next) {
		handle = *next;
		if (handle_matches(handle, id, sys_name, event_name,
				   func, context))
			break;
	}

	if (!(*next))
		return -1;

	*next = handle->next;
	free_handler(handle);

	return 0;
}

/**
 * tep_alloc - create a tep handle
 */
struct tep_handle *tep_alloc(void)
{
	struct tep_handle *tep = calloc(1, sizeof(*tep));

	if (tep) {
		tep->ref_count = 1;
		tep->host_bigendian = tep_is_bigendian();
	}

	return tep;
}

void tep_ref(struct tep_handle *tep)
{
	tep->ref_count++;
}

int tep_get_ref(struct tep_handle *tep)
{
	if (tep)
		return tep->ref_count;
	return 0;
}

__hidden void free_tep_format_field(struct tep_format_field *field)
{
	free(field->type);
	if (field->alias != field->name)
		free(field->alias);
	free(field->name);
	free(field);
}

static void free_format_fields(struct tep_format_field *field)
{
	struct tep_format_field *next;

	while (field) {
		next = field->next;
		free_tep_format_field(field);
		field = next;
	}
}

static void free_formats(struct tep_format *format)
{
	free_format_fields(format->common_fields);
	free_format_fields(format->fields);
}

__hidden void free_tep_event(struct tep_event *event)
{
	free(event->name);
	free(event->system);

	free_formats(&event->format);

	free(event->print_fmt.format);
	free_args(event->print_fmt.args);
	free_parse_args(event->print_fmt.print_cache);
	free(event);
}

/**
 * tep_free - free a tep handle
 * @tep: the tep handle to free
 */
void tep_free(struct tep_handle *tep)
{
	struct cmdline_list *cmdlist, *cmdnext;
	struct func_list *funclist, *funcnext;
	struct printk_list *printklist, *printknext;
	struct tep_function_handler *func_handler;
	struct event_handler *handle;
	int i;

	if (!tep)
		return;

	cmdlist = tep->cmdlist;
	funclist = tep->funclist;
	printklist = tep->printklist;

	tep->ref_count--;
	if (tep->ref_count)
		return;

	if (tep->cmdlines) {
		for (i = 0; i < tep->cmdline_count; i++)
			free(tep->cmdlines[i].comm);
		free(tep->cmdlines);
	}

	while (cmdlist) {
		cmdnext = cmdlist->next;
		free(cmdlist->comm);
		free(cmdlist);
		cmdlist = cmdnext;
	}

	if (tep->func_map) {
		for (i = 0; i < (int)tep->func_count; i++) {
			free(tep->func_map[i].func);
			free(tep->func_map[i].mod);
		}
		free(tep->func_map);
	}

	while (funclist) {
		funcnext = funclist->next;
		free(funclist->func);
		free(funclist->mod);
		free(funclist);
		funclist = funcnext;
	}

	while (tep->func_handlers) {
		func_handler = tep->func_handlers;
		tep->func_handlers = func_handler->next;
		free_func_handle(func_handler);
	}

	if (tep->printk_map) {
		for (i = 0; i < (int)tep->printk_count; i++)
			free(tep->printk_map[i].printk);
		free(tep->printk_map);
	}

	while (printklist) {
		printknext = printklist->next;
		free(printklist->printk);
		free(printklist);
		printklist = printknext;
	}

	for (i = 0; i < tep->nr_events; i++)
		free_tep_event(tep->events[i]);

	while (tep->handlers) {
		handle = tep->handlers;
		tep->handlers = handle->next;
		free_handler(handle);
	}

	free(tep->events);
	free(tep->sort_events);
	free(tep->func_resolver);
	free_tep_plugin_paths(tep);

	free(tep);
}

void tep_unref(struct tep_handle *tep)
{
	tep_free(tep);
}
