1 /* Copyright (C) 2011 Ericsson AB, Nils Carlson <nils.carlson@ericsson.com>
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 /* This dummy command is needed to create the sections in cli.o before
25 * other .o files have these sections, usefull for development.
27 static int _dummy(int argc
, char *argv
[]) {
31 /* Define a dummy cmd to guarantee existence of the builtin variables */
32 struct cli_cmd __cli_cmds __dummy_cli_cmd
[] = {
43 extern struct cli_cmd __start___cli_cmds
[] __attribute__((visibility("hidden")));
44 extern struct cli_cmd __stop___cli_cmds
[] __attribute__((visibility("hidden")));
46 static struct cli_cmd
**cli_cmd_list
;
47 static int cli_cmd_list_size
;
49 static char *process_name
;
51 static int compute_cli_cmds_size(void)
53 long cli_cmds_start
, cli_cmds_end
;
55 cli_cmds_start
= (long)__start___cli_cmds
;
56 cli_cmds_end
= (long)__stop___cli_cmds
;
58 return (cli_cmds_end
- cli_cmds_start
) / sizeof(struct cli_cmd
);
61 static void __attribute__((constructor
)) generate_cli_cmd_list(int argc
, char *argv
[])
63 struct cli_cmd
*cli_cmd
;
66 process_name
= basename(argv
[0]);
68 section_size
= compute_cli_cmds_size();
70 cli_cmd_list
= malloc(section_size
* sizeof(void *));
72 fprintf(stderr
, "Failed to allocate command list!");
76 cli_cmd_list_size
= 0;
78 cli_cmd
= __start___cli_cmds
;
79 for (i
= 0; i
< section_size
; i
++) {
80 if (&cli_cmd
[i
] == &__dummy_cli_cmd
[0]) {
84 if (cli_cmd
[i
].name
) {
85 cli_cmd_list
[cli_cmd_list_size
++] = &cli_cmd
[i
];
90 struct cli_cmd
*find_cli_cmd(const char *command
)
94 for (i
= 0; i
< cli_cmd_list_size
; i
++) {
95 if (!strcmp(cli_cmd_list
[i
]->name
, command
)) {
96 return cli_cmd_list
[i
];
103 static int cmpcli_cmds(const void *p1
, const void *p2
)
105 return strcmp(* (char * const *) ((struct cli_cmd
*)p1
)->name
,
106 * (char * const *) ((struct cli_cmd
*)p2
)->name
);
109 #define HELP_BUFFER_SIZE 4096
111 static void print_cmd_help(const char *prefix
, const char *infix
,
112 struct cli_cmd
*cli_cmd
)
114 if (cli_cmd
->help_text
) {
115 fprintf(stderr
, "%s%s%s",
119 } else if (cli_cmd
->description
) {
120 fprintf(stderr
, "%s%s%s\n%s\n",
124 cli_cmd
->description
);
126 fprintf(stderr
, "No help available for %s\n",
131 void list_cli_cmds(int option
)
135 qsort(cli_cmd_list
, cli_cmd_list_size
, sizeof(void *), cmpcli_cmds
);
137 for (i
= 0; i
< cli_cmd_list_size
; i
++) {
139 case CLI_SIMPLE_LIST
:
140 fprintf(stderr
, "%s ", cli_cmd_list
[i
]->name
);
142 case CLI_DESCRIPTIVE_LIST
:
143 fprintf(stderr
, " %-25s%s\n", cli_cmd_list
[i
]->name
,
144 cli_cmd_list
[i
]->description
);
146 case CLI_EXTENDED_LIST
:
147 print_cmd_help("", "", cli_cmd_list
[i
]);
148 fprintf(stderr
, "\n");
153 if (option
== CLI_SIMPLE_LIST
) {
154 fprintf(stderr
, "\n");
158 int cli_print_help(const char *command
)
160 struct cli_cmd
*cli_cmd
;
162 cli_cmd
= find_cli_cmd(command
);
167 print_cmd_help(process_name
, " ", cli_cmd
);
172 static void cli_check_argc(const char *command
, int args
,
173 int operator, int desired_args
)
177 if (args
!= desired_args
)
181 if (args
< desired_args
)
189 fprintf(stderr
, "%s %s requires %s%d argument%s, see usage.\n",
190 process_name
, command
, operator == CLI_EQ
? "" : "at least ",
191 desired_args
, desired_args
> 1 ? "s" : "");
192 cli_print_help(command
);
197 void cli_dispatch_cmd(struct cli_cmd
*cmd
, int argc
, char *argv
[])
199 cli_check_argc(cmd
->name
, argc
- 1, cmd
->desired_args_op
,
202 if (cmd
->function(argc
, argv
)) {