|
15 | 15 | #define _GNU_SOURCE |
16 | 16 | #define _POSIX_C_SOURCE 200809L /* strdup */ |
17 | 17 |
|
| 18 | +#include <dirent.h> |
18 | 19 | #include <errno.h> |
19 | 20 | #include <stdint.h> |
20 | 21 | #include <stdio.h> |
21 | 22 | #include <stdlib.h> |
22 | 23 | #include <string.h> |
| 24 | +#include <sys/stat.h> |
23 | 25 |
|
24 | 26 | #include "libyang.h" |
25 | 27 |
|
|
28 | 30 | #include "compat.h" |
29 | 31 | #include "linenoise/linenoise.h" |
30 | 32 |
|
| 33 | +/* This function can be called in user completion callback to fill |
| 34 | + * path completion for them. hint parameter is actually the whole path |
| 35 | + * and buf is unused, but included to match the completion callback prototype. */ |
| 36 | +static void |
| 37 | +path_completion(const char *buf, const char *hint, linenoiseCompletions *lc) |
| 38 | +{ |
| 39 | + const char *ptr; |
| 40 | + char *full_path, *hint_ptr, match[FILENAME_MAX + 2]; |
| 41 | + DIR *dir; |
| 42 | + struct dirent *ent; |
| 43 | + struct stat st; |
| 44 | + |
| 45 | + (void)buf; |
| 46 | + |
| 47 | + lc->path = 1; |
| 48 | + |
| 49 | + ptr = strrchr(hint, '/'); |
| 50 | + |
| 51 | + /* new relative path */ |
| 52 | + if (ptr == NULL) { |
| 53 | + full_path = malloc(2 + FILENAME_MAX + 1); |
| 54 | + strcpy(full_path, "./"); |
| 55 | + |
| 56 | + ptr = hint; |
| 57 | + } else { |
| 58 | + full_path = malloc((int)(ptr - hint) + FILENAME_MAX + 1); |
| 59 | + ++ptr; |
| 60 | + sprintf(full_path, "%.*s", (int)(ptr - hint), hint); |
| 61 | + } |
| 62 | + hint_ptr = full_path + strlen(full_path); |
| 63 | + |
| 64 | + dir = opendir(full_path); |
| 65 | + if (dir == NULL) { |
| 66 | + free(full_path); |
| 67 | + return; |
| 68 | + } |
| 69 | + |
| 70 | + while ((ent = readdir(dir))) { |
| 71 | + if (ent->d_name[0] == '.') { |
| 72 | + continue; |
| 73 | + } |
| 74 | + |
| 75 | + if (!strncmp(ptr, ent->d_name, strlen(ptr))) { |
| 76 | + /* is it a directory? */ |
| 77 | + strcpy(hint_ptr, ent->d_name); |
| 78 | + if (stat(full_path, &st)) { |
| 79 | + /* skip this item */ |
| 80 | + continue; |
| 81 | + } |
| 82 | + |
| 83 | + strcpy(match, ent->d_name); |
| 84 | + if (S_ISDIR(st.st_mode)) { |
| 85 | + strcat(match, "/"); |
| 86 | + } |
| 87 | + |
| 88 | + linenoiseAddCompletion(lc, match); |
| 89 | + } |
| 90 | + } |
| 91 | + |
| 92 | + free(full_path); |
| 93 | + closedir(dir); |
| 94 | +} |
| 95 | + |
31 | 96 | /* from the main.c */ |
32 | 97 | extern struct ly_ctx *ctx; |
33 | 98 |
|
@@ -433,22 +498,22 @@ complete_cmd(const char *buf, const char *hint, linenoiseCompletions *lc) |
433 | 498 | void (*ln_cb)(const char *, const char *, linenoiseCompletions *); /**< linenoise callback to call */ |
434 | 499 | void (*yl_cb)(const char *, char ***, unsigned int *); /**< yanglint callback to call */ |
435 | 500 | } ac[] = { |
436 | | - {CMD_ADD, NULL, linenoisePathCompletion, NULL}, |
| 501 | + {CMD_ADD, NULL, path_completion, NULL}, |
437 | 502 | {CMD_PRINT, "-f", NULL, get_print_format_arg}, |
438 | 503 | {CMD_PRINT, "-P", NULL, get_schema_completion}, |
439 | | - {CMD_PRINT, "-o", linenoisePathCompletion, NULL}, |
| 504 | + {CMD_PRINT, "-o", path_completion, NULL}, |
440 | 505 | {CMD_PRINT, NULL, NULL, get_model_completion}, |
441 | | - {CMD_SEARCHPATH, NULL, linenoisePathCompletion, NULL}, |
442 | | - {CMD_EXTDATA, NULL, linenoisePathCompletion, NULL}, |
443 | | - {CMD_CLEAR, "-Y", linenoisePathCompletion, NULL}, |
| 506 | + {CMD_SEARCHPATH, NULL, path_completion, NULL}, |
| 507 | + {CMD_EXTDATA, NULL, path_completion, NULL}, |
| 508 | + {CMD_CLEAR, "-Y", path_completion, NULL}, |
444 | 509 | {CMD_DATA, "-t", NULL, get_data_type_arg}, |
445 | | - {CMD_DATA, "-O", linenoisePathCompletion, NULL}, |
446 | | - {CMD_DATA, "-R", linenoisePathCompletion, NULL}, |
| 510 | + {CMD_DATA, "-O", path_completion, NULL}, |
| 511 | + {CMD_DATA, "-R", path_completion, NULL}, |
447 | 512 | {CMD_DATA, "-f", NULL, get_data_in_format_arg}, |
448 | 513 | {CMD_DATA, "-F", NULL, get_data_in_format_arg}, |
449 | 514 | {CMD_DATA, "-d", NULL, get_data_default_arg}, |
450 | | - {CMD_DATA, "-o", linenoisePathCompletion, NULL}, |
451 | | - {CMD_DATA, NULL, linenoisePathCompletion, NULL}, |
| 515 | + {CMD_DATA, "-o", path_completion, NULL}, |
| 516 | + {CMD_DATA, NULL, path_completion, NULL}, |
452 | 517 | {CMD_LIST, NULL, NULL, get_list_format_arg}, |
453 | 518 | {CMD_FEATURE, NULL, NULL, get_model_completion}, |
454 | 519 | {CMD_VERB, NULL, NULL, get_verb_arg}, |
|
0 commit comments