-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathqcli.h
More file actions
278 lines (247 loc) · 8.07 KB
/
qcli.h
File metadata and controls
278 lines (247 loc) · 8.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
/**
* Author: luoqi
* Created Date: 2024-08-01 16:28:28
* Last Modified: 2026-04-10 11:34:27
* Modified By: luoqi at <**@****>
* Copyright (c) 2025 <*****>
* Description:
*/
/**
* @file qcli.h
* @brief A lightweight command-line interface (CLI) library for embedded systems.
*
* This library provides a simple CLI framework with command registration,
* history management, tab completion, and basic input handling.
*
* @author luoqi
* @date 2024-08-01
* @copyright (c) 2025 <*****>
*/
#ifndef _QCLI_H_
#define _QCLI_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
/**
* @def QCLI_USE_STDLIBC
* @brief Define to use standard C library functions for string operations.
* If not defined, custom implementations are used.
*/
#ifndef QCLI_USE_STDLIBC
#define QCLI_USE_STDLIBC_ 0
#else
#define QCLI_USE_STDLIBC_ 1
#endif
/**
* @def QCLI_HISTORY_MAX
* @brief Maximum number of history entries.
*/
#ifndef QCLI_HISTORY_MAX
#define QCLI_HISTORY_MAX 10
#endif
/**
* @def QCLI_CMD_STR_MAX
* @brief Maximum length of a command string.
*/
#ifndef QCLI_CMD_STR_MAX
#define QCLI_CMD_STR_MAX 50
#endif
/**
* @def QCLI_CMD_ARGC_MAX
* @brief Maximum number of arguments in a command.
*/
#ifndef QCLI_CMD_ARGC_MAX
#define QCLI_CMD_ARGC_MAX 10
#endif
/**
* @def QCLI_SHOW_TITLE
* @brief Enable or disable showing the title on initialization.
*/
#ifndef QCLI_SHOW_TITLE
#define QCLI_SHOW_TITLE 0
#endif
/**
* @brief Doubly linked list structure for command management.
*/
typedef struct QcliList QcliList;
struct QcliList {
QcliList *prev; /**< Pointer to the previous node. */
QcliList *next; /**< Pointer to the next node. */
};
/**
* @brief Error codes for CLI operations.
*/
typedef enum {
QCLI_ERR_PARAM_UNKNOWN = -5, /**< Unknown parameter. */
QCLI_ERR_PARAM_TYPE = -4, /**< Parameter type error. */
QCLI_ERR_PARAM_MORE = -3, /**< Too many parameters. */
QCLI_ERR_PARAM_LESS = -2, /**< Too few parameters. */
QCLI_ERR_PARAM = -1, /**< General parameter error. */
QCLI_EOK = 0, /**< Operation successful. */
} QCliError;
/**
* @brief Callback function type for command execution.
* @param argc Number of arguments.
* @param argv Array of argument strings.
* @return Error code.
*/
typedef int (*QcmdCallback)(int, char **);
/**
* @brief Print function type for output.
* @param fmt Format string.
* @return Number of characters printed.
*/
typedef int (*QcliPrint)(const char *fmt, ...);
typedef struct Qcli Qcli; /**< Forward declaration for CLI object. */
/**
* @brief Structure representing a CLI command.
*/
typedef struct QcliCmd QcliCmd; /**< Forward declaration for command. */
struct QcliCmd {
Qcli *cli; /**< Pointer to the associated CLI object. */
const char *name; /**< Command name. */
QcmdCallback cb; /**< Callback function. */
const char *desc; /**< Usage description. */
struct QcliCmd *parent; /**< Pointer to parent command. */
QcliList node; /**< Linked list node. */
QcliList sublevel; /**< Linked list of subcommands. */
bool hierarchy; /**< Flag indicating if this command has subcommands. */
};
/**
* @brief Ring buffer structure for command history.
*/
typedef struct {
char entries[QCLI_HISTORY_MAX][QCLI_CMD_STR_MAX + 1]; /**< History entries. */
size_t head; /**< Head index of the ring buffer. */
size_t tail; /**< Tail index of the ring buffer. */
size_t count; /**< Number of entries in the ring buffer. */
size_t capacity; /**< Capacity of the ring buffer. */
} QcliRb;
/**
* @brief Structure representing the CLI object.
*/
struct Qcli {
char args[QCLI_CMD_STR_MAX + 1]; /**< Input argument buffer. */
char *argv[QCLI_CMD_ARGC_MAX + 1]; /**< Parsed argument pointers. */
QcliRb history; /**< Command history ring buffer. */
uint16_t args_size; /**< Current size of args buffer. */
union {
struct {
uint8_t is_echo : 1; /**< Echo input flag. */
uint8_t is_disp : 1; /**< Display output flag. */
uint8_t reserved : 6; /**< Reserved bits. */
} flags;
uint8_t flags_; /**< Combined flags value. */
}; /**< Flags union. */
uint8_t cursor_idx; /**< Current cursor index in args. */
uint8_t hist_idx; /**< Current history index. */
uint8_t hist_recall_idx; /**< Recall index for history. */
uint8_t hist_recall_times; /**< Number of recalls. */
uint8_t special_key; /**< State for special key handling. */
int argc; /**< Number of parsed arguments. */
QcliPrint print; /**< Print function. */
QcliCmd _disp; /**< Built-in display command. */
QcliCmd _history; /**< Built-in history command. */
QcliCmd _help; /**< Built-in help command. */
QcliCmd _clear; /**< Built-in clear command. */
QcliList cmds; /**< List of registered commands. */
};
/**
* @brief Structure for argument table.
*/
typedef struct {
const char *name; /**< Argument name. */
QcmdCallback cb; /**< Callback function. */
const char *desc; /**< Usage description. */
} QcliTable;
/**
* @brief Execute arguments from a table.
* @param argc Number of arguments.
* @param argv Argument array.
* @param table Argument table.
* @param table_size Size of the table.
* @return Error code.
*/
int qcli_args_trick(int argc, char **argv, const QcliTable *table, size_t table_size);
/**
* @brief Initialize the CLI object.
* @param cli Pointer to CLI object.
* @param print Print function.
* @return Error code.
*/
int qcli_init(Qcli *cli, QcliPrint print);
/**
* @brief Display the CLI title.
* @param cli Pointer to CLI object.
* @return Error code.
*/
int qcli_title(Qcli *cli);
/**
* @brief Add a command to the CLI.
* @param cli Pointer to CLI object.
* @param cmd Pointer to command structure.
* @param name Command name.
* @param cb Callback function.
* @param desc Usage string.
* @return Error code.
*/
int qcli_add(Qcli *cli, QcliCmd *cmd, const char *name, QcmdCallback cb, const char *desc);
/**
* @brief Delete a command from the CLI.
* @param cli Pointer to CLI object.
* @param name Command name.
* @return Error code.
*/
int qcli_del(Qcli *cli, const char *name);
/**
* @brief Insert a command at the beginning of the command list.
* @param cli Pointer to CLI object.
* @param cmd Pointer to command structure.
* @return Error code.
*/
int qcli_insert(Qcli *cli, QcliCmd *cmd);
/**
* @brief Find a command by name.
* @param cli Pointer to CLI object.
* @param name Command name.
* @return Pointer to command or NULL.
*/
QcliCmd *qcli_find(Qcli *cli, const char *name);
/**
* @brief Add a subcommand to a parent command.
* @param parent Parent command structure.
* @param cmd Pointer to subcommand structure.
* @param name Subcommand name.
* @param cb Callback function.
* @param desc Usage string.
* @return Error code.
*/
int qcli_sub_add(QcliCmd *parent, QcliCmd *cmd, const char *name, QcmdCallback cb, const char *desc);
/**
* @brief Find a subcommand by name in a parent command.
* @param parent Parent command.
* @param name Subcommand name.
* @return Pointer to subcommand or NULL.
*/
QcliCmd *qcli_sub_find(QcliCmd *parent, const char *name);
/**
* @brief Execute a character input for the CLI.
* @param cli Pointer to CLI object.
* @param c Input character.
* @return Error code.
*/
int qcli_exec(Qcli *cli, char c);
/**
* @brief Echo a command string to the CLI.
* @param cli Pointer to CLI object.
* @param str Command string.
* @return Error code.
*/
int qcli_xstr(Qcli *cli, char *str);
#ifdef __cplusplus
}
#endif
#endif