You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
214 lines
5.8 KiB
214 lines
5.8 KiB
2 years ago
|
/**
|
||
|
* Utilities for console commands
|
||
|
*
|
||
|
* Created on 2020/03/11.
|
||
|
*/
|
||
|
|
||
|
#ifndef LIBCONSOLE_UTILS_H
|
||
|
#define LIBCONSOLE_UTILS_H
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <console/console.h>
|
||
|
|
||
|
#ifndef STR
|
||
|
#define STR_HELPER(x) #x
|
||
|
#define STR(x) STR_HELPER(x)
|
||
|
#endif
|
||
|
|
||
|
#ifndef MIN
|
||
|
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||
|
#endif
|
||
|
|
||
|
#ifndef MAX
|
||
|
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||
|
#endif
|
||
|
|
||
|
#ifndef OBC_FIRMWARE
|
||
|
#define EXPENDABLE_STRING(x) x
|
||
|
#define EXPENDABLE_CODE(x) x
|
||
|
#else
|
||
|
#define EXPENDABLE_STRING(x) ""
|
||
|
#define EXPENDABLE_CODE(x) do {} while(0);
|
||
|
#endif
|
||
|
|
||
|
/**
|
||
|
* Read an argument, or return default if it is empty.
|
||
|
*
|
||
|
* This works for commands arg_int0
|
||
|
*
|
||
|
* Usage:
|
||
|
*
|
||
|
* \code
|
||
|
* static struct {
|
||
|
* struct arg_int *foo;
|
||
|
* } args;
|
||
|
*
|
||
|
* args.foo = arg_int0(...);
|
||
|
*
|
||
|
* int foo = GET_ARG_INT0(args.foo, 1234);
|
||
|
* \endcode
|
||
|
*/
|
||
|
#define GET_ARG_INT0(_arg, _def) ((_arg)->count ? (_arg)->ival[0] : (_def))
|
||
|
|
||
|
/**
|
||
|
* Get CSP node ID from an argument table, using own address as default.
|
||
|
*
|
||
|
* Usage:
|
||
|
*
|
||
|
* \code
|
||
|
* static struct {
|
||
|
* struct arg_int *node;
|
||
|
* } args;
|
||
|
*
|
||
|
* args.node = arg_int0(...);
|
||
|
*
|
||
|
* int node = GET_ARG_CSPADDR0(args.node);
|
||
|
* \endcode
|
||
|
*/
|
||
|
#define GET_ARG_CSPADDR0(_arg) GET_ARG_INT0((_arg), csp_get_address())
|
||
|
|
||
|
/**
|
||
|
* Shortcut to get a timeout argument's value, using CSP_DEF_TIMEOUT_MS as default.
|
||
|
*/
|
||
|
#define GET_ARG_TIMEOUT0(_arg) GET_ARG_INT0((_arg), CONSOLE_CSP_DEF_TIMEOUT_MS)
|
||
|
|
||
|
/**
|
||
|
* Define an optional CSP node argument
|
||
|
*/
|
||
|
#define arg_cspaddr0() arg_int0(NULL, NULL, "<node>", EXPENDABLE_STRING("node ID"))
|
||
|
|
||
|
/**
|
||
|
* Define a mandatory CSP node argument
|
||
|
*/
|
||
|
#define arg_cspaddr1() arg_int1(NULL, NULL, "<node>", EXPENDABLE_STRING("node ID"))
|
||
|
|
||
|
/**
|
||
|
* Define an optional timeout argument, with `CSP_DEF_TIMEOUT_MS`
|
||
|
* shown as default. Use `GET_ARG_TIMEOUT0()` to retrieve its value.
|
||
|
*/
|
||
|
#define arg_timeout0() arg_int0("t", "timeout", "<ms>", EXPENDABLE_STRING("timeout in ms (default "STR(CONSOLE_CSP_DEF_TIMEOUT_MS)")"))
|
||
|
|
||
|
/**
|
||
|
* Define a timeout argument with a custom value shown as default.
|
||
|
* Use `GET_ARG_INT0()` with the matching default to retrieve its value.
|
||
|
*/
|
||
|
#define arg_timeout0_def(_def) arg_int0("t", "timeout", "<ms>", EXPENDABLE_STRING("timeout in ms (default "STR(_def)")"))
|
||
|
|
||
|
|
||
|
#define EMPTY_CMD_SETUP(_helptext) \
|
||
|
(void)ctx; \
|
||
|
static struct { \
|
||
|
struct arg_end *end; \
|
||
|
} args; \
|
||
|
\
|
||
|
if (reg) { \
|
||
|
args.end = arg_end(1); \
|
||
|
\
|
||
|
reg->argtable = &args; \
|
||
|
reg->help = EXPENDABLE_STRING(_helptext); \
|
||
|
return 0; \
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Hexdump a buffer
|
||
|
*
|
||
|
* @param outf - output file
|
||
|
* @param data - data to dump
|
||
|
* @param len - data size
|
||
|
*/
|
||
|
void console_hexdump(const void *data, size_t len);
|
||
|
|
||
|
/**
|
||
|
* Decode hexa string to binary
|
||
|
*
|
||
|
* @param hex - hexa string, upper or lower case, must have even length
|
||
|
* @param dest - destination buffer
|
||
|
* @param capacity - buffer size
|
||
|
* @return destination length, or: -1 (bad args), -2 (bad format), -3 (too long)
|
||
|
*/
|
||
|
int console_base16_decode(const char *hex, void *dest, size_t capacity);
|
||
|
|
||
|
#if CONSOLE_USE_MEMSTREAM
|
||
|
|
||
|
/**
|
||
|
* Data struct for the filecap utilities
|
||
|
*/
|
||
|
struct console_filecap {
|
||
|
char *buf;
|
||
|
size_t buf_size;
|
||
|
FILE *file;
|
||
|
};
|
||
|
|
||
|
typedef struct console_filecap console_filecap_t;
|
||
|
|
||
|
/**
|
||
|
* Open a temporary in-memory file that can be used to capture the output
|
||
|
* of functions taking a FILE * argument.
|
||
|
*
|
||
|
* @param cap - pointer to a filecap struct (can be on stack)
|
||
|
* @return success
|
||
|
*/
|
||
|
console_err_t console_filecap_init(console_filecap_t *cap);
|
||
|
|
||
|
/**
|
||
|
* Clean up the capture struct.
|
||
|
*
|
||
|
* If the buffer is to be used elsewhere, place NULL in the struct to avoid freeing it.
|
||
|
*
|
||
|
* If the struct itself was allocated on heap, it is the caller's responsibility to free it manually.
|
||
|
*
|
||
|
* @param cap - pointer to a filecap struct
|
||
|
*/
|
||
|
void console_filecap_end(console_filecap_t *cap);
|
||
|
|
||
|
/**
|
||
|
* Print the captured output to console output stream and clean up the struct (calls `console_filecap_end()`)
|
||
|
*
|
||
|
* @param cap - pointer to a filecap struct
|
||
|
*/
|
||
|
void console_filecap_print_end(console_filecap_t *cap);
|
||
|
|
||
|
#endif // CONSOLE_USE_MEMSTREAM
|
||
|
|
||
|
/**
|
||
|
* Cross-platform malloc that can be used from console commands.
|
||
|
* If CSP is available and the platform is not POSIX, the implementation from there is used (i.e. FreeRTOS alloc)
|
||
|
*/
|
||
|
void * __attribute__((malloc)) console_malloc(size_t size);
|
||
|
|
||
|
/**
|
||
|
* Cross-platform realloc that can be used from console commands.
|
||
|
*
|
||
|
* It is not possible to determine the size of an allocated memory region in a portable way,
|
||
|
* that's why this function takes the old size as an argument. On POSIX, the argument is simply ignored.
|
||
|
*
|
||
|
* If CSP is available and the platform is not POSIX, the implementation from there is used (i.e. FreeRTOS alloc).
|
||
|
* NOTE: CSP does not provide realloc, therefore this function allocates a new buffer, copies data, and frees the old buffer.
|
||
|
*
|
||
|
* Returns the original buffer if the new size is <= old size.
|
||
|
*/
|
||
|
void * console_realloc(void *ptr, size_t oldsize, size_t newsize);
|
||
|
|
||
|
/**
|
||
|
* Cross-platform calloc that can be used from console commands.
|
||
|
* If CSP is available and the platform is not POSIX, the implementation from there is used (i.e. FreeRTOS alloc)
|
||
|
*/
|
||
|
void * __attribute__((malloc,alloc_size(1,2))) console_calloc(size_t nmemb, size_t size);
|
||
|
|
||
|
/**
|
||
|
* `free()` for memory allocated by `console_malloc()` or `console_calloc()`
|
||
|
*/
|
||
|
void console_free(void *ptr);
|
||
|
|
||
|
/**
|
||
|
* `strdup()` using `console_malloc()`. Free with `console_free()`
|
||
|
*/
|
||
|
char * console_strdup(const char *ptr);
|
||
|
|
||
|
/**
|
||
|
* `strndup()` using `console_malloc()`. Free with `console_free()`
|
||
|
*/
|
||
|
char * console_strndup(const char *ptr, size_t maxlen);
|
||
|
|
||
|
#endif //LIBCONSOLE_UTILS_H
|