1e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/*
2e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
3e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
4e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This program is free software; you can redistribute it and/or
6e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * modify it under the terms of the GNU Lesser General Public
7e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * License as published by the Free Software Foundation;
8e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * version 2.1 of the License (not later!)
9e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
10e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This program is distributed in the hope that it will be useful,
11e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * but WITHOUT ANY WARRANTY; without even the implied warranty of
12e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * GNU Lesser General Public License for more details.
14e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
15e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * You should have received a copy of the GNU Lesser General Public
16e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * License along with this program; if not,  see <http://www.gnu.org/licenses>
17e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
18e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
19e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
20e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *  The parts for function graph printing was taken and modified from the
21e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *  Linux Kernel that were written by
22e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *    - Copyright (C) 2009  Frederic Weisbecker,
23e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *  Frederic Weisbecker gave his permission to relicense the code to
24e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *  the Lesser General Public License.
25e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
26e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <stdio.h>
27e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <stdlib.h>
28e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <string.h>
29e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <stdarg.h>
30e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <ctype.h>
31e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <errno.h>
32e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <stdint.h>
33e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <limits.h>
34e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
35e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "event-parse.h"
36e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "event-utils.h"
37e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
38e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic const char *input_buf;
39e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic unsigned long long input_buf_ptr;
40e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic unsigned long long input_buf_siz;
41e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
42e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int is_flag_field;
43e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int is_symbolic_field;
44e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
45e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int show_warning = 1;
46e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
47e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define do_warning(fmt, ...)				\
48e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	do {						\
49e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (show_warning)			\
50e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			warning(fmt, ##__VA_ARGS__);	\
51e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	} while (0)
52e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
53e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void init_input_buf(const char *buf, unsigned long long size)
54e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
55e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	input_buf = buf;
56e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	input_buf_siz = size;
57e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	input_buf_ptr = 0;
58e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
59e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
60e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengconst char *pevent_get_input_buf(void)
61e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
62e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return input_buf;
63e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
64e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
65e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengunsigned long long pevent_get_input_buf_ptr(void)
66e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
67e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return input_buf_ptr;
68e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
69e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
70e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct event_handler {
71e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct event_handler		*next;
72e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int				id;
73e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const char			*sys_name;
74e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const char			*event_name;
75e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent_event_handler_func	func;
76e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	void				*context;
77e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
78e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
79e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct pevent_func_params {
80e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pevent_func_params	*next;
81e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	enum pevent_func_arg_type	type;
82e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
83e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
84e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct pevent_function_handler {
85e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pevent_function_handler	*next;
86e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	enum pevent_func_arg_type	ret_type;
87e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char				*name;
88e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent_func_handler		func;
89e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pevent_func_params	*params;
90e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int				nr_args;
91e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
92e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
93e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic unsigned long long
94e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengprocess_defined_func(struct trace_seq *s, void *data, int size,
95e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		     struct event_format *event, struct print_arg *arg);
96e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
97e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void free_func_handle(struct pevent_function_handler *func);
98e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
99e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
100e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_buffer_init - init buffer for parsing
101e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @buf: buffer to parse
102e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @size: the size of the buffer
103e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
104e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * For use with pevent_read_token(), this initializes the internal
105e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * buffer that pevent_read_token() will parse.
106e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
107e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid pevent_buffer_init(const char *buf, unsigned long long size)
108e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
109e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	init_input_buf(buf, size);
110e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
111e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
112e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid breakpoint(void)
113e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
114e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	static int x;
115e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	x++;
116e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
117e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
118e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct print_arg *alloc_arg(void)
119e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
120e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return calloc(1, sizeof(struct print_arg));
121e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
122e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
123e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct cmdline {
124e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *comm;
125e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int pid;
126e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
127e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
128e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int cmdline_cmp(const void *a, const void *b)
129e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
130e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const struct cmdline *ca = a;
131e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const struct cmdline *cb = b;
132e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
133e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (ca->pid < cb->pid)
134e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
135e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (ca->pid > cb->pid)
136e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 1;
137e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
138e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
139e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
140e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
141e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct cmdline_list {
142e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct cmdline_list	*next;
143e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char			*comm;
144e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int			pid;
145e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
146e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
147e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int cmdline_init(struct pevent *pevent)
148e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
149e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct cmdline_list *cmdlist = pevent->cmdlist;
150e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct cmdline_list *item;
151e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct cmdline *cmdlines;
152e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int i;
153e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
154e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	cmdlines = malloc(sizeof(*cmdlines) * pevent->cmdline_count);
155e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!cmdlines)
156e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
157e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
158e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	i = 0;
159e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (cmdlist) {
160e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		cmdlines[i].pid = cmdlist->pid;
161e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		cmdlines[i].comm = cmdlist->comm;
162e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		i++;
163e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		item = cmdlist;
164e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		cmdlist = cmdlist->next;
165e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(item);
166e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
167e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
168e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	qsort(cmdlines, pevent->cmdline_count, sizeof(*cmdlines), cmdline_cmp);
169e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
170e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent->cmdlines = cmdlines;
171e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent->cmdlist = NULL;
172e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
173e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
174e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
175e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
176e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic const char *find_cmdline(struct pevent *pevent, int pid)
177e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
178e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const struct cmdline *comm;
179e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct cmdline key;
180e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
181e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!pid)
182e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return "<idle>";
183e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
184e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!pevent->cmdlines && cmdline_init(pevent))
185e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return "<not enough memory for cmdlines!>";
186e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
187e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	key.pid = pid;
188e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
189e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	comm = bsearch(&key, pevent->cmdlines, pevent->cmdline_count,
190e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		       sizeof(*pevent->cmdlines), cmdline_cmp);
191e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
192e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (comm)
193e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return comm->comm;
194e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return "<...>";
195e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
196e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
197e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
198e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_pid_is_registered - return if a pid has a cmdline registered
199e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @pevent: handle for the pevent
200e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @pid: The pid to check if it has a cmdline registered with.
201e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
202e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Returns 1 if the pid has a cmdline mapped to it
203e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 0 otherwise.
204e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
205e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint pevent_pid_is_registered(struct pevent *pevent, int pid)
206e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
207e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const struct cmdline *comm;
208e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct cmdline key;
209e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
210e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!pid)
211e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 1;
212e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
213e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!pevent->cmdlines && cmdline_init(pevent))
214e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 0;
215e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
216e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	key.pid = pid;
217e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
218e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	comm = bsearch(&key, pevent->cmdlines, pevent->cmdline_count,
219e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		       sizeof(*pevent->cmdlines), cmdline_cmp);
220e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
221e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (comm)
222e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 1;
223e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
224e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
225e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
226e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/*
227e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * If the command lines have been converted to an array, then
228e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * we must add this pid. This is much slower than when cmdlines
229e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * are added before the array is initialized.
230e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
231e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int add_new_comm(struct pevent *pevent, const char *comm, int pid)
232e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
233e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct cmdline *cmdlines = pevent->cmdlines;
234e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const struct cmdline *cmdline;
235e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct cmdline key;
236e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
237e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!pid)
238e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 0;
239e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
240e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* avoid duplicates */
241e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	key.pid = pid;
242e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
243e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	cmdline = bsearch(&key, pevent->cmdlines, pevent->cmdline_count,
244e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		       sizeof(*pevent->cmdlines), cmdline_cmp);
245e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (cmdline) {
246e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		errno = EEXIST;
247e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
248e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
249e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
250e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	cmdlines = realloc(cmdlines, sizeof(*cmdlines) * (pevent->cmdline_count + 1));
251e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!cmdlines) {
252e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		errno = ENOMEM;
253e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
254e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
255e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
256e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	cmdlines[pevent->cmdline_count].comm = strdup(comm);
257e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!cmdlines[pevent->cmdline_count].comm) {
258e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(cmdlines);
259e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		errno = ENOMEM;
260e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
261e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
262e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
263e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	cmdlines[pevent->cmdline_count].pid = pid;
264e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
265e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (cmdlines[pevent->cmdline_count].comm)
266e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pevent->cmdline_count++;
267e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
268e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	qsort(cmdlines, pevent->cmdline_count, sizeof(*cmdlines), cmdline_cmp);
269e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent->cmdlines = cmdlines;
270e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
271e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
272e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
273e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
274e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
275e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_register_comm - register a pid / comm mapping
276e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @pevent: handle for the pevent
277e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @comm: the command line to register
278e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @pid: the pid to map the command line to
279e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
280e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This adds a mapping to search for command line names with
281e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * a given pid. The comm is duplicated.
282e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
283e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint pevent_register_comm(struct pevent *pevent, const char *comm, int pid)
284e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
285e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct cmdline_list *item;
286e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
287e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (pevent->cmdlines)
288e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return add_new_comm(pevent, comm, pid);
289e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
290e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	item = malloc(sizeof(*item));
291e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!item)
292e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
293e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
294e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	item->comm = strdup(comm);
295e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!item->comm) {
296e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(item);
297e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
298e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
299e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	item->pid = pid;
300e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	item->next = pevent->cmdlist;
301e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
302e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent->cmdlist = item;
303e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent->cmdline_count++;
304e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
305e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
306e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
307e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
308e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct func_map {
309e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long long		addr;
310e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char				*func;
311e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char				*mod;
312e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
313e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
314e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct func_list {
315e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct func_list	*next;
316e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long long	addr;
317e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char			*func;
318e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char			*mod;
319e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
320e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
321e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int func_cmp(const void *a, const void *b)
322e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
323e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const struct func_map *fa = a;
324e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const struct func_map *fb = b;
325e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
326e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (fa->addr < fb->addr)
327e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
328e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (fa->addr > fb->addr)
329e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 1;
330e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
331e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
332e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
333e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
334e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/*
335e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * We are searching for a record in between, not an exact
336e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * match.
337e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
338e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int func_bcmp(const void *a, const void *b)
339e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
340e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const struct func_map *fa = a;
341e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const struct func_map *fb = b;
342e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
343e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if ((fa->addr == fb->addr) ||
344e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
345e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    (fa->addr > fb->addr &&
346e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	     fa->addr < (fb+1)->addr))
347e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 0;
348e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
349e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (fa->addr < fb->addr)
350e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
351e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
352e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 1;
353e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
354e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
355e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int func_map_init(struct pevent *pevent)
356e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
357e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct func_list *funclist;
358e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct func_list *item;
359e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct func_map *func_map;
360e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int i;
361e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
362e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	func_map = malloc(sizeof(*func_map) * (pevent->func_count + 1));
363e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!func_map)
364e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
365e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
366e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	funclist = pevent->funclist;
367e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
368e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	i = 0;
369e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (funclist) {
370e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		func_map[i].func = funclist->func;
371e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		func_map[i].addr = funclist->addr;
372e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		func_map[i].mod = funclist->mod;
373e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		i++;
374e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		item = funclist;
375e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		funclist = funclist->next;
376e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(item);
377e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
378e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
379e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	qsort(func_map, pevent->func_count, sizeof(*func_map), func_cmp);
380e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
381e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/*
382e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 * Add a special record at the end.
383e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 */
384e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	func_map[pevent->func_count].func = NULL;
385e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	func_map[pevent->func_count].addr = 0;
386e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	func_map[pevent->func_count].mod = NULL;
387e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
388e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent->func_map = func_map;
389e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent->funclist = NULL;
390e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
391e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
392e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
393e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
394e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic struct func_map *
395e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengfind_func(struct pevent *pevent, unsigned long long addr)
396e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
397e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct func_map *func;
398e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct func_map key;
399e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
400e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!pevent->func_map)
401e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		func_map_init(pevent);
402e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
403e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	key.addr = addr;
404e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
405e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	func = bsearch(&key, pevent->func_map, pevent->func_count,
406e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		       sizeof(*pevent->func_map), func_bcmp);
407e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
408e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return func;
409e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
410e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
411e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
412e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_find_function - find a function by a given address
413e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @pevent: handle for the pevent
414e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @addr: the address to find the function with
415e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
416e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Returns a pointer to the function stored that has the given
417e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * address. Note, the address does not have to be exact, it
418e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * will select the function that would contain the address.
419e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
420e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengconst char *pevent_find_function(struct pevent *pevent, unsigned long long addr)
421e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
422e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct func_map *map;
423e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
424e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	map = find_func(pevent, addr);
425e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!map)
426e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
427e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
428e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return map->func;
429e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
430e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
431e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
432e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_find_function_address - find a function address by a given address
433e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @pevent: handle for the pevent
434e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @addr: the address to find the function with
435e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
436e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Returns the address the function starts at. This can be used in
437e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * conjunction with pevent_find_function to print both the function
438e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * name and the function offset.
439e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
440e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengunsigned long long
441e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengpevent_find_function_address(struct pevent *pevent, unsigned long long addr)
442e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
443e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct func_map *map;
444e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
445e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	map = find_func(pevent, addr);
446e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!map)
447e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 0;
448e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
449e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return map->addr;
450e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
451e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
452e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
453e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_register_function - register a function with a given address
454e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @pevent: handle for the pevent
455e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @function: the function name to register
456e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @addr: the address the function starts at
457e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @mod: the kernel module the function may be in (NULL for none)
458e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
459e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This registers a function name with an address and module.
460e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * The @func passed in is duplicated.
461e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
462e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint pevent_register_function(struct pevent *pevent, char *func,
463e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			     unsigned long long addr, char *mod)
464e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
465e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct func_list *item = malloc(sizeof(*item));
466e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
467e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!item)
468e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
469e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
470e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	item->next = pevent->funclist;
471e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	item->func = strdup(func);
472e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!item->func)
473e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_free;
474e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
475e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (mod) {
476e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		item->mod = strdup(mod);
477e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!item->mod)
478e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto out_free_func;
479e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	} else
480e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		item->mod = NULL;
481e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	item->addr = addr;
482e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
483e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent->funclist = item;
484e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent->func_count++;
485e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
486e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
487e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
488e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_free_func:
489e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free(item->func);
490e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	item->func = NULL;
491e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_free:
492e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free(item);
493e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	errno = ENOMEM;
494e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return -1;
495e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
496e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
497e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
498e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_print_funcs - print out the stored functions
499e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @pevent: handle for the pevent
500e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
501e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This prints out the stored functions.
502e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
503e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid pevent_print_funcs(struct pevent *pevent)
504e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
505e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int i;
506e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
507e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!pevent->func_map)
508e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		func_map_init(pevent);
509e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
510e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (i = 0; i < (int)pevent->func_count; i++) {
511e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		printf("%016llx %s",
512e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		       pevent->func_map[i].addr,
513e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		       pevent->func_map[i].func);
514e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (pevent->func_map[i].mod)
515e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			printf(" [%s]\n", pevent->func_map[i].mod);
516e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		else
517e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			printf("\n");
518e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
519e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
520e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
521e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct printk_map {
522e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long long		addr;
523e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char				*printk;
524e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
525e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
526e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct printk_list {
527e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct printk_list	*next;
528e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long long	addr;
529e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char			*printk;
530e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
531e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
532e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int printk_cmp(const void *a, const void *b)
533e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
534e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const struct printk_map *pa = a;
535e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const struct printk_map *pb = b;
536e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
537e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (pa->addr < pb->addr)
538e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
539e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (pa->addr > pb->addr)
540e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 1;
541e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
542e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
543e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
544e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
545e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int printk_map_init(struct pevent *pevent)
546e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
547e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct printk_list *printklist;
548e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct printk_list *item;
549e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct printk_map *printk_map;
550e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int i;
551e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
552e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	printk_map = malloc(sizeof(*printk_map) * (pevent->printk_count + 1));
553e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!printk_map)
554e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
555e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
556e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	printklist = pevent->printklist;
557e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
558e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	i = 0;
559e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (printklist) {
560e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		printk_map[i].printk = printklist->printk;
561e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		printk_map[i].addr = printklist->addr;
562e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		i++;
563e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		item = printklist;
564e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		printklist = printklist->next;
565e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(item);
566e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
567e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
568e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	qsort(printk_map, pevent->printk_count, sizeof(*printk_map), printk_cmp);
569e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
570e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent->printk_map = printk_map;
571e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent->printklist = NULL;
572e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
573e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
574e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
575e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
576e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic struct printk_map *
577e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengfind_printk(struct pevent *pevent, unsigned long long addr)
578e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
579e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct printk_map *printk;
580e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct printk_map key;
581e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
582e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!pevent->printk_map && printk_map_init(pevent))
583e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
584e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
585e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	key.addr = addr;
586e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
587e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	printk = bsearch(&key, pevent->printk_map, pevent->printk_count,
588e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			 sizeof(*pevent->printk_map), printk_cmp);
589e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
590e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return printk;
591e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
592e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
593e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
594e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_register_print_string - register a string by its address
595e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @pevent: handle for the pevent
596e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @fmt: the string format to register
597e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @addr: the address the string was located at
598e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
599e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This registers a string by the address it was stored in the kernel.
600e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * The @fmt passed in is duplicated.
601e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
602e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint pevent_register_print_string(struct pevent *pevent, char *fmt,
603e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				 unsigned long long addr)
604e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
605e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct printk_list *item = malloc(sizeof(*item));
606e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
607e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!item)
608e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
609e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
610e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	item->next = pevent->printklist;
611e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	item->addr = addr;
612e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
613e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	item->printk = strdup(fmt);
614e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!item->printk)
615e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_free;
616e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
617e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent->printklist = item;
618e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent->printk_count++;
619e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
620e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
621e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
622e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_free:
623e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free(item);
624e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	errno = ENOMEM;
625e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return -1;
626e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
627e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
628e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
629e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_print_printk - print out the stored strings
630e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @pevent: handle for the pevent
631e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
632e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This prints the string formats that were stored.
633e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
634e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid pevent_print_printk(struct pevent *pevent)
635e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
636e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int i;
637e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
638e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!pevent->printk_map)
639e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		printk_map_init(pevent);
640e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
641e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (i = 0; i < (int)pevent->printk_count; i++) {
642e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		printf("%016llx %s\n",
643e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		       pevent->printk_map[i].addr,
644e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		       pevent->printk_map[i].printk);
645e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
646e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
647e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
648e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic struct event_format *alloc_event(void)
649e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
650e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return calloc(1, sizeof(struct event_format));
651e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
652e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
653e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int add_event(struct pevent *pevent, struct event_format *event)
654e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
655e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int i;
656e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct event_format **events = realloc(pevent->events, sizeof(event) *
657e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					       (pevent->nr_events + 1));
658e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!events)
659e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
660e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
661e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent->events = events;
662e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
663e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (i = 0; i < pevent->nr_events; i++) {
664e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (pevent->events[i]->id > event->id)
665e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
666e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
667e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (i < pevent->nr_events)
668e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		memmove(&pevent->events[i + 1],
669e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			&pevent->events[i],
670e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			sizeof(event) * (pevent->nr_events - i));
671e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
672e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent->events[i] = event;
673e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent->nr_events++;
674e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
675e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	event->pevent = pevent;
676e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
677e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
678e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
679e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
680e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int event_item_type(enum event_type type)
681e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
682e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	switch (type) {
683e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case EVENT_ITEM ... EVENT_SQUOTE:
684e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 1;
685e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case EVENT_ERROR ... EVENT_DELIM:
686e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	default:
687e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 0;
688e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
689e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
690e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
691e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void free_flag_sym(struct print_flag_sym *fsym)
692e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
693e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct print_flag_sym *next;
694e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
695e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (fsym) {
696e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		next = fsym->next;
697e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(fsym->value);
698e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(fsym->str);
699e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(fsym);
700e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		fsym = next;
701e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
702e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
703e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
704e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void free_arg(struct print_arg *arg)
705e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
706e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct print_arg *farg;
707e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
708e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!arg)
709e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return;
710e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
711e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	switch (arg->type) {
712e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_ATOM:
713e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(arg->atom.atom);
714e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
715e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_FIELD:
716e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(arg->field.name);
717e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
718e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_FLAGS:
719e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_arg(arg->flags.field);
720e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(arg->flags.delim);
721e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_flag_sym(arg->flags.flags);
722e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
723e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_SYMBOL:
724e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_arg(arg->symbol.field);
725e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_flag_sym(arg->symbol.symbols);
726e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
727e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_HEX:
728e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_arg(arg->hex.field);
729e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_arg(arg->hex.size);
730e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
731e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_TYPE:
732e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(arg->typecast.type);
733e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_arg(arg->typecast.item);
734e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
735e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_STRING:
736e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_BSTRING:
737e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(arg->string.string);
738e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
739e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_DYNAMIC_ARRAY:
740e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(arg->dynarray.index);
741e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
742e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_OP:
743e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(arg->op.op);
744e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_arg(arg->op.left);
745e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_arg(arg->op.right);
746e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
747e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_FUNC:
748e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		while (arg->func.args) {
749e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			farg = arg->func.args;
750e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			arg->func.args = farg->next;
751e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			free_arg(farg);
752e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
753e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
754e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
755e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_NULL:
756e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	default:
757e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
758e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
759e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
760e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free(arg);
761e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
762e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
763e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic enum event_type get_type(int ch)
764e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
765e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (ch == '\n')
766e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return EVENT_NEWLINE;
767e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (isspace(ch))
768e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return EVENT_SPACE;
769e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (isalnum(ch) || ch == '_')
770e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return EVENT_ITEM;
771e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (ch == '\'')
772e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return EVENT_SQUOTE;
773e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (ch == '"')
774e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return EVENT_DQUOTE;
775e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!isprint(ch))
776e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return EVENT_NONE;
777e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (ch == '(' || ch == ')' || ch == ',')
778e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return EVENT_DELIM;
779e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
780e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return EVENT_OP;
781e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
782e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
783e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int __read_char(void)
784e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
785e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (input_buf_ptr >= input_buf_siz)
786e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
787e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
788e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return input_buf[input_buf_ptr++];
789e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
790e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
791e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int __peek_char(void)
792e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
793e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (input_buf_ptr >= input_buf_siz)
794e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
795e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
796e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return input_buf[input_buf_ptr];
797e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
798e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
799e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
800e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_peek_char - peek at the next character that will be read
801e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
802e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Returns the next character read, or -1 if end of buffer.
803e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
804e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint pevent_peek_char(void)
805e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
806e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return __peek_char();
807e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
808e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
809e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int extend_token(char **tok, char *buf, int size)
810e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
811e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *newtok = realloc(*tok, size);
812e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
813e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!newtok) {
814e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(*tok);
815e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*tok = NULL;
816e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
817e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
818e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
819e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!*tok)
820e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		strcpy(newtok, buf);
821e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	else
822e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		strcat(newtok, buf);
823e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*tok = newtok;
824e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
825e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
826e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
827e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
828e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic enum event_type force_token(const char *str, char **tok);
829e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
830e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic enum event_type __read_token(char **tok)
831e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
832e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char buf[BUFSIZ];
833e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int ch, last_ch, quote_ch, next_ch;
834e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int i = 0;
835e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int tok_size = 0;
836e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	enum event_type type;
837e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
838e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*tok = NULL;
839e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
840e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
841e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ch = __read_char();
842e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (ch < 0)
843e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return EVENT_NONE;
844e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
845e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = get_type(ch);
846e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (type == EVENT_NONE)
847e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return type;
848e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
849e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	buf[i++] = ch;
850e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
851e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	switch (type) {
852e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case EVENT_NEWLINE:
853e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case EVENT_DELIM:
854e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (asprintf(tok, "%c", ch) < 0)
855e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return EVENT_ERROR;
856e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
857e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return type;
858e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
859e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case EVENT_OP:
860e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		switch (ch) {
861e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '-':
862e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			next_ch = __peek_char();
863e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (next_ch == '>') {
864e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				buf[i++] = __read_char();
865e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
866e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
867e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			/* fall through */
868e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '+':
869e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '|':
870e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '&':
871e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '>':
872e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '<':
873e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			last_ch = ch;
874e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			ch = __peek_char();
875e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (ch != last_ch)
876e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto test_equal;
877e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			buf[i++] = __read_char();
878e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			switch (last_ch) {
879e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case '>':
880e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case '<':
881e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto test_equal;
882e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			default:
883e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
884e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
885e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
886e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '!':
887e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '=':
888e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto test_equal;
889e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		default: /* what should we do instead? */
890e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
891e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
892e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		buf[i] = 0;
893e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*tok = strdup(buf);
894e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return type;
895e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
896e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng test_equal:
897e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ch = __peek_char();
898e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (ch == '=')
899e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			buf[i++] = __read_char();
900e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out;
901e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
902e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case EVENT_DQUOTE:
903e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case EVENT_SQUOTE:
904e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* don't keep quotes */
905e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		i--;
906e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		quote_ch = ch;
907e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		last_ch = 0;
908e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng concat:
909e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		do {
910e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (i == (BUFSIZ - 1)) {
911e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				buf[i] = 0;
912e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				tok_size += BUFSIZ;
913e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
914e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (extend_token(tok, buf, tok_size) < 0)
915e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					return EVENT_NONE;
916e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				i = 0;
917e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
918e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			last_ch = ch;
919e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			ch = __read_char();
920e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			buf[i++] = ch;
921e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			/* the '\' '\' will cancel itself */
922e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (ch == '\\' && last_ch == '\\')
923e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				last_ch = 0;
924e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		} while (ch != quote_ch || last_ch == '\\');
925e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* remove the last quote */
926e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		i--;
927e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
928e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/*
929e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 * For strings (double quotes) check the next token.
930e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 * If it is another string, concatinate the two.
931e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 */
932e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (type == EVENT_DQUOTE) {
933e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			unsigned long long save_input_buf_ptr = input_buf_ptr;
934e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
935e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			do {
936e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				ch = __read_char();
937e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			} while (isspace(ch));
938e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (ch == '"')
939e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto concat;
940e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			input_buf_ptr = save_input_buf_ptr;
941e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
942e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
943e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out;
944e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
945e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case EVENT_ERROR ... EVENT_SPACE:
946e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case EVENT_ITEM:
947e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	default:
948e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
949e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
950e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
951e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (get_type(__peek_char()) == type) {
952e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (i == (BUFSIZ - 1)) {
953e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			buf[i] = 0;
954e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			tok_size += BUFSIZ;
955e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
956e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (extend_token(tok, buf, tok_size) < 0)
957e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				return EVENT_NONE;
958e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			i = 0;
959e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
960e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ch = __read_char();
961e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		buf[i++] = ch;
962e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
963e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
964e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng out:
965e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	buf[i] = 0;
966e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (extend_token(tok, buf, tok_size + i + 1) < 0)
967e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return EVENT_NONE;
968e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
969e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (type == EVENT_ITEM) {
970e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/*
971e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 * Older versions of the kernel has a bug that
972e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 * creates invalid symbols and will break the mac80211
973e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 * parsing. This is a work around to that bug.
974e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 *
975e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 * See Linux kernel commit:
976e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 *  811cb50baf63461ce0bdb234927046131fc7fa8b
977e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 */
978e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (strcmp(*tok, "LOCAL_PR_FMT") == 0) {
979e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			free(*tok);
980e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			*tok = NULL;
981e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return force_token("\"\%s\" ", tok);
982e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		} else if (strcmp(*tok, "STA_PR_FMT") == 0) {
983e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			free(*tok);
984e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			*tok = NULL;
985e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return force_token("\" sta:%pM\" ", tok);
986e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		} else if (strcmp(*tok, "VIF_PR_FMT") == 0) {
987e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			free(*tok);
988e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			*tok = NULL;
989e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return force_token("\" vif:%p(%d)\" ", tok);
990e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
991e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
992e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
993e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return type;
994e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
995e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
996e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic enum event_type force_token(const char *str, char **tok)
997e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
998e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const char *save_input_buf;
999e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long long save_input_buf_ptr;
1000e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long long save_input_buf_siz;
1001e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	enum event_type type;
1002e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1003e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* save off the current input pointers */
1004e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	save_input_buf = input_buf;
1005e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	save_input_buf_ptr = input_buf_ptr;
1006e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	save_input_buf_siz = input_buf_siz;
1007e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1008e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	init_input_buf(str, strlen(str));
1009e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1010e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = __read_token(tok);
1011e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1012e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* reset back to original token */
1013e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	input_buf = save_input_buf;
1014e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	input_buf_ptr = save_input_buf_ptr;
1015e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	input_buf_siz = save_input_buf_siz;
1016e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1017e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return type;
1018e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1019e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1020e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void free_token(char *tok)
1021e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1022e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (tok)
1023e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(tok);
1024e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1025e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1026e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic enum event_type read_token(char **tok)
1027e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1028e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	enum event_type type;
1029e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1030e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (;;) {
1031e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = __read_token(tok);
1032e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (type != EVENT_SPACE)
1033e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return type;
1034e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1035e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_token(*tok);
1036e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
1037e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1038e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* not reached */
1039e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*tok = NULL;
1040e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return EVENT_NONE;
1041e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1042e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1043e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
1044e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_read_token - access to utilites to use the pevent parser
1045e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @tok: The token to return
1046e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
1047e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This will parse tokens from the string given by
1048e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_init_data().
1049e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
1050e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Returns the token type.
1051e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
1052e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengenum event_type pevent_read_token(char **tok)
1053e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1054e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return read_token(tok);
1055e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1056e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1057e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
1058e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_free_token - free a token returned by pevent_read_token
1059e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @token: the token to free
1060e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
1061e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid pevent_free_token(char *token)
1062e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1063e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
1064e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1065e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1066e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/* no newline */
1067e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic enum event_type read_token_item(char **tok)
1068e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1069e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	enum event_type type;
1070e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1071e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (;;) {
1072e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = __read_token(tok);
1073e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (type != EVENT_SPACE && type != EVENT_NEWLINE)
1074e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return type;
1075e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_token(*tok);
1076e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*tok = NULL;
1077e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
1078e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1079e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* not reached */
1080e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*tok = NULL;
1081e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return EVENT_NONE;
1082e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1083e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1084e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int test_type(enum event_type type, enum event_type expect)
1085e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1086e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (type != expect) {
1087e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		do_warning("Error: expected type %d but read %d",
1088e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		    expect, type);
1089e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
1090e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
1091e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
1092e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1093e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1094e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int test_type_token(enum event_type type, const char *token,
1095e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		    enum event_type expect, const char *expect_tok)
1096e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1097e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (type != expect) {
1098e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		do_warning("Error: expected type %d but read %d",
1099e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		    expect, type);
1100e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
1101e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
1102e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1103e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (strcmp(token, expect_tok) != 0) {
1104e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		do_warning("Error: expected '%s' but read '%s'",
1105e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		    expect_tok, token);
1106e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
1107e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
1108e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
1109e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1110e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1111e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int __read_expect_type(enum event_type expect, char **tok, int newline_ok)
1112e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1113e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	enum event_type type;
1114e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1115e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (newline_ok)
1116e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = read_token(tok);
1117e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	else
1118e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = read_token_item(tok);
1119e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return test_type(type, expect);
1120e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1121e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1122e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int read_expect_type(enum event_type expect, char **tok)
1123e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1124e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return __read_expect_type(expect, tok, 1);
1125e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1126e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1127e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int __read_expected(enum event_type expect, const char *str,
1128e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			   int newline_ok)
1129e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1130e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	enum event_type type;
1131e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *token;
1132e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int ret;
1133e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1134e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (newline_ok)
1135e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = read_token(&token);
1136e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	else
1137e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = read_token_item(&token);
1138e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1139e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ret = test_type_token(type, token, expect, str);
1140e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1141e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
1142e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1143e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return ret;
1144e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1145e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1146e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int read_expected(enum event_type expect, const char *str)
1147e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1148e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return __read_expected(expect, str, 1);
1149e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1150e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1151e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int read_expected_item(enum event_type expect, const char *str)
1152e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1153e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return __read_expected(expect, str, 0);
1154e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1155e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1156e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic char *event_read_name(void)
1157e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1158e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *token;
1159e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1160e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expected(EVENT_ITEM, "name") < 0)
1161e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
1162e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1163e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expected(EVENT_OP, ":") < 0)
1164e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
1165e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1166e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expect_type(EVENT_ITEM, &token) < 0)
1167e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto fail;
1168e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1169e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return token;
1170e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1171e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng fail:
1172e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
1173e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return NULL;
1174e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1175e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1176e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int event_read_id(void)
1177e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1178e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *token;
1179e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int id;
1180e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1181e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expected_item(EVENT_ITEM, "ID") < 0)
1182e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
1183e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1184e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expected(EVENT_OP, ":") < 0)
1185e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
1186e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1187e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expect_type(EVENT_ITEM, &token) < 0)
1188e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto fail;
1189e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1190e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	id = strtoul(token, NULL, 0);
1191e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
1192e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return id;
1193e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1194e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng fail:
1195e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
1196e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return -1;
1197e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1198e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1199e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int field_is_string(struct format_field *field)
1200e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1201e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if ((field->flags & FIELD_IS_ARRAY) &&
1202e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    (strstr(field->type, "char") || strstr(field->type, "u8") ||
1203e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	     strstr(field->type, "s8")))
1204e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 1;
1205e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1206e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
1207e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1208e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1209e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int field_is_dynamic(struct format_field *field)
1210e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1211e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (strncmp(field->type, "__data_loc", 10) == 0)
1212e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 1;
1213e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1214e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
1215e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1216e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1217e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int field_is_long(struct format_field *field)
1218e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1219e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* includes long long */
1220e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (strstr(field->type, "long"))
1221e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 1;
1222e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1223e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
1224e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1225e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1226e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic unsigned int type_size(const char *name)
1227e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1228e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* This covers all FIELD_IS_STRING types. */
1229e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	static struct {
1230e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		const char *type;
1231e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		unsigned int size;
1232e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	} table[] = {
1233e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		{ "u8",   1 },
1234e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		{ "u16",  2 },
1235e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		{ "u32",  4 },
1236e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		{ "u64",  8 },
1237e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		{ "s8",   1 },
1238e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		{ "s16",  2 },
1239e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		{ "s32",  4 },
1240e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		{ "s64",  8 },
1241e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		{ "char", 1 },
1242e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		{ },
1243e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	};
1244e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int i;
1245e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1246e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (i = 0; table[i].type; i++) {
1247e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!strcmp(table[i].type, name))
1248e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return table[i].size;
1249e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
1250e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1251e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
1252e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1253e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1254e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int event_read_fields(struct event_format *event, struct format_field **fields)
1255e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1256e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct format_field *field = NULL;
1257e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	enum event_type type;
1258e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *token;
1259e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *last_token;
1260e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int count = 0;
1261e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1262e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	do {
1263e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		unsigned int size_dynamic = 0;
1264e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1265e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = read_token(&token);
1266e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (type == EVENT_NEWLINE) {
1267e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			free_token(token);
1268e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return count;
1269e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
1270e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1271e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		count++;
1272e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1273e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (test_type_token(type, token, EVENT_ITEM, "field"))
1274e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto fail;
1275e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_token(token);
1276e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1277e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = read_token(&token);
1278e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/*
1279e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 * The ftrace fields may still use the "special" name.
1280e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 * Just ignore it.
1281e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 */
1282e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (event->flags & EVENT_FL_ISFTRACE &&
1283e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		    type == EVENT_ITEM && strcmp(token, "special") == 0) {
1284e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			free_token(token);
1285e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			type = read_token(&token);
1286e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
1287e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1288e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (test_type_token(type, token, EVENT_OP, ":") < 0)
1289e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto fail;
1290e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1291e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_token(token);
1292e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (read_expect_type(EVENT_ITEM, &token) < 0)
1293e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto fail;
1294e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1295e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		last_token = token;
1296e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1297e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		field = calloc(1, sizeof(*field));
1298e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!field)
1299e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto fail;
1300e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1301e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		field->event = event;
1302e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1303e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* read the rest of the type */
1304e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		for (;;) {
1305e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			type = read_token(&token);
1306e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (type == EVENT_ITEM ||
1307e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			    (type == EVENT_OP && strcmp(token, "*") == 0) ||
1308e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			    /*
1309e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			     * Some of the ftrace fields are broken and have
1310e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			     * an illegal "." in them.
1311e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			     */
1312e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			    (event->flags & EVENT_FL_ISFTRACE &&
1313e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			     type == EVENT_OP && strcmp(token, ".") == 0)) {
1314e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1315e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (strcmp(token, "*") == 0)
1316e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					field->flags |= FIELD_IS_POINTER;
1317e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1318e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (field->type) {
1319e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					char *new_type;
1320e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					new_type = realloc(field->type,
1321e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng							   strlen(field->type) +
1322e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng							   strlen(last_token) + 2);
1323e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					if (!new_type) {
1324e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						free(last_token);
1325e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						goto fail;
1326e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					}
1327e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					field->type = new_type;
1328e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					strcat(field->type, " ");
1329e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					strcat(field->type, last_token);
1330e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					free(last_token);
1331e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				} else
1332e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					field->type = last_token;
1333e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				last_token = token;
1334e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				continue;
1335e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
1336e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1337e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
1338e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
1339e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1340e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!field->type) {
1341e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			do_warning("%s: no type found", __func__);
1342e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto fail;
1343e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
1344e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		field->name = last_token;
1345e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1346e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (test_type(type, EVENT_OP))
1347e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto fail;
1348e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1349e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (strcmp(token, "[") == 0) {
1350e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			enum event_type last_type = type;
1351e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			char *brackets = token;
1352e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			char *new_brackets;
1353e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			int len;
1354e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1355e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			field->flags |= FIELD_IS_ARRAY;
1356e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1357e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			type = read_token(&token);
1358e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1359e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (type == EVENT_ITEM)
1360e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				field->arraylen = strtoul(token, NULL, 0);
1361e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			else
1362e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				field->arraylen = 0;
1363e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1364e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		        while (strcmp(token, "]") != 0) {
1365e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (last_type == EVENT_ITEM &&
1366e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				    type == EVENT_ITEM)
1367e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					len = 2;
1368e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				else
1369e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					len = 1;
1370e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				last_type = type;
1371e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1372e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				new_brackets = realloc(brackets,
1373e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						       strlen(brackets) +
1374e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						       strlen(token) + len);
1375e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (!new_brackets) {
1376e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					free(brackets);
1377e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					goto fail;
1378e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				}
1379e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				brackets = new_brackets;
1380e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (len == 2)
1381e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					strcat(brackets, " ");
1382e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				strcat(brackets, token);
1383e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				/* We only care about the last token */
1384e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				field->arraylen = strtoul(token, NULL, 0);
1385e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				free_token(token);
1386e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				type = read_token(&token);
1387e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (type == EVENT_NONE) {
1388e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					do_warning("failed to find token");
1389e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					goto fail;
1390e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				}
1391e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
1392e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1393e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			free_token(token);
1394e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1395e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			new_brackets = realloc(brackets, strlen(brackets) + 2);
1396e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!new_brackets) {
1397e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				free(brackets);
1398e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto fail;
1399e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
1400e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			brackets = new_brackets;
1401e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			strcat(brackets, "]");
1402e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1403e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			/* add brackets to type */
1404e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1405e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			type = read_token(&token);
1406e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			/*
1407e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			 * If the next token is not an OP, then it is of
1408e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			 * the format: type [] item;
1409e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			 */
1410e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (type == EVENT_ITEM) {
1411e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				char *new_type;
1412e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				new_type = realloc(field->type,
1413e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						   strlen(field->type) +
1414e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						   strlen(field->name) +
1415e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						   strlen(brackets) + 2);
1416e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (!new_type) {
1417e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					free(brackets);
1418e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					goto fail;
1419e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				}
1420e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				field->type = new_type;
1421e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				strcat(field->type, " ");
1422e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				strcat(field->type, field->name);
1423e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				size_dynamic = type_size(field->name);
1424e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				free_token(field->name);
1425e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				strcat(field->type, brackets);
1426e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				field->name = token;
1427e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				type = read_token(&token);
1428e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			} else {
1429e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				char *new_type;
1430e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				new_type = realloc(field->type,
1431e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						   strlen(field->type) +
1432e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						   strlen(brackets) + 1);
1433e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (!new_type) {
1434e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					free(brackets);
1435e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					goto fail;
1436e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				}
1437e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				field->type = new_type;
1438e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				strcat(field->type, brackets);
1439e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
1440e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			free(brackets);
1441e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
1442e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1443e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (field_is_string(field))
1444e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			field->flags |= FIELD_IS_STRING;
1445e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (field_is_dynamic(field))
1446e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			field->flags |= FIELD_IS_DYNAMIC;
1447e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (field_is_long(field))
1448e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			field->flags |= FIELD_IS_LONG;
1449e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1450e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (test_type_token(type, token,  EVENT_OP, ";"))
1451e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto fail;
1452e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_token(token);
1453e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1454e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (read_expected(EVENT_ITEM, "offset") < 0)
1455e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto fail_expect;
1456e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1457e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (read_expected(EVENT_OP, ":") < 0)
1458e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto fail_expect;
1459e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1460e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (read_expect_type(EVENT_ITEM, &token))
1461e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto fail;
1462e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		field->offset = strtoul(token, NULL, 0);
1463e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_token(token);
1464e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1465e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (read_expected(EVENT_OP, ";") < 0)
1466e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto fail_expect;
1467e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1468e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (read_expected(EVENT_ITEM, "size") < 0)
1469e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto fail_expect;
1470e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1471e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (read_expected(EVENT_OP, ":") < 0)
1472e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto fail_expect;
1473e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1474e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (read_expect_type(EVENT_ITEM, &token))
1475e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto fail;
1476e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		field->size = strtoul(token, NULL, 0);
1477e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_token(token);
1478e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1479e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (read_expected(EVENT_OP, ";") < 0)
1480e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto fail_expect;
1481e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1482e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = read_token(&token);
1483e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (type != EVENT_NEWLINE) {
1484e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			/* newer versions of the kernel have a "signed" type */
1485e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (test_type_token(type, token, EVENT_ITEM, "signed"))
1486e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto fail;
1487e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1488e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			free_token(token);
1489e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1490e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (read_expected(EVENT_OP, ":") < 0)
1491e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto fail_expect;
1492e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1493e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (read_expect_type(EVENT_ITEM, &token))
1494e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto fail;
1495e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1496e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (strtoul(token, NULL, 0))
1497e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				field->flags |= FIELD_IS_SIGNED;
1498e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1499e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			free_token(token);
1500e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (read_expected(EVENT_OP, ";") < 0)
1501e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto fail_expect;
1502e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1503e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (read_expect_type(EVENT_NEWLINE, &token))
1504e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto fail;
1505e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
1506e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1507e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_token(token);
1508e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1509e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (field->flags & FIELD_IS_ARRAY) {
1510e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (field->arraylen)
1511e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				field->elementsize = field->size / field->arraylen;
1512e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			else if (field->flags & FIELD_IS_DYNAMIC)
1513e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				field->elementsize = size_dynamic;
1514e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			else if (field->flags & FIELD_IS_STRING)
1515e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				field->elementsize = 1;
1516e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			else if (field->flags & FIELD_IS_LONG)
1517e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				field->elementsize = event->pevent ?
1518e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						     event->pevent->long_size :
1519e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						     sizeof(long);
1520e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		} else
1521e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			field->elementsize = field->size;
1522e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1523e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*fields = field;
1524e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		fields = &field->next;
1525e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1526e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	} while (1);
1527e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1528e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
1529e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1530e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengfail:
1531e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
1532e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengfail_expect:
1533e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (field) {
1534e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(field->type);
1535e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(field->name);
1536e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(field);
1537e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
1538e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return -1;
1539e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1540e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1541e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int event_read_format(struct event_format *event)
1542e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1543e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *token;
1544e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int ret;
1545e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1546e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expected_item(EVENT_ITEM, "format") < 0)
1547e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
1548e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1549e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expected(EVENT_OP, ":") < 0)
1550e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
1551e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1552e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expect_type(EVENT_NEWLINE, &token))
1553e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto fail;
1554e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
1555e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1556e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ret = event_read_fields(event, &event->format.common_fields);
1557e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (ret < 0)
1558e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return ret;
1559e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	event->format.nr_common = ret;
1560e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1561e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ret = event_read_fields(event, &event->format.fields);
1562e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (ret < 0)
1563e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return ret;
1564e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	event->format.nr_fields = ret;
1565e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1566e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
1567e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1568e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng fail:
1569e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
1570e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return -1;
1571e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1572e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1573e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic enum event_type
1574e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengprocess_arg_token(struct event_format *event, struct print_arg *arg,
1575e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		  char **tok, enum event_type type);
1576e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1577e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic enum event_type
1578e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengprocess_arg(struct event_format *event, struct print_arg *arg, char **tok)
1579e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1580e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	enum event_type type;
1581e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *token;
1582e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1583e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = read_token(&token);
1584e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*tok = token;
1585e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1586e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return process_arg_token(event, arg, tok, type);
1587e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1588e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1589e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic enum event_type
1590e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengprocess_op(struct event_format *event, struct print_arg *arg, char **tok);
1591e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1592e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic enum event_type
1593e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengprocess_cond(struct event_format *event, struct print_arg *top, char **tok)
1594e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1595e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct print_arg *arg, *left, *right;
1596e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	enum event_type type;
1597e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *token = NULL;
1598e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1599e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	arg = alloc_arg();
1600e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	left = alloc_arg();
1601e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	right = alloc_arg();
1602e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1603e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!arg || !left || !right) {
1604e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		do_warning("%s: not enough memory!", __func__);
1605e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* arg will be freed at out_free */
1606e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_arg(left);
1607e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_arg(right);
1608e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_free;
1609e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
1610e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1611e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	arg->type = PRINT_OP;
1612e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	arg->op.left = left;
1613e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	arg->op.right = right;
1614e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1615e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*tok = NULL;
1616e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = process_arg(event, left, &token);
1617e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1618e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng again:
1619e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* Handle other operations in the arguments */
1620e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (type == EVENT_OP && strcmp(token, ":") != 0) {
1621e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = process_op(event, left, &token);
1622e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto again;
1623e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
1624e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1625e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (test_type_token(type, token, EVENT_OP, ":"))
1626e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_free;
1627e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1628e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	arg->op.op = token;
1629e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1630e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = process_arg(event, right, &token);
1631e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1632e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	top->op.right = arg;
1633e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1634e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*tok = token;
1635e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return type;
1636e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1637e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_free:
1638e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* Top may point to itself */
1639e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	top->op.right = NULL;
1640e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
1641e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_arg(arg);
1642e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return EVENT_ERROR;
1643e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1644e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1645e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic enum event_type
1646e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengprocess_array(struct event_format *event, struct print_arg *top, char **tok)
1647e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1648e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct print_arg *arg;
1649e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	enum event_type type;
1650e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *token = NULL;
1651e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1652e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	arg = alloc_arg();
1653e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!arg) {
1654e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		do_warning("%s: not enough memory!", __func__);
1655e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* '*tok' is set to top->op.op.  No need to free. */
1656e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*tok = NULL;
1657e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return EVENT_ERROR;
1658e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
1659e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1660e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*tok = NULL;
1661e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = process_arg(event, arg, &token);
1662e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (test_type_token(type, token, EVENT_OP, "]"))
1663e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_free;
1664e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1665e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	top->op.right = arg;
1666e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1667e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
1668e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = read_token_item(&token);
1669e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*tok = token;
1670e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1671e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return type;
1672e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1673e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_free:
1674e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
1675e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_arg(arg);
1676e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return EVENT_ERROR;
1677e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1678e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1679e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int get_op_prio(char *op)
1680e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1681e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!op[1]) {
1682e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		switch (op[0]) {
1683e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '~':
1684e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '!':
1685e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return 4;
1686e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '*':
1687e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '/':
1688e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '%':
1689e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return 6;
1690e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '+':
1691e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '-':
1692e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return 7;
1693e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			/* '>>' and '<<' are 8 */
1694e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '<':
1695e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '>':
1696e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return 9;
1697e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			/* '==' and '!=' are 10 */
1698e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '&':
1699e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return 11;
1700e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '^':
1701e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return 12;
1702e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '|':
1703e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return 13;
1704e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '?':
1705e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return 16;
1706e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		default:
1707e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			do_warning("unknown op '%c'", op[0]);
1708e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return -1;
1709e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
1710e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	} else {
1711e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (strcmp(op, "++") == 0 ||
1712e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		    strcmp(op, "--") == 0) {
1713e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return 3;
1714e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		} else if (strcmp(op, ">>") == 0 ||
1715e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			   strcmp(op, "<<") == 0) {
1716e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return 8;
1717e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		} else if (strcmp(op, ">=") == 0 ||
1718e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			   strcmp(op, "<=") == 0) {
1719e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return 9;
1720e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		} else if (strcmp(op, "==") == 0 ||
1721e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			   strcmp(op, "!=") == 0) {
1722e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return 10;
1723e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		} else if (strcmp(op, "&&") == 0) {
1724e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return 14;
1725e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		} else if (strcmp(op, "||") == 0) {
1726e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return 15;
1727e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		} else {
1728e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			do_warning("unknown op '%s'", op);
1729e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return -1;
1730e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
1731e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
1732e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1733e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1734e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int set_op_prio(struct print_arg *arg)
1735e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1736e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1737e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* single ops are the greatest */
1738e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!arg->op.left || arg->op.left->type == PRINT_NULL)
1739e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->op.prio = 0;
1740e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	else
1741e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->op.prio = get_op_prio(arg->op.op);
1742e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1743e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return arg->op.prio;
1744e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1745e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1746e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/* Note, *tok does not get freed, but will most likely be saved */
1747e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic enum event_type
1748e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengprocess_op(struct event_format *event, struct print_arg *arg, char **tok)
1749e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1750e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct print_arg *left, *right = NULL;
1751e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	enum event_type type;
1752e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *token;
1753e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1754e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* the op is passed in via tok */
1755e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	token = *tok;
1756e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1757e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (arg->type == PRINT_OP && !arg->op.left) {
1758e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* handle single op */
1759e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (token[1]) {
1760e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			do_warning("bad op token %s", token);
1761e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto out_free;
1762e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
1763e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		switch (token[0]) {
1764e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '~':
1765e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '!':
1766e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '+':
1767e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '-':
1768e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
1769e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		default:
1770e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			do_warning("bad op token %s", token);
1771e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto out_free;
1772e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1773e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
1774e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1775e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* make an empty left */
1776e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		left = alloc_arg();
1777e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!left)
1778e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto out_warn_free;
1779e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1780e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		left->type = PRINT_NULL;
1781e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->op.left = left;
1782e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1783e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		right = alloc_arg();
1784e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!right)
1785e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto out_warn_free;
1786e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1787e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->op.right = right;
1788e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1789e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* do not free the token, it belongs to an op */
1790e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*tok = NULL;
1791e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = process_arg(event, right, tok);
1792e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1793e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	} else if (strcmp(token, "?") == 0) {
1794e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1795e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		left = alloc_arg();
1796e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!left)
1797e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto out_warn_free;
1798e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1799e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* copy the top arg to the left */
1800e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*left = *arg;
1801e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1802e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->type = PRINT_OP;
1803e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->op.op = token;
1804e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->op.left = left;
1805e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->op.prio = 0;
1806e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1807e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* it will set arg->op.right */
1808e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = process_cond(event, arg, tok);
1809e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1810e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	} else if (strcmp(token, ">>") == 0 ||
1811e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		   strcmp(token, "<<") == 0 ||
1812e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		   strcmp(token, "&") == 0 ||
1813e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		   strcmp(token, "|") == 0 ||
1814e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		   strcmp(token, "&&") == 0 ||
1815e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		   strcmp(token, "||") == 0 ||
1816e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		   strcmp(token, "-") == 0 ||
1817e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		   strcmp(token, "+") == 0 ||
1818e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		   strcmp(token, "*") == 0 ||
1819e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		   strcmp(token, "^") == 0 ||
1820e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		   strcmp(token, "/") == 0 ||
1821e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		   strcmp(token, "<") == 0 ||
1822e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		   strcmp(token, ">") == 0 ||
1823e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		   strcmp(token, "<=") == 0 ||
1824e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		   strcmp(token, ">=") == 0 ||
1825e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		   strcmp(token, "==") == 0 ||
1826e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		   strcmp(token, "!=") == 0) {
1827e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1828e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		left = alloc_arg();
1829e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!left)
1830e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto out_warn_free;
1831e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1832e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* copy the top arg to the left */
1833e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*left = *arg;
1834e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1835e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->type = PRINT_OP;
1836e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->op.op = token;
1837e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->op.left = left;
1838e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->op.right = NULL;
1839e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1840e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (set_op_prio(arg) == -1) {
1841e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			event->flags |= EVENT_FL_FAILED;
1842e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			/* arg->op.op (= token) will be freed at out_free */
1843e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			arg->op.op = NULL;
1844e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto out_free;
1845e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
1846e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1847e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = read_token_item(&token);
1848e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*tok = token;
1849e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1850e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* could just be a type pointer */
1851e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if ((strcmp(arg->op.op, "*") == 0) &&
1852e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		    type == EVENT_DELIM && (strcmp(token, ")") == 0)) {
1853e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			char *new_atom;
1854e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1855e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (left->type != PRINT_ATOM) {
1856e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				do_warning("bad pointer type");
1857e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto out_free;
1858e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
1859e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			new_atom = realloc(left->atom.atom,
1860e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					    strlen(left->atom.atom) + 3);
1861e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!new_atom)
1862e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto out_warn_free;
1863e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1864e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			left->atom.atom = new_atom;
1865e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			strcat(left->atom.atom, " *");
1866e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			free(arg->op.op);
1867e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			*arg = *left;
1868e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			free(left);
1869e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1870e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return type;
1871e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
1872e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1873e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		right = alloc_arg();
1874e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!right)
1875e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto out_warn_free;
1876e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1877e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = process_arg_token(event, right, tok, type);
1878e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->op.right = right;
1879e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1880e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	} else if (strcmp(token, "[") == 0) {
1881e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1882e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		left = alloc_arg();
1883e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!left)
1884e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto out_warn_free;
1885e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1886e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*left = *arg;
1887e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1888e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->type = PRINT_OP;
1889e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->op.op = token;
1890e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->op.left = left;
1891e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1892e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->op.prio = 0;
1893e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1894e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* it will set arg->op.right */
1895e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = process_array(event, arg, tok);
1896e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1897e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	} else {
1898e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		do_warning("unknown op '%s'", token);
1899e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		event->flags |= EVENT_FL_FAILED;
1900e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* the arg is now the left side */
1901e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_free;
1902e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
1903e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1904e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (type == EVENT_OP && strcmp(*tok, ":") != 0) {
1905e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		int prio;
1906e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1907e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* higher prios need to be closer to the root */
1908e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		prio = get_op_prio(*tok);
1909e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1910e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (prio > arg->op.prio)
1911e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return process_op(event, arg, tok);
1912e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1913e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return process_op(event, right, tok);
1914e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
1915e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1916e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return type;
1917e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1918e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_warn_free:
1919e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	do_warning("%s: not enough memory!", __func__);
1920e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_free:
1921e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
1922e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*tok = NULL;
1923e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return EVENT_ERROR;
1924e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1925e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1926e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic enum event_type
1927e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengprocess_entry(struct event_format *event __maybe_unused, struct print_arg *arg,
1928e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	      char **tok)
1929e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1930e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	enum event_type type;
1931e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *field;
1932e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *token;
1933e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1934e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expected(EVENT_OP, "->") < 0)
1935e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_err;
1936e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1937e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expect_type(EVENT_ITEM, &token) < 0)
1938e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_free;
1939e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	field = token;
1940e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1941e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	arg->type = PRINT_FIELD;
1942e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	arg->field.name = field;
1943e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1944e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (is_flag_field) {
1945e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->field.field = pevent_find_any_field(event, arg->field.name);
1946e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->field.field->flags |= FIELD_IS_FLAG;
1947e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		is_flag_field = 0;
1948e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	} else if (is_symbolic_field) {
1949e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->field.field = pevent_find_any_field(event, arg->field.name);
1950e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->field.field->flags |= FIELD_IS_SYMBOLIC;
1951e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		is_symbolic_field = 0;
1952e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
1953e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1954e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = read_token(&token);
1955e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*tok = token;
1956e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1957e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return type;
1958e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1959e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng out_free:
1960e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
1961e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng out_err:
1962e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*tok = NULL;
1963e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return EVENT_ERROR;
1964e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1965e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1966e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic char *arg_eval (struct print_arg *arg);
1967e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1968e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic unsigned long long
1969e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengeval_type_str(unsigned long long val, const char *type, int pointer)
1970e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1971e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int sign = 0;
1972e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *ref;
1973e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int len;
1974e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1975e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	len = strlen(type);
1976e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1977e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (pointer) {
1978e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1979e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (type[len-1] != '*') {
1980e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			do_warning("pointer expected with non pointer type");
1981e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return val;
1982e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
1983e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1984e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ref = malloc(len);
1985e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!ref) {
1986e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			do_warning("%s: not enough memory!", __func__);
1987e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return val;
1988e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
1989e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		memcpy(ref, type, len);
1990e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1991e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* chop off the " *" */
1992e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ref[len - 2] = 0;
1993e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1994e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		val = eval_type_str(val, ref, 0);
1995e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(ref);
1996e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return val;
1997e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
1998e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1999e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* check if this is a pointer */
2000e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (type[len - 1] == '*')
2001e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return val;
2002e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2003e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* Try to figure out the arg size*/
2004e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (strncmp(type, "struct", 6) == 0)
2005e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* all bets off */
2006e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return val;
2007e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2008e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (strcmp(type, "u8") == 0)
2009e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return val & 0xff;
2010e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2011e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (strcmp(type, "u16") == 0)
2012e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return val & 0xffff;
2013e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2014e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (strcmp(type, "u32") == 0)
2015e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return val & 0xffffffff;
2016e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2017e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (strcmp(type, "u64") == 0 ||
2018e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    strcmp(type, "s64"))
2019e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return val;
2020e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2021e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (strcmp(type, "s8") == 0)
2022e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return (unsigned long long)(char)val & 0xff;
2023e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2024e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (strcmp(type, "s16") == 0)
2025e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return (unsigned long long)(short)val & 0xffff;
2026e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2027e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (strcmp(type, "s32") == 0)
2028e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return (unsigned long long)(int)val & 0xffffffff;
2029e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2030e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (strncmp(type, "unsigned ", 9) == 0) {
2031e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		sign = 0;
2032e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type += 9;
2033e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
2034e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2035e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (strcmp(type, "char") == 0) {
2036e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (sign)
2037e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return (unsigned long long)(char)val & 0xff;
2038e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		else
2039e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return val & 0xff;
2040e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
2041e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2042e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (strcmp(type, "short") == 0) {
2043e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (sign)
2044e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return (unsigned long long)(short)val & 0xffff;
2045e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		else
2046e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return val & 0xffff;
2047e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
2048e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2049e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (strcmp(type, "int") == 0) {
2050e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (sign)
2051e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return (unsigned long long)(int)val & 0xffffffff;
2052e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		else
2053e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return val & 0xffffffff;
2054e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
2055e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2056e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return val;
2057e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
2058e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2059e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/*
2060e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Try to figure out the type.
2061e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
2062e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic unsigned long long
2063e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengeval_type(unsigned long long val, struct print_arg *arg, int pointer)
2064e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
2065e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (arg->type != PRINT_TYPE) {
2066e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		do_warning("expected type argument");
2067e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 0;
2068e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
2069e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2070e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return eval_type_str(val, arg->typecast.type, pointer);
2071e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
2072e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2073e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int arg_num_eval(struct print_arg *arg, long long *val)
2074e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
2075e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	long long left, right;
2076e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int ret = 1;
2077e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2078e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	switch (arg->type) {
2079e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_ATOM:
2080e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*val = strtoll(arg->atom.atom, NULL, 0);
2081e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
2082e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_TYPE:
2083e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ret = arg_num_eval(arg->typecast.item, val);
2084e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!ret)
2085e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
2086e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*val = eval_type(*val, arg, 0);
2087e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
2088e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_OP:
2089e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		switch (arg->op.op[0]) {
2090e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '|':
2091e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			ret = arg_num_eval(arg->op.left, &left);
2092e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!ret)
2093e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
2094e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			ret = arg_num_eval(arg->op.right, &right);
2095e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!ret)
2096e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
2097e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (arg->op.op[1])
2098e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				*val = left || right;
2099e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			else
2100e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				*val = left | right;
2101e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
2102e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '&':
2103e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			ret = arg_num_eval(arg->op.left, &left);
2104e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!ret)
2105e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
2106e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			ret = arg_num_eval(arg->op.right, &right);
2107e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!ret)
2108e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
2109e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (arg->op.op[1])
2110e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				*val = left && right;
2111e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			else
2112e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				*val = left & right;
2113e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
2114e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '<':
2115e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			ret = arg_num_eval(arg->op.left, &left);
2116e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!ret)
2117e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
2118e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			ret = arg_num_eval(arg->op.right, &right);
2119e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!ret)
2120e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
2121e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			switch (arg->op.op[1]) {
2122e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case 0:
2123e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				*val = left < right;
2124e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
2125e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case '<':
2126e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				*val = left << right;
2127e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
2128e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case '=':
2129e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				*val = left <= right;
2130e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
2131e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			default:
2132e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				do_warning("unknown op '%s'", arg->op.op);
2133e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				ret = 0;
2134e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
2135e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
2136e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '>':
2137e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			ret = arg_num_eval(arg->op.left, &left);
2138e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!ret)
2139e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
2140e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			ret = arg_num_eval(arg->op.right, &right);
2141e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!ret)
2142e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
2143e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			switch (arg->op.op[1]) {
2144e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case 0:
2145e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				*val = left > right;
2146e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
2147e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case '>':
2148e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				*val = left >> right;
2149e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
2150e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case '=':
2151e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				*val = left >= right;
2152e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
2153e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			default:
2154e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				do_warning("unknown op '%s'", arg->op.op);
2155e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				ret = 0;
2156e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
2157e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
2158e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '=':
2159e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			ret = arg_num_eval(arg->op.left, &left);
2160e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!ret)
2161e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
2162e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			ret = arg_num_eval(arg->op.right, &right);
2163e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!ret)
2164e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
2165e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2166e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (arg->op.op[1] != '=') {
2167e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				do_warning("unknown op '%s'", arg->op.op);
2168e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				ret = 0;
2169e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			} else
2170e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				*val = left == right;
2171e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
2172e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '!':
2173e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			ret = arg_num_eval(arg->op.left, &left);
2174e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!ret)
2175e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
2176e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			ret = arg_num_eval(arg->op.right, &right);
2177e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!ret)
2178e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
2179e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2180e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			switch (arg->op.op[1]) {
2181e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case '=':
2182e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				*val = left != right;
2183e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
2184e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			default:
2185e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				do_warning("unknown op '%s'", arg->op.op);
2186e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				ret = 0;
2187e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
2188e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
2189e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '-':
2190e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			/* check for negative */
2191e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (arg->op.left->type == PRINT_NULL)
2192e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				left = 0;
2193e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			else
2194e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				ret = arg_num_eval(arg->op.left, &left);
2195e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!ret)
2196e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
2197e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			ret = arg_num_eval(arg->op.right, &right);
2198e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!ret)
2199e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
2200e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			*val = left - right;
2201e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
2202e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '+':
2203e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (arg->op.left->type == PRINT_NULL)
2204e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				left = 0;
2205e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			else
2206e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				ret = arg_num_eval(arg->op.left, &left);
2207e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!ret)
2208e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
2209e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			ret = arg_num_eval(arg->op.right, &right);
2210e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!ret)
2211e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
2212e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			*val = left + right;
2213e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
2214e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		default:
2215e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			do_warning("unknown op '%s'", arg->op.op);
2216e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			ret = 0;
2217e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
2218e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
2219e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2220e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_NULL:
2221e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_FIELD ... PRINT_SYMBOL:
2222e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_STRING:
2223e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_BSTRING:
2224e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	default:
2225e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		do_warning("invalid eval type %d", arg->type);
2226e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ret = 0;
2227e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2228e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
2229e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return ret;
2230e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
2231e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2232e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic char *arg_eval (struct print_arg *arg)
2233e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
2234e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	long long val;
2235e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	static char buf[20];
2236e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2237e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	switch (arg->type) {
2238e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_ATOM:
2239e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return arg->atom.atom;
2240e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_TYPE:
2241e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return arg_eval(arg->typecast.item);
2242e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_OP:
2243e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!arg_num_eval(arg, &val))
2244e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
2245e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		sprintf(buf, "%lld", val);
2246e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return buf;
2247e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2248e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_NULL:
2249e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_FIELD ... PRINT_SYMBOL:
2250e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_STRING:
2251e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_BSTRING:
2252e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	default:
2253e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		do_warning("invalid eval type %d", arg->type);
2254e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
2255e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
2256e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2257e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return NULL;
2258e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
2259e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2260e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic enum event_type
2261e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengprocess_fields(struct event_format *event, struct print_flag_sym **list, char **tok)
2262e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
2263e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	enum event_type type;
2264e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct print_arg *arg = NULL;
2265e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct print_flag_sym *field;
2266e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *token = *tok;
2267e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *value;
2268e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2269e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	do {
2270e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_token(token);
2271e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = read_token_item(&token);
2272e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (test_type_token(type, token, EVENT_OP, "{"))
2273e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
2274e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2275e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg = alloc_arg();
2276e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!arg)
2277e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto out_free;
2278e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2279e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_token(token);
2280e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = process_arg(event, arg, &token);
2281e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2282e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (type == EVENT_OP)
2283e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			type = process_op(event, arg, &token);
2284e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2285e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (type == EVENT_ERROR)
2286e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto out_free;
2287e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2288e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (test_type_token(type, token, EVENT_DELIM, ","))
2289e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto out_free;
2290e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2291e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		field = calloc(1, sizeof(*field));
2292e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!field)
2293e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto out_free;
2294e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2295e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		value = arg_eval(arg);
2296e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (value == NULL)
2297e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto out_free_field;
2298e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		field->value = strdup(value);
2299e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (field->value == NULL)
2300e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto out_free_field;
2301e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2302e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_arg(arg);
2303e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg = alloc_arg();
2304e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!arg)
2305e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto out_free;
2306e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2307e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_token(token);
2308e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = process_arg(event, arg, &token);
2309e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (test_type_token(type, token, EVENT_OP, "}"))
2310e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto out_free_field;
2311e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2312e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		value = arg_eval(arg);
2313e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (value == NULL)
2314e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto out_free_field;
2315e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		field->str = strdup(value);
2316e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (field->str == NULL)
2317e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto out_free_field;
2318e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_arg(arg);
2319e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg = NULL;
2320e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2321e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*list = field;
2322e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		list = &field->next;
2323e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2324e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_token(token);
2325e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = read_token_item(&token);
2326e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	} while (type == EVENT_DELIM && strcmp(token, ",") == 0);
2327e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2328e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*tok = token;
2329e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return type;
2330e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2331e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_free_field:
2332e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_flag_sym(field);
2333e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_free:
2334e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_arg(arg);
2335e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
2336e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*tok = NULL;
2337e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2338e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return EVENT_ERROR;
2339e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
2340e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2341e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic enum event_type
2342e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengprocess_flags(struct event_format *event, struct print_arg *arg, char **tok)
2343e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
2344e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct print_arg *field;
2345e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	enum event_type type;
2346e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *token;
2347e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2348e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	memset(arg, 0, sizeof(*arg));
2349e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	arg->type = PRINT_FLAGS;
2350e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2351e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	field = alloc_arg();
2352e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!field) {
2353e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		do_warning("%s: not enough memory!", __func__);
2354e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_free;
2355e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
2356e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2357e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = process_arg(event, field, &token);
2358e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2359e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* Handle operations in the first argument */
2360e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (type == EVENT_OP)
2361e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = process_op(event, field, &token);
2362e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2363e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (test_type_token(type, token, EVENT_DELIM, ","))
2364e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_free_field;
2365e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
2366e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2367e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	arg->flags.field = field;
2368e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2369e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = read_token_item(&token);
2370e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (event_item_type(type)) {
2371e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->flags.delim = token;
2372e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = read_token_item(&token);
2373e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
2374e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2375e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (test_type_token(type, token, EVENT_DELIM, ","))
2376e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_free;
2377e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2378e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = process_fields(event, &arg->flags.flags, &token);
2379e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (test_type_token(type, token, EVENT_DELIM, ")"))
2380e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_free;
2381e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2382e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
2383e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = read_token_item(tok);
2384e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return type;
2385e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2386e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_free_field:
2387e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_arg(field);
2388e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_free:
2389e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
2390e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*tok = NULL;
2391e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return EVENT_ERROR;
2392e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
2393e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2394e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic enum event_type
2395e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengprocess_symbols(struct event_format *event, struct print_arg *arg, char **tok)
2396e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
2397e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct print_arg *field;
2398e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	enum event_type type;
2399e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *token;
2400e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2401e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	memset(arg, 0, sizeof(*arg));
2402e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	arg->type = PRINT_SYMBOL;
2403e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2404e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	field = alloc_arg();
2405e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!field) {
2406e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		do_warning("%s: not enough memory!", __func__);
2407e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_free;
2408e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
2409e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2410e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = process_arg(event, field, &token);
2411e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (test_type_token(type, token, EVENT_DELIM, ","))
2412e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_free_field;
2413e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2414e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	arg->symbol.field = field;
2415e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2416e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = process_fields(event, &arg->symbol.symbols, &token);
2417e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (test_type_token(type, token, EVENT_DELIM, ")"))
2418e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_free;
2419e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2420e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
2421e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = read_token_item(tok);
2422e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return type;
2423e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2424e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_free_field:
2425e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_arg(field);
2426e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_free:
2427e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
2428e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*tok = NULL;
2429e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return EVENT_ERROR;
2430e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
2431e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2432e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic enum event_type
2433e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengprocess_hex(struct event_format *event, struct print_arg *arg, char **tok)
2434e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
2435e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct print_arg *field;
2436e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	enum event_type type;
2437e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *token;
2438e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2439e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	memset(arg, 0, sizeof(*arg));
2440e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	arg->type = PRINT_HEX;
2441e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2442e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	field = alloc_arg();
2443e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!field) {
2444e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		do_warning("%s: not enough memory!", __func__);
2445e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_free;
2446e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
2447e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2448e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = process_arg(event, field, &token);
2449e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2450e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (test_type_token(type, token, EVENT_DELIM, ","))
2451e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_free;
2452e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2453e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	arg->hex.field = field;
2454e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2455e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
2456e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2457e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	field = alloc_arg();
2458e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!field) {
2459e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		do_warning("%s: not enough memory!", __func__);
2460e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*tok = NULL;
2461e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return EVENT_ERROR;
2462e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
2463e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2464e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = process_arg(event, field, &token);
2465e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2466e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (test_type_token(type, token, EVENT_DELIM, ")"))
2467e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_free;
2468e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2469e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	arg->hex.size = field;
2470e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2471e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
2472e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = read_token_item(tok);
2473e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return type;
2474e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2475e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng out_free:
2476e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_arg(field);
2477e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
2478e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*tok = NULL;
2479e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return EVENT_ERROR;
2480e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
2481e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2482e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic enum event_type
2483e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengprocess_dynamic_array(struct event_format *event, struct print_arg *arg, char **tok)
2484e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
2485e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct format_field *field;
2486e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	enum event_type type;
2487e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *token;
2488e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2489e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	memset(arg, 0, sizeof(*arg));
2490e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	arg->type = PRINT_DYNAMIC_ARRAY;
2491e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2492e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/*
2493e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 * The item within the parenthesis is another field that holds
2494e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 * the index into where the array starts.
2495e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 */
2496e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = read_token(&token);
2497e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*tok = token;
2498e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (type != EVENT_ITEM)
2499e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_free;
2500e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2501e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* Find the field */
2502e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2503e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	field = pevent_find_field(event, token);
2504e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!field)
2505e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_free;
2506e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2507e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	arg->dynarray.field = field;
2508e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	arg->dynarray.index = 0;
2509e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2510e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expected(EVENT_DELIM, ")") < 0)
2511e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_free;
2512e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2513e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
2514e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = read_token_item(&token);
2515e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*tok = token;
2516e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (type != EVENT_OP || strcmp(token, "[") != 0)
2517e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return type;
2518e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2519e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
2520e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	arg = alloc_arg();
2521e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!arg) {
2522e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		do_warning("%s: not enough memory!", __func__);
2523e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*tok = NULL;
2524e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return EVENT_ERROR;
2525e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
2526e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2527e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = process_arg(event, arg, &token);
2528e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (type == EVENT_ERROR)
2529e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_free_arg;
2530e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2531e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!test_type_token(type, token, EVENT_OP, "]"))
2532e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_free_arg;
2533e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2534e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
2535e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = read_token_item(tok);
2536e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return type;
2537e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2538e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng out_free_arg:
2539e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_arg(arg);
2540e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng out_free:
2541e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
2542e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*tok = NULL;
2543e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return EVENT_ERROR;
2544e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
2545e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2546e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic enum event_type
2547e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengprocess_paren(struct event_format *event, struct print_arg *arg, char **tok)
2548e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
2549e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct print_arg *item_arg;
2550e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	enum event_type type;
2551e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *token;
2552e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2553e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = process_arg(event, arg, &token);
2554e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2555e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (type == EVENT_ERROR)
2556e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_free;
2557e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2558e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (type == EVENT_OP)
2559e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = process_op(event, arg, &token);
2560e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2561e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (type == EVENT_ERROR)
2562e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_free;
2563e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2564e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (test_type_token(type, token, EVENT_DELIM, ")"))
2565e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_free;
2566e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2567e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
2568e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = read_token_item(&token);
2569e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2570e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/*
2571e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 * If the next token is an item or another open paren, then
2572e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 * this was a typecast.
2573e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 */
2574e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (event_item_type(type) ||
2575e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    (type == EVENT_DELIM && strcmp(token, "(") == 0)) {
2576e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2577e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* make this a typecast and contine */
2578e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2579e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* prevous must be an atom */
2580e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (arg->type != PRINT_ATOM) {
2581e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			do_warning("previous needed to be PRINT_ATOM");
2582e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto out_free;
2583e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
2584e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2585e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		item_arg = alloc_arg();
2586e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!item_arg) {
2587e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			do_warning("%s: not enough memory!", __func__);
2588e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto out_free;
2589e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
2590e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2591e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->type = PRINT_TYPE;
2592e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->typecast.type = arg->atom.atom;
2593e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->typecast.item = item_arg;
2594e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = process_arg_token(event, item_arg, &token, type);
2595e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2596e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
2597e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2598e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*tok = token;
2599e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return type;
2600e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2601e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng out_free:
2602e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
2603e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*tok = NULL;
2604e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return EVENT_ERROR;
2605e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
2606e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2607e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2608e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic enum event_type
2609e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengprocess_str(struct event_format *event __maybe_unused, struct print_arg *arg,
2610e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    char **tok)
2611e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
2612e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	enum event_type type;
2613e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *token;
2614e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2615e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expect_type(EVENT_ITEM, &token) < 0)
2616e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_free;
2617e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2618e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	arg->type = PRINT_STRING;
2619e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	arg->string.string = token;
2620e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	arg->string.offset = -1;
2621e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2622e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expected(EVENT_DELIM, ")") < 0)
2623e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_err;
2624e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2625e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = read_token(&token);
2626e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*tok = token;
2627e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2628e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return type;
2629e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2630e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng out_free:
2631e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
2632e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng out_err:
2633e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*tok = NULL;
2634e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return EVENT_ERROR;
2635e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
2636e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2637e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic struct pevent_function_handler *
2638e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengfind_func_handler(struct pevent *pevent, char *func_name)
2639e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
2640e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pevent_function_handler *func;
2641e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2642e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!pevent)
2643e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
2644e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2645e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (func = pevent->func_handlers; func; func = func->next) {
2646e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (strcmp(func->name, func_name) == 0)
2647e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
2648e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
2649e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2650e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return func;
2651e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
2652e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2653e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void remove_func_handler(struct pevent *pevent, char *func_name)
2654e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
2655e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pevent_function_handler *func;
2656e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pevent_function_handler **next;
2657e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2658e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	next = &pevent->func_handlers;
2659e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while ((func = *next)) {
2660e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (strcmp(func->name, func_name) == 0) {
2661e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			*next = func->next;
2662e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			free_func_handle(func);
2663e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
2664e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
2665e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		next = &func->next;
2666e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
2667e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
2668e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2669e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic enum event_type
2670e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengprocess_func_handler(struct event_format *event, struct pevent_function_handler *func,
2671e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		     struct print_arg *arg, char **tok)
2672e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
2673e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct print_arg **next_arg;
2674e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct print_arg *farg;
2675e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	enum event_type type;
2676e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *token;
2677e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const char *test;
2678e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int i;
2679e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2680e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	arg->type = PRINT_FUNC;
2681e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	arg->func.func = func;
2682e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2683e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*tok = NULL;
2684e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2685e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	next_arg = &(arg->func.args);
2686e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (i = 0; i < func->nr_args; i++) {
2687e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		farg = alloc_arg();
2688e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!farg) {
2689e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			do_warning("%s: not enough memory!", __func__);
2690e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return EVENT_ERROR;
2691e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
2692e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2693e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = process_arg(event, farg, &token);
2694e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (i < (func->nr_args - 1))
2695e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			test = ",";
2696e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		else
2697e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			test = ")";
2698e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2699e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (test_type_token(type, token, EVENT_DELIM, test)) {
2700e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			free_arg(farg);
2701e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			free_token(token);
2702e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return EVENT_ERROR;
2703e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
2704e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2705e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*next_arg = farg;
2706e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		next_arg = &(farg->next);
2707e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_token(token);
2708e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
2709e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2710e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = read_token(&token);
2711e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*tok = token;
2712e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2713e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return type;
2714e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
2715e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2716e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic enum event_type
2717e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengprocess_function(struct event_format *event, struct print_arg *arg,
2718e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 char *token, char **tok)
2719e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
2720e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pevent_function_handler *func;
2721e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2722e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (strcmp(token, "__print_flags") == 0) {
2723e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_token(token);
2724e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		is_flag_field = 1;
2725e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return process_flags(event, arg, tok);
2726e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
2727e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (strcmp(token, "__print_symbolic") == 0) {
2728e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_token(token);
2729e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		is_symbolic_field = 1;
2730e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return process_symbols(event, arg, tok);
2731e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
2732e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (strcmp(token, "__print_hex") == 0) {
2733e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_token(token);
2734e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return process_hex(event, arg, tok);
2735e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
2736e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (strcmp(token, "__get_str") == 0) {
2737e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_token(token);
2738e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return process_str(event, arg, tok);
2739e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
2740e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (strcmp(token, "__get_dynamic_array") == 0) {
2741e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_token(token);
2742e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return process_dynamic_array(event, arg, tok);
2743e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
2744e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2745e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	func = find_func_handler(event->pevent, token);
2746e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (func) {
2747e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_token(token);
2748e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return process_func_handler(event, func, arg, tok);
2749e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
2750e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2751e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	do_warning("function %s not defined", token);
2752e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
2753e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return EVENT_ERROR;
2754e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
2755e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2756e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic enum event_type
2757e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengprocess_arg_token(struct event_format *event, struct print_arg *arg,
2758e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		  char **tok, enum event_type type)
2759e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
2760e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *token;
2761e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *atom;
2762e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2763e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	token = *tok;
2764e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2765e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	switch (type) {
2766e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case EVENT_ITEM:
2767e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (strcmp(token, "REC") == 0) {
2768e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			free_token(token);
2769e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			type = process_entry(event, arg, &token);
2770e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
2771e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
2772e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		atom = token;
2773e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* test the next token */
2774e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = read_token_item(&token);
2775e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2776e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/*
2777e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 * If the next token is a parenthesis, then this
2778e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 * is a function.
2779e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 */
2780e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (type == EVENT_DELIM && strcmp(token, "(") == 0) {
2781e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			free_token(token);
2782e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			token = NULL;
2783e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			/* this will free atom. */
2784e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			type = process_function(event, arg, atom, &token);
2785e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
2786e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
2787e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* atoms can be more than one token long */
2788e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		while (type == EVENT_ITEM) {
2789e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			char *new_atom;
2790e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			new_atom = realloc(atom,
2791e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					   strlen(atom) + strlen(token) + 2);
2792e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!new_atom) {
2793e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				free(atom);
2794e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				*tok = NULL;
2795e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				free_token(token);
2796e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				return EVENT_ERROR;
2797e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
2798e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			atom = new_atom;
2799e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			strcat(atom, " ");
2800e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			strcat(atom, token);
2801e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			free_token(token);
2802e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			type = read_token_item(&token);
2803e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
2804e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2805e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->type = PRINT_ATOM;
2806e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->atom.atom = atom;
2807e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
2808e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2809e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case EVENT_DQUOTE:
2810e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case EVENT_SQUOTE:
2811e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->type = PRINT_ATOM;
2812e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->atom.atom = token;
2813e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = read_token_item(&token);
2814e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
2815e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case EVENT_DELIM:
2816e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (strcmp(token, "(") == 0) {
2817e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			free_token(token);
2818e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			type = process_paren(event, arg, &token);
2819e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
2820e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
2821e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case EVENT_OP:
2822e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* handle single ops */
2823e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->type = PRINT_OP;
2824e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->op.op = token;
2825e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->op.left = NULL;
2826e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = process_op(event, arg, &token);
2827e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2828e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* On error, the op is freed */
2829e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (type == EVENT_ERROR)
2830e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			arg->op.op = NULL;
2831e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2832e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* return error type if errored */
2833e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
2834e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2835e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case EVENT_ERROR ... EVENT_NEWLINE:
2836e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	default:
2837e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		do_warning("unexpected type %d", type);
2838e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return EVENT_ERROR;
2839e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
2840e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*tok = token;
2841e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2842e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return type;
2843e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
2844e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2845e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int event_read_print_args(struct event_format *event, struct print_arg **list)
2846e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
2847e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	enum event_type type = EVENT_ERROR;
2848e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct print_arg *arg;
2849e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *token;
2850e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int args = 0;
2851e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2852e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	do {
2853e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (type == EVENT_NEWLINE) {
2854e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			type = read_token_item(&token);
2855e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			continue;
2856e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
2857e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2858e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg = alloc_arg();
2859e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!arg) {
2860e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			do_warning("%s: not enough memory!", __func__);
2861e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return -1;
2862e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
2863e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2864e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = process_arg(event, arg, &token);
2865e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2866e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (type == EVENT_ERROR) {
2867e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			free_token(token);
2868e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			free_arg(arg);
2869e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return -1;
2870e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
2871e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2872e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*list = arg;
2873e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		args++;
2874e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2875e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (type == EVENT_OP) {
2876e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			type = process_op(event, arg, &token);
2877e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			free_token(token);
2878e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (type == EVENT_ERROR) {
2879e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				*list = NULL;
2880e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				free_arg(arg);
2881e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				return -1;
2882e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
2883e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			list = &arg->next;
2884e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			continue;
2885e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
2886e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2887e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (type == EVENT_DELIM && strcmp(token, ",") == 0) {
2888e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			free_token(token);
2889e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			*list = arg;
2890e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			list = &arg->next;
2891e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			continue;
2892e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
2893e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
2894e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	} while (type != EVENT_NONE);
2895e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2896e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (type != EVENT_NONE && type != EVENT_ERROR)
2897e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_token(token);
2898e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2899e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return args;
2900e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
2901e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2902e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int event_read_print(struct event_format *event)
2903e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
2904e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	enum event_type type;
2905e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *token;
2906e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int ret;
2907e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2908e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expected_item(EVENT_ITEM, "print") < 0)
2909e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
2910e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2911e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expected(EVENT_ITEM, "fmt") < 0)
2912e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
2913e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2914e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expected(EVENT_OP, ":") < 0)
2915e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
2916e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2917e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expect_type(EVENT_DQUOTE, &token) < 0)
2918e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto fail;
2919e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2920e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng concat:
2921e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	event->print_fmt.format = token;
2922e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	event->print_fmt.args = NULL;
2923e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2924e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* ok to have no arg */
2925e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = read_token_item(&token);
2926e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2927e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (type == EVENT_NONE)
2928e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 0;
2929e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2930e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* Handle concatenation of print lines */
2931e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (type == EVENT_DQUOTE) {
2932e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		char *cat;
2933e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2934e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (asprintf(&cat, "%s%s", event->print_fmt.format, token) < 0)
2935e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto fail;
2936e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_token(token);
2937e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_token(event->print_fmt.format);
2938e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		event->print_fmt.format = NULL;
2939e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		token = cat;
2940e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto concat;
2941e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
2942e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2943e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (test_type_token(type, token, EVENT_DELIM, ","))
2944e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto fail;
2945e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2946e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
2947e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2948e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ret = event_read_print_args(event, &event->print_fmt.args);
2949e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (ret < 0)
2950e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
2951e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2952e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return ret;
2953e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2954e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng fail:
2955e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
2956e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return -1;
2957e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
2958e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2959e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
2960e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_find_common_field - return a common field by event
2961e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @event: handle for the event
2962e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @name: the name of the common field to return
2963e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
2964e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Returns a common field from the event by the given @name.
2965e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This only searchs the common fields and not all field.
2966e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
2967e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct format_field *
2968e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengpevent_find_common_field(struct event_format *event, const char *name)
2969e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
2970e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct format_field *format;
2971e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2972e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (format = event->format.common_fields;
2973e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	     format; format = format->next) {
2974e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (strcmp(format->name, name) == 0)
2975e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
2976e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
2977e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2978e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return format;
2979e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
2980e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2981e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
2982e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_find_field - find a non-common field
2983e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @event: handle for the event
2984e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @name: the name of the non-common field
2985e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
2986e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Returns a non-common field by the given @name.
2987e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This does not search common fields.
2988e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
2989e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct format_field *
2990e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengpevent_find_field(struct event_format *event, const char *name)
2991e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
2992e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct format_field *format;
2993e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
2994e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (format = event->format.fields;
2995e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	     format; format = format->next) {
2996e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (strcmp(format->name, name) == 0)
2997e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
2998e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
2999e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3000e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return format;
3001e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
3002e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3003e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
3004e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_find_any_field - find any field by name
3005e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @event: handle for the event
3006e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @name: the name of the field
3007e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
3008e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Returns a field by the given @name.
3009e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This searchs the common field names first, then
3010e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * the non-common ones if a common one was not found.
3011e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
3012e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct format_field *
3013e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengpevent_find_any_field(struct event_format *event, const char *name)
3014e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
3015e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct format_field *format;
3016e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3017e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	format = pevent_find_common_field(event, name);
3018e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (format)
3019e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return format;
3020e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return pevent_find_field(event, name);
3021e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
3022e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3023e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
3024e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_read_number - read a number from data
3025e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @pevent: handle for the pevent
3026e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @ptr: the raw data
3027e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @size: the size of the data that holds the number
3028e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
3029e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Returns the number (converted to host) from the
3030e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * raw data.
3031e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
3032e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengunsigned long long pevent_read_number(struct pevent *pevent,
3033e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				      const void *ptr, int size)
3034e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
3035e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	switch (size) {
3036e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case 1:
3037e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return *(unsigned char *)ptr;
3038e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case 2:
3039e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return data2host2(pevent, ptr);
3040e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case 4:
3041e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return data2host4(pevent, ptr);
3042e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case 8:
3043e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return data2host8(pevent, ptr);
3044e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	default:
3045e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* BUG! */
3046e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 0;
3047e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
3048e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
3049e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3050e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
3051e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_read_number_field - read a number from data
3052e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @field: a handle to the field
3053e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @data: the raw data to read
3054e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @value: the value to place the number in
3055e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
3056e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Reads raw data according to a field offset and size,
3057e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * and translates it into @value.
3058e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
3059e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Returns 0 on success, -1 otherwise.
3060e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
3061e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint pevent_read_number_field(struct format_field *field, const void *data,
3062e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			     unsigned long long *value)
3063e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
3064e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!field)
3065e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
3066e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	switch (field->size) {
3067e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case 1:
3068e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case 2:
3069e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case 4:
3070e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case 8:
3071e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*value = pevent_read_number(field->event->pevent,
3072e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					    data + field->offset, field->size);
3073e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 0;
3074e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	default:
3075e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
3076e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
3077e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
3078e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3079e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int get_common_info(struct pevent *pevent,
3080e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			   const char *type, int *offset, int *size)
3081e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
3082e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct event_format *event;
3083e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct format_field *field;
3084e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3085e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/*
3086e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 * All events should have the same common elements.
3087e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 * Pick any event to find where the type is;
3088e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 */
3089e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!pevent->events) {
3090e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		do_warning("no event_list!");
3091e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
3092e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
3093e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3094e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	event = pevent->events[0];
3095e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	field = pevent_find_common_field(event, type);
3096e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!field)
3097e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
3098e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3099e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*offset = field->offset;
3100e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*size = field->size;
3101e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3102e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
3103e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
3104e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3105e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int __parse_common(struct pevent *pevent, void *data,
3106e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			  int *size, int *offset, const char *name)
3107e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
3108e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int ret;
3109e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3110e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!*size) {
3111e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ret = get_common_info(pevent, name, offset, size);
3112e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (ret < 0)
3113e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return ret;
3114e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
3115e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return pevent_read_number(pevent, data + *offset, *size);
3116e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
3117e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3118e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int trace_parse_common_type(struct pevent *pevent, void *data)
3119e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
3120e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return __parse_common(pevent, data,
3121e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			      &pevent->type_size, &pevent->type_offset,
3122e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			      "common_type");
3123e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
3124e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3125e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int parse_common_pid(struct pevent *pevent, void *data)
3126e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
3127e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return __parse_common(pevent, data,
3128e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			      &pevent->pid_size, &pevent->pid_offset,
3129e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			      "common_pid");
3130e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
3131e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3132e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int parse_common_pc(struct pevent *pevent, void *data)
3133e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
3134e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return __parse_common(pevent, data,
3135e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			      &pevent->pc_size, &pevent->pc_offset,
3136e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			      "common_preempt_count");
3137e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
3138e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3139e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int parse_common_flags(struct pevent *pevent, void *data)
3140e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
3141e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return __parse_common(pevent, data,
3142e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			      &pevent->flags_size, &pevent->flags_offset,
3143e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			      "common_flags");
3144e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
3145e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3146e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int parse_common_lock_depth(struct pevent *pevent, void *data)
3147e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
3148e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return __parse_common(pevent, data,
3149e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			      &pevent->ld_size, &pevent->ld_offset,
3150e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			      "common_lock_depth");
3151e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
3152e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3153e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int parse_common_migrate_disable(struct pevent *pevent, void *data)
3154e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
3155e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return __parse_common(pevent, data,
3156e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			      &pevent->ld_size, &pevent->ld_offset,
3157e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			      "common_migrate_disable");
3158e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
3159e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3160e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int events_id_cmp(const void *a, const void *b);
3161e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3162e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
3163e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_find_event - find an event by given id
3164e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @pevent: a handle to the pevent
3165e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @id: the id of the event
3166e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
3167e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Returns an event that has a given @id.
3168e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
3169e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct event_format *pevent_find_event(struct pevent *pevent, int id)
3170e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
3171e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct event_format **eventptr;
3172e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct event_format key;
3173e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct event_format *pkey = &key;
3174e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3175e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* Check cache first */
3176e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (pevent->last_event && pevent->last_event->id == id)
3177e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return pevent->last_event;
3178e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3179e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	key.id = id;
3180e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3181e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	eventptr = bsearch(&pkey, pevent->events, pevent->nr_events,
3182e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			   sizeof(*pevent->events), events_id_cmp);
3183e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3184e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (eventptr) {
3185e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pevent->last_event = *eventptr;
3186e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return *eventptr;
3187e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
3188e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3189e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return NULL;
3190e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
3191e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3192e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
3193e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_find_event_by_name - find an event by given name
3194e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @pevent: a handle to the pevent
3195e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @sys: the system name to search for
3196e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @name: the name of the event to search for
3197e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
3198e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This returns an event with a given @name and under the system
3199e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @sys. If @sys is NULL the first event with @name is returned.
3200e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
3201e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct event_format *
3202e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengpevent_find_event_by_name(struct pevent *pevent,
3203e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			  const char *sys, const char *name)
3204e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
3205e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct event_format *event;
3206e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int i;
3207e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3208e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (pevent->last_event &&
3209e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    strcmp(pevent->last_event->name, name) == 0 &&
3210e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    (!sys || strcmp(pevent->last_event->system, sys) == 0))
3211e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return pevent->last_event;
3212e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3213e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (i = 0; i < pevent->nr_events; i++) {
3214e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		event = pevent->events[i];
3215e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (strcmp(event->name, name) == 0) {
3216e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!sys)
3217e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
3218e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (strcmp(event->system, sys) == 0)
3219e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
3220e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
3221e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
3222e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (i == pevent->nr_events)
3223e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		event = NULL;
3224e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3225e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent->last_event = event;
3226e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return event;
3227e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
3228e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3229e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic unsigned long long
3230e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengeval_num_arg(void *data, int size, struct event_format *event, struct print_arg *arg)
3231e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
3232e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pevent *pevent = event->pevent;
3233e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long long val = 0;
3234e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long long left, right;
3235e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct print_arg *typearg = NULL;
3236e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct print_arg *larg;
3237e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long offset;
3238e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned int field_size;
3239e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3240e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	switch (arg->type) {
3241e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_NULL:
3242e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* ?? */
3243e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 0;
3244e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_ATOM:
3245e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return strtoull(arg->atom.atom, NULL, 0);
3246e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_FIELD:
3247e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!arg->field.field) {
3248e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			arg->field.field = pevent_find_any_field(event, arg->field.name);
3249e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!arg->field.field)
3250e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto out_warning_field;
3251e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3252e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
3253e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* must be a number */
3254e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		val = pevent_read_number(pevent, data + arg->field.field->offset,
3255e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				arg->field.field->size);
3256e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
3257e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_FLAGS:
3258e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_SYMBOL:
3259e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_HEX:
3260e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
3261e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_TYPE:
3262e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		val = eval_num_arg(data, size, event, arg->typecast.item);
3263e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return eval_type(val, arg, 0);
3264e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_STRING:
3265e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_BSTRING:
3266e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 0;
3267e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_FUNC: {
3268e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		struct trace_seq s;
3269e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		trace_seq_init(&s);
3270e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		val = process_defined_func(&s, data, size, event, arg);
3271e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		trace_seq_destroy(&s);
3272e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return val;
3273e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
3274e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_OP:
3275e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (strcmp(arg->op.op, "[") == 0) {
3276e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			/*
3277e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			 * Arrays are special, since we don't want
3278e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			 * to read the arg as is.
3279e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			 */
3280e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			right = eval_num_arg(data, size, event, arg->op.right);
3281e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3282e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			/* handle typecasts */
3283e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			larg = arg->op.left;
3284e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			while (larg->type == PRINT_TYPE) {
3285e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (!typearg)
3286e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					typearg = larg;
3287e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				larg = larg->typecast.item;
3288e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
3289e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3290e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			/* Default to long size */
3291e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			field_size = pevent->long_size;
3292e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3293e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			switch (larg->type) {
3294e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case PRINT_DYNAMIC_ARRAY:
3295e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				offset = pevent_read_number(pevent,
3296e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						   data + larg->dynarray.field->offset,
3297e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						   larg->dynarray.field->size);
3298e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (larg->dynarray.field->elementsize)
3299e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					field_size = larg->dynarray.field->elementsize;
3300e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				/*
3301e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				 * The actual length of the dynamic array is stored
3302e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				 * in the top half of the field, and the offset
3303e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				 * is in the bottom half of the 32 bit field.
3304e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				 */
3305e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				offset &= 0xffff;
3306e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				offset += right;
3307e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
3308e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case PRINT_FIELD:
3309e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (!larg->field.field) {
3310e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					larg->field.field =
3311e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						pevent_find_any_field(event, larg->field.name);
3312e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					if (!larg->field.field) {
3313e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						arg = larg;
3314e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						goto out_warning_field;
3315e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					}
3316e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				}
3317e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				field_size = larg->field.field->elementsize;
3318e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				offset = larg->field.field->offset +
3319e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					right * larg->field.field->elementsize;
3320e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
3321e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			default:
3322e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto default_op; /* oops, all bets off */
3323e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
3324e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			val = pevent_read_number(pevent,
3325e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						 data + offset, field_size);
3326e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (typearg)
3327e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				val = eval_type(val, typearg, 1);
3328e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
3329e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		} else if (strcmp(arg->op.op, "?") == 0) {
3330e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			left = eval_num_arg(data, size, event, arg->op.left);
3331e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			arg = arg->op.right;
3332e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (left)
3333e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				val = eval_num_arg(data, size, event, arg->op.left);
3334e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			else
3335e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				val = eval_num_arg(data, size, event, arg->op.right);
3336e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
3337e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
3338e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng default_op:
3339e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		left = eval_num_arg(data, size, event, arg->op.left);
3340e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		right = eval_num_arg(data, size, event, arg->op.right);
3341e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		switch (arg->op.op[0]) {
3342e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '!':
3343e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			switch (arg->op.op[1]) {
3344e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case 0:
3345e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				val = !right;
3346e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
3347e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case '=':
3348e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				val = left != right;
3349e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
3350e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			default:
3351e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto out_warning_op;
3352e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
3353e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
3354e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '~':
3355e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			val = ~right;
3356e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
3357e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '|':
3358e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (arg->op.op[1])
3359e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				val = left || right;
3360e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			else
3361e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				val = left | right;
3362e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
3363e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '&':
3364e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (arg->op.op[1])
3365e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				val = left && right;
3366e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			else
3367e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				val = left & right;
3368e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
3369e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '<':
3370e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			switch (arg->op.op[1]) {
3371e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case 0:
3372e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				val = left < right;
3373e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
3374e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case '<':
3375e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				val = left << right;
3376e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
3377e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case '=':
3378e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				val = left <= right;
3379e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
3380e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			default:
3381e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto out_warning_op;
3382e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
3383e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
3384e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '>':
3385e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			switch (arg->op.op[1]) {
3386e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case 0:
3387e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				val = left > right;
3388e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
3389e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case '>':
3390e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				val = left >> right;
3391e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
3392e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case '=':
3393e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				val = left >= right;
3394e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
3395e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			default:
3396e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto out_warning_op;
3397e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
3398e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
3399e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '=':
3400e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (arg->op.op[1] != '=')
3401e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto out_warning_op;
3402e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3403e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			val = left == right;
3404e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
3405e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '-':
3406e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			val = left - right;
3407e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
3408e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '+':
3409e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			val = left + right;
3410e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
3411e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '/':
3412e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			val = left / right;
3413e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
3414e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '*':
3415e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			val = left * right;
3416e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
3417e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		default:
3418e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto out_warning_op;
3419e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
3420e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
3421e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	default: /* not sure what to do there */
3422e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 0;
3423e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
3424e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return val;
3425e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3426e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_warning_op:
3427e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	do_warning("%s: unknown op '%s'", __func__, arg->op.op);
3428e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
3429e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3430e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_warning_field:
3431e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	do_warning("%s: field %s not found", __func__, arg->field.name);
3432e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
3433e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
3434e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3435e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct flag {
3436e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const char *name;
3437e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long long value;
3438e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
3439e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3440e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic const struct flag flags[] = {
3441e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "HI_SOFTIRQ", 0 },
3442e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "TIMER_SOFTIRQ", 1 },
3443e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "NET_TX_SOFTIRQ", 2 },
3444e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "NET_RX_SOFTIRQ", 3 },
3445e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "BLOCK_SOFTIRQ", 4 },
3446e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "BLOCK_IOPOLL_SOFTIRQ", 5 },
3447e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "TASKLET_SOFTIRQ", 6 },
3448e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "SCHED_SOFTIRQ", 7 },
3449e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "HRTIMER_SOFTIRQ", 8 },
3450e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "RCU_SOFTIRQ", 9 },
3451e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3452e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "HRTIMER_NORESTART", 0 },
3453e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "HRTIMER_RESTART", 1 },
3454e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
3455e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3456e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic unsigned long long eval_flag(const char *flag)
3457e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
3458e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int i;
3459e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3460e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/*
3461e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 * Some flags in the format files do not get converted.
3462e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 * If the flag is not numeric, see if it is something that
3463e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 * we already know about.
3464e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 */
3465e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (isdigit(flag[0]))
3466e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return strtoull(flag, NULL, 0);
3467e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3468e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (i = 0; i < (int)(sizeof(flags)/sizeof(flags[0])); i++)
3469e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (strcmp(flags[i].name, flag) == 0)
3470e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return flags[i].value;
3471e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3472e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
3473e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
3474e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3475e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void print_str_to_seq(struct trace_seq *s, const char *format,
3476e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			     int len_arg, const char *str)
3477e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
3478e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (len_arg >= 0)
3479e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		trace_seq_printf(s, format, len_arg, str);
3480e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	else
3481e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		trace_seq_printf(s, format, str);
3482e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
3483e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3484e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void print_str_arg(struct trace_seq *s, void *data, int size,
3485e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			  struct event_format *event, const char *format,
3486e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			  int len_arg, struct print_arg *arg)
3487e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
3488e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pevent *pevent = event->pevent;
3489e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct print_flag_sym *flag;
3490e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct format_field *field;
3491e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long long val, fval;
3492e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long addr;
3493e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *str;
3494e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned char *hex;
3495e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int print;
3496e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int i, len;
3497e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3498e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	switch (arg->type) {
3499e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_NULL:
3500e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* ?? */
3501e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return;
3502e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_ATOM:
3503e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		print_str_to_seq(s, format, len_arg, arg->atom.atom);
3504e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return;
3505e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_FIELD:
3506e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		field = arg->field.field;
3507e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!field) {
3508e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			field = pevent_find_any_field(event, arg->field.name);
3509e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!field) {
3510e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				str = arg->field.name;
3511e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto out_warning_field;
3512e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
3513e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			arg->field.field = field;
3514e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
3515e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* Zero sized fields, mean the rest of the data */
3516e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		len = field->size ? : size - field->offset;
3517e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3518e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/*
3519e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 * Some events pass in pointers. If this is not an array
3520e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 * and the size is the same as long_size, assume that it
3521e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 * is a pointer.
3522e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 */
3523e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!(field->flags & FIELD_IS_ARRAY) &&
3524e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		    field->size == pevent->long_size) {
3525e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			addr = *(unsigned long *)(data + field->offset);
3526e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			trace_seq_printf(s, "%lx", addr);
3527e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
3528e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
3529e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		str = malloc(len + 1);
3530e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!str) {
3531e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			do_warning("%s: not enough memory!", __func__);
3532e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return;
3533e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
3534e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		memcpy(str, data + field->offset, len);
3535e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		str[len] = 0;
3536e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		print_str_to_seq(s, format, len_arg, str);
3537e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(str);
3538e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
3539e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_FLAGS:
3540e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		val = eval_num_arg(data, size, event, arg->flags.field);
3541e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		print = 0;
3542e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		for (flag = arg->flags.flags; flag; flag = flag->next) {
3543e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			fval = eval_flag(flag->value);
3544e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!val && !fval) {
3545e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				print_str_to_seq(s, format, len_arg, flag->str);
3546e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
3547e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
3548e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (fval && (val & fval) == fval) {
3549e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (print && arg->flags.delim)
3550e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					trace_seq_puts(s, arg->flags.delim);
3551e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				print_str_to_seq(s, format, len_arg, flag->str);
3552e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				print = 1;
3553e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				val &= ~fval;
3554e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
3555e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
3556e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
3557e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_SYMBOL:
3558e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		val = eval_num_arg(data, size, event, arg->symbol.field);
3559e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		for (flag = arg->symbol.symbols; flag; flag = flag->next) {
3560e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			fval = eval_flag(flag->value);
3561e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (val == fval) {
3562e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				print_str_to_seq(s, format, len_arg, flag->str);
3563e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
3564e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
3565e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
3566e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
3567e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_HEX:
3568e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		field = arg->hex.field->field.field;
3569e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!field) {
3570e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			str = arg->hex.field->field.name;
3571e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			field = pevent_find_any_field(event, str);
3572e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!field)
3573e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto out_warning_field;
3574e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			arg->hex.field->field.field = field;
3575e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
3576e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		hex = data + field->offset;
3577e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		len = eval_num_arg(data, size, event, arg->hex.size);
3578e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		for (i = 0; i < len; i++) {
3579e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (i)
3580e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				trace_seq_putc(s, ' ');
3581e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			trace_seq_printf(s, "%02x", hex[i]);
3582e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
3583e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
3584e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3585e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_TYPE:
3586e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
3587e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_STRING: {
3588e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		int str_offset;
3589e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3590e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (arg->string.offset == -1) {
3591e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			struct format_field *f;
3592e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3593e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			f = pevent_find_any_field(event, arg->string.string);
3594e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			arg->string.offset = f->offset;
3595e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
3596e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		str_offset = data2host4(pevent, data + arg->string.offset);
3597e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		str_offset &= 0xffff;
3598e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		print_str_to_seq(s, format, len_arg, ((char *)data) + str_offset);
3599e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
3600e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
3601e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_BSTRING:
3602e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		print_str_to_seq(s, format, len_arg, arg->string.string);
3603e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
3604e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_OP:
3605e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/*
3606e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 * The only op for string should be ? :
3607e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 */
3608e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (arg->op.op[0] != '?')
3609e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return;
3610e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		val = eval_num_arg(data, size, event, arg->op.left);
3611e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (val)
3612e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			print_str_arg(s, data, size, event,
3613e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				      format, len_arg, arg->op.right->op.left);
3614e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		else
3615e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			print_str_arg(s, data, size, event,
3616e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				      format, len_arg, arg->op.right->op.right);
3617e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
3618e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_FUNC:
3619e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		process_defined_func(s, data, size, event, arg);
3620e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
3621e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	default:
3622e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* well... */
3623e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
3624e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
3625e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3626e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return;
3627e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3628e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_warning_field:
3629e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	do_warning("%s: field %s not found", __func__, arg->field.name);
3630e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
3631e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3632e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic unsigned long long
3633e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengprocess_defined_func(struct trace_seq *s, void *data, int size,
3634e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		     struct event_format *event, struct print_arg *arg)
3635e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
3636e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pevent_function_handler *func_handle = arg->func.func;
3637e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pevent_func_params *param;
3638e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long long *args;
3639e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long long ret;
3640e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct print_arg *farg;
3641e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct trace_seq str;
3642e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct save_str {
3643e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		struct save_str *next;
3644e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		char *str;
3645e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	} *strings = NULL, *string;
3646e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int i;
3647e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3648e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!func_handle->nr_args) {
3649e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ret = (*func_handle->func)(s, NULL);
3650e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out;
3651e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
3652e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3653e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	farg = arg->func.args;
3654e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	param = func_handle->params;
3655e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3656e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ret = ULLONG_MAX;
3657e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	args = malloc(sizeof(*args) * func_handle->nr_args);
3658e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!args)
3659e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out;
3660e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3661e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (i = 0; i < func_handle->nr_args; i++) {
3662e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		switch (param->type) {
3663e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case PEVENT_FUNC_ARG_INT:
3664e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case PEVENT_FUNC_ARG_LONG:
3665e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case PEVENT_FUNC_ARG_PTR:
3666e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			args[i] = eval_num_arg(data, size, event, farg);
3667e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
3668e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case PEVENT_FUNC_ARG_STRING:
3669e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			trace_seq_init(&str);
3670e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			print_str_arg(&str, data, size, event, "%s", -1, farg);
3671e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			trace_seq_terminate(&str);
3672e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			string = malloc(sizeof(*string));
3673e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!string) {
3674e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				do_warning("%s(%d): malloc str", __func__, __LINE__);
3675e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto out_free;
3676e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
3677e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			string->next = strings;
3678e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			string->str = strdup(str.buffer);
3679e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!string->str) {
3680e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				free(string);
3681e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				do_warning("%s(%d): malloc str", __func__, __LINE__);
3682e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto out_free;
3683e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
3684e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			args[i] = (uintptr_t)string->str;
3685e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			strings = string;
3686e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			trace_seq_destroy(&str);
3687e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
3688e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		default:
3689e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			/*
3690e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			 * Something went totally wrong, this is not
3691e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			 * an input error, something in this code broke.
3692e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			 */
3693e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			do_warning("Unexpected end of arguments\n");
3694e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto out_free;
3695e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
3696e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		farg = farg->next;
3697e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		param = param->next;
3698e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
3699e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3700e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ret = (*func_handle->func)(s, args);
3701e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_free:
3702e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free(args);
3703e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (strings) {
3704e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		string = strings;
3705e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		strings = string->next;
3706e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(string->str);
3707e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(string);
3708e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
3709e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3710e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng out:
3711e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* TBD : handle return type here */
3712e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return ret;
3713e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
3714e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3715e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void free_args(struct print_arg *args)
3716e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
3717e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct print_arg *next;
3718e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3719e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (args) {
3720e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		next = args->next;
3721e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3722e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_arg(args);
3723e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		args = next;
3724e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
3725e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
3726e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3727e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic struct print_arg *make_bprint_args(char *fmt, void *data, int size, struct event_format *event)
3728e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
3729e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pevent *pevent = event->pevent;
3730e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct format_field *field, *ip_field;
3731e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct print_arg *args, *arg, **next;
3732e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long long ip, val;
3733e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *ptr;
3734e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	void *bptr;
3735e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int vsize;
3736e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3737e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	field = pevent->bprint_buf_field;
3738e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ip_field = pevent->bprint_ip_field;
3739e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3740e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!field) {
3741e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		field = pevent_find_field(event, "buf");
3742e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!field) {
3743e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			do_warning("can't find buffer field for binary printk");
3744e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return NULL;
3745e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
3746e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ip_field = pevent_find_field(event, "ip");
3747e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!ip_field) {
3748e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			do_warning("can't find ip field for binary printk");
3749e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return NULL;
3750e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
3751e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pevent->bprint_buf_field = field;
3752e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pevent->bprint_ip_field = ip_field;
3753e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
3754e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3755e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ip = pevent_read_number(pevent, data + ip_field->offset, ip_field->size);
3756e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3757e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/*
3758e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 * The first arg is the IP pointer.
3759e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 */
3760e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	args = alloc_arg();
3761e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!args) {
3762e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		do_warning("%s(%d): not enough memory!", __func__, __LINE__);
3763e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
3764e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
3765e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	arg = args;
3766e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	arg->next = NULL;
3767e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	next = &arg->next;
3768e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3769e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	arg->type = PRINT_ATOM;
3770e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3771e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (asprintf(&arg->atom.atom, "%lld", ip) < 0)
3772e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_free;
3773e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3774e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* skip the first "%pf : " */
3775e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (ptr = fmt + 6, bptr = data + field->offset;
3776e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	     bptr < data + size && *ptr; ptr++) {
3777e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		int ls = 0;
3778e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3779e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (*ptr == '%') {
3780e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng process_again:
3781e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			ptr++;
3782e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			switch (*ptr) {
3783e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case '%':
3784e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
3785e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case 'l':
3786e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				ls++;
3787e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto process_again;
3788e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case 'L':
3789e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				ls = 2;
3790e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto process_again;
3791e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case '0' ... '9':
3792e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto process_again;
3793e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case '.':
3794e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto process_again;
3795e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case 'p':
3796e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				ls = 1;
3797e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				/* fall through */
3798e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case 'd':
3799e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case 'u':
3800e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case 'x':
3801e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case 'i':
3802e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				switch (ls) {
3803e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				case 0:
3804e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					vsize = 4;
3805e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					break;
3806e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				case 1:
3807e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					vsize = pevent->long_size;
3808e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					break;
3809e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				case 2:
3810e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					vsize = 8;
3811e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					break;
3812e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				default:
3813e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					vsize = ls; /* ? */
3814e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					break;
3815e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				}
3816e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			/* fall through */
3817e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case '*':
3818e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (*ptr == '*')
3819e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					vsize = 4;
3820e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3821e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				/* the pointers are always 4 bytes aligned */
3822e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				bptr = (void *)(((unsigned long)bptr + 3) &
3823e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						~3);
3824e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				val = pevent_read_number(pevent, bptr, vsize);
3825e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				bptr += vsize;
3826e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				arg = alloc_arg();
3827e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (!arg) {
3828e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					do_warning("%s(%d): not enough memory!",
3829e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						   __func__, __LINE__);
3830e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					goto out_free;
3831e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				}
3832e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				arg->next = NULL;
3833e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				arg->type = PRINT_ATOM;
3834e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (asprintf(&arg->atom.atom, "%lld", val) < 0) {
3835e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					free(arg);
3836e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					goto out_free;
3837e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				}
3838e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				*next = arg;
3839e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				next = &arg->next;
3840e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				/*
3841e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				 * The '*' case means that an arg is used as the length.
3842e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				 * We need to continue to figure out for what.
3843e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				 */
3844e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (*ptr == '*')
3845e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					goto process_again;
3846e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3847e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
3848e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case 's':
3849e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				arg = alloc_arg();
3850e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (!arg) {
3851e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					do_warning("%s(%d): not enough memory!",
3852e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						   __func__, __LINE__);
3853e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					goto out_free;
3854e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				}
3855e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				arg->next = NULL;
3856e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				arg->type = PRINT_BSTRING;
3857e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				arg->string.string = strdup(bptr);
3858e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (!arg->string.string)
3859e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					goto out_free;
3860e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				bptr += strlen(bptr) + 1;
3861e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				*next = arg;
3862e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				next = &arg->next;
3863e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			default:
3864e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
3865e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
3866e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
3867e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
3868e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3869e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return args;
3870e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3871e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_free:
3872e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_args(args);
3873e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return NULL;
3874e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
3875e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3876e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic char *
3877e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengget_bprint_format(void *data, int size __maybe_unused,
3878e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		  struct event_format *event)
3879e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
3880e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pevent *pevent = event->pevent;
3881e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long long addr;
3882e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct format_field *field;
3883e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct printk_map *printk;
3884e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *format;
3885e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *p;
3886e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3887e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	field = pevent->bprint_fmt_field;
3888e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3889e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!field) {
3890e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		field = pevent_find_field(event, "fmt");
3891e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!field) {
3892e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			do_warning("can't find format field for binary printk");
3893e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return NULL;
3894e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
3895e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pevent->bprint_fmt_field = field;
3896e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
3897e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3898e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	addr = pevent_read_number(pevent, data + field->offset, field->size);
3899e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3900e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	printk = find_printk(pevent, addr);
3901e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!printk) {
3902e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (asprintf(&format, "%%pf : (NO FORMAT FOUND at %llx)\n", addr) < 0)
3903e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return NULL;
3904e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return format;
3905e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
3906e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3907e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	p = printk->printk;
3908e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* Remove any quotes. */
3909e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (*p == '"')
3910e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		p++;
3911e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (asprintf(&format, "%s : %s", "%pf", p) < 0)
3912e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
3913e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* remove ending quotes and new line since we will add one too */
3914e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	p = format + strlen(format) - 1;
3915e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (*p == '"')
3916e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*p = 0;
3917e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3918e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	p -= 2;
3919e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (strcmp(p, "\\n") == 0)
3920e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*p = 0;
3921e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3922e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return format;
3923e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
3924e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3925e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void print_mac_arg(struct trace_seq *s, int mac, void *data, int size,
3926e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			  struct event_format *event, struct print_arg *arg)
3927e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
3928e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned char *buf;
3929e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const char *fmt = "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x";
3930e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3931e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (arg->type == PRINT_FUNC) {
3932e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		process_defined_func(s, data, size, event, arg);
3933e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return;
3934e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
3935e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3936e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (arg->type != PRINT_FIELD) {
3937e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d",
3938e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				 arg->type);
3939e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return;
3940e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
3941e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3942e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (mac == 'm')
3943e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		fmt = "%.2x%.2x%.2x%.2x%.2x%.2x";
3944e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!arg->field.field) {
3945e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg->field.field =
3946e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pevent_find_any_field(event, arg->field.name);
3947e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!arg->field.field) {
3948e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			do_warning("%s: field %s not found",
3949e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				   __func__, arg->field.name);
3950e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return;
3951e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
3952e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
3953e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (arg->field.field->size != 6) {
3954e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		trace_seq_printf(s, "INVALIDMAC");
3955e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return;
3956e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
3957e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	buf = data + arg->field.field->offset;
3958e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
3959e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
3960e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3961e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int is_printable_array(char *p, unsigned int len)
3962e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
3963e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned int i;
3964e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3965e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (i = 0; i < len && p[i]; i++)
3966e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!isprint(p[i]))
3967e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		    return 0;
3968e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 1;
3969e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
3970e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3971e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void print_event_fields(struct trace_seq *s, void *data,
3972e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			       int size __maybe_unused,
3973e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			       struct event_format *event)
3974e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
3975e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct format_field *field;
3976e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long long val;
3977e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned int offset, len, i;
3978e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
3979e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	field = event->format.fields;
3980e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (field) {
3981e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		trace_seq_printf(s, " %s=", field->name);
3982e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (field->flags & FIELD_IS_ARRAY) {
3983e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			offset = field->offset;
3984e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			len = field->size;
3985e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (field->flags & FIELD_IS_DYNAMIC) {
3986e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				val = pevent_read_number(event->pevent, data + offset, len);
3987e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				offset = val;
3988e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				len = offset >> 16;
3989e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				offset &= 0xffff;
3990e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
3991e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (field->flags & FIELD_IS_STRING &&
3992e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			    is_printable_array(data + offset, len)) {
3993e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				trace_seq_printf(s, "%s", (char *)data + offset);
3994e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			} else {
3995e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				trace_seq_puts(s, "ARRAY[");
3996e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				for (i = 0; i < len; i++) {
3997e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					if (i)
3998e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						trace_seq_puts(s, ", ");
3999e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					trace_seq_printf(s, "%02x",
4000e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng							 *((unsigned char *)data + offset + i));
4001e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				}
4002e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				trace_seq_putc(s, ']');
4003e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				field->flags &= ~FIELD_IS_STRING;
4004e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
4005e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		} else {
4006e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			val = pevent_read_number(event->pevent, data + field->offset,
4007e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						 field->size);
4008e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (field->flags & FIELD_IS_POINTER) {
4009e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				trace_seq_printf(s, "0x%llx", val);
4010e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			} else if (field->flags & FIELD_IS_SIGNED) {
4011e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				switch (field->size) {
4012e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				case 4:
4013e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					/*
4014e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					 * If field is long then print it in hex.
4015e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					 * A long usually stores pointers.
4016e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					 */
4017e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					if (field->flags & FIELD_IS_LONG)
4018e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						trace_seq_printf(s, "0x%x", (int)val);
4019e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					else
4020e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						trace_seq_printf(s, "%d", (int)val);
4021e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					break;
4022e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				case 2:
4023e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					trace_seq_printf(s, "%2d", (short)val);
4024e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					break;
4025e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				case 1:
4026e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					trace_seq_printf(s, "%1d", (char)val);
4027e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					break;
4028e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				default:
4029e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					trace_seq_printf(s, "%lld", val);
4030e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				}
4031e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			} else {
4032e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (field->flags & FIELD_IS_LONG)
4033e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					trace_seq_printf(s, "0x%llx", val);
4034e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				else
4035e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					trace_seq_printf(s, "%llu", val);
4036e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
4037e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
4038e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		field = field->next;
4039e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4040e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
4041e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4042e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void pretty_print(struct trace_seq *s, void *data, int size, struct event_format *event)
4043e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
4044e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pevent *pevent = event->pevent;
4045e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct print_fmt *print_fmt = &event->print_fmt;
4046e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct print_arg *arg = print_fmt->args;
4047e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct print_arg *args = NULL;
4048e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const char *ptr = print_fmt->format;
4049e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long long val;
4050e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct func_map *func;
4051e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const char *saveptr;
4052e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *bprint_fmt = NULL;
4053e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char format[32];
4054e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int show_func;
4055e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int len_as_arg;
4056e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int len_arg;
4057e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int len;
4058e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int ls;
4059e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4060e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (event->flags & EVENT_FL_FAILED) {
4061e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		trace_seq_printf(s, "[FAILED TO PARSE]");
4062e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		print_event_fields(s, data, size, event);
4063e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return;
4064e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4065e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4066e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (event->flags & EVENT_FL_ISBPRINT) {
4067e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		bprint_fmt = get_bprint_format(data, size, event);
4068e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		args = make_bprint_args(bprint_fmt, data, size, event);
4069e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		arg = args;
4070e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ptr = bprint_fmt;
4071e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4072e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4073e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (; *ptr; ptr++) {
4074e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ls = 0;
4075e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (*ptr == '\\') {
4076e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			ptr++;
4077e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			switch (*ptr) {
4078e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case 'n':
4079e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				trace_seq_putc(s, '\n');
4080e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
4081e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case 't':
4082e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				trace_seq_putc(s, '\t');
4083e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
4084e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case 'r':
4085e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				trace_seq_putc(s, '\r');
4086e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
4087e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case '\\':
4088e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				trace_seq_putc(s, '\\');
4089e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
4090e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			default:
4091e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				trace_seq_putc(s, *ptr);
4092e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
4093e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
4094e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4095e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		} else if (*ptr == '%') {
4096e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			saveptr = ptr;
4097e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			show_func = 0;
4098e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			len_as_arg = 0;
4099e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng cont_process:
4100e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			ptr++;
4101e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			switch (*ptr) {
4102e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case '%':
4103e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				trace_seq_putc(s, '%');
4104e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
4105e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case '#':
4106e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				/* FIXME: need to handle properly */
4107e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto cont_process;
4108e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case 'h':
4109e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				ls--;
4110e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto cont_process;
4111e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case 'l':
4112e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				ls++;
4113e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto cont_process;
4114e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case 'L':
4115e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				ls = 2;
4116e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto cont_process;
4117e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case '*':
4118e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				/* The argument is the length. */
4119e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (!arg) {
4120e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					do_warning("no argument match");
4121e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					event->flags |= EVENT_FL_FAILED;
4122e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					goto out_failed;
4123e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				}
4124e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				len_arg = eval_num_arg(data, size, event, arg);
4125e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				len_as_arg = 1;
4126e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				arg = arg->next;
4127e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto cont_process;
4128e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case '.':
4129e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case 'z':
4130e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case 'Z':
4131e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case '0' ... '9':
4132e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto cont_process;
4133e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case 'p':
4134e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (pevent->long_size == 4)
4135e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					ls = 1;
4136e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				else
4137e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					ls = 2;
4138e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4139e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (*(ptr+1) == 'F' ||
4140e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				    *(ptr+1) == 'f') {
4141e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					ptr++;
4142e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					show_func = *ptr;
4143e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				} else if (*(ptr+1) == 'M' || *(ptr+1) == 'm') {
4144e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					print_mac_arg(s, *(ptr+1), data, size, event, arg);
4145e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					ptr++;
4146e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					arg = arg->next;
4147e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					break;
4148e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				}
4149e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4150e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				/* fall through */
4151e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case 'd':
4152e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case 'i':
4153e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case 'x':
4154e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case 'X':
4155e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case 'u':
4156e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (!arg) {
4157e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					do_warning("no argument match");
4158e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					event->flags |= EVENT_FL_FAILED;
4159e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					goto out_failed;
4160e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				}
4161e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4162e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				len = ((unsigned long)ptr + 1) -
4163e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					(unsigned long)saveptr;
4164e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4165e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				/* should never happen */
4166e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (len > 31) {
4167e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					do_warning("bad format!");
4168e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					event->flags |= EVENT_FL_FAILED;
4169e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					len = 31;
4170e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				}
4171e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4172e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				memcpy(format, saveptr, len);
4173e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				format[len] = 0;
4174e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4175e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				val = eval_num_arg(data, size, event, arg);
4176e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				arg = arg->next;
4177e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4178e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (show_func) {
4179e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					func = find_func(pevent, val);
4180e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					if (func) {
4181e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						trace_seq_puts(s, func->func);
4182e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						if (show_func == 'F')
4183e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng							trace_seq_printf(s,
4184e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng							       "+0x%llx",
4185e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng							       val - func->addr);
4186e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						break;
4187e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					}
4188e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				}
4189e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (pevent->long_size == 8 && ls &&
4190e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				    sizeof(long) != 8) {
4191e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					char *p;
4192e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4193e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					ls = 2;
4194e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					/* make %l into %ll */
4195e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					p = strchr(format, 'l');
4196e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					if (p)
4197e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						memmove(p+1, p, strlen(p)+1);
4198e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					else if (strcmp(format, "%p") == 0)
4199e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						strcpy(format, "0x%llx");
4200e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				}
4201e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				switch (ls) {
4202e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				case -2:
4203e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					if (len_as_arg)
4204e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						trace_seq_printf(s, format, len_arg, (char)val);
4205e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					else
4206e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						trace_seq_printf(s, format, (char)val);
4207e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					break;
4208e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				case -1:
4209e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					if (len_as_arg)
4210e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						trace_seq_printf(s, format, len_arg, (short)val);
4211e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					else
4212e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						trace_seq_printf(s, format, (short)val);
4213e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					break;
4214e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				case 0:
4215e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					if (len_as_arg)
4216e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						trace_seq_printf(s, format, len_arg, (int)val);
4217e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					else
4218e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						trace_seq_printf(s, format, (int)val);
4219e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					break;
4220e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				case 1:
4221e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					if (len_as_arg)
4222e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						trace_seq_printf(s, format, len_arg, (long)val);
4223e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					else
4224e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						trace_seq_printf(s, format, (long)val);
4225e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					break;
4226e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				case 2:
4227e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					if (len_as_arg)
4228e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						trace_seq_printf(s, format, len_arg,
4229e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng								 (long long)val);
4230e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					else
4231e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						trace_seq_printf(s, format, (long long)val);
4232e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					break;
4233e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				default:
4234e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					do_warning("bad count (%d)", ls);
4235e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					event->flags |= EVENT_FL_FAILED;
4236e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				}
4237e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
4238e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			case 's':
4239e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (!arg) {
4240e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					do_warning("no matching argument");
4241e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					event->flags |= EVENT_FL_FAILED;
4242e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					goto out_failed;
4243e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				}
4244e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4245e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				len = ((unsigned long)ptr + 1) -
4246e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					(unsigned long)saveptr;
4247e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4248e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				/* should never happen */
4249e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (len > 31) {
4250e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					do_warning("bad format!");
4251e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					event->flags |= EVENT_FL_FAILED;
4252e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					len = 31;
4253e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				}
4254e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4255e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				memcpy(format, saveptr, len);
4256e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				format[len] = 0;
4257e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				if (!len_as_arg)
4258e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					len_arg = -1;
4259e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				print_str_arg(s, data, size, event,
4260e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					      format, len_arg, arg);
4261e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				arg = arg->next;
4262e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				break;
4263e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			default:
4264e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				trace_seq_printf(s, ">%c<", *ptr);
4265e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4266e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
4267e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		} else
4268e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			trace_seq_putc(s, *ptr);
4269e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4270e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4271e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (event->flags & EVENT_FL_FAILED) {
4272e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_failed:
4273e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		trace_seq_printf(s, "[FAILED TO PARSE]");
4274e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4275e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4276e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (args) {
4277e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_args(args);
4278e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(bprint_fmt);
4279e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4280e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
4281e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4282e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
4283e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_data_lat_fmt - parse the data for the latency format
4284e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @pevent: a handle to the pevent
4285e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @s: the trace_seq to write to
4286e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @record: the record to read from
4287e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
4288e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This parses out the Latency format (interrupts disabled,
4289e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * need rescheduling, in hard/soft interrupt, preempt count
4290e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * and lock depth) and places it into the trace_seq.
4291e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
4292e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid pevent_data_lat_fmt(struct pevent *pevent,
4293e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			 struct trace_seq *s, struct pevent_record *record)
4294e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
4295e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	static int check_lock_depth = 1;
4296e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	static int check_migrate_disable = 1;
4297e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	static int lock_depth_exists;
4298e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	static int migrate_disable_exists;
4299e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned int lat_flags;
4300e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned int pc;
4301e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int lock_depth;
4302e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int migrate_disable;
4303e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int hardirq;
4304e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int softirq;
4305e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	void *data = record->data;
4306e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4307e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	lat_flags = parse_common_flags(pevent, data);
4308e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pc = parse_common_pc(pevent, data);
4309e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* lock_depth may not always exist */
4310e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (lock_depth_exists)
4311e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		lock_depth = parse_common_lock_depth(pevent, data);
4312e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	else if (check_lock_depth) {
4313e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		lock_depth = parse_common_lock_depth(pevent, data);
4314e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (lock_depth < 0)
4315e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			check_lock_depth = 0;
4316e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		else
4317e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			lock_depth_exists = 1;
4318e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4319e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4320e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* migrate_disable may not always exist */
4321e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (migrate_disable_exists)
4322e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		migrate_disable = parse_common_migrate_disable(pevent, data);
4323e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	else if (check_migrate_disable) {
4324e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		migrate_disable = parse_common_migrate_disable(pevent, data);
4325e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (migrate_disable < 0)
4326e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			check_migrate_disable = 0;
4327e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		else
4328e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			migrate_disable_exists = 1;
4329e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4330e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4331e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	hardirq = lat_flags & TRACE_FLAG_HARDIRQ;
4332e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	softirq = lat_flags & TRACE_FLAG_SOFTIRQ;
4333e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4334e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	trace_seq_printf(s, "%c%c%c",
4335e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	       (lat_flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
4336e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	       (lat_flags & TRACE_FLAG_IRQS_NOSUPPORT) ?
4337e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	       'X' : '.',
4338e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	       (lat_flags & TRACE_FLAG_NEED_RESCHED) ?
4339e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	       'N' : '.',
4340e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	       (hardirq && softirq) ? 'H' :
4341e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	       hardirq ? 'h' : softirq ? 's' : '.');
4342e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4343e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (pc)
4344e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		trace_seq_printf(s, "%x", pc);
4345e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	else
4346e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		trace_seq_putc(s, '.');
4347e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4348e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (migrate_disable_exists) {
4349e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (migrate_disable < 0)
4350e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			trace_seq_putc(s, '.');
4351e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		else
4352e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			trace_seq_printf(s, "%d", migrate_disable);
4353e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4354e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4355e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (lock_depth_exists) {
4356e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (lock_depth < 0)
4357e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			trace_seq_putc(s, '.');
4358e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		else
4359e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			trace_seq_printf(s, "%d", lock_depth);
4360e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4361e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4362e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	trace_seq_terminate(s);
4363e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
4364e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4365e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
4366e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_data_type - parse out the given event type
4367e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @pevent: a handle to the pevent
4368e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @rec: the record to read from
4369e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
4370e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This returns the event id from the @rec.
4371e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
4372e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint pevent_data_type(struct pevent *pevent, struct pevent_record *rec)
4373e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
4374e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return trace_parse_common_type(pevent, rec->data);
4375e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
4376e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4377e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
4378e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_data_event_from_type - find the event by a given type
4379e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @pevent: a handle to the pevent
4380e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @type: the type of the event.
4381e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
4382e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This returns the event form a given @type;
4383e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
4384e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct event_format *pevent_data_event_from_type(struct pevent *pevent, int type)
4385e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
4386e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return pevent_find_event(pevent, type);
4387e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
4388e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4389e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
4390e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_data_pid - parse the PID from raw data
4391e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @pevent: a handle to the pevent
4392e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @rec: the record to parse
4393e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
4394e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This returns the PID from a raw data.
4395e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
4396e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint pevent_data_pid(struct pevent *pevent, struct pevent_record *rec)
4397e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
4398e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return parse_common_pid(pevent, rec->data);
4399e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
4400e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4401e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
4402e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_data_comm_from_pid - return the command line from PID
4403e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @pevent: a handle to the pevent
4404e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @pid: the PID of the task to search for
4405e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
4406e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This returns a pointer to the command line that has the given
4407e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @pid.
4408e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
4409e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengconst char *pevent_data_comm_from_pid(struct pevent *pevent, int pid)
4410e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
4411e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const char *comm;
4412e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4413e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	comm = find_cmdline(pevent, pid);
4414e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return comm;
4415e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
4416e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4417e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
4418e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_data_comm_from_pid - parse the data into the print format
4419e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @s: the trace_seq to write to
4420e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @event: the handle to the event
4421e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @record: the record to read from
4422e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
4423e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This parses the raw @data using the given @event information and
4424e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * writes the print format into the trace_seq.
4425e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
4426e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid pevent_event_info(struct trace_seq *s, struct event_format *event,
4427e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		       struct pevent_record *record)
4428e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
4429e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int print_pretty = 1;
4430e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4431e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (event->pevent->print_raw)
4432e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		print_event_fields(s, record->data, record->size, event);
4433e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	else {
4434e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4435e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (event->handler)
4436e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			print_pretty = event->handler(s, record, event,
4437e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng						      event->context);
4438e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4439e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (print_pretty)
4440e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pretty_print(s, record->data, record->size, event);
4441e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4442e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4443e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	trace_seq_terminate(s);
4444e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
4445e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4446e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid pevent_print_event(struct pevent *pevent, struct trace_seq *s,
4447e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			struct pevent_record *record)
4448e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
4449e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	static const char *spaces = "                    "; /* 20 spaces */
4450e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct event_format *event;
4451e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long secs;
4452e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long usecs;
4453e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long nsecs;
4454e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const char *comm;
4455e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	void *data = record->data;
4456e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int type;
4457e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int pid;
4458e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int len;
4459e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int p;
4460e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4461e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	secs = record->ts / NSECS_PER_SEC;
4462e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	nsecs = record->ts - secs * NSECS_PER_SEC;
4463e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4464e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (record->size < 0) {
4465e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		do_warning("ug! negative record size %d", record->size);
4466e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return;
4467e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4468e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4469e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = trace_parse_common_type(pevent, data);
4470e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4471e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	event = pevent_find_event(pevent, type);
4472e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!event) {
4473e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		do_warning("ug! no event found for type %d", type);
4474e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return;
4475e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4476e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4477e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pid = parse_common_pid(pevent, data);
4478e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	comm = find_cmdline(pevent, pid);
4479e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4480e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (pevent->latency_format) {
4481e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		trace_seq_printf(s, "%8.8s-%-5d %3d",
4482e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		       comm, pid, record->cpu);
4483e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pevent_data_lat_fmt(pevent, s, record);
4484e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	} else
4485e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		trace_seq_printf(s, "%16s-%-5d [%03d]", comm, pid, record->cpu);
4486e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4487e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (pevent->flags & PEVENT_NSEC_OUTPUT) {
4488e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		usecs = nsecs;
4489e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		p = 9;
4490e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	} else {
4491e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		usecs = (nsecs + 500) / NSECS_PER_USEC;
4492e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		p = 6;
4493e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4494e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4495e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	trace_seq_printf(s, " %5lu.%0*lu: %s: ", secs, p, usecs, event->name);
4496e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4497e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* Space out the event names evenly. */
4498e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	len = strlen(event->name);
4499e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (len < 20)
4500e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		trace_seq_printf(s, "%.*s", 20 - len, spaces);
4501e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4502e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent_event_info(s, event, record);
4503e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
4504e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4505e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int events_id_cmp(const void *a, const void *b)
4506e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
4507e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct event_format * const * ea = a;
4508e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct event_format * const * eb = b;
4509e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4510e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if ((*ea)->id < (*eb)->id)
4511e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
4512e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4513e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if ((*ea)->id > (*eb)->id)
4514e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 1;
4515e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4516e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
4517e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
4518e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4519e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int events_name_cmp(const void *a, const void *b)
4520e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
4521e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct event_format * const * ea = a;
4522e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct event_format * const * eb = b;
4523e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int res;
4524e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4525e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	res = strcmp((*ea)->name, (*eb)->name);
4526e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (res)
4527e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return res;
4528e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4529e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	res = strcmp((*ea)->system, (*eb)->system);
4530e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (res)
4531e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return res;
4532e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4533e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return events_id_cmp(a, b);
4534e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
4535e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4536e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int events_system_cmp(const void *a, const void *b)
4537e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
4538e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct event_format * const * ea = a;
4539e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct event_format * const * eb = b;
4540e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int res;
4541e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4542e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	res = strcmp((*ea)->system, (*eb)->system);
4543e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (res)
4544e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return res;
4545e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4546e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	res = strcmp((*ea)->name, (*eb)->name);
4547e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (res)
4548e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return res;
4549e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4550e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return events_id_cmp(a, b);
4551e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
4552e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4553e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct event_format **pevent_list_events(struct pevent *pevent, enum event_sort_type sort_type)
4554e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
4555e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct event_format **events;
4556e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int (*sort)(const void *a, const void *b);
4557e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4558e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	events = pevent->sort_events;
4559e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4560e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (events && pevent->last_type == sort_type)
4561e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return events;
4562e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4563e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!events) {
4564e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		events = malloc(sizeof(*events) * (pevent->nr_events + 1));
4565e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!events)
4566e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return NULL;
4567e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4568e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		memcpy(events, pevent->events, sizeof(*events) * pevent->nr_events);
4569e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		events[pevent->nr_events] = NULL;
4570e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4571e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pevent->sort_events = events;
4572e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4573e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* the internal events are sorted by id */
4574e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (sort_type == EVENT_SORT_ID) {
4575e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pevent->last_type = sort_type;
4576e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return events;
4577e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
4578e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4579e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4580e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	switch (sort_type) {
4581e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case EVENT_SORT_ID:
4582e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		sort = events_id_cmp;
4583e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
4584e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case EVENT_SORT_NAME:
4585e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		sort = events_name_cmp;
4586e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
4587e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case EVENT_SORT_SYSTEM:
4588e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		sort = events_system_cmp;
4589e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
4590e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	default:
4591e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return events;
4592e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4593e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4594e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	qsort(events, pevent->nr_events, sizeof(*events), sort);
4595e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent->last_type = sort_type;
4596e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4597e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return events;
4598e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
4599e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4600e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic struct format_field **
4601e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengget_event_fields(const char *type, const char *name,
4602e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 int count, struct format_field *list)
4603e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
4604e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct format_field **fields;
4605e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct format_field *field;
4606e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int i = 0;
4607e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4608e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	fields = malloc(sizeof(*fields) * (count + 1));
4609e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!fields)
4610e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
4611e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4612e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (field = list; field; field = field->next) {
4613e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		fields[i++] = field;
4614e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (i == count + 1) {
4615e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			do_warning("event %s has more %s fields than specified",
4616e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				name, type);
4617e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			i--;
4618e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
4619e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
4620e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4621e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4622e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (i != count)
4623e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		do_warning("event %s has less %s fields than specified",
4624e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			name, type);
4625e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4626e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	fields[i] = NULL;
4627e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4628e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return fields;
4629e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
4630e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4631e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
4632e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_event_common_fields - return a list of common fields for an event
4633e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @event: the event to return the common fields of.
4634e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
4635e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Returns an allocated array of fields. The last item in the array is NULL.
4636e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * The array must be freed with free().
4637e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
4638e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct format_field **pevent_event_common_fields(struct event_format *event)
4639e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
4640e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return get_event_fields("common", event->name,
4641e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				event->format.nr_common,
4642e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				event->format.common_fields);
4643e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
4644e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4645e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
4646e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_event_fields - return a list of event specific fields for an event
4647e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @event: the event to return the fields of.
4648e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
4649e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Returns an allocated array of fields. The last item in the array is NULL.
4650e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * The array must be freed with free().
4651e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
4652e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct format_field **pevent_event_fields(struct event_format *event)
4653e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
4654e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return get_event_fields("event", event->name,
4655e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				event->format.nr_fields,
4656e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				event->format.fields);
4657e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
4658e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4659e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void print_fields(struct trace_seq *s, struct print_flag_sym *field)
4660e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
4661e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	trace_seq_printf(s, "{ %s, %s }", field->value, field->str);
4662e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (field->next) {
4663e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		trace_seq_puts(s, ", ");
4664e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		print_fields(s, field->next);
4665e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4666e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
4667e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4668e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/* for debugging */
4669e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void print_args(struct print_arg *args)
4670e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
4671e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int print_paren = 1;
4672e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct trace_seq s;
4673e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4674e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	switch (args->type) {
4675e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_NULL:
4676e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		printf("null");
4677e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
4678e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_ATOM:
4679e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		printf("%s", args->atom.atom);
4680e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
4681e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_FIELD:
4682e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		printf("REC->%s", args->field.name);
4683e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
4684e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_FLAGS:
4685e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		printf("__print_flags(");
4686e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		print_args(args->flags.field);
4687e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		printf(", %s, ", args->flags.delim);
4688e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		trace_seq_init(&s);
4689e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		print_fields(&s, args->flags.flags);
4690e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		trace_seq_do_printf(&s);
4691e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		trace_seq_destroy(&s);
4692e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		printf(")");
4693e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
4694e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_SYMBOL:
4695e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		printf("__print_symbolic(");
4696e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		print_args(args->symbol.field);
4697e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		printf(", ");
4698e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		trace_seq_init(&s);
4699e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		print_fields(&s, args->symbol.symbols);
4700e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		trace_seq_do_printf(&s);
4701e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		trace_seq_destroy(&s);
4702e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		printf(")");
4703e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
4704e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_HEX:
4705e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		printf("__print_hex(");
4706e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		print_args(args->hex.field);
4707e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		printf(", ");
4708e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		print_args(args->hex.size);
4709e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		printf(")");
4710e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
4711e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_STRING:
4712e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_BSTRING:
4713e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		printf("__get_str(%s)", args->string.string);
4714e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
4715e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_TYPE:
4716e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		printf("(%s)", args->typecast.type);
4717e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		print_args(args->typecast.item);
4718e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
4719e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PRINT_OP:
4720e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (strcmp(args->op.op, ":") == 0)
4721e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			print_paren = 0;
4722e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (print_paren)
4723e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			printf("(");
4724e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		print_args(args->op.left);
4725e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		printf(" %s ", args->op.op);
4726e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		print_args(args->op.right);
4727e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (print_paren)
4728e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			printf(")");
4729e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
4730e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	default:
4731e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* we should warn... */
4732e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return;
4733e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4734e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (args->next) {
4735e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		printf("\n");
4736e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		print_args(args->next);
4737e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4738e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
4739e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4740e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void parse_header_field(const char *field,
4741e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			       int *offset, int *size, int mandatory)
4742e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
4743e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long long save_input_buf_ptr;
4744e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long long save_input_buf_siz;
4745e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *token;
4746e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int type;
4747e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4748e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	save_input_buf_ptr = input_buf_ptr;
4749e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	save_input_buf_siz = input_buf_siz;
4750e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4751e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expected(EVENT_ITEM, "field") < 0)
4752e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return;
4753e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expected(EVENT_OP, ":") < 0)
4754e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return;
4755e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4756e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* type */
4757e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expect_type(EVENT_ITEM, &token) < 0)
4758e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto fail;
4759e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
4760e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4761e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/*
4762e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 * If this is not a mandatory field, then test it first.
4763e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 */
4764e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (mandatory) {
4765e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (read_expected(EVENT_ITEM, field) < 0)
4766e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return;
4767e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	} else {
4768e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (read_expect_type(EVENT_ITEM, &token) < 0)
4769e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto fail;
4770e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (strcmp(token, field) != 0)
4771e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto discard;
4772e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_token(token);
4773e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4774e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4775e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expected(EVENT_OP, ";") < 0)
4776e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return;
4777e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expected(EVENT_ITEM, "offset") < 0)
4778e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return;
4779e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expected(EVENT_OP, ":") < 0)
4780e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return;
4781e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expect_type(EVENT_ITEM, &token) < 0)
4782e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto fail;
4783e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*offset = atoi(token);
4784e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
4785e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expected(EVENT_OP, ";") < 0)
4786e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return;
4787e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expected(EVENT_ITEM, "size") < 0)
4788e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return;
4789e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expected(EVENT_OP, ":") < 0)
4790e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return;
4791e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expect_type(EVENT_ITEM, &token) < 0)
4792e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto fail;
4793e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*size = atoi(token);
4794e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
4795e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (read_expected(EVENT_OP, ";") < 0)
4796e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return;
4797e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	type = read_token(&token);
4798e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (type != EVENT_NEWLINE) {
4799e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* newer versions of the kernel have a "signed" type */
4800e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (type != EVENT_ITEM)
4801e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto fail;
4802e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4803e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (strcmp(token, "signed") != 0)
4804e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto fail;
4805e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4806e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_token(token);
4807e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4808e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (read_expected(EVENT_OP, ":") < 0)
4809e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return;
4810e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4811e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (read_expect_type(EVENT_ITEM, &token))
4812e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto fail;
4813e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4814e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_token(token);
4815e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (read_expected(EVENT_OP, ";") < 0)
4816e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return;
4817e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4818e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (read_expect_type(EVENT_NEWLINE, &token))
4819e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto fail;
4820e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4821e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng fail:
4822e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
4823e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return;
4824e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4825e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng discard:
4826e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	input_buf_ptr = save_input_buf_ptr;
4827e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	input_buf_siz = save_input_buf_siz;
4828e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*offset = 0;
4829e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*size = 0;
4830e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_token(token);
4831e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
4832e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4833e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
4834e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_parse_header_page - parse the data stored in the header page
4835e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @pevent: the handle to the pevent
4836e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @buf: the buffer storing the header page format string
4837e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @size: the size of @buf
4838e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @long_size: the long size to use if there is no header
4839e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
4840e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This parses the header page format for information on the
4841e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * ring buffer used. The @buf should be copied from
4842e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
4843e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * /sys/kernel/debug/tracing/events/header_page
4844e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
4845e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long size,
4846e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			     int long_size)
4847e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
4848e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int ignore;
4849e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4850e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!size) {
4851e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/*
4852e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 * Old kernels did not have header page info.
4853e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 * Sorry but we just use what we find here in user space.
4854e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 */
4855e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pevent->header_page_ts_size = sizeof(long long);
4856e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pevent->header_page_size_size = long_size;
4857e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pevent->header_page_data_offset = sizeof(long long) + long_size;
4858e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pevent->old_format = 1;
4859e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
4860e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4861e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	init_input_buf(buf, size);
4862e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4863e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	parse_header_field("timestamp", &pevent->header_page_ts_offset,
4864e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			   &pevent->header_page_ts_size, 1);
4865e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	parse_header_field("commit", &pevent->header_page_size_offset,
4866e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			   &pevent->header_page_size_size, 1);
4867e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	parse_header_field("overwrite", &pevent->header_page_overwrite,
4868e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			   &ignore, 0);
4869e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	parse_header_field("data", &pevent->header_page_data_offset,
4870e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			   &pevent->header_page_data_size, 1);
4871e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4872e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
4873e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
4874e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4875e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int event_matches(struct event_format *event,
4876e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			 int id, const char *sys_name,
4877e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			 const char *event_name)
4878e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
4879e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (id >= 0 && id != event->id)
4880e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 0;
4881e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4882e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (event_name && (strcmp(event_name, event->name) != 0))
4883e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 0;
4884e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4885e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (sys_name && (strcmp(sys_name, event->system) != 0))
4886e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 0;
4887e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4888e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 1;
4889e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
4890e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4891e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void free_handler(struct event_handler *handle)
4892e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
4893e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free((void *)handle->sys_name);
4894e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free((void *)handle->event_name);
4895e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free(handle);
4896e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
4897e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4898e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int find_event_handle(struct pevent *pevent, struct event_format *event)
4899e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
4900e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct event_handler *handle, **next;
4901e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4902e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (next = &pevent->handlers; *next;
4903e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	     next = &(*next)->next) {
4904e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		handle = *next;
4905e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (event_matches(event, handle->id,
4906e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				  handle->sys_name,
4907e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				  handle->event_name))
4908e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
4909e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4910e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4911e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!(*next))
4912e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 0;
4913e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4914e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pr_stat("overriding event (%d) %s:%s with new print handler",
4915e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		event->id, event->system, event->name);
4916e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4917e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	event->handler = handle->func;
4918e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	event->context = handle->context;
4919e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4920e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*next = handle->next;
4921e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_handler(handle);
4922e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4923e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 1;
4924e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
4925e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4926e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
4927e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * __pevent_parse_format - parse the event format
4928e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @buf: the buffer storing the event format string
4929e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @size: the size of @buf
4930e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @sys: the system the event belongs to
4931e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
4932e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This parses the event format and creates an event structure
4933e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * to quickly parse raw data for a given event.
4934e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
4935e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * These files currently come from:
4936e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
4937e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * /sys/kernel/debug/tracing/events/.../.../format
4938e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
4939e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengenum pevent_errno __pevent_parse_format(struct event_format **eventp,
4940e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					struct pevent *pevent, const char *buf,
4941e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					unsigned long size, const char *sys)
4942e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
4943e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct event_format *event;
4944e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int ret;
4945e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4946e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	init_input_buf(buf, size);
4947e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4948e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*eventp = event = alloc_event();
4949e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!event)
4950e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return PEVENT_ERRNO__MEM_ALLOC_FAILED;
4951e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4952e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	event->name = event_read_name();
4953e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!event->name) {
4954e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* Bad event? */
4955e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ret = PEVENT_ERRNO__MEM_ALLOC_FAILED;
4956e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto event_alloc_failed;
4957e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4958e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4959e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (strcmp(sys, "ftrace") == 0) {
4960e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		event->flags |= EVENT_FL_ISFTRACE;
4961e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4962e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (strcmp(event->name, "bprint") == 0)
4963e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			event->flags |= EVENT_FL_ISBPRINT;
4964e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4965e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4966e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	event->id = event_read_id();
4967e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (event->id < 0) {
4968e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ret = PEVENT_ERRNO__READ_ID_FAILED;
4969e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/*
4970e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 * This isn't an allocation error actually.
4971e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 * But as the ID is critical, just bail out.
4972e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 */
4973e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto event_alloc_failed;
4974e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4975e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4976e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	event->system = strdup(sys);
4977e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!event->system) {
4978e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ret = PEVENT_ERRNO__MEM_ALLOC_FAILED;
4979e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto event_alloc_failed;
4980e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4981e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4982e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* Add pevent to event so that it can be referenced */
4983e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	event->pevent = pevent;
4984e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4985e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ret = event_read_format(event);
4986e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (ret < 0) {
4987e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ret = PEVENT_ERRNO__READ_FORMAT_FAILED;
4988e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto event_parse_failed;
4989e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
4990e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4991e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/*
4992e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 * If the event has an override, don't print warnings if the event
4993e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 * print format fails to parse.
4994e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 */
4995e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (pevent && find_event_handle(pevent, event))
4996e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		show_warning = 0;
4997e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4998e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ret = event_read_print(event);
4999e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	show_warning = 1;
5000e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5001e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (ret < 0) {
5002e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ret = PEVENT_ERRNO__READ_PRINT_FAILED;
5003e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto event_parse_failed;
5004e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
5005e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5006e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!ret && (event->flags & EVENT_FL_ISFTRACE)) {
5007e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		struct format_field *field;
5008e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		struct print_arg *arg, **list;
5009e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5010e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* old ftrace had no args */
5011e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		list = &event->print_fmt.args;
5012e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		for (field = event->format.fields; field; field = field->next) {
5013e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			arg = alloc_arg();
5014e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!arg) {
5015e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				event->flags |= EVENT_FL_FAILED;
5016e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				return PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED;
5017e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
5018e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			arg->type = PRINT_FIELD;
5019e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			arg->field.name = strdup(field->name);
5020e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!arg->field.name) {
5021e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				event->flags |= EVENT_FL_FAILED;
5022e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				free_arg(arg);
5023e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				return PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED;
5024e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
5025e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			arg->field.field = field;
5026e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			*list = arg;
5027e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			list = &arg->next;
5028e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
5029e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 0;
5030e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
5031e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5032e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
5033e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5034e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event_parse_failed:
5035e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	event->flags |= EVENT_FL_FAILED;
5036e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return ret;
5037e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5038e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event_alloc_failed:
5039e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free(event->system);
5040e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free(event->name);
5041e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free(event);
5042e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*eventp = NULL;
5043e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return ret;
5044e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
5045e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5046e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
5047e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_parse_format - parse the event format
5048e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @buf: the buffer storing the event format string
5049e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @size: the size of @buf
5050e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @sys: the system the event belongs to
5051e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
5052e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This parses the event format and creates an event structure
5053e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * to quickly parse raw data for a given event.
5054e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
5055e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * These files currently come from:
5056e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
5057e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * /sys/kernel/debug/tracing/events/.../.../format
5058e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
5059e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengenum pevent_errno pevent_parse_format(struct event_format **eventp, const char *buf,
5060e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				      unsigned long size, const char *sys)
5061e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
5062e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return __pevent_parse_format(eventp, NULL, buf, size, sys);
5063e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
5064e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5065e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
5066e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_parse_event - parse the event format
5067e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @pevent: the handle to the pevent
5068e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @buf: the buffer storing the event format string
5069e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @size: the size of @buf
5070e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @sys: the system the event belongs to
5071e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
5072e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This parses the event format and creates an event structure
5073e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * to quickly parse raw data for a given event.
5074e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
5075e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * These files currently come from:
5076e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
5077e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * /sys/kernel/debug/tracing/events/.../.../format
5078e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
5079e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengenum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf,
5080e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				     unsigned long size, const char *sys)
5081e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
5082e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct event_format *event = NULL;
5083e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int ret = __pevent_parse_format(&event, pevent, buf, size, sys);
5084e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5085e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (event == NULL)
5086e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return ret;
5087e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5088e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (add_event(pevent, event)) {
5089e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ret = PEVENT_ERRNO__MEM_ALLOC_FAILED;
5090e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto event_add_failed;
5091e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
5092e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5093e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define PRINT_ARGS 0
5094e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (PRINT_ARGS && event->print_fmt.args)
5095e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		print_args(event->print_fmt.args);
5096e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5097e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
5098e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5099e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengevent_add_failed:
5100e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent_free_format(event);
5101e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return ret;
5102e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
5103e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5104e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#undef _PE
5105e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define _PE(code, str) str
5106e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic const char * const pevent_error_str[] = {
5107e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PEVENT_ERRORS
5108e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
5109e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#undef _PE
5110e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5111e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint pevent_strerror(struct pevent *pevent __maybe_unused,
5112e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		    enum pevent_errno errnum, char *buf, size_t buflen)
5113e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
5114e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int idx;
5115e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const char *msg;
5116e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5117e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (errnum >= 0) {
5118e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		msg = strerror_r(errnum, buf, buflen);
5119e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (msg != buf) {
5120e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			size_t len = strlen(msg);
5121e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			memcpy(buf, msg, min(buflen - 1, len));
5122e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			*(buf + min(buflen - 1, len)) = '\0';
5123e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
5124e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 0;
5125e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
5126e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5127e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (errnum <= __PEVENT_ERRNO__START ||
5128e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    errnum >= __PEVENT_ERRNO__END)
5129e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
5130e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5131e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	idx = errnum - __PEVENT_ERRNO__START - 1;
5132e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	msg = pevent_error_str[idx];
5133e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5134e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	switch (errnum) {
5135e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PEVENT_ERRNO__MEM_ALLOC_FAILED:
5136e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PEVENT_ERRNO__PARSE_EVENT_FAILED:
5137e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PEVENT_ERRNO__READ_ID_FAILED:
5138e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PEVENT_ERRNO__READ_FORMAT_FAILED:
5139e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PEVENT_ERRNO__READ_PRINT_FAILED:
5140e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED:
5141e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	case PEVENT_ERRNO__INVALID_ARG_TYPE:
5142e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		snprintf(buf, buflen, "%s", msg);
5143e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
5144e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5145e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	default:
5146e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* cannot reach here */
5147e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		break;
5148e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
5149e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5150e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
5151e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
5152e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5153e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint get_field_val(struct trace_seq *s, struct format_field *field,
5154e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		  const char *name, struct pevent_record *record,
5155e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		  unsigned long long *val, int err)
5156e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
5157e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!field) {
5158e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (err)
5159e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			trace_seq_printf(s, "<CANT FIND FIELD %s>", name);
5160e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
5161e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
5162e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5163e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (pevent_read_number_field(field, record->data, val)) {
5164e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (err)
5165e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			trace_seq_printf(s, " %s=INVALID", name);
5166e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
5167e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
5168e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5169e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
5170e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
5171e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5172e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
5173e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_get_field_raw - return the raw pointer into the data field
5174e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @s: The seq to print to on error
5175e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @event: the event that the field is for
5176e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @name: The name of the field
5177e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @record: The record with the field name.
5178e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @len: place to store the field length.
5179e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @err: print default error if failed.
5180e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
5181e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Returns a pointer into record->data of the field and places
5182e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * the length of the field in @len.
5183e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
5184e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * On failure, it returns NULL.
5185e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
5186e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid *pevent_get_field_raw(struct trace_seq *s, struct event_format *event,
5187e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			   const char *name, struct pevent_record *record,
5188e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			   int *len, int err)
5189e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
5190e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct format_field *field;
5191e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	void *data = record->data;
5192e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned offset;
5193e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int dummy;
5194e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5195e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!event)
5196e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
5197e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5198e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	field = pevent_find_field(event, name);
5199e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5200e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!field) {
5201e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (err)
5202e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			trace_seq_printf(s, "<CANT FIND FIELD %s>", name);
5203e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
5204e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
5205e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5206e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* Allow @len to be NULL */
5207e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!len)
5208e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		len = &dummy;
5209e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5210e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	offset = field->offset;
5211e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (field->flags & FIELD_IS_DYNAMIC) {
5212e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		offset = pevent_read_number(event->pevent,
5213e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					    data + offset, field->size);
5214e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*len = offset >> 16;
5215e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		offset &= 0xffff;
5216e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	} else
5217e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*len = field->size;
5218e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5219e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return data + offset;
5220e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
5221e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5222e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
5223e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_get_field_val - find a field and return its value
5224e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @s: The seq to print to on error
5225e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @event: the event that the field is for
5226e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @name: The name of the field
5227e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @record: The record with the field name.
5228e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @val: place to store the value of the field.
5229e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @err: print default error if failed.
5230e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
5231e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Returns 0 on success -1 on field not found.
5232e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
5233e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint pevent_get_field_val(struct trace_seq *s, struct event_format *event,
5234e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			 const char *name, struct pevent_record *record,
5235e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			 unsigned long long *val, int err)
5236e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
5237e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct format_field *field;
5238e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5239e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!event)
5240e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
5241e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5242e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	field = pevent_find_field(event, name);
5243e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5244e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return get_field_val(s, field, name, record, val, err);
5245e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
5246e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5247e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
5248e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_get_common_field_val - find a common field and return its value
5249e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @s: The seq to print to on error
5250e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @event: the event that the field is for
5251e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @name: The name of the field
5252e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @record: The record with the field name.
5253e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @val: place to store the value of the field.
5254e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @err: print default error if failed.
5255e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
5256e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Returns 0 on success -1 on field not found.
5257e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
5258e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint pevent_get_common_field_val(struct trace_seq *s, struct event_format *event,
5259e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				const char *name, struct pevent_record *record,
5260e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				unsigned long long *val, int err)
5261e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
5262e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct format_field *field;
5263e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5264e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!event)
5265e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
5266e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5267e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	field = pevent_find_common_field(event, name);
5268e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5269e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return get_field_val(s, field, name, record, val, err);
5270e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
5271e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5272e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
5273e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_get_any_field_val - find a any field and return its value
5274e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @s: The seq to print to on error
5275e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @event: the event that the field is for
5276e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @name: The name of the field
5277e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @record: The record with the field name.
5278e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @val: place to store the value of the field.
5279e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @err: print default error if failed.
5280e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
5281e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Returns 0 on success -1 on field not found.
5282e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
5283e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint pevent_get_any_field_val(struct trace_seq *s, struct event_format *event,
5284e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			     const char *name, struct pevent_record *record,
5285e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			     unsigned long long *val, int err)
5286e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
5287e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct format_field *field;
5288e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5289e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!event)
5290e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
5291e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5292e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	field = pevent_find_any_field(event, name);
5293e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5294e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return get_field_val(s, field, name, record, val, err);
5295e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
5296e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5297e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
5298e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_print_num_field - print a field and a format
5299e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @s: The seq to print to
5300e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @fmt: The printf format to print the field with.
5301e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @event: the event that the field is for
5302e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @name: The name of the field
5303e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @record: The record with the field name.
5304e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @err: print default error if failed.
5305e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
5306e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Returns: 0 on success, -1 field not found, or 1 if buffer is full.
5307e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
5308e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint pevent_print_num_field(struct trace_seq *s, const char *fmt,
5309e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			   struct event_format *event, const char *name,
5310e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			   struct pevent_record *record, int err)
5311e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
5312e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct format_field *field = pevent_find_field(event, name);
5313e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long long val;
5314e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5315e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!field)
5316e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto failed;
5317e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5318e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (pevent_read_number_field(field, record->data, &val))
5319e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto failed;
5320e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5321e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return trace_seq_printf(s, fmt, val);
5322e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5323e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng failed:
5324e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (err)
5325e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		trace_seq_printf(s, "CAN'T FIND FIELD \"%s\"", name);
5326e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return -1;
5327e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
5328e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5329e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void free_func_handle(struct pevent_function_handler *func)
5330e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
5331e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pevent_func_params *params;
5332e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5333e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free(func->name);
5334e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5335e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (func->params) {
5336e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		params = func->params;
5337e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		func->params = params->next;
5338e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(params);
5339e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
5340e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5341e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free(func);
5342e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
5343e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5344e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
5345e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_register_print_function - register a helper function
5346e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @pevent: the handle to the pevent
5347e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @func: the function to process the helper function
5348e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @ret_type: the return type of the helper function
5349e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @name: the name of the helper function
5350e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @parameters: A list of enum pevent_func_arg_type
5351e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
5352e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Some events may have helper functions in the print format arguments.
5353e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This allows a plugin to dynamically create a way to process one
5354e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * of these functions.
5355e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
5356e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * The @parameters is a variable list of pevent_func_arg_type enums that
5357e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * must end with PEVENT_FUNC_ARG_VOID.
5358e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
5359e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint pevent_register_print_function(struct pevent *pevent,
5360e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				   pevent_func_handler func,
5361e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				   enum pevent_func_arg_type ret_type,
5362e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				   char *name, ...)
5363e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
5364e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pevent_function_handler *func_handle;
5365e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pevent_func_params **next_param;
5366e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pevent_func_params *param;
5367e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	enum pevent_func_arg_type type;
5368e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	va_list ap;
5369e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int ret;
5370e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5371e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	func_handle = find_func_handler(pevent, name);
5372e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (func_handle) {
5373e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/*
5374e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 * This is most like caused by the users own
5375e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 * plugins updating the function. This overrides the
5376e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 * system defaults.
5377e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 */
5378e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pr_stat("override of function helper '%s'", name);
5379e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		remove_func_handler(pevent, name);
5380e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
5381e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5382e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	func_handle = calloc(1, sizeof(*func_handle));
5383e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!func_handle) {
5384e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		do_warning("Failed to allocate function handler");
5385e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return PEVENT_ERRNO__MEM_ALLOC_FAILED;
5386e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
5387e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5388e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	func_handle->ret_type = ret_type;
5389e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	func_handle->name = strdup(name);
5390e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	func_handle->func = func;
5391e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!func_handle->name) {
5392e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		do_warning("Failed to allocate function name");
5393e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(func_handle);
5394e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return PEVENT_ERRNO__MEM_ALLOC_FAILED;
5395e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
5396e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5397e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	next_param = &(func_handle->params);
5398e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	va_start(ap, name);
5399e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (;;) {
5400e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		type = va_arg(ap, enum pevent_func_arg_type);
5401e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (type == PEVENT_FUNC_ARG_VOID)
5402e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
5403e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5404e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (type >= PEVENT_FUNC_ARG_MAX_TYPES) {
5405e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			do_warning("Invalid argument type %d", type);
5406e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			ret = PEVENT_ERRNO__INVALID_ARG_TYPE;
5407e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto out_free;
5408e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
5409e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5410e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		param = malloc(sizeof(*param));
5411e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!param) {
5412e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			do_warning("Failed to allocate function param");
5413e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			ret = PEVENT_ERRNO__MEM_ALLOC_FAILED;
5414e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto out_free;
5415e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
5416e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		param->type = type;
5417e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		param->next = NULL;
5418e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5419e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*next_param = param;
5420e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		next_param = &(param->next);
5421e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5422e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		func_handle->nr_args++;
5423e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
5424e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	va_end(ap);
5425e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5426e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	func_handle->next = pevent->func_handlers;
5427e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent->func_handlers = func_handle;
5428e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5429e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
5430e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng out_free:
5431e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	va_end(ap);
5432e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_func_handle(func_handle);
5433e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return ret;
5434e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
5435e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5436e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
5437e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_register_event_handler - register a way to parse an event
5438e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @pevent: the handle to the pevent
5439e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @id: the id of the event to register
5440e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @sys_name: the system name the event belongs to
5441e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @event_name: the name of the event
5442e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @func: the function to call to parse the event information
5443e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @context: the data to be passed to @func
5444e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
5445e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This function allows a developer to override the parsing of
5446e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * a given event. If for some reason the default print format
5447e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * is not sufficient, this function will register a function
5448e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * for an event to be used to parse the data instead.
5449e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
5450e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * If @id is >= 0, then it is used to find the event.
5451e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * else @sys_name and @event_name are used.
5452e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
5453e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint pevent_register_event_handler(struct pevent *pevent, int id,
5454e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				  const char *sys_name, const char *event_name,
5455e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				  pevent_event_handler_func func, void *context)
5456e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
5457e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct event_format *event;
5458e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct event_handler *handle;
5459e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5460e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (id >= 0) {
5461e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* search by id */
5462e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		event = pevent_find_event(pevent, id);
5463e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!event)
5464e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto not_found;
5465e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (event_name && (strcmp(event_name, event->name) != 0))
5466e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto not_found;
5467e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (sys_name && (strcmp(sys_name, event->system) != 0))
5468e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto not_found;
5469e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	} else {
5470e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		event = pevent_find_event_by_name(pevent, sys_name, event_name);
5471e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!event)
5472e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto not_found;
5473e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
5474e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5475e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pr_stat("overriding event (%d) %s:%s with new print handler",
5476e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		event->id, event->system, event->name);
5477e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5478e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	event->handler = func;
5479e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	event->context = context;
5480e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
5481e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5482e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng not_found:
5483e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* Save for later use. */
5484e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	handle = calloc(1, sizeof(*handle));
5485e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!handle) {
5486e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		do_warning("Failed to allocate event handler");
5487e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return PEVENT_ERRNO__MEM_ALLOC_FAILED;
5488e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
5489e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5490e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	handle->id = id;
5491e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (event_name)
5492e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		handle->event_name = strdup(event_name);
5493e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (sys_name)
5494e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		handle->sys_name = strdup(sys_name);
5495e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5496e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if ((event_name && !handle->event_name) ||
5497e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    (sys_name && !handle->sys_name)) {
5498e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		do_warning("Failed to allocate event/sys name");
5499e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free((void *)handle->event_name);
5500e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free((void *)handle->sys_name);
5501e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(handle);
5502e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return PEVENT_ERRNO__MEM_ALLOC_FAILED;
5503e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
5504e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5505e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	handle->func = func;
5506e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	handle->next = pevent->handlers;
5507e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent->handlers = handle;
5508e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	handle->context = context;
5509e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5510e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return -1;
5511e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
5512e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5513e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
5514e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_alloc - create a pevent handle
5515e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
5516e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct pevent *pevent_alloc(void)
5517e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
5518e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pevent *pevent = calloc(1, sizeof(*pevent));
5519e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5520e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (pevent)
5521e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pevent->ref_count = 1;
5522e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5523e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return pevent;
5524e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
5525e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5526e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid pevent_ref(struct pevent *pevent)
5527e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
5528e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent->ref_count++;
5529e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
5530e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5531e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void free_format_fields(struct format_field *field)
5532e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
5533e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct format_field *next;
5534e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5535e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (field) {
5536e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		next = field->next;
5537e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(field->type);
5538e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(field->name);
5539e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(field);
5540e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		field = next;
5541e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
5542e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
5543e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5544e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void free_formats(struct format *format)
5545e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
5546e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_format_fields(format->common_fields);
5547e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_format_fields(format->fields);
5548e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
5549e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5550e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid pevent_free_format(struct event_format *event)
5551e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
5552e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free(event->name);
5553e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free(event->system);
5554e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5555e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_formats(&event->format);
5556e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5557e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free(event->print_fmt.format);
5558e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free_args(event->print_fmt.args);
5559e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5560e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free(event);
5561e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
5562e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5563e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
5564e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * pevent_free - free a pevent handle
5565e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @pevent: the pevent handle to free
5566e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
5567e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid pevent_free(struct pevent *pevent)
5568e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
5569e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct cmdline_list *cmdlist, *cmdnext;
5570e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct func_list *funclist, *funcnext;
5571e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct printk_list *printklist, *printknext;
5572e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pevent_function_handler *func_handler;
5573e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct event_handler *handle;
5574e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int i;
5575e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5576e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!pevent)
5577e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return;
5578e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5579e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	cmdlist = pevent->cmdlist;
5580e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	funclist = pevent->funclist;
5581e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	printklist = pevent->printklist;
5582e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5583e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent->ref_count--;
5584e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (pevent->ref_count)
5585e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return;
5586e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5587e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (pevent->cmdlines) {
5588e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		for (i = 0; i < pevent->cmdline_count; i++)
5589e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			free(pevent->cmdlines[i].comm);
5590e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(pevent->cmdlines);
5591e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
5592e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5593e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (cmdlist) {
5594e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		cmdnext = cmdlist->next;
5595e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(cmdlist->comm);
5596e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(cmdlist);
5597e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		cmdlist = cmdnext;
5598e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
5599e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5600e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (pevent->func_map) {
5601e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		for (i = 0; i < (int)pevent->func_count; i++) {
5602e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			free(pevent->func_map[i].func);
5603e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			free(pevent->func_map[i].mod);
5604e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
5605e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(pevent->func_map);
5606e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
5607e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5608e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (funclist) {
5609e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		funcnext = funclist->next;
5610e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(funclist->func);
5611e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(funclist->mod);
5612e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(funclist);
5613e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		funclist = funcnext;
5614e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
5615e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5616e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (pevent->func_handlers) {
5617e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		func_handler = pevent->func_handlers;
5618e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pevent->func_handlers = func_handler->next;
5619e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_func_handle(func_handler);
5620e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
5621e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5622e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (pevent->printk_map) {
5623e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		for (i = 0; i < (int)pevent->printk_count; i++)
5624e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			free(pevent->printk_map[i].printk);
5625e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(pevent->printk_map);
5626e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
5627e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5628e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (printklist) {
5629e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		printknext = printklist->next;
5630e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(printklist->printk);
5631e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(printklist);
5632e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		printklist = printknext;
5633e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
5634e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5635e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (i = 0; i < pevent->nr_events; i++)
5636e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pevent_free_format(pevent->events[i]);
5637e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5638e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (pevent->handlers) {
5639e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		handle = pevent->handlers;
5640e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pevent->handlers = handle->next;
5641e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free_handler(handle);
5642e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
5643e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5644e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free(pevent->events);
5645e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free(pevent->sort_events);
5646e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5647e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free(pevent);
5648e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
5649e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
5650e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid pevent_unref(struct pevent *pevent)
5651e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
5652e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent_free(pevent);
5653e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
5654