diff options
author | Lai Jiangshan <laijs@cn.fujitsu.com> | 2011-03-10 04:57:58 -0500 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2011-03-10 09:59:12 -0500 |
commit | 025c5a6e6f8348ea8742b306ca9d05feee17ed5e (patch) | |
tree | 3203211e10f33e67c9e095c1735191de6830d8bd | |
parent | 49dce72f8d2f9416a7c0b01a3d3727e59cf91e32 (diff) |
trace-cmd: Correct cpu list parsing
Old parsing code is incorrect, when we execute
./trace-cmd report --cpu 1,2-4,6,9-13
the result of filter_cpus will be:
1,2,1,2,3,4,6,9,5,6,7,8,9,10,11,12,13
The correct filter_cpus should be:
1,2,3,4,6,9,10,11,12,13,
I could change about 10 existing lines to make it correct, but the result
would still be poorly readable, so I ported the neat and nicely readable code:
linux_kernel_src/lib/bitmap.c:bitmap_parselist()
to here and replaced the origin code.
Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
LKML-Reference: <4D78A0A6.2060009@cn.fujitsu.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r-- | trace-read.c | 76 |
1 files changed, 19 insertions, 57 deletions
diff --git a/trace-read.c b/trace-read.c index 1cd9bd3..932f5aa 100644 --- a/trace-read.c +++ b/trace-read.c | |||
@@ -738,9 +738,8 @@ static void sig_end(int sig) | |||
738 | exit(0); | 738 | exit(0); |
739 | } | 739 | } |
740 | 740 | ||
741 | static const char *inc_and_test_char(const char *p, const char *cpu_str) | 741 | static const char *skip_space_and_test_digit(const char *p, const char *cpu_str) |
742 | { | 742 | { |
743 | p++; | ||
744 | while (isspace(*p)) | 743 | while (isspace(*p)) |
745 | p++; | 744 | p++; |
746 | if (!isdigit(*p)) | 745 | if (!isdigit(*p)) |
@@ -754,64 +753,27 @@ static void __add_cpu(int cpu) | |||
754 | filter_cpus = tracecmd_add_id(filter_cpus, cpu, nr_filter_cpus++); | 753 | filter_cpus = tracecmd_add_id(filter_cpus, cpu, nr_filter_cpus++); |
755 | } | 754 | } |
756 | 755 | ||
757 | static int process_cpu_str(const char *cpu_str) | 756 | static void parse_cpulist(const char *cpu_str) |
758 | { | 757 | { |
759 | const char *p = cpu_str; | 758 | unsigned a, b; |
760 | int cpu, ncpu, ret_cpu = 1; | 759 | const char *s = cpu_str; |
761 | 760 | ||
762 | do { | 761 | do { |
763 | while (isspace(*p)) | 762 | s = skip_space_and_test_digit(s, cpu_str); |
764 | p++; | 763 | b = a = strtoul(s, (char **)&s, 10); |
765 | 764 | if (*s == '-') { | |
766 | cpu = atoi(p); | 765 | s = skip_space_and_test_digit(s + 1, cpu_str); |
767 | __add_cpu(cpu); | 766 | b = strtoul(s, (char **)&s, 10); |
768 | |||
769 | again: | ||
770 | while (isdigit(*p)) | ||
771 | p++; | ||
772 | while (isspace(*p)) | ||
773 | p++; | ||
774 | |||
775 | if (*p) { | ||
776 | ret_cpu = 0; | ||
777 | switch (*p) { | ||
778 | case '-': | ||
779 | p = inc_and_test_char(p, cpu_str); | ||
780 | ncpu = atoi(p); | ||
781 | if (ncpu < cpu) | ||
782 | die("range of cpu numbers must be lower to greater"); | ||
783 | for (; cpu <= ncpu; cpu++) | ||
784 | __add_cpu(cpu); | ||
785 | break; | ||
786 | |||
787 | case ',': | ||
788 | case ':': | ||
789 | p = inc_and_test_char(p, cpu_str); | ||
790 | ncpu = atoi(p); | ||
791 | __add_cpu(ncpu); | ||
792 | break; | ||
793 | default: | ||
794 | die("invalid character '%c' in cpu string '%s'", | ||
795 | *p, cpu_str); | ||
796 | } | ||
797 | goto again; | ||
798 | } | 767 | } |
799 | } while (*p); | 768 | if (!(a <= b)) |
800 | 769 | die("range of cpu numbers must be lower to greater"); | |
801 | if (ret_cpu) | 770 | while (a <= b) { |
802 | return cpu; | 771 | __add_cpu(a); |
803 | 772 | a++; | |
804 | /* Return -1 if we added more than one CPU */ | 773 | } |
805 | return -1; | 774 | if (*s == ',' || *s == ':') |
806 | } | 775 | s++; |
807 | 776 | } while (*s != '\0'); | |
808 | static void add_cpu(const char *cpu_str) | ||
809 | { | ||
810 | int cpu; | ||
811 | |||
812 | cpu = process_cpu_str(cpu_str); | ||
813 | if (cpu >= 0) | ||
814 | __add_cpu(cpu); | ||
815 | } | 777 | } |
816 | 778 | ||
817 | static void read_file_fd(int fd, char *dst, int len) | 779 | static void read_file_fd(int fd, char *dst, int len) |
@@ -958,7 +920,7 @@ void trace_report (int argc, char **argv) | |||
958 | case 0: | 920 | case 0: |
959 | switch(option_index) { | 921 | switch(option_index) { |
960 | case 0: /* cpu */ | 922 | case 0: /* cpu */ |
961 | add_cpu(optarg); | 923 | parse_cpulist(optarg); |
962 | break; | 924 | break; |
963 | case 1: /* events */ | 925 | case 1: /* events */ |
964 | print_events = 1; | 926 | print_events = 1; |