perf time-utils: Add support for multiple explicit time intervals
Currently only a single explicit time range is accepted. Add support for multiple ranges separated by spaces, which requires the string to be quoted. Update the time utils test accordingly. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Cc: Jin Yao <yao.jin@linux.intel.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/r/20190604130017.31207-20-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:

committed by
Arnaldo Carvalho de Melo

parent
e39a12cbd2
commit
a77a05e233
@@ -7,6 +7,7 @@
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "perf.h"
|
||||
#include "debug.h"
|
||||
@@ -116,6 +117,69 @@ int perf_time__parse_str(struct perf_time_interval *ptime, const char *ostr)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int perf_time__parse_strs(struct perf_time_interval *ptime,
|
||||
const char *ostr, int size)
|
||||
{
|
||||
const char *cp;
|
||||
char *str, *arg, *p;
|
||||
int i, num = 0, rc = 0;
|
||||
|
||||
/* Count the commas */
|
||||
for (cp = ostr; *cp; cp++)
|
||||
num += !!(*cp == ',');
|
||||
|
||||
if (!num)
|
||||
return -EINVAL;
|
||||
|
||||
BUG_ON(num > size);
|
||||
|
||||
str = strdup(ostr);
|
||||
if (!str)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Split the string and parse each piece, except the last */
|
||||
for (i = 0, p = str; i < num - 1; i++) {
|
||||
arg = p;
|
||||
/* Find next comma, there must be one */
|
||||
p = strchr(p, ',') + 1;
|
||||
/* Skip white space */
|
||||
while (isspace(*p))
|
||||
p++;
|
||||
/* Skip the value, must not contain space or comma */
|
||||
while (*p && !isspace(*p)) {
|
||||
if (*p++ == ',') {
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
/* Split and parse */
|
||||
if (*p)
|
||||
*p++ = 0;
|
||||
rc = perf_time__parse_str(ptime + i, arg);
|
||||
if (rc < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Parse the last piece */
|
||||
rc = perf_time__parse_str(ptime + i, p);
|
||||
if (rc < 0)
|
||||
goto out;
|
||||
|
||||
/* Check there is no overlap */
|
||||
for (i = 0; i < num - 1; i++) {
|
||||
if (ptime[i].end >= ptime[i + 1].start) {
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
rc = num;
|
||||
out:
|
||||
free(str);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int parse_percent(double *pcnt, char *str)
|
||||
{
|
||||
char *c, *endptr;
|
||||
@@ -424,15 +488,13 @@ int perf_time__parse_for_ranges(const char *time_str,
|
||||
time_str,
|
||||
session->evlist->first_sample_time,
|
||||
session->evlist->last_sample_time);
|
||||
|
||||
if (num < 0)
|
||||
goto error_invalid;
|
||||
} else {
|
||||
if (perf_time__parse_str(ptime_range, time_str))
|
||||
goto error_invalid;
|
||||
num = 1;
|
||||
num = perf_time__parse_strs(ptime_range, time_str, size);
|
||||
}
|
||||
|
||||
if (num < 0)
|
||||
goto error_invalid;
|
||||
|
||||
*range_size = size;
|
||||
*range_num = num;
|
||||
*ranges = ptime_range;
|
||||
|
Reference in New Issue
Block a user