mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 07:04:22 +01:00
cli: Sort human_readable output by categories
A new field is available in the command json object : 'category' (corresponding to whether "bitcoin", "channel", "network", "payment", "plugin", "utility", "developer"). We use it to printf commands ordered by categories. credits @rustyrussel
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <ccan/asort/asort.h>
|
||||||
#include <ccan/err/err.h>
|
#include <ccan/err/err.h>
|
||||||
#include <ccan/opt/opt.h>
|
#include <ccan/opt/opt.h>
|
||||||
#include <ccan/read_write_all/read_write_all.h>
|
#include <ccan/read_write_all/read_write_all.h>
|
||||||
@@ -10,6 +11,7 @@
|
|||||||
#include <ccan/tal/str/str.h>
|
#include <ccan/tal/str/str.h>
|
||||||
#include <common/configdir.h>
|
#include <common/configdir.h>
|
||||||
#include <common/json.h>
|
#include <common/json.h>
|
||||||
|
#include <common/json_command.h>
|
||||||
#include <common/json_escaped.h>
|
#include <common/json_escaped.h>
|
||||||
#include <common/memleak.h>
|
#include <common/memleak.h>
|
||||||
#include <common/utils.h>
|
#include <common/utils.h>
|
||||||
@@ -94,21 +96,104 @@ static size_t human_readable(const char *buffer, const jsmntok_t *t, char term)
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void human_help(const char *buffer, const jsmntok_t *result, bool has_command) {
|
static int compare_tok(const jsmntok_t *a, const jsmntok_t *b,
|
||||||
int i;
|
const char *buffer)
|
||||||
const jsmntok_t * help_array = result + 2;
|
{
|
||||||
/* the first command object */
|
int a_len = a->end - a->start, b_len = b->end - b->start, min_len, cmp;
|
||||||
const jsmntok_t * curr = help_array + 1;
|
|
||||||
/* iterate through all commands, printing the name and description */
|
if (a_len > b_len)
|
||||||
for (i = 0; i < help_array->size; i++) {
|
min_len = b_len;
|
||||||
curr += 2;
|
else
|
||||||
printf("%.*s\n", curr->end - curr->start, buffer + curr->start);
|
min_len = a_len;
|
||||||
curr += 2;
|
|
||||||
printf(" %.*s\n\n", curr->end - curr->start, buffer + curr->start);
|
cmp = memcmp(buffer + a->start, buffer + b->start, min_len);
|
||||||
curr += 2;
|
if (cmp != 0)
|
||||||
/* advance to next command */
|
return cmp;
|
||||||
curr++;
|
/* If equal, shorter one wins. */
|
||||||
|
return a_len - b_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int compare_help(const jsmntok_t *const *a,
|
||||||
|
const jsmntok_t *const *b,
|
||||||
|
char *buffer)
|
||||||
|
{
|
||||||
|
const jsmntok_t *cat_a, *cat_b;
|
||||||
|
bool a_is_developer, b_is_developer;
|
||||||
|
int cmp;
|
||||||
|
|
||||||
|
cat_a = json_get_member(buffer, *a, "category");
|
||||||
|
cat_b = json_get_member(buffer, *b, "category");
|
||||||
|
|
||||||
|
/* Just in case it's an older lightningd! */
|
||||||
|
if (!cat_a)
|
||||||
|
goto same_category;
|
||||||
|
|
||||||
|
/* We always tweak "developer" category to last. */
|
||||||
|
a_is_developer = json_tok_streq(buffer, cat_a, "developer");
|
||||||
|
b_is_developer = json_tok_streq(buffer, cat_b, "developer");
|
||||||
|
|
||||||
|
if (a_is_developer && b_is_developer)
|
||||||
|
cmp = 0;
|
||||||
|
else if (a_is_developer)
|
||||||
|
cmp = 1;
|
||||||
|
else if (b_is_developer)
|
||||||
|
cmp = -1;
|
||||||
|
else
|
||||||
|
/* Otherwise we order category alphabetically. */
|
||||||
|
cmp = compare_tok(cat_a, cat_b, buffer);
|
||||||
|
|
||||||
|
if (cmp != 0)
|
||||||
|
return cmp;
|
||||||
|
|
||||||
|
/* After category, we order by name */
|
||||||
|
same_category:
|
||||||
|
return compare_tok(json_get_member(buffer, *a, "command"),
|
||||||
|
json_get_member(buffer, *b, "command"),
|
||||||
|
buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void human_help(char *buffer, const jsmntok_t *result, bool has_command) {
|
||||||
|
unsigned int i;
|
||||||
|
/* `curr` is used as a temporary token */
|
||||||
|
const jsmntok_t *curr;
|
||||||
|
const char *prev_cat;
|
||||||
|
/* Contains all commands objects, which have the following structure :
|
||||||
|
* {
|
||||||
|
* "command": "The command name and usage",
|
||||||
|
* "category": "The command category",
|
||||||
|
* "description": "The command's description",
|
||||||
|
* "verbose": "The command's detailed description"
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
const jsmntok_t * help_array = json_get_member(buffer, result, "help");
|
||||||
|
const jsmntok_t **help = tal_arr(NULL, const jsmntok_t *,
|
||||||
|
help_array->size);
|
||||||
|
|
||||||
|
/* Populate an array for easy sorting with asort */
|
||||||
|
json_for_each_arr(i, curr, help_array)
|
||||||
|
help[i] = curr;
|
||||||
|
|
||||||
|
asort(help, tal_count(help), compare_help, buffer);
|
||||||
|
|
||||||
|
prev_cat = "";
|
||||||
|
for (i = 0; i < tal_count(help); i++) {
|
||||||
|
const jsmntok_t *category, *command, *desc;
|
||||||
|
|
||||||
|
category = json_get_member(buffer, help[i], "category");
|
||||||
|
if (category && !json_tok_streq(buffer, category, prev_cat)) {
|
||||||
|
prev_cat = json_strdup(help, buffer, category);
|
||||||
|
if (!has_command)
|
||||||
|
printf("=== %s ===\n\n", prev_cat);
|
||||||
|
}
|
||||||
|
|
||||||
|
command = json_get_member(buffer, help[i], "command");
|
||||||
|
desc = json_get_member(buffer, help[i], "description");
|
||||||
|
printf("%.*s\n",
|
||||||
|
command->end - command->start, buffer + command->start);
|
||||||
|
printf(" %.*s\n\n",
|
||||||
|
desc->end - desc->start, buffer + desc->start);
|
||||||
}
|
}
|
||||||
|
tal_free(help);
|
||||||
|
|
||||||
if (!has_command)
|
if (!has_command)
|
||||||
printf("---\nrun `lightning-cli help <command>` for more information on a specific command\n");
|
printf("---\nrun `lightning-cli help <command>` for more information on a specific command\n");
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include "config.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <common/amount.h>
|
#include <common/amount.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|||||||
Reference in New Issue
Block a user