summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt (Google) <rostedt@goodmis.org>2022-02-01 12:34:23 -0500
committerSteven Rostedt (Google) <rostedt@goodmis.org>2022-02-01 12:34:23 -0500
commitf9b6e031d0ab384786d3e58067544142e3ed618f (patch)
tree5e6fbe956fd1f08267293f0449acb8ce03e1d61c
parent2709c2de791c58dc12e75f55b12fa672ce6b4cf7 (diff)
downloadktrace-f9b6e031d0ab384786d3e58067544142e3ed618f.tar.gz
ktrace: Use the ccli_list_* helper functions for completions
Managing the list of completions is tedious and error prone, use the helper functions now provided by the ccli library for managing the list of completions to return. Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
-rw-r--r--src/create.c199
1 files changed, 86 insertions, 113 deletions
diff --git a/src/create.c b/src/create.c
index 38cb0b6..bd851d8 100644
--- a/src/create.c
+++ b/src/create.c
@@ -502,7 +502,7 @@ static int get_mods(char ***mods)
return cnt;
}
-static int load_available_filter(char ***list, char *match)
+static int load_available_filter(struct ccli *ccli, char ***list, char *match)
{
char **funcs = NULL;
char **mods = NULL;
@@ -511,10 +511,10 @@ static int load_available_filter(char ***list, char *match)
char *p;
int ret;
int cnt = 0;
+ int fcnt = 0;
int mcnt = 0;
int i;
- *list = NULL;
if ((p = strchr(match, ':'))) {
mod = strdup(match);
if (!mod)
@@ -532,24 +532,23 @@ static int load_available_filter(char ***list, char *match)
if (ret < 0)
goto out;
- cnt = tracefs_list_size(funcs);
- if (cnt < 0)
+ fcnt = tracefs_list_size(funcs);
+ if (fcnt < 0)
goto out;
- *list = calloc(cnt + mcnt, sizeof(**list));
for (i = 0; i < mcnt; i++) {
- (*list)[i] = mods[i];
+ ret = ccli_list_insert(ccli, list, &cnt, mods[i]);
+ if (ret < 0)
+ goto out;
mods[i] = NULL;
}
- for (i = 0; i < cnt; i++) {
- if (mod) {
- ret = asprintf(&p, "%s:%s", mod, funcs[i]);
- if (ret < 0)
- p = NULL;
- } else
- p = strdup(funcs[i]);
- (*list)[i + mcnt] = p;
+ for (i = 0; i < fcnt; i++) {
+ if (mod)
+ ret = ccli_list_add_printf(ccli, list, &cnt,
+ "%s:%s", mod, funcs[i]);
+ else
+ ret = ccli_list_add(ccli, list, &cnt, funcs[i]);
}
out:
tracefs_list_free(funcs);
@@ -558,46 +557,42 @@ static int load_available_filter(char ***list, char *match)
free(mods[i]);
free(mods);
free(mod);
- /* It's possible to get here without allocating list */
- return *list ? cnt + mcnt : 0;
+ if (ret < 0)
+ ccli_list_free(ccli, list, cnt);
+ return ret;
}
-static int type_completion(char ***list, char *match, int len)
+static int type_completion(struct ccli *ccli, char ***list, char *match, int len)
{
static char *types[] = {"string" , "ustring", "x8", "x16", "x32", "x64",
"u8", "u16", "u32", "u64", "s8", "s16", "s32", "s64" };
- char **words;
- int i, x;
+ int cnt = 0;
+ int ret = 0;
+ int i;
- x = ARRAY_SIZE(types);
- words = calloc(x, sizeof(char *));
- if (!words)
- return 0;
- for (i = 0; i < x; i++) {
- asprintf(&words[i], "%.*s.%s",
- len, match, types[i]);
+ for (i = 0; ret >= 0 && i < ARRAY_SIZE(types); i++) {
+ ret = ccli_list_add_printf(ccli, list, &cnt, "%.*s.%s",
+ len, match, types[i]);
}
- *list = words;
- match[strlen(match)] = CCLI_NOSPACE;
- return x;
+ if (ret > 0)
+ match[strlen(match)] = CCLI_NOSPACE;
+ return ret;
}
-static int offset_completion(char m, char ***list, char *match, int len)
+static int offset_completion(struct ccli *ccli, char m, char ***list, char *match, int len)
{
- char **words;
+ int cnt = 0;
+ int ret;
if (!m) {
- words = calloc(1, sizeof(char *));
- if (!words)
- return 0;
- asprintf(&words[0], "%.*s->",
- len, match);
- *list = words;
+ ret = ccli_list_add_printf(ccli, list, &cnt, "%.*s->",
+ len, match);
match[strlen(match)] = CCLI_NOSPACE;
- return 1;
+ return ret;
}
return 0;
}
+
static int kprobe_completion(struct ccli *ccli, void *data,
int argc, char **argv,
char ***list, int word, char *match)
@@ -627,7 +622,7 @@ static int kprobe_completion(struct ccli *ccli, void *data,
ccli_line_refresh(ccli);
return 0;
}
- ret = load_available_filter(list, match);
+ ret = load_available_filter(ccli, list, match);
match[strlen(match)] = CCLI_NOSPACE;
return ret;
default:
@@ -648,9 +643,9 @@ static int kprobe_completion(struct ccli *ccli, void *data,
switch (*m) {
case '.':
- return type_completion(list, match, len);
+ return type_completion(ccli, list, match, len);
case '-':
- return offset_completion(m[1], list, match, len);
+ return offset_completion(ccli, m[1], list, match, len);
}
}
return 0;
@@ -661,10 +656,11 @@ static int event_completion(struct ccli *ccli, struct tep_handle *tep,
{
char **systems;
char **events;
- char **words;
char *system;
char *event;
char *p;
+ int cnt = 0;
+ int ret = 0;
int i;
p = strchr(match, '/');
@@ -678,16 +674,17 @@ static int event_completion(struct ccli *ccli, struct tep_handle *tep,
free(system);
return 0;
}
- words = calloc(tracefs_list_size(events), sizeof(char *));
i = 0;
- if (words) {
- for (; events[i]; i++) {
- asprintf(&event, "%s/%s", system, events[i]);
- if (append && event && !strcmp(event, match)) {
- asprintf(words + i, "%s.", event);
- free(event);
- } else
- words[i] = event;
+ for (; ret >= 0 && events[i]; i++) {
+ ret = asprintf(&event, "%s/%s", system, events[i]);
+ if (ret < 0)
+ break;
+ if (append && event && !strcmp(event, match)) {
+ ret = ccli_list_add_printf(ccli, list, &cnt,
+ "%s.", event);
+ free(event);
+ } else {
+ ret = ccli_list_insert(ccli, list, &cnt, event);
}
}
tracefs_list_free(events);
@@ -695,18 +692,14 @@ static int event_completion(struct ccli *ccli, struct tep_handle *tep,
systems = tracefs_event_systems(NULL);
if (!systems)
return 0;
- words = calloc(tracefs_list_size(systems), sizeof(char *));
- i = 0;
- if (words) {
- for (; systems[i]; i++)
- words[i] = strdup(systems[i]);
- }
+ for (i = 0; ret >= 0 && systems[i]; i++)
+ ret = ccli_list_add(ccli, list, &cnt, systems[i]);
+
tracefs_list_free(systems);
/* Use '/' as a delim */
match[strlen(match)] = '/';
}
- *list = words;
- return i;
+ return ret;
}
static struct tep_event *find_event(struct tep_handle *tep, char *ename)
@@ -728,42 +721,30 @@ static struct tep_event *find_event(struct tep_handle *tep, char *ename)
return event;
}
-static int field_completion(struct tep_event *event, char ***list, char *prefix)
+static int field_completion(struct ccli *ccli,
+ struct tep_event *event, char ***list, char *prefix,
+ int *cnt)
{
struct tep_format_field **common_fields;
struct tep_format_field **fields;
- char **words;
- char **tmp;
- int i, x;
+ int ret;
+ int i;
common_fields = tep_event_common_fields(event);
fields = tep_event_fields(event);
- words = NULL;
- x = 0;
for (i = 0; common_fields && common_fields[i]; i++) {
- tmp = realloc(words, sizeof(char *) * (x + 2));
- if (!tmp) {
- ccli_argv_free(words);
- return 0;
- }
- words = tmp;
- asprintf(&words[x++], "%s%s", prefix, common_fields[i]->name);
- words[x] = NULL;
+ ret = ccli_list_add_printf(ccli, list, cnt,
+ "%s%s", prefix, common_fields[i]->name);
}
for (i = 0; fields && fields[i]; i++) {
- tmp = realloc(words, sizeof(char *) * (x + 2));
- if (!tmp) {
- ccli_argv_free(words);
- return 0;
- }
- words = tmp;
- asprintf(&words[x++], "%s%s", prefix, fields[i]->name);
- words[x] = NULL;
+ ret = ccli_list_add_printf(ccli, list, cnt,
+ "%s%s", prefix, fields[i]->name);
}
free(common_fields);
free(fields);
- *list = words;
- return x;
+ if (ret < 0)
+ ccli_list_free(ccli, list, *cnt);
+ return ret;
}
static int eprobe_completion(struct ccli *ccli, void *data,
@@ -774,6 +755,7 @@ static int eprobe_completion(struct ccli *ccli, void *data,
struct tep_event *event;
char *prefix;
char *p, *m;
+ int cnt = 0;
int len;
int ret;
@@ -810,15 +792,15 @@ static int eprobe_completion(struct ccli *ccli, void *data,
asprintf(&prefix, "%.*s=", len, match);
if (!prefix)
return 0;
- ret = field_completion(event, list, prefix);
+ ret = field_completion(ccli, event, list, prefix, &cnt);
free(prefix);
if (ret > 0)
match[strlen(match)] = CCLI_NOSPACE;
return ret;
case '.':
- return type_completion(list, match, len);
+ return type_completion(ccli, list, match, len);
case '-':
- return offset_completion(m[1], list, match, len);
+ return offset_completion(ccli, m[1], list, match, len);
}
}
printf("\neprobe word=%d match=%s\n", word, match);
@@ -829,6 +811,7 @@ static int append_event_field(struct ccli *ccli, struct tep_handle *tep, char **
char *ename, char *match)
{
struct tep_event *event;
+ int cnt = 0;
char *p;
/* Find the end of the event */
@@ -850,14 +833,14 @@ static int append_event_field(struct ccli *ccli, struct tep_handle *tep, char **
p++;
*p = '\0';
- return field_completion(event, list, ename);
+ return field_completion(ccli, event, list, ename, &cnt);
}
static int append_field_ts(struct ccli *ccli, struct tep_handle *tep, char ***list,
char *ename)
{
struct tep_event *event;
- char **words;
+ int cnt = 0;
char *e;
char *p;
int ret;
@@ -885,15 +868,13 @@ static int append_field_ts(struct ccli *ccli, struct tep_handle *tep, char ***li
*p = '.';
p[1] = '\0';
- ret = field_completion(event, list, ename);
+ ret = field_completion(ccli, event, list, ename, &cnt);
if (ret > 0) {
- words = realloc(*list, sizeof(*words) * (ret + 1));
- if (words) {
- asprintf(words + ret, "%sTIMESTAMP", ename);
- *list = words;
- ret++;
- }
+ ret = ccli_list_add_printf(ccli, list, &cnt,
+ "%sTIMESTAMP", ename);
+ if (ret < 0)
+ ccli_list_free(ccli, list, cnt);
}
return ret;
}
@@ -904,8 +885,8 @@ static int synthetic_completion(struct ccli *ccli, void *data,
{
struct tep_handle *tep = data;
struct tep_event *event1, *event2;
- char **words;
char *p;
+ int cnt = 0;
int len;
int ret;
@@ -967,17 +948,13 @@ static int synthetic_completion(struct ccli *ccli, void *data,
return 0;
}
- words = calloc(2, sizeof(*words));
- if (!words)
- return 0;
- asprintf(words, "%s=%s/%s", argv[word],
- event1->system, event1->name);
- asprintf(words + 1, "%s=%s/%s", argv[word],
- event2->system, event2->name);
- *list = words;
+ ccli_list_add_printf(ccli, list, &cnt, "%s=%s/%s", argv[word],
+ event1->system, event1->name);
+ ret = ccli_list_add_printf(ccli, list, &cnt, "%s=%s/%s",
+ argv[word], event2->system, event2->name);
match[strlen(match)] = '.';
- return 2;
+ return ret;
}
printf("\neprobe word=%d match=%s\n", word, match);
return 0;
@@ -988,20 +965,16 @@ int create_completion(struct ccli *ccli, const char *command,
char *match, char ***list, void *data)
{
char *types[] = { "kprobe", "eprobe", "synthetic" };
- char **words;
char **argv;
int argc;
+ int cnt = 0;
int ret = 0;
int i;
if (word == 1) {
- words = calloc(ARRAY_SIZE(types), sizeof(char *));
- if (!words)
- return 0;
- for (i = 0; i < ARRAY_SIZE(types); i++)
- words[i] = strdup(types[i]);
- *list = words;
- return i;
+ for (i = 0; ret >= 0 && i < ARRAY_SIZE(types); i++)
+ ret = ccli_list_add(ccli, list, &cnt, types[i]);
+ return ret;
}
argc = ccli_line_parse(line, &argv);