1/**
2 * @file op_parse_event.c
3 * event parsing
4 *
5 * You can have silliness here.
6 *
7 * @remark Copyright 2002 OProfile authors
8 * @remark Read the file COPYING
9 *
10 * @author John Levon
11 * @author Philippe Elie
12 */
13
14#include <stdio.h>
15#include <stdlib.h>
16
17#include "op_parse_event.h"
18#include "op_string.h"
19
20static char * next_part(char const ** str)
21{
22	char const * c;
23	char * ret;
24
25	if ((*str)[0] == '\0')
26		return NULL;
27
28	if ((*str)[0] == ':')
29		++(*str);
30
31	c = *str;
32
33	while (*c != '\0' && *c != ':')
34		++c;
35
36	if (c == *str)
37		return NULL;
38
39	ret = op_xstrndup(*str, c - *str);
40	*str += c - *str;
41	return ret;
42}
43
44
45static int parse_ulong(char const * str)
46{
47	unsigned long value;
48	char * end;
49	value = strtoul(str, &end, 0);
50	if (end && *end) {
51		fprintf(stderr, "Invalid event part %s\n", str);
52		exit(EXIT_FAILURE);
53	}
54
55	return value;
56}
57
58
59size_t parse_events(struct parsed_event * parsed_events, size_t max_events,
60                  char const * const * events)
61{
62	size_t i = 0;
63
64	while (events[i]) {
65		char const * cp = events[i];
66		char * part = next_part(&cp);
67
68		if (i >= max_events) {
69			fprintf(stderr, "Too many events specified: CPU "
70			        "only has %lu counters.\n",
71				(unsigned long) max_events);
72			exit(EXIT_FAILURE);
73		}
74
75		if (!part) {
76			fprintf(stderr, "Invalid event %s\n", cp);
77			exit(EXIT_FAILURE);
78		}
79
80		parsed_events[i].name = part;
81
82		part = next_part(&cp);
83
84		if (!part) {
85			fprintf(stderr, "Invalid count for event %s\n", events[i]);
86			exit(EXIT_FAILURE);
87		}
88
89		parsed_events[i].count = parse_ulong(part);
90		free(part);
91
92		parsed_events[i].unit_mask = 0;
93		part = next_part(&cp);
94
95		if (part) {
96			parsed_events[i].unit_mask_valid = 1;
97			parsed_events[i].unit_mask = parse_ulong(part);
98			free(part);
99		}
100
101		parsed_events[i].kernel = 1;
102		part = next_part(&cp);
103
104		if (part) {
105			parsed_events[i].kernel = parse_ulong(part);
106			free(part);
107		}
108
109		parsed_events[i].user = 1;
110		part = next_part(&cp);
111
112		if (part) {
113			parsed_events[i].user = parse_ulong(part);
114			free(part);
115		}
116
117		++i;
118	}
119
120	return i;
121}
122