|
Packit |
8fb591 |
/**
|
|
Packit |
8fb591 |
* @file completion.c
|
|
Packit |
8fb591 |
* @author Michal Vasko <mvasko@cesnet.cz>
|
|
Packit |
8fb591 |
* @brief libyang's yanglint tool auto completion
|
|
Packit |
8fb591 |
*
|
|
Packit |
8fb591 |
* Copyright (c) 2015 CESNET, z.s.p.o.
|
|
Packit |
8fb591 |
*
|
|
Packit |
8fb591 |
* This source code is licensed under BSD 3-Clause License (the "License").
|
|
Packit |
8fb591 |
* You may not use this file except in compliance with the License.
|
|
Packit |
8fb591 |
* You may obtain a copy of the License at
|
|
Packit |
8fb591 |
*
|
|
Packit |
8fb591 |
* https://opensource.org/licenses/BSD-3-Clause
|
|
Packit |
8fb591 |
*/
|
|
Packit |
8fb591 |
|
|
Packit |
8fb591 |
#include <stdlib.h>
|
|
Packit |
8fb591 |
#include <stdio.h>
|
|
Packit |
8fb591 |
#include <sys/types.h>
|
|
Packit |
8fb591 |
#include <dirent.h>
|
|
Packit |
8fb591 |
#include <errno.h>
|
|
Packit |
8fb591 |
#include <string.h>
|
|
Packit |
8fb591 |
|
|
Packit |
8fb591 |
#include "commands.h"
|
|
Packit |
8fb591 |
#include "../../linenoise/linenoise.h"
|
|
Packit |
8fb591 |
#include "libyang.h"
|
|
Packit |
8fb591 |
|
|
Packit |
8fb591 |
extern struct ly_ctx *ctx;
|
|
Packit |
8fb591 |
|
|
Packit |
8fb591 |
static void
|
|
Packit |
8fb591 |
get_cmd_completion(const char *hint, char ***matches, unsigned int *match_count)
|
|
Packit |
8fb591 |
{
|
|
Packit |
8fb591 |
int i;
|
|
Packit |
8fb591 |
void *p;
|
|
Packit |
8fb591 |
|
|
Packit |
8fb591 |
*match_count = 0;
|
|
Packit |
8fb591 |
*matches = NULL;
|
|
Packit |
8fb591 |
|
|
Packit |
8fb591 |
for (i = 0; commands[i].name; i++) {
|
|
Packit |
8fb591 |
if (!strncmp(hint, commands[i].name, strlen(hint))) {
|
|
Packit |
8fb591 |
++(*match_count);
|
|
Packit |
8fb591 |
p = realloc(*matches, *match_count * sizeof **matches);
|
|
Packit |
8fb591 |
if (!p) {
|
|
Packit |
8fb591 |
fprintf(stderr, "Memory allocation failed (%s:%d, %s)", __FILE__, __LINE__, strerror(errno));
|
|
Packit |
8fb591 |
return;
|
|
Packit |
8fb591 |
}
|
|
Packit |
8fb591 |
*matches = p;
|
|
Packit |
8fb591 |
(*matches)[*match_count-1] = strdup(commands[i].name);
|
|
Packit |
8fb591 |
}
|
|
Packit |
8fb591 |
}
|
|
Packit |
8fb591 |
}
|
|
Packit |
8fb591 |
|
|
Packit |
8fb591 |
static int
|
|
Packit |
8fb591 |
last_is_opt(const char *hint)
|
|
Packit |
8fb591 |
{
|
|
Packit |
8fb591 |
const char *ptr;
|
|
Packit |
8fb591 |
|
|
Packit |
8fb591 |
/* last is option */
|
|
Packit |
8fb591 |
if (hint[0] == '-') {
|
|
Packit |
8fb591 |
return 1;
|
|
Packit |
8fb591 |
}
|
|
Packit |
8fb591 |
|
|
Packit |
8fb591 |
do {
|
|
Packit |
8fb591 |
--hint;
|
|
Packit |
8fb591 |
} while (hint[0] == ' ');
|
|
Packit |
8fb591 |
|
|
Packit |
8fb591 |
/* last is option argument */
|
|
Packit |
8fb591 |
ptr = strrchr(hint, ' ');
|
|
Packit |
8fb591 |
if (ptr) {
|
|
Packit |
8fb591 |
++ptr;
|
|
Packit |
8fb591 |
if (ptr[0] == '-') {
|
|
Packit |
8fb591 |
return 1;
|
|
Packit |
8fb591 |
}
|
|
Packit |
8fb591 |
}
|
|
Packit |
8fb591 |
|
|
Packit |
8fb591 |
return 0;
|
|
Packit |
8fb591 |
}
|
|
Packit |
8fb591 |
|
|
Packit |
8fb591 |
static void
|
|
Packit |
8fb591 |
get_model_completion(const char *hint, char ***matches, unsigned int *match_count)
|
|
Packit |
8fb591 |
{
|
|
Packit |
8fb591 |
int i;
|
|
Packit |
8fb591 |
uint32_t idx = 0;
|
|
Packit |
8fb591 |
const struct lys_module *module;
|
|
Packit |
8fb591 |
void *p;
|
|
Packit |
8fb591 |
|
|
Packit |
8fb591 |
*match_count = 0;
|
|
Packit |
8fb591 |
*matches = NULL;
|
|
Packit |
8fb591 |
|
|
Packit |
8fb591 |
while ((module = ly_ctx_get_module_iter(ctx, &idx))) {
|
|
Packit |
8fb591 |
if (!strncmp(hint, module->name, strlen(hint))) {
|
|
Packit |
8fb591 |
++(*match_count);
|
|
Packit |
8fb591 |
p = realloc(*matches, *match_count * sizeof **matches);
|
|
Packit |
8fb591 |
if (!p) {
|
|
Packit |
8fb591 |
fprintf(stderr, "Memory allocation failed (%s:%d, %s)", __FILE__, __LINE__, strerror(errno));
|
|
Packit |
8fb591 |
return;
|
|
Packit |
8fb591 |
}
|
|
Packit |
8fb591 |
*matches = p;
|
|
Packit |
8fb591 |
(*matches)[*match_count-1] = strdup(module->name);
|
|
Packit |
8fb591 |
}
|
|
Packit |
8fb591 |
|
|
Packit |
8fb591 |
for (i = 0; i < module->inc_size; ++i) {
|
|
Packit |
8fb591 |
if (!strncmp(hint, module->inc[i].submodule->name, strlen(hint))) {
|
|
Packit |
8fb591 |
++(*match_count);
|
|
Packit |
8fb591 |
p = realloc(*matches, *match_count * sizeof **matches);
|
|
Packit |
8fb591 |
if (!p) {
|
|
Packit |
8fb591 |
fprintf(stderr, "Memory allocation failed (%s:%d, %s)", __FILE__, __LINE__, strerror(errno));
|
|
Packit |
8fb591 |
return;
|
|
Packit |
8fb591 |
}
|
|
Packit |
8fb591 |
*matches = p;
|
|
Packit |
8fb591 |
(*matches)[*match_count-1] = strdup(module->inc[i].submodule->name);
|
|
Packit |
8fb591 |
}
|
|
Packit |
8fb591 |
}
|
|
Packit |
8fb591 |
}
|
|
Packit |
8fb591 |
}
|
|
Packit |
8fb591 |
|
|
Packit |
8fb591 |
void
|
|
Packit |
8fb591 |
complete_cmd(const char *buf, const char *hint, linenoiseCompletions *lc)
|
|
Packit |
8fb591 |
{
|
|
Packit |
8fb591 |
char **matches = NULL;
|
|
Packit |
8fb591 |
unsigned int match_count = 0, i;
|
|
Packit |
8fb591 |
|
|
Packit |
8fb591 |
if (!strncmp(buf, "add ", 4)) {
|
|
Packit |
8fb591 |
linenoisePathCompletion(buf, hint, lc);
|
|
Packit |
8fb591 |
} else if ((!strncmp(buf, "searchpath ", 11) || !strncmp(buf, "data ", 5)
|
|
Packit |
8fb591 |
|| !strncmp(buf, "config ", 7) || !strncmp(buf, "filter ", 7)
|
|
Packit |
8fb591 |
|| !strncmp(buf, "xpath ", 6) || !strncmp(buf, "clear ", 6)) && !last_is_opt(hint)) {
|
|
Packit |
8fb591 |
linenoisePathCompletion(buf, hint, lc);
|
|
Packit |
8fb591 |
} else if ((!strncmp(buf, "print ", 6) || !strncmp(buf, "feature ", 8)) && !last_is_opt(hint)) {
|
|
Packit |
8fb591 |
get_model_completion(hint, &matches, &match_count);
|
|
Packit |
8fb591 |
} else if (!strchr(buf, ' ') && hint[0]) {
|
|
Packit |
8fb591 |
get_cmd_completion(hint, &matches, &match_count);
|
|
Packit |
8fb591 |
}
|
|
Packit |
8fb591 |
|
|
Packit |
8fb591 |
for (i = 0; i < match_count; ++i) {
|
|
Packit |
8fb591 |
linenoiseAddCompletion(lc, matches[i]);
|
|
Packit |
8fb591 |
free(matches[i]);
|
|
Packit |
8fb591 |
}
|
|
Packit |
8fb591 |
free(matches);
|
|
Packit |
8fb591 |
}
|