| /* | 
 |  * HMP commands related to tracing | 
 |  * | 
 |  * Copyright (c) 2003-2004 Fabrice Bellard | 
 |  * | 
 |  * Permission is hereby granted, free of charge, to any person obtaining a copy | 
 |  * of this software and associated documentation files (the "Software"), to deal | 
 |  * in the Software without restriction, including without limitation the rights | 
 |  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | 
 |  * copies of the Software, and to permit persons to whom the Software is | 
 |  * furnished to do so, subject to the following conditions: | 
 |  * | 
 |  * The above copyright notice and this permission notice shall be included in | 
 |  * all copies or substantial portions of the Software. | 
 |  * | 
 |  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 
 |  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
 |  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | 
 |  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | 
 |  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | 
 |  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | 
 |  * THE SOFTWARE. | 
 |  */ | 
 |  | 
 | #include "qemu/osdep.h" | 
 | #include "monitor/hmp.h" | 
 | #include "monitor/monitor.h" | 
 | #include "qapi/error.h" | 
 | #include "qapi/qapi-commands-trace.h" | 
 | #include "qapi/qmp/qdict.h" | 
 | #include "trace/control.h" | 
 | #ifdef CONFIG_TRACE_SIMPLE | 
 | #include "trace/simple.h" | 
 | #endif | 
 |  | 
 | void hmp_trace_event(Monitor *mon, const QDict *qdict) | 
 | { | 
 |     const char *tp_name = qdict_get_str(qdict, "name"); | 
 |     bool new_state = qdict_get_bool(qdict, "option"); | 
 |     Error *local_err = NULL; | 
 |  | 
 |     qmp_trace_event_set_state(tp_name, new_state, | 
 |                               true, true, false, 0, &local_err); | 
 |     if (local_err) { | 
 |         error_report_err(local_err); | 
 |     } | 
 | } | 
 |  | 
 | #ifdef CONFIG_TRACE_SIMPLE | 
 | void hmp_trace_file(Monitor *mon, const QDict *qdict) | 
 | { | 
 |     const char *op = qdict_get_try_str(qdict, "op"); | 
 |     const char *arg = qdict_get_try_str(qdict, "arg"); | 
 |  | 
 |     if (!op) { | 
 |         st_print_trace_file_status(); | 
 |     } else if (!strcmp(op, "on")) { | 
 |         st_set_trace_file_enabled(true); | 
 |     } else if (!strcmp(op, "off")) { | 
 |         st_set_trace_file_enabled(false); | 
 |     } else if (!strcmp(op, "flush")) { | 
 |         st_flush_trace_buffer(); | 
 |     } else if (!strcmp(op, "set")) { | 
 |         if (arg) { | 
 |             st_set_trace_file(arg); | 
 |         } | 
 |     } else { | 
 |         monitor_printf(mon, "unexpected argument \"%s\"\n", op); | 
 |         hmp_help_cmd(mon, "trace-file"); | 
 |     } | 
 | } | 
 | #endif | 
 |  | 
 | void hmp_info_trace_events(Monitor *mon, const QDict *qdict) | 
 | { | 
 |     const char *name = qdict_get_try_str(qdict, "name"); | 
 |     TraceEventInfoList *events; | 
 |     TraceEventInfoList *elem; | 
 |     Error *local_err = NULL; | 
 |  | 
 |     if (name == NULL) { | 
 |         name = "*"; | 
 |     } | 
 |  | 
 |     events = qmp_trace_event_get_state(name, false, 0, &local_err); | 
 |     if (local_err) { | 
 |         error_report_err(local_err); | 
 |         return; | 
 |     } | 
 |  | 
 |     for (elem = events; elem != NULL; elem = elem->next) { | 
 |         monitor_printf(mon, "%s : state %u\n", | 
 |                        elem->value->name, | 
 |                        elem->value->state == TRACE_EVENT_STATE_ENABLED ? 1 : 0); | 
 |     } | 
 |     qapi_free_TraceEventInfoList(events); | 
 | } | 
 |  | 
 | void info_trace_events_completion(ReadLineState *rs, int nb_args, const char *str) | 
 | { | 
 |     size_t len; | 
 |  | 
 |     len = strlen(str); | 
 |     readline_set_completion_index(rs, len); | 
 |     if (nb_args == 2) { | 
 |         TraceEventIter iter; | 
 |         TraceEvent *ev; | 
 |         char *pattern = g_strdup_printf("%s*", str); | 
 |         trace_event_iter_init_pattern(&iter, pattern); | 
 |         while ((ev = trace_event_iter_next(&iter)) != NULL) { | 
 |             readline_add_completion(rs, trace_event_get_name(ev)); | 
 |         } | 
 |         g_free(pattern); | 
 |     } | 
 | } | 
 |  | 
 | void trace_event_completion(ReadLineState *rs, int nb_args, const char *str) | 
 | { | 
 |     size_t len; | 
 |  | 
 |     len = strlen(str); | 
 |     readline_set_completion_index(rs, len); | 
 |     if (nb_args == 2) { | 
 |         TraceEventIter iter; | 
 |         TraceEvent *ev; | 
 |         char *pattern = g_strdup_printf("%s*", str); | 
 |         trace_event_iter_init_pattern(&iter, pattern); | 
 |         while ((ev = trace_event_iter_next(&iter)) != NULL) { | 
 |             readline_add_completion(rs, trace_event_get_name(ev)); | 
 |         } | 
 |         g_free(pattern); | 
 |     } else if (nb_args == 3) { | 
 |         readline_add_completion_of(rs, str, "on"); | 
 |         readline_add_completion_of(rs, str, "off"); | 
 |     } | 
 | } |