1
0
Fork 0

Merging upstream version 3.7.8.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-05 08:08:50 +01:00
parent 099007bbc4
commit a3c6363c26
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
52 changed files with 13518 additions and 998 deletions

View file

@ -15,11 +15,13 @@
#define _GNU_SOURCE
#define _POSIX_C_SOURCE 200809L /* strdup */
#include <dirent.h>
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include "libyang.h"
@ -28,6 +30,70 @@
#include "compat.h"
#include "linenoise/linenoise.h"
/**
* @brief Fill path completion.
*
* @param[in] hint Path to directory.
* @param[in] lc For adding completions.
*/
static void
path_completion(const char *hint, linenoiseCompletions *lc)
{
const char *ptr;
char *full_path, *hint_ptr, match[FILENAME_MAX + 2];
DIR *dir;
struct dirent *ent;
struct stat st;
lc->path = 1;
ptr = strrchr(hint, '/');
/* new relative path */
if (ptr == NULL) {
full_path = malloc(2 + FILENAME_MAX + 1);
strcpy(full_path, "./");
ptr = hint;
} else {
full_path = malloc((int)(ptr - hint) + FILENAME_MAX + 1);
++ptr;
sprintf(full_path, "%.*s", (int)(ptr - hint), hint);
}
hint_ptr = full_path + strlen(full_path);
dir = opendir(full_path);
if (dir == NULL) {
free(full_path);
return;
}
while ((ent = readdir(dir))) {
if (ent->d_name[0] == '.') {
continue;
}
if (!strncmp(ptr, ent->d_name, strlen(ptr))) {
/* is it a directory? */
strcpy(hint_ptr, ent->d_name);
if (stat(full_path, &st)) {
/* skip this item */
continue;
}
strcpy(match, ent->d_name);
if (S_ISDIR(st.st_mode)) {
strcat(match, "/");
}
linenoiseAddCompletion(lc, match);
}
}
free(full_path);
closedir(dir);
}
/* from the main.c */
extern struct ly_ctx *ctx;
@ -430,29 +496,28 @@ complete_cmd(const char *buf, const char *hint, linenoiseCompletions *lc)
struct autocomplete {
enum COMMAND_INDEX ci; /**< command index to global variable 'commands' */
const char *opt; /**< optional option */
void (*ln_cb)(const char *, const char *, linenoiseCompletions *); /**< linenoise callback to call */
void (*yl_cb)(const char *, char ***, unsigned int *); /**< yanglint callback to call */
void (*yl_cb)(const char *, char ***, unsigned int *); /**< yanglint callback to call */
} ac[] = {
{CMD_ADD, NULL, linenoisePathCompletion, NULL},
{CMD_PRINT, "-f", NULL, get_print_format_arg},
{CMD_PRINT, "-P", NULL, get_schema_completion},
{CMD_PRINT, "-o", linenoisePathCompletion, NULL},
{CMD_PRINT, NULL, NULL, get_model_completion},
{CMD_SEARCHPATH, NULL, linenoisePathCompletion, NULL},
{CMD_EXTDATA, NULL, linenoisePathCompletion, NULL},
{CMD_CLEAR, "-Y", linenoisePathCompletion, NULL},
{CMD_DATA, "-t", NULL, get_data_type_arg},
{CMD_DATA, "-O", linenoisePathCompletion, NULL},
{CMD_DATA, "-R", linenoisePathCompletion, NULL},
{CMD_DATA, "-f", NULL, get_data_in_format_arg},
{CMD_DATA, "-F", NULL, get_data_in_format_arg},
{CMD_DATA, "-d", NULL, get_data_default_arg},
{CMD_DATA, "-o", linenoisePathCompletion, NULL},
{CMD_DATA, NULL, linenoisePathCompletion, NULL},
{CMD_LIST, NULL, NULL, get_list_format_arg},
{CMD_FEATURE, NULL, NULL, get_model_completion},
{CMD_VERB, NULL, NULL, get_verb_arg},
{CMD_DEBUG, NULL, NULL, get_debug_arg},
{CMD_ADD, NULL, NULL},
{CMD_PRINT, "-f", get_print_format_arg},
{CMD_PRINT, "-P", get_schema_completion},
{CMD_PRINT, "-o", NULL},
{CMD_PRINT, NULL, get_model_completion},
{CMD_SEARCHPATH, NULL, NULL},
{CMD_EXTDATA, NULL, NULL},
{CMD_CLEAR, "-Y", NULL},
{CMD_DATA, "-t", get_data_type_arg},
{CMD_DATA, "-O", NULL},
{CMD_DATA, "-R", NULL},
{CMD_DATA, "-f", get_data_in_format_arg},
{CMD_DATA, "-F", get_data_in_format_arg},
{CMD_DATA, "-d", get_data_default_arg},
{CMD_DATA, "-o", NULL},
{CMD_DATA, NULL, NULL},
{CMD_LIST, NULL, get_list_format_arg},
{CMD_FEATURE, NULL, get_model_completion},
{CMD_VERB, NULL, get_verb_arg},
{CMD_DEBUG, NULL, get_debug_arg},
};
size_t name_len;
const char *last, *name, *getoptstr;
@ -490,10 +555,10 @@ complete_cmd(const char *buf, const char *hint, linenoiseCompletions *lc)
}
/* callback */
if (ac[i].ln_cb) {
ac[i].ln_cb(buf, hint, lc);
} else {
if (ac[i].yl_cb) {
ac[i].yl_cb(hint, &matches, &match_count);
} else {
path_completion(hint, lc);
}
break;
}