Most of the commands have the implementation in a dedicated file.
Those commands without a dedicated file are implemented in the
`main()` function. This patch uniform the code by moving the commands
implemented in the `main()` function to dedicated files.

Signed-off-by: Federico Vaga <[email protected]>
---
 Makefile             |   3 +-
 trace-check-events.c |  66 ++++++
 trace-cmd.c          | 631 +--------------------------------------------------
 trace-list.c         | 486 +++++++++++++++++++++++++++++++++++++++
 trace-local.h        |   7 +
 trace-show.c         | 176 ++++++++++++++
 6 files changed, 741 insertions(+), 628 deletions(-)
 create mode 100644 trace-check-events.c
 create mode 100644 trace-list.c
 create mode 100644 trace-show.c

diff --git a/Makefile b/Makefile
index a3c6bfa..2be2754 100644
--- a/Makefile
+++ b/Makefile
@@ -341,7 +341,8 @@ TRACE_GUI_OBJS = trace-filter.o trace-compat.o 
trace-filter-hash.o trace-dialog.
                trace-xml.o
 TRACE_CMD_OBJS = trace-cmd.o trace-record.o trace-read.o trace-split.o 
trace-listen.o \
         trace-stack.o trace-hist.o trace-mem.o trace-snapshot.o trace-stat.o \
-        trace-hash.o trace-profile.o trace-stream.o trace-record.o 
trace-restore.o
+        trace-hash.o trace-profile.o trace-stream.o trace-record.o 
trace-restore.o \
+        trace-check-events.o trace-show.o trace-list.o
 TRACE_VIEW_OBJS = trace-view.o trace-view-store.o
 TRACE_GRAPH_OBJS = trace-graph.o trace-plot.o trace-plot-cpu.o 
trace-plot-task.o
 TRACE_VIEW_MAIN_OBJS = trace-view-main.o $(TRACE_VIEW_OBJS) $(TRACE_GUI_OBJS)
diff --git a/trace-check-events.c b/trace-check-events.c
new file mode 100644
index 0000000..c5a0127
--- /dev/null
+++ b/trace-check-events.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <[email protected]>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License (not later!)
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not,  see <http://www.gnu.org/licenses>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+#include <stdlib.h>
+#include <getopt.h>
+#include <errno.h>
+
+#include "trace-local.h"
+
+void trace_check_events(int argc, char **argv)
+{
+       const char *tracing;
+       int ret, c;
+       struct pevent *pevent = NULL;
+       struct plugin_list *list = NULL;
+
+       while ((c = getopt(argc-1, argv+1, "+hN")) >= 0) {
+               switch (c) {
+               case 'h':
+               default:
+                       usage(argv);
+                       break;
+               case 'N':
+                       tracecmd_disable_plugins = 1;
+                       break;
+               }
+       }
+       tracing = tracecmd_get_tracing_dir();
+
+       if (!tracing) {
+               printf("Can not find or mount tracing directory!\n"
+                      "Either tracing is not configured for this "
+                      "kernel\n"
+                      "or you do not have the proper permissions to "
+                      "mount the directory");
+               exit(EINVAL);
+       }
+
+       pevent = pevent_alloc();
+       if (!pevent)
+               exit(EINVAL);
+       list = tracecmd_load_plugins(pevent);
+       ret = tracecmd_fill_local_events(tracing, pevent);
+       if (ret || pevent->parsing_failures)
+               ret = EINVAL;
+       tracecmd_unload_plugins(list, pevent);
+       pevent_free(pevent);
+
+       return;
+}
diff --git a/trace-cmd.c b/trace-cmd.c
index 6a023e8..39bcc06 100644
--- a/trace-cmd.c
+++ b/trace-cmd.c
@@ -75,346 +75,9 @@ void *malloc_or_die(unsigned int size)
        return data;
 }
 
-static void dump_file_content(const char *path)
-{
-       char buf[BUFSIZ];
-       ssize_t n;
-       FILE *fp;
-
-       fp = fopen(path, "r");
-       if (!fp)
-               die("reading %s", path);
-
-       do {
-               n = fread(buf, 1, BUFSIZ, fp);
-               if (n > 0)
-                       fwrite(buf, 1, n, stdout);
-       } while (n > 0);
-       fclose(fp);
-}
-
-void show_file(const char *name)
-{
-       char *path;
-
-       path = tracecmd_get_tracing_file(name);
-       dump_file_content(path);
-       tracecmd_put_tracing_file(path);
-}
-
-typedef int (*process_file_func)(char *buf, int len);
-
-static void process_file_re(process_file_func func,
-                           const char *name, const char *re)
-{
-       regex_t reg;
-       char *path;
-       char *buf = NULL;
-       char *str;
-       FILE *fp;
-       ssize_t n;
-       size_t l = strlen(re);
-
-       /* Just in case :-p */
-       if (!re || l == 0) {
-               show_file(name);
-               return;
-       }
-
-       /* Handle the newline at end of names for the user */
-       str = malloc(l + 3);
-       if (!str)
-               die("Failed to allocate reg ex %s", re);
-       strcpy(str, re);
-       if (re[l-1] == '$')
-               strcpy(&str[l-1], "\n*$");
-               
-       if (regcomp(&reg, str, REG_ICASE|REG_NOSUB))
-               die("invalid function regex '%s'", re);
-
-       free(str);
-
-       path = tracecmd_get_tracing_file(name);
-       fp = fopen(path, "r");
-       if (!fp)
-               die("reading %s", path);
-       tracecmd_put_tracing_file(path);
-
-       do {
-               n = getline(&buf, &l, fp);
-               if (n > 0 && regexec(&reg, buf, 0, NULL, 0) == 0)
-                       func(buf, n);
-       } while (n > 0);
-       free(buf);
-       fclose(fp);
-
-       regfree(&reg);
-}
-
-static int show_file_write(char *buf, int len)
-{
-       return fwrite(buf, 1, len, stdout);
-}
-
-static void show_file_re(const char *name, const char *re)
-{
-       process_file_re(show_file_write, name, re);
-}
-
-static char *get_event_file(const char *type, char *buf, int len)
-{
-       char *system;
-       char *event;
-       char *path;
-       char *file;
-
-       if (buf[len-1] == '\n')
-               buf[len-1] = '\0';
-
-       system = strtok(buf, ":");
-       if (!system)
-               die("no system found in %s", buf);
-
-       event = strtok(NULL, ":");
-       if (!event)
-               die("no event found in %s\n", buf);
-
-       path = tracecmd_get_tracing_file("events");
-       file = malloc(strlen(path) + strlen(system) + strlen(event) +
-                     strlen(type) + strlen("///") + 1);
-       if (!file)
-               die("Failed to allocate event file %s %s", system, event);
-       sprintf(file, "%s/%s/%s/%s", path, system, event, type);
-       tracecmd_put_tracing_file(path);
-
-       return file;
-}
-
-static int event_filter_write(char *buf, int len)
-{
-       char *file;
-
-       if (buf[len-1] == '\n')
-               buf[len-1] = '\0';
-
-       printf("%s\n", buf);
-
-       file = get_event_file("filter", buf, len);
-       dump_file_content(file);
-       free(file);
-       printf("\n");
-
-       return 0;
-}
-
-static int event_trigger_write(char *buf, int len)
-{
-       char *file;
-
-       if (buf[len-1] == '\n')
-               buf[len-1] = '\0';
-
-       printf("%s\n", buf);
-
-       file = get_event_file("trigger", buf, len);
-       dump_file_content(file);
-       free(file);
-       printf("\n");
-
-       return 0;
-}
-
-static int event_format_write(char *fbuf, int len)
-{
-       char *file = get_event_file("format", fbuf, len);
-       char *buf = NULL;
-       size_t l;
-       FILE *fp;
-       int n;
-
-       /* The get_event_file() crops system in fbuf */
-       printf("system: %s\n", fbuf);
-
-       /* Don't print the print fmt, it's ugly */
-
-       fp = fopen(file, "r");
-       if (!fp)
-               die("reading %s", file);
-
-       do {
-               n = getline(&buf, &l, fp);
-               if (n > 0) {
-                       if (strncmp(buf, "print fmt", 9) == 0)
-                               break;
-                       fwrite(buf, 1, n, stdout);
-               }
-       } while (n > 0);
-       fclose(fp);
-       free(buf);
-       free(file);
-
-       return 0;
-}
-
-static void show_event_filter_re(const char *re)
-{
-       process_file_re(event_filter_write, "available_events", re);
-}
-
-static void show_event_trigger_re(const char *re)
-{
-       process_file_re(event_trigger_write, "available_events", re);
-}
-
-static void show_event_format_re(const char *re)
-{
-       process_file_re(event_format_write, "available_events", re);
-}
-
-void show_instance_file(struct buffer_instance *instance, const char *name)
-{
-       char *path;
-
-       path = get_instance_file(instance, name);
-       dump_file_content(path);
-       tracecmd_put_tracing_file(path);
-}
-
-enum {
-       SHOW_EVENT_FORMAT               = 1 << 0,
-       SHOW_EVENT_FILTER               = 1 << 1,
-       SHOW_EVENT_TRIGGER              = 1 << 2,
-};
-
-static void show_events(const char *eventre, int flags)
-{
-       if (flags && !eventre)
-               die("When specifying event files, an event must be named");
-
-       if (eventre) {
-               if (flags & SHOW_EVENT_FORMAT)
-                       show_event_format_re(eventre);
-
-               else if (flags & SHOW_EVENT_FILTER)
-                       show_event_filter_re(eventre);
-
-               else if (flags & SHOW_EVENT_TRIGGER)
-                       show_event_trigger_re(eventre);
-               else
-                       show_file_re("available_events", eventre);
-       } else
-               show_file("available_events");
-}
-
-static void show_tracers(void)
-{
-       show_file("available_tracers");
-}
-
-static void show_options(void)
-{
-       show_file("trace_options");
-}
-
-static void show_clocks(void)
-{
-       show_file("trace_clock");
-}
-
-static void show_functions(const char *funcre)
-{
-       if (funcre)
-               show_file_re("available_filter_functions", funcre);
-       else
-               show_file("available_filter_functions");
-}
-
-static void show_buffers(void)
-{
-       struct dirent *dent;
-       DIR *dir;
-       char *path;
-       int printed = 0;
-
-       path = tracecmd_get_tracing_file("instances");
-       dir = opendir(path);
-       tracecmd_put_tracing_file(path);
-       if (!dir)
-               die("Can not read instance directory");
-
-       while ((dent = readdir(dir))) {
-               const char *name = dent->d_name;
-
-               if (strcmp(name, ".") == 0 ||
-                   strcmp(name, "..") == 0)
-                       continue;
-
-               printf("%s\n", name);
-               printed = 1;
-       }
-       closedir(dir);
-
-       if (!printed)
-               printf("No buffer instances defined\n");
-}
-
-static void show_plugins(void)
-{
-       struct pevent *pevent;
-       struct plugin_list *list;
-       struct trace_seq s;
-
-       pevent = pevent_alloc();
-       if (!pevent)
-               die("Can not allocate pevent\n");
-
-       trace_seq_init(&s);
-
-       list = tracecmd_load_plugins(pevent);
-       trace_util_print_plugins(&s, "  ", "\n", list);
-       trace_seq_do_printf(&s);
-       tracecmd_unload_plugins(list, pevent);
-       pevent_free(pevent);
-}
-
-static void show_plugin_options(void)
-{
-       struct pevent *pevent;
-       struct plugin_list *list;
-       struct trace_seq s;
-
-       tracecmd_ftrace_load_options();
-
-       pevent = pevent_alloc();
-       if (!pevent)
-               die("Can not allocate pevent\n");
-
-       trace_seq_init(&s);
-
-       list = tracecmd_load_plugins(pevent);
-       trace_util_print_plugin_options(&s);
-       trace_seq_do_printf(&s);
-       tracecmd_unload_plugins(list, pevent);
-       pevent_free(pevent);
-}
-
-enum {
-       OPT_tracing_on                  = 255,
-       OPT_current_tracer              = 254,
-       OPT_buffer_size_kb              = 253,
-       OPT_buffer_total_size_kb        = 252,
-       OPT_ftrace_filter               = 251,
-       OPT_ftrace_notrace              = 250,
-       OPT_ftrace_pid                  = 249,
-       OPT_graph_function              = 248,
-       OPT_graph_notrace               = 247,
-       OPT_cpumask                     = 246,
-};
 
 int main (int argc, char **argv)
 {
-       int c;
-
        errno = 0;
 
        if (argc < 2)
@@ -445,44 +108,8 @@ int main (int argc, char **argv)
                trace_stack(argc, argv);
                exit(0);
        } else if (strcmp(argv[1], "check-events") == 0) {
-               const char *tracing;
-               int ret;
-               struct pevent *pevent = NULL;
-               struct plugin_list *list = NULL;
-
-               while ((c = getopt(argc-1, argv+1, "+hN")) >= 0) {
-                       switch (c) {
-                       case 'h':
-                       default:
-                               usage(argv);
-                               break;
-                       case 'N':
-                               tracecmd_disable_plugins = 1;
-                               break;
-                       }
-               }
-               tracing = tracecmd_get_tracing_dir();
-
-               if (!tracing) {
-                       printf("Can not find or mount tracing directory!\n"
-                               "Either tracing is not configured for this "
-                               "kernel\n"
-                               "or you do not have the proper permissions to "
-                               "mount the directory");
-                       exit(EINVAL);
-               }
-
-               pevent = pevent_alloc();
-               if (!pevent)
-                       exit(EINVAL);
-               list = tracecmd_load_plugins(pevent);
-               ret = tracecmd_fill_local_events(tracing, pevent);
-               if (ret || pevent->parsing_failures)
-                       ret = EINVAL;
-               tracecmd_unload_plugins(list, pevent);
-               pevent_free(pevent);
-               exit(ret);
-
+               trace_check_events(argc, argv);
+               exit(0);
        } else if (strcmp(argv[1], "record") == 0 ||
                   strcmp(argv[1], "start") == 0 ||
                   strcmp(argv[1], "extract") == 0 ||
@@ -502,261 +129,11 @@ int main (int argc, char **argv)
                show_plugin_options();
                exit(0);
        } else if (strcmp(argv[1], "show") == 0) {
-               const char *buffer = NULL;
-               const char *file = "trace";
-               const char *cpu = NULL;
-               struct buffer_instance *instance = &top_instance;
-               char cpu_path[128];
-               char *path;
-               int snap = 0;
-               int pipe = 0;
-               int show_name = 0;
-               int option_index = 0;
-               int stop = 0;
-               static struct option long_options[] = {
-                       {"tracing_on", no_argument, NULL, OPT_tracing_on},
-                       {"current_tracer", no_argument, NULL, 
OPT_current_tracer},
-                       {"buffer_size", no_argument, NULL, OPT_buffer_size_kb},
-                       {"buffer_total_size", no_argument, NULL, 
OPT_buffer_total_size_kb},
-                       {"ftrace_filter", no_argument, NULL, OPT_ftrace_filter},
-                       {"ftrace_notrace", no_argument, NULL, 
OPT_ftrace_notrace},
-                       {"ftrace_pid", no_argument, NULL, OPT_ftrace_pid},
-                       {"graph_function", no_argument, NULL, 
OPT_graph_function},
-                       {"graph_notrace", no_argument, NULL, OPT_graph_notrace},
-                       {"cpumask", no_argument, NULL, OPT_cpumask},
-                       {"help", no_argument, NULL, '?'},
-                       {NULL, 0, NULL, 0}
-               };
-
-               while ((c = getopt_long(argc-1, argv+1, "B:c:fsp",
-                                       long_options, &option_index)) >= 0) {
-                       switch (c) {
-                       case 'h':
-                               usage(argv);
-                               break;
-                       case 'B':
-                               if (buffer)
-                                       die("Can only show one buffer at a 
time");
-                               buffer = optarg;
-                               instance = create_instance(optarg);
-                               if (!instance)
-                                       die("Failed to create instance");
-                               break;
-                       case 'c':
-                               if (cpu)
-                                       die("Can only show one CPU at a time");
-                               cpu = optarg;
-                               break;
-                       case 'f':
-                               show_name = 1;
-                               break;
-                       case 's':
-                               snap = 1;
-                               if (pipe)
-                                       die("Can not have -s and -p together");
-                               break;
-                       case 'p':
-                               pipe = 1;
-                               if (snap)
-                                       die("Can not have -s and -p together");
-                               break;
-                       case OPT_tracing_on:
-                               show_instance_file(instance, "tracing_on");
-                               stop = 1;
-                               break;
-                       case OPT_current_tracer:
-                               show_instance_file(instance, "current_tracer");
-                               stop = 1;
-                               break;
-                       case OPT_buffer_size_kb:
-                               show_instance_file(instance, "buffer_size_kb");
-                               stop = 1;
-                               break;
-                       case OPT_buffer_total_size_kb:
-                               show_instance_file(instance, 
"buffer_total_size_kb");
-                               stop = 1;
-                               break;
-                       case OPT_ftrace_filter:
-                               show_instance_file(instance, 
"set_ftrace_filter");
-                               stop = 1;
-                               break;
-                       case OPT_ftrace_notrace:
-                               show_instance_file(instance, 
"set_ftrace_notrace");
-                               stop = 1;
-                               break;
-                       case OPT_ftrace_pid:
-                               show_instance_file(instance, "set_ftrace_pid");
-                               stop = 1;
-                               break;
-                       case OPT_graph_function:
-                               show_instance_file(instance, 
"set_graph_function");
-                               stop = 1;
-                               break;
-                       case OPT_graph_notrace:
-                               show_instance_file(instance, 
"set_graph_notrace");
-                               stop = 1;
-                               break;
-                       case OPT_cpumask:
-                               show_instance_file(instance, "tracing_cpumask");
-                               stop = 1;
-                               break;
-                       default:
-                               usage(argv);
-                       }
-               }
-               if (stop)
-                       exit(0);
-               if (pipe)
-                       file = "trace_pipe";
-               else if (snap)
-                       file = "snapshot";
-
-               if (cpu) {
-                       snprintf(cpu_path, 128, "per_cpu/cpu%d/%s", atoi(cpu), 
file);
-                       file = cpu_path;
-               }
-                       
-               if (buffer) {
-                       path = malloc(strlen(buffer) + strlen("instances//") +
-                                     strlen(file) + 1);
-                       if (!path)
-                               die("Failed to allocate instance path %s", 
file);
-                       sprintf(path, "instances/%s/%s", buffer, file);
-                       file = path;
-               }
-
-               if (show_name) {
-                       char *name;
-                       name = tracecmd_get_tracing_file(file);
-                       printf("%s\n", name);
-                       tracecmd_put_tracing_file(name);
-               }
-               show_file(file);
-               if (buffer)
-                       free(path);
-
+               trace_show(argc, argv);
                exit(0);
        } else if (strcmp(argv[1], "list") == 0) {
-               int events = 0;
-               int tracer = 0;
-               int options = 0;
-               int funcs = 0;
-               int buffers = 0;
-               int clocks = 0;
-               int plug = 0;
-               int plug_op = 0;
-               int flags = 0;
-               int show_all = 1;
-               int i;
-               const char *arg;
-               const char *funcre = NULL;
-               const char *eventre = NULL;
-
-               for (i = 2; i < argc; i++) {
-                       arg = NULL;
-                       if (argv[i][0] == '-') {
-                               if (i < argc - 1) {
-                                       if (argv[i+1][0] != '-')
-                                               arg = argv[i+1];
-                               }
-                               switch (argv[i][1]) {
-                               case 'h':
-                                       usage(argv);
-                                       break;
-                               case 'e':
-                                       events = 1;
-                                       eventre = arg;
-                                       show_all = 0;
-                                       break;
-                               case 'B':
-                                       buffers = 1;
-                                       show_all = 0;
-                                       break;
-                               case 'C':
-                                       clocks = 1;
-                                       show_all = 0;
-                                       break;
-                               case 'F':
-                                       flags |= SHOW_EVENT_FORMAT;
-                                       break;
-                               case 'R':
-                                       flags |= SHOW_EVENT_TRIGGER;
-                                       break;
-                               case 'l':
-                                       flags |= SHOW_EVENT_FILTER;
-                                       break;
-                               case 'p':
-                               case 't':
-                                       tracer = 1;
-                                       show_all = 0;
-                                       break;
-                               case 'P':
-                                       plug = 1;
-                                       show_all = 0;
-                                       break;
-                               case 'O':
-                                       plug_op = 1;
-                                       show_all = 0;
-                                       break;
-                               case 'o':
-                                       options = 1;
-                                       show_all = 0;
-                                       break;
-                               case 'f':
-                                       funcs = 1;
-                                       funcre = arg;
-                                       show_all = 0;
-                                       break;
-                               case '-':
-                                       if (strcmp(argv[i], "--debug") == 0) {
-                                               debug = true;
-                                               break;
-                                       }
-                                       fprintf(stderr, "list: invalid option 
-- '%s'\n",
-                                               argv[i]);
-                               default:
-                                       fprintf(stderr, "list: invalid option 
-- '%c'\n",
-                                               argv[i][1]);
-                                       usage(argv);
-                               }
-                       }
-               }
-
-               if (events)
-                       show_events(eventre, flags);
-
-               if (tracer)
-                       show_tracers();
-
-               if (options)
-                       show_options();
-
-               if (plug)
-                       show_plugins();
-
-               if (plug_op)
-                       show_plugin_options();
-
-               if (funcs)
-                       show_functions(funcre);
-
-               if (buffers)
-                       show_buffers();
-
-               if (clocks)
-                       show_clocks();
-
-               if (show_all) {
-                       printf("events:\n");
-                       show_events(NULL, 0);
-                       printf("\ntracers:\n");
-                       show_tracers();
-                       printf("\noptions:\n");
-                       show_options();
-               }
-
+               trace_list(argc, argv);
                exit(0);
-
        } else if (strcmp(argv[1], "-h") == 0 ||
                   strcmp(argv[1], "help") == 0) {
                usage(argv);
diff --git a/trace-list.c b/trace-list.c
new file mode 100644
index 0000000..3fdca34
--- /dev/null
+++ b/trace-list.c
@@ -0,0 +1,486 @@
+/*
+ * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <[email protected]>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License (not later!)
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not,  see <http://www.gnu.org/licenses>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <stdlib.h>
+
+#include "trace-local.h"
+
+
+static void dump_file_content(const char *path)
+{
+       char buf[BUFSIZ];
+       ssize_t n;
+       FILE *fp;
+
+       fp = fopen(path, "r");
+       if (!fp)
+               die("reading %s", path);
+
+       do {
+               n = fread(buf, 1, BUFSIZ, fp);
+               if (n > 0)
+                       fwrite(buf, 1, n, stdout);
+       } while (n > 0);
+       fclose(fp);
+}
+
+
+
+void show_instance_file(struct buffer_instance *instance, const char *name)
+{
+       char *path;
+
+       path = get_instance_file(instance, name);
+       dump_file_content(path);
+       tracecmd_put_tracing_file(path);
+}
+
+enum {
+       SHOW_EVENT_FORMAT               = 1 << 0,
+       SHOW_EVENT_FILTER               = 1 << 1,
+       SHOW_EVENT_TRIGGER              = 1 << 2,
+};
+
+
+void show_file(const char *name)
+{
+       char *path;
+
+       path = tracecmd_get_tracing_file(name);
+       dump_file_content(path);
+       tracecmd_put_tracing_file(path);
+}
+
+typedef int (*process_file_func)(char *buf, int len);
+
+static void process_file_re(process_file_func func,
+                           const char *name, const char *re)
+{
+       regex_t reg;
+       char *path;
+       char *buf = NULL;
+       char *str;
+       FILE *fp;
+       ssize_t n;
+       size_t l = strlen(re);
+
+       /* Just in case :-p */
+       if (!re || l == 0) {
+               show_file(name);
+               return;
+       }
+
+       /* Handle the newline at end of names for the user */
+       str = malloc(l + 3);
+       if (!str)
+               die("Failed to allocate reg ex %s", re);
+       strcpy(str, re);
+       if (re[l-1] == '$')
+               strcpy(&str[l-1], "\n*$");
+
+       if (regcomp(&reg, str, REG_ICASE|REG_NOSUB))
+               die("invalid function regex '%s'", re);
+
+       free(str);
+
+       path = tracecmd_get_tracing_file(name);
+       fp = fopen(path, "r");
+       if (!fp)
+               die("reading %s", path);
+       tracecmd_put_tracing_file(path);
+
+       do {
+               n = getline(&buf, &l, fp);
+               if (n > 0 && regexec(&reg, buf, 0, NULL, 0) == 0)
+                       func(buf, n);
+       } while (n > 0);
+       free(buf);
+       fclose(fp);
+
+       regfree(&reg);
+}
+
+static int show_file_write(char *buf, int len)
+{
+       return fwrite(buf, 1, len, stdout);
+}
+
+static void show_file_re(const char *name, const char *re)
+{
+       process_file_re(show_file_write, name, re);
+}
+
+static char *get_event_file(const char *type, char *buf, int len)
+{
+       char *system;
+       char *event;
+       char *path;
+       char *file;
+
+       if (buf[len-1] == '\n')
+               buf[len-1] = '\0';
+
+       system = strtok(buf, ":");
+       if (!system)
+               die("no system found in %s", buf);
+
+       event = strtok(NULL, ":");
+       if (!event)
+               die("no event found in %s\n", buf);
+
+       path = tracecmd_get_tracing_file("events");
+       file = malloc(strlen(path) + strlen(system) + strlen(event) +
+                     strlen(type) + strlen("///") + 1);
+       if (!file)
+               die("Failed to allocate event file %s %s", system, event);
+       sprintf(file, "%s/%s/%s/%s", path, system, event, type);
+       tracecmd_put_tracing_file(path);
+
+       return file;
+}
+
+static int event_filter_write(char *buf, int len)
+{
+       char *file;
+
+       if (buf[len-1] == '\n')
+               buf[len-1] = '\0';
+
+       printf("%s\n", buf);
+
+       file = get_event_file("filter", buf, len);
+       dump_file_content(file);
+       free(file);
+       printf("\n");
+
+       return 0;
+}
+
+static int event_trigger_write(char *buf, int len)
+{
+       char *file;
+
+       if (buf[len-1] == '\n')
+               buf[len-1] = '\0';
+
+       printf("%s\n", buf);
+
+       file = get_event_file("trigger", buf, len);
+       dump_file_content(file);
+       free(file);
+       printf("\n");
+
+       return 0;
+}
+
+static int event_format_write(char *fbuf, int len)
+{
+       char *file = get_event_file("format", fbuf, len);
+       char *buf = NULL;
+       size_t l;
+       FILE *fp;
+       int n;
+
+       /* The get_event_file() crops system in fbuf */
+       printf("system: %s\n", fbuf);
+
+       /* Don't print the print fmt, it's ugly */
+
+       fp = fopen(file, "r");
+       if (!fp)
+               die("reading %s", file);
+
+       do {
+               n = getline(&buf, &l, fp);
+               if (n > 0) {
+                       if (strncmp(buf, "print fmt", 9) == 0)
+                               break;
+                       fwrite(buf, 1, n, stdout);
+               }
+       } while (n > 0);
+       fclose(fp);
+       free(buf);
+       free(file);
+
+       return 0;
+}
+
+
+static void show_event_filter_re(const char *re)
+{
+       process_file_re(event_filter_write, "available_events", re);
+}
+
+
+static void show_event_trigger_re(const char *re)
+{
+       process_file_re(event_trigger_write, "available_events", re);
+}
+
+
+static void show_event_format_re(const char *re)
+{
+       process_file_re(event_format_write, "available_events", re);
+}
+
+
+static void show_events(const char *eventre, int flags)
+{
+       if (flags && !eventre)
+               die("When specifying event files, an event must be named");
+
+       if (eventre) {
+               if (flags & SHOW_EVENT_FORMAT)
+                       show_event_format_re(eventre);
+
+               else if (flags & SHOW_EVENT_FILTER)
+                       show_event_filter_re(eventre);
+
+               else if (flags & SHOW_EVENT_TRIGGER)
+                       show_event_trigger_re(eventre);
+               else
+                       show_file_re("available_events", eventre);
+       } else
+               show_file("available_events");
+}
+
+
+static void show_tracers(void)
+{
+       show_file("available_tracers");
+}
+
+
+static void show_options(void)
+{
+       show_file("trace_options");
+}
+
+
+static void show_clocks(void)
+{
+       show_file("trace_clock");
+}
+
+
+static void show_functions(const char *funcre)
+{
+       if (funcre)
+               show_file_re("available_filter_functions", funcre);
+       else
+               show_file("available_filter_functions");
+}
+
+
+static void show_buffers(void)
+{
+       struct dirent *dent;
+       DIR *dir;
+       char *path;
+       int printed = 0;
+
+       path = tracecmd_get_tracing_file("instances");
+       dir = opendir(path);
+       tracecmd_put_tracing_file(path);
+       if (!dir)
+               die("Can not read instance directory");
+
+       while ((dent = readdir(dir))) {
+               const char *name = dent->d_name;
+
+               if (strcmp(name, ".") == 0 ||
+                   strcmp(name, "..") == 0)
+                       continue;
+
+               printf("%s\n", name);
+               printed = 1;
+       }
+       closedir(dir);
+
+       if (!printed)
+               printf("No buffer instances defined\n");
+}
+
+
+void show_plugin_options(void)
+{
+       struct pevent *pevent;
+       struct plugin_list *list;
+       struct trace_seq s;
+
+       tracecmd_ftrace_load_options();
+
+       pevent = pevent_alloc();
+       if (!pevent)
+               die("Can not allocate pevent\n");
+
+       trace_seq_init(&s);
+
+       list = tracecmd_load_plugins(pevent);
+       trace_util_print_plugin_options(&s);
+       trace_seq_do_printf(&s);
+       tracecmd_unload_plugins(list, pevent);
+       pevent_free(pevent);
+}
+
+
+static void show_plugins(void)
+{
+       struct pevent *pevent;
+       struct plugin_list *list;
+       struct trace_seq s;
+
+       pevent = pevent_alloc();
+       if (!pevent)
+               die("Can not allocate pevent\n");
+
+       trace_seq_init(&s);
+
+       list = tracecmd_load_plugins(pevent);
+       trace_util_print_plugins(&s, "  ", "\n", list);
+       trace_seq_do_printf(&s);
+       tracecmd_unload_plugins(list, pevent);
+       pevent_free(pevent);
+}
+
+
+void trace_list(int argc, char **argv)
+{
+       int events = 0;
+       int tracer = 0;
+       int options = 0;
+       int funcs = 0;
+       int buffers = 0;
+       int clocks = 0;
+       int plug = 0;
+       int plug_op = 0;
+       int flags = 0;
+       int show_all = 1;
+       int i;
+       const char *arg;
+       const char *funcre = NULL;
+       const char *eventre = NULL;
+
+       for (i = 2; i < argc; i++) {
+               arg = NULL;
+               if (argv[i][0] == '-') {
+                       if (i < argc - 1) {
+                               if (argv[i+1][0] != '-')
+                                       arg = argv[i+1];
+                       }
+                       switch (argv[i][1]) {
+                       case 'h':
+                               usage(argv);
+                               break;
+                       case 'e':
+                               events = 1;
+                               eventre = arg;
+                               show_all = 0;
+                               break;
+                       case 'B':
+                               buffers = 1;
+                               show_all = 0;
+                               break;
+                       case 'C':
+                               clocks = 1;
+                               show_all = 0;
+                               break;
+                       case 'F':
+                               flags |= SHOW_EVENT_FORMAT;
+                               break;
+                       case 'R':
+                               flags |= SHOW_EVENT_TRIGGER;
+                               break;
+                       case 'l':
+                               flags |= SHOW_EVENT_FILTER;
+                               break;
+                       case 'p':
+                       case 't':
+                               tracer = 1;
+                               show_all = 0;
+                               break;
+                       case 'P':
+                               plug = 1;
+                               show_all = 0;
+                               break;
+                       case 'O':
+                               plug_op = 1;
+                               show_all = 0;
+                               break;
+                       case 'o':
+                               options = 1;
+                               show_all = 0;
+                               break;
+                       case 'f':
+                               funcs = 1;
+                               funcre = arg;
+                               show_all = 0;
+                               break;
+                       case '-':
+                               if (strcmp(argv[i], "--debug") == 0) {
+                                       debug = true;
+                                       break;
+                               }
+                               fprintf(stderr, "list: invalid option -- 
'%s'\n",
+                                       argv[i]);
+                       default:
+                               fprintf(stderr, "list: invalid option -- 
'%c'\n",
+                                       argv[i][1]);
+                               usage(argv);
+                       }
+               }
+       }
+
+       if (events)
+               show_events(eventre, flags);
+
+       if (tracer)
+               show_tracers();
+
+       if (options)
+               show_options();
+
+       if (plug)
+               show_plugins();
+
+       if (plug_op)
+               show_plugin_options();
+
+       if (funcs)
+               show_functions(funcre);
+
+       if (buffers)
+               show_buffers();
+
+       if (clocks)
+               show_clocks();
+
+       if (show_all) {
+               printf("events:\n");
+               show_events(NULL, 0);
+               printf("\ntracers:\n");
+               show_tracers();
+               printf("\noptions:\n");
+               show_options();
+       }
+
+       return;
+
+}
diff --git a/trace-local.h b/trace-local.h
index 46aa979..ee518fb 100644
--- a/trace-local.h
+++ b/trace-local.h
@@ -65,6 +65,8 @@ void trace_listen(int argc, char **argv);
 
 void trace_restore(int argc, char **argv);
 
+void trace_check_events(int argc, char **argv);
+
 void trace_stack(int argc, char **argv);
 
 void trace_option(int argc, char **argv);
@@ -77,6 +79,10 @@ void trace_mem(int argc, char **argv);
 
 void trace_stat(int argc, char **argv);
 
+void trace_show(int argc, char **argv);
+
+void trace_list(int argc, char **argv);
+
 struct hook_list;
 
 void trace_init_profile(struct tracecmd_input *handle, struct hook_list *hooks,
@@ -183,6 +189,7 @@ char *get_instance_file(struct buffer_instance *instance, 
const char *file);
 void update_first_instance(struct buffer_instance *instance, int topt);
 
 void show_instance_file(struct buffer_instance *instance, const char *name);
+void show_plugin_options(void);
 int count_cpus(void);
 
 /* No longer in event-utils.h */
diff --git a/trace-show.c b/trace-show.c
new file mode 100644
index 0000000..14b786c
--- /dev/null
+++ b/trace-show.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <[email protected]>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License (not later!)
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not,  see <http://www.gnu.org/licenses>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+#include <stdlib.h>
+#include <getopt.h>
+#include <errno.h>
+
+#include "trace-local.h"
+
+enum {
+       OPT_tracing_on                  = 255,
+       OPT_current_tracer              = 254,
+       OPT_buffer_size_kb              = 253,
+       OPT_buffer_total_size_kb        = 252,
+       OPT_ftrace_filter               = 251,
+       OPT_ftrace_notrace              = 250,
+       OPT_ftrace_pid                  = 249,
+       OPT_graph_function              = 248,
+       OPT_graph_notrace               = 247,
+       OPT_cpumask                     = 246,
+};
+
+void trace_show(int argc, char **argv)
+{
+       const char *buffer = NULL;
+       const char *file = "trace";
+       const char *cpu = NULL;
+       struct buffer_instance *instance = &top_instance;
+       char cpu_path[128];
+       char *path;
+       int snap = 0;
+       int pipe = 0;
+       int show_name = 0;
+       int option_index = 0;
+       int stop = 0;
+       int c;
+       static struct option long_options[] = {
+               {"tracing_on", no_argument, NULL, OPT_tracing_on},
+               {"current_tracer", no_argument, NULL, OPT_current_tracer},
+               {"buffer_size", no_argument, NULL, OPT_buffer_size_kb},
+               {"buffer_total_size", no_argument, NULL, 
OPT_buffer_total_size_kb},
+               {"ftrace_filter", no_argument, NULL, OPT_ftrace_filter},
+               {"ftrace_notrace", no_argument, NULL, OPT_ftrace_notrace},
+               {"ftrace_pid", no_argument, NULL, OPT_ftrace_pid},
+               {"graph_function", no_argument, NULL, OPT_graph_function},
+               {"graph_notrace", no_argument, NULL, OPT_graph_notrace},
+               {"cpumask", no_argument, NULL, OPT_cpumask},
+               {"help", no_argument, NULL, '?'},
+               {NULL, 0, NULL, 0}
+       };
+
+       while ((c = getopt_long(argc-1, argv+1, "B:c:fsp",
+                               long_options, &option_index)) >= 0) {
+               switch (c) {
+               case 'h':
+                       usage(argv);
+                       break;
+               case 'B':
+                       if (buffer)
+                               die("Can only show one buffer at a time");
+                       buffer = optarg;
+                       instance = create_instance(optarg);
+                       if (!instance)
+                               die("Failed to create instance");
+                       break;
+               case 'c':
+                       if (cpu)
+                               die("Can only show one CPU at a time");
+                       cpu = optarg;
+                       break;
+               case 'f':
+                       show_name = 1;
+                       break;
+               case 's':
+                       snap = 1;
+                       if (pipe)
+                               die("Can not have -s and -p together");
+                       break;
+               case 'p':
+                       pipe = 1;
+                       if (snap)
+                               die("Can not have -s and -p together");
+                       break;
+               case OPT_tracing_on:
+                       show_instance_file(instance, "tracing_on");
+                       stop = 1;
+                       break;
+               case OPT_current_tracer:
+                       show_instance_file(instance, "current_tracer");
+                       stop = 1;
+                       break;
+               case OPT_buffer_size_kb:
+                       show_instance_file(instance, "buffer_size_kb");
+                       stop = 1;
+                       break;
+               case OPT_buffer_total_size_kb:
+                       show_instance_file(instance, "buffer_total_size_kb");
+                       stop = 1;
+                       break;
+               case OPT_ftrace_filter:
+                       show_instance_file(instance, "set_ftrace_filter");
+                       stop = 1;
+                       break;
+               case OPT_ftrace_notrace:
+                       show_instance_file(instance, "set_ftrace_notrace");
+                       stop = 1;
+                       break;
+               case OPT_ftrace_pid:
+                       show_instance_file(instance, "set_ftrace_pid");
+                       stop = 1;
+                       break;
+               case OPT_graph_function:
+                       show_instance_file(instance, "set_graph_function");
+                       stop = 1;
+                       break;
+               case OPT_graph_notrace:
+                       show_instance_file(instance, "set_graph_notrace");
+                       stop = 1;
+                       break;
+               case OPT_cpumask:
+                       show_instance_file(instance, "tracing_cpumask");
+                       stop = 1;
+                       break;
+               default:
+                       usage(argv);
+               }
+       }
+       if (stop)
+               exit(0);
+       if (pipe)
+               file = "trace_pipe";
+       else if (snap)
+               file = "snapshot";
+
+       if (cpu) {
+               snprintf(cpu_path, 128, "per_cpu/cpu%d/%s", atoi(cpu), file);
+               file = cpu_path;
+       }
+
+       if (buffer) {
+               path = malloc(strlen(buffer) + strlen("instances//") +
+                             strlen(file) + 1);
+               if (!path)
+                       die("Failed to allocate instance path %s", file);
+               sprintf(path, "instances/%s/%s", buffer, file);
+               file = path;
+       }
+
+       if (show_name) {
+               char *name;
+               name = tracecmd_get_tracing_file(file);
+               printf("%s\n", name);
+               tracecmd_put_tracing_file(name);
+       }
+       show_file(file);
+       if (buffer)
+               free(path);
+
+       return;
+}
-- 
2.9.3

Reply via email to