Merge remote-tracking branch 'pmaydell/arm-devs.next' into staging
[qemu/agraf.git] / trace / control.c
blob49f61e137b5b8f7e1156eb460dc7754d18db13be
1 /*
2 * Interface for configuring and controlling the state of tracing events.
4 * Copyright (C) 2011-2012 LluĂ­s Vilanova <vilanova@ac.upc.edu>
6 * This work is licensed under the terms of the GNU GPL, version 2 or later.
7 * See the COPYING file in the top-level directory.
8 */
10 #include "trace/control.h"
13 TraceEvent *trace_event_name(const char *name)
15 assert(name != NULL);
17 TraceEventID i;
18 for (i = 0; i < trace_event_count(); i++) {
19 TraceEvent *ev = trace_event_id(i);
20 if (strcmp(trace_event_get_name(ev), name) == 0) {
21 return ev;
24 return NULL;
27 static bool pattern_glob(const char *pat, const char *ev)
29 while (*pat != '\0' && *ev != '\0') {
30 if (*pat == *ev) {
31 pat++;
32 ev++;
34 else if (*pat == '*') {
35 if (pattern_glob(pat, ev+1)) {
36 return true;
37 } else if (pattern_glob(pat+1, ev)) {
38 return true;
39 } else {
40 return false;
42 } else {
43 return false;
47 while (*pat == '*') {
48 pat++;
51 if (*pat == '\0' && *ev == '\0') {
52 return true;
53 } else {
54 return false;
58 TraceEvent *trace_event_pattern(const char *pat, TraceEvent *ev)
60 assert(pat != NULL);
62 TraceEventID i;
64 if (ev == NULL) {
65 i = -1;
66 } else {
67 i = trace_event_get_id(ev);
69 i++;
71 while (i < trace_event_count()) {
72 TraceEvent *res = trace_event_id(i);
73 if (pattern_glob(pat, trace_event_get_name(res))) {
74 return res;
76 i++;
79 return NULL;
82 void trace_backend_init_events(const char *fname)
84 if (fname == NULL) {
85 return;
88 FILE *fp = fopen(fname, "r");
89 if (!fp) {
90 fprintf(stderr, "error: could not open trace events file '%s': %s\n",
91 fname, strerror(errno));
92 exit(1);
94 char line_buf[1024];
95 while (fgets(line_buf, sizeof(line_buf), fp)) {
96 size_t len = strlen(line_buf);
97 if (len > 1) { /* skip empty lines */
98 line_buf[len - 1] = '\0';
99 if ('#' == line_buf[0]) { /* skip commented lines */
100 continue;
102 const bool enable = ('-' != line_buf[0]);
103 char *line_ptr = enable ? line_buf : line_buf + 1;
104 if (trace_event_is_pattern(line_ptr)) {
105 TraceEvent *ev = NULL;
106 while ((ev = trace_event_pattern(line_ptr, ev)) != NULL) {
107 if (trace_event_get_state_static(ev)) {
108 trace_event_set_state_dynamic(ev, enable);
111 } else {
112 TraceEvent *ev = trace_event_name(line_ptr);
113 if (ev == NULL) {
114 fprintf(stderr,
115 "error: trace event '%s' does not exist\n", line_ptr);
116 exit(1);
118 if (!trace_event_get_state_static(ev)) {
119 fprintf(stderr,
120 "error: trace event '%s' is not traceable\n", line_ptr);
121 exit(1);
123 trace_event_set_state_dynamic(ev, enable);
127 if (fclose(fp) != 0) {
128 fprintf(stderr, "error: closing file '%s': %s\n",
129 fname, strerror(errno));
130 exit(1);