1 /* Copyright (C) 2018 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
3 /** \file lsu.c Utilities related to the lopsub library. */
12 static int lsu_lopsub_error(int ret, char **errctx, char **result, unsigned *num_chars)
14 const char *se = para_strerror(-ret);
18 n = xasprintf(result, "%s: %s\n", *errctx, se);
20 n = xasprintf(result, "lopsub error: %s\n", se);
28 static void lsu_get_subcommand_summary(bool long_summary,
29 const struct lls_suite *suite,
30 const char *(*aux_info_cb)(unsigned cmd_num, bool verbose),
31 char **result, unsigned *num_chars)
34 const struct lls_command *cmd;
35 const char *name, *aux_info = NULL;
36 struct para_buffer pb = {.max_size = 0 /* unlimited */};
38 para_printf(&pb, "Available subcommands:\n");
40 int maxname = 0, max_aux_info = 0;
41 for (i = 1; (cmd = lls_cmd(i, suite)); i++) {
42 maxname = PARA_MAX(maxname,
43 (int)strlen(lls_command_name(cmd)));
45 aux_info = aux_info_cb(i, false);
48 max_aux_info = PARA_MAX(max_aux_info,
49 (int)strlen(aux_info));
52 for (i = 1; (cmd = lls_cmd(i, suite)); i++) {
54 aux_info = aux_info_cb(i, false);
55 para_printf(&pb, "%-*s %-*s %s\n", maxname,
56 lls_command_name(cmd), max_aux_info, aux_info?
57 aux_info : "", lls_purpose(cmd));
61 para_printf(&pb, "\t");
62 for (i = 1; (cmd = lls_cmd(i, suite)); i++) {
63 name = lls_command_name(cmd);
65 n += para_printf(&pb, ", ");
67 para_printf(&pb, "\n\t");
70 n += para_printf(&pb, "%s", name);
72 para_printf(&pb, "\n");
76 *num_chars = pb.offset;
80 * A generic implementation of the help subcommand.
82 * This function returns the help text for the given subcommand, or the list of
83 * all subcommands if no non-option argument is given. The function is generic
84 * in that it works for arbitrary lopsub suites.
86 * \param long_help Applies to both command list and command help.
87 * \param suite The supercommand, if any, is omitted.
88 * \param lpr Used to determine whether a non-option argument is given.
89 * \param aux_info_cb Optional callback, may return NULL, static memory.
90 * \param result Must be freed by the caller.
91 * \param num_chars Initialized to the length of the returned string, optional.
93 * If the optional aux_info_cb function pointer is not NULL, the callback
94 * function must return the string representation of the aux_info structure of
95 * the given command, or NULL to indicate that this command has no aux info
98 * The function fails if lpr has more than one non-option argument, or if there
99 * is exactly one non-option argument, but this argument is not the name of a
100 * subcommand in the given lopsub suite.
102 * \return Standard. In the failure case a suitable error message is returned
103 * via the result pointer and num_chars is set accordingly.
105 int lsu_com_help(bool long_help, const struct lls_parse_result *lpr,
106 const struct lls_suite *suite,
107 const char *(*aux_info_cb)(unsigned cmd_num, bool verbose),
108 char **result, unsigned *num_chars)
113 const char *arg, *aux_info = NULL;
114 const struct lls_command *cmd;
116 ret = lls(lls_check_arg_count(lpr, 0, 1, &errctx));
118 return lsu_lopsub_error(ret, &errctx, result, num_chars);
119 if (lls_num_inputs(lpr) == 0) {
120 lsu_get_subcommand_summary(long_help, suite,
121 aux_info_cb, result, num_chars);
124 arg = lls_input(0, lpr);
125 ret = lls(lls_lookup_subcmd(arg, suite, &errctx));
127 return lsu_lopsub_error(ret, &errctx, result, num_chars);
128 cmd = lls_cmd(ret, suite);
129 tmp = long_help? lls_long_help(cmd) : lls_short_help(cmd);
131 aux_info = aux_info_cb(ret, true);
132 n = xasprintf(result, "%s%s%s", tmp, aux_info? aux_info : "",
133 aux_info? "\n" : "");