initial version made by removing all csp stuff from cspemu

This commit is contained in:
2021-12-10 22:23:34 +01:00
parent 4829c5414b
commit c8ec93722e
120 changed files with 20830 additions and 4 deletions
@@ -0,0 +1,24 @@
//
// Header with useful defines and common includes
// to use when defining console commands.
//
// This file aims to concentrate the most common includes
// and utility macros to make command definitions easier to write.
//
// Created by MightyPork on 2020/03/11.
//
#ifndef LIBCONSOLE_CMDDEF_H
#define LIBCONSOLE_CMDDEF_H
#include <stdint.h>
#include <argtable3.h>
#include "console/console.h"
#if CONSOLE_HAVE_CSP
#include <csp/csp.h>
#endif
#include "console/utils.h"
#endif //LIBCONSOLE_CMDDEF_H
@@ -0,0 +1,22 @@
/**
* Console configuration file, filled by CMake
*
* Created on 2020/03/16.
*/
#ifndef LIBCONSOLE_CONFIG_H
#define LIBCONSOLE_CONFIG_H
#cmakedefine CONSOLE_LINE_BUF_LEN @CONSOLE_LINE_BUF_LEN@
#cmakedefine CONSOLE_MAX_NUM_ARGS @CONSOLE_MAX_NUM_ARGS@
#cmakedefine CONSOLE_PROMPT_MAX_LEN @CONSOLE_PROMPT_MAX_LEN@
#cmakedefine CONSOLE_HISTORY_LEN @CONSOLE_HISTORY_LEN@
#cmakedefine01 CONSOLE_FILE_SUPPORT
#cmakedefine01 CONSOLE_USE_FILE_IO_STREAMS
#cmakedefine01 CONSOLE_USE_TERMIOS
#cmakedefine01 CONSOLE_USE_MEMSTREAM
#cmakedefine01 CONSOLE_USE_FREERTOS
#cmakedefine01 CONSOLE_USE_PTHREADS
#cmakedefine01 CONSOLE_TESTING_ALLOC_FUNCS
#endif //LIBCONSOLE_CONFIG_H
@@ -0,0 +1,362 @@
/**
* Console - VCOM command engine
*
* Created on 2020/02/28 by Ondrej Hruska
*
* Parts are based on the console component from esp-idf
* licensed under the Apache 2 license.
*/
#ifndef LIBCONSOLE_H
#define LIBCONSOLE_H
#include <stdio.h>
#include <console/config.h>
#include <stdint.h>
#include <stdbool.h>
typedef enum {
/* Colors */
COLOR_RESET = 0xF0,
COLOR_BLACK = 0x01,
COLOR_RED = 0x02,
COLOR_GREEN = 0x03,
COLOR_YELLOW = 0x04,
COLOR_BLUE = 0x05,
COLOR_MAGENTA = 0x06,
COLOR_CYAN = 0x07,
COLOR_WHITE = 0x08,
/* Modifiers */
COLOR_NORMAL = 0x0F,
COLOR_BOLD = 0x10,
COLOR_UNDERLINE = 0x20,
COLOR_BLINK = 0x30,
COLOR_HIDE = 0x40,
} console_color_t;
#if CONSOLE_USE_FREERTOS
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
typedef SemaphoreHandle_t console_mutex_t;
#endif
#if CONSOLE_USE_PTHREADS
#include <pthread.h>
typedef pthread_mutex_t console_mutex_t;
#endif
#if CONSOLE_USE_TERMIOS
#include <termios.h>
#endif
/**
* Console config struct
*/
struct console_config {
/**
* Timeout waiting for execution lock when handling a command.
* This should be longer than the slowest command in the system.
*/
uint32_t execution_lock_timeout_ms;
};
/**
* Macro to init the console config struct
*/
#define CONSOLE_CONFIG_DEFAULTS() { \
.execution_lock_timeout_ms = 10000, \
}
typedef struct console_config console_config_t;
struct console_ctx; // early declaration
/**
* Console context
*/
typedef struct console_ctx console_ctx_t;
/**
* Console errors - return codes
*/
enum console_err {
CONSOLE_OK = 0,
/** unspecified error */
CONSOLE_ERROR = 1,
/** Allocation failed */
CONSOLE_ERR_NO_MEM,
/** Function call not allowed (e.g. console not inited) */
CONSOLE_ERR_BAD_CALL,
/** Argument validation failed */
CONSOLE_ERR_INVALID_ARG,
/** Command not recognized */
CONSOLE_ERR_UNKNOWN_CMD,
/** Timeout */
CONSOLE_ERR_TIMEOUT,
/** IO error (file open fail, etc.) */
CONSOLE_ERR_IO,
/** Operation denied (not allowed / insufficient rights) */
CONSOLE_ERR_NOT_POSSIBLE,
/** End marker */
_CONSOLE_ERR_MAX,
};
/**
* Print string describing console error.
* In case of unknown error, the number is shown.
*
* The argument should be `enum console_err`, but any number is valid.
*/
void console_err_print_ctx(struct console_ctx *ctx, int e);
// TODO error-to-string function
typedef enum console_err console_err_t;
// early decl's
struct cmd_signature;
typedef struct cmd_signature cmd_signature_t;
/**
* Command signature, passed as the last argument to the command handler
* to perform registration.
*
* \note Fill only fields that differ from default (zeros/NULLs)
*/
struct cmd_signature {
const char* command; //!< Command name, used in invocations (filled internally, do not set)
const char* help; //!< Command help text, shown when called with -h
const char* hint; //!< Hint text, generated from argtable if hint==NULL & argtable!=NULL
bool no_history; //!< Command skips history
bool custom_args; //!< Disable argtable parsing in the handler function, will be parsed manually from argv/argc
/**
* Argtable, struct or array that must end with arg_end().
* Used by the register function and for disambiguation.
*/
void* argtable;
};
/**
* Active console context pointer, valid only when handling a console command (otherwise NULL).
*
* Used by the console printf & other IO methods.
*/
extern struct console_ctx * console_active_ctx;
/**
* Function handling a callback from the console loop.
*/
typedef void(*console_callback_t)(console_ctx_t *ctx);
/**
* Console context struct
*/
struct console_ctx {
#if CONSOLE_USE_FILE_IO_STREAMS
// Streams
FILE* in; //!< stdin fd, can be -1 if not available (running commands in non-interactive mode)
FILE* out; //!< stdout fd
#if CONSOLE_USE_TERMIOS
// original termios is stored here before entering raw mode
struct termios orig_termios;
#endif
#else
void *ioctx;
#endif //CONSOLE_USE_FILE_IO_STREAMS
#if CONSOLE_FILE_SUPPORT
char *history_file;
#endif //CONSOLE_FILE_SUPPORT
bool __internal_heap_allocated;
bool exit_allowed;
char prompt[CONSOLE_PROMPT_MAX_LEN]; //!< Prompt, can be modified by a command or `before_readline_fn`
char line_buffer[CONSOLE_LINE_BUF_LEN];
/**
* Callback fired in the command evaluation loop, each time before the prompt is shown and new line read.
* This command can print to the output streams, change prompt, shutdown console, etc.
*/
console_callback_t loop_handler;
/**
* Callback fired before the console task shuts down
*/
console_callback_t shutdown_handler;
/**
* Shutdown requested. Console will exit as soon as possible.
*/
bool exit_requested;
/**
* Interactive mode. Enables additional outputs for user convenience.
*/
bool interactive;
/**
* Enable ANSI colors
*/
bool use_colors;
/* These fields are valid only during command execution */
const char **argv; //!< The current argv
size_t argc; //!< The current argc
const cmd_signature_t *cmd; //!< Pointer to the currently executed command signature
/** Used for argument validation */
uint32_t __internal_magic;
};
#define CONSOLE_CTX_MAGIC 0x6f587468
/**
* Command handler type.
*
* @param ctx - console context, including input/output files
* @param reg - signature struct; if not NULL, init the static argtable, fill this struct, and return OK (0).
* @return status code, 0 = OK (use cons_err_t constants if possible)
*/
typedef int (*console_command_t)(console_ctx_t *ctx, struct cmd_signature *reg);
/**
* Intialize the console
*
* @param config - config pointer, NULL to use defaults
* @return status code
*/
console_err_t console_init(const console_config_t *config);
/**
* @brief Register console command
*
* If the command function is already registered, this creates an alias.
* A multi-word command automatically create a command group. The group can
* be described using a description string by calling `console_group_add()`
* - at convenience before or after the commands are registered.
*
* @param name - command name (may contain spaces for "multi-part commands")
* @param handler pointer to the command handler.
* @return status code
*/
console_err_t console_cmd_register(console_command_t handler, const char *name);
/**
* @brief Register a command group.
*
* Command groups are created automatically when used.
* This method can create a group with description, or attach a custom description
* to an existing group.
*
* @param name - group name (first word of multi-part commands)
* @param descr - description to attach, can be NULL
* @return staus code
*/
console_err_t console_group_add(const char *name, const char *descr);
/**
* Add alias to an existing command by name.
*
* @param original - original command name
* @param alias - command's alias
* @return status code
*/
console_err_t console_cmd_add_alias(const char *original, const char *alias);
/**
* Add alias by handler function
*
* @param handler - command handler
* @param alias - new name
* @return status code
*/
console_err_t console_cmd_add_alias_fn(console_command_t handler, const char *alias);
/**
* Internal error print function. Has WEAK linkage, can be overridden.
*
* This function is used to report detected bugs and should not be called
* in well-written "production code".
*
* @param msg - error message
*/
void console_internal_error_print(const char *msg);
/**
* This function is guarded by a mutex and will wait for the execution lock as
* configured in console_config.
*
* @brief Run command line
* @param[in] outf
* @param[in] inf
* @param cmdline command line (command name followed by a number of arguments)
* @param[out] pRetval return code from the command (set if command was run)
* @param[out] pCommandSig - is set to a pointer to the matched command signature, or NULL on error
* @return status code
*/
console_err_t console_handle_cmd(
console_ctx_t *ctx,
const char *cmdline,
int *pRetval,
const struct cmd_signature **pCommandSig
);
/**
* Count all registered commands
*
* @return
*/
size_t console_count_commands(void);
/**
* Create a console IO context and init it to defaults.
*
* takes stdin and stdout file descriptors, or IO context (based on config flags)
*
* In the FD variant, pass NULL as STDIN if not available.
*
* @param ctx - context, if using static alloc, NULL to allocate internally.
* @return the context, NULL if alloc or init fails
*/
console_ctx_t *console_ctx_init(
console_ctx_t *ctx,
#if CONSOLE_USE_FILE_IO_STREAMS
FILE* inf, FILE* outf
#else
void * ioctx
#endif
);
/**
* Destroy a console IO context.
*
* Make sure to release any user fields (ioctx, for example) beforehand.
*
* @attention ONLY CALL THIS IF THE CONTEXT WAS DYNAMICALLY ALLOCATED!
*
* @param[in,out] ctx - pointer to context, will be set to NULL.
*/
void console_ctx_destroy(console_ctx_t *ctx);
/**
* Console task
*
* @param[in] param - must be a valid console context (see `console_ctx_init()`)
*/
void console_task(void *param);
/**
* Variant of 'console_task' for pthreads (returns NULL)
*/
void* console_task_posix(void *param);
#include "console_io.h"
#endif //LIBCONSOLE_H
@@ -0,0 +1,196 @@
/**
* Console IO functions.
*
* This header is included internally by console.h
*
* Created on 2020/04/09.
*/
#ifndef LIBCONSOLE_IO_H
#define LIBCONSOLE_IO_H
#ifndef LIBCONSOLE_H
#error Include console.h!
#endif
#include <stdarg.h>
// ------ If the FILE based IO streams option is OFF, these are extern -------
/**
* Write to console context.
*
* In command context, the more convenient "console_write", "console_print", "console_println"
* and "console_printf" functions can be used instead.
*
* This function is a Linenoise write callback.
*
* Return number of characters written, -1 on error.
*/
extern int console_write_ctx(console_ctx_t *ctx, const char *text, size_t len);
/**
* Read from console context's input stream.
*
* In command context, the more convenient "console_read" function and the
* "console_can_read" and "console_have_stdin" helper functions can be used instead.
*
* This is also a Linenoise read callback.
*
* Return number of characters read, -1 on error
*/
extern int console_read_ctx(console_ctx_t *ctx, char *dest, size_t count);
/**
* Check if console input stream has bytes ready.
*
* @return number of queued bytes, 0 if none, -1 on error.
*/
extern int console_can_read_ctx(console_ctx_t *ctx);
/**
* Test if console context is not NULL and has stdin stream available
*
* @return have stdin
*/
extern bool console_have_stdin_ctx(console_ctx_t *ctx);
// ----- end extern interface -----
/**
* Print zero-terminated string to to console output
*
* @param text - characters to write
* @return number of characters written, or -1 on error
*/
int console_print_ctx(console_ctx_t *ctx, const char *text);
/**
* Print zero-terminated string to console output, followed by a newline
*
* @param text - characters to write
* @return number of characters written, or -1 on error
*/
ssize_t console_println_ctx(console_ctx_t *ctx, const char *text);
/**
* Console printf
*
* @param ctx - console context
* @param color - color to use, COLOR_RESET = default
* @param format
* @param ...
* @return bytes written, or -1 on error
*/
ssize_t console_printf_ctx(console_ctx_t *ctx, console_color_t color, const char *format, ...) __attribute__((format(printf,3,4)));
/**
* Console vprintf
*
* @param ctx - console context
* @param color - color to use, COLOR_RESET = default
* @param format - format string
* @param args - varargs passed as a va_list
* @return bytes written, or -1 on error
*/
ssize_t console_vprintf_ctx(console_ctx_t *ctx, console_color_t color, const char *format, va_list args);
/**
* Write to console output
*
* @attention Can only be used within a console command context
*
* @param text - characters to write
* @param len - text length
* @return number of characters written, or -1 on error
*/
ssize_t console_write(const char *text, size_t len);
// -------------------- Convenience functions -------------------------
/**
* Test if we are in the console command context.
*
* @return in command context
*/
static inline bool console_context_available(void) {
return console_active_ctx != NULL;
}
/**
* Test if we are in the console command context AND the console context has an input stream
* (input stream may be used in interactive commands)
*
* @return have stdin
*/
bool console_have_stdin(void);
/**
* Console printf. Defined as a macro to pass variadic arguments
*
* @attention Can only be used within a console command context
*
* @param format
* @param ...
* @return bytes written, or -1 on error
*/
#define console_printf(format, ...) console_printf_ctx(console_active_ctx, COLOR_RESET, format, ##__VA_ARGS__)
/**
* Console printf with colors. Defined as a macro to pass variadic arguments
*
* @attention Can only be used within a console command context
*
* @param color - from console_colors_t enum
* @param format
* @param ...
* @return bytes written, or -1 on error
*/
#define console_color_printf(color, format, ...) console_printf_ctx(console_active_ctx, color, format, ##__VA_ARGS__)
/**
* Read from console input
*
* @attention Can only be used within a console command context
*
* @param dest - destination buffer
* @param count - how many characters to read
* @return number of characters read, or -1 on error
*/
ssize_t console_read(char *dest, size_t count);
/**
* Check if console input stream has bytes ready.
*
* @attention Can only be used within a console command context
*
* @return number of queued bytes, 0 if none, -1 on error.
*/
int console_can_read(void);
/**
* Print zero-terminated string to to console output
*
* @attention Can only be used within a console command context
*
* @param text - characters to write
* @return number of characters written, or -1 on error
*/
static inline int console_print(const char *text) {
return console_print_ctx(console_active_ctx, text);
}
/**
* Print zero-terminated string to console output, followed by a newline
*
* @attention Can only be used within a console command context
*
* @param text - characters to write
* @return number of characters written, or -1 on error
*/
ssize_t console_println(const char *text);
#endif //LIBCONSOLE_IO_H
@@ -0,0 +1,94 @@
/**
* Prefix Match
*
* Match input value to a list of options, allowing non-ambiguous abbreviation and partial matching.
* This library was designed for command recognition in interactive consoles and command interfaces.
*
* Created on 2020/06/09 by Ondřej Hruška
*/
#ifndef _PREFIX_MATCH_H
#define _PREFIX_MATCH_H
#include <stdbool.h>
#include <stddef.h>
/** Use case-sensitive matching */
#define PREFIXMATCH_CASE_SENSITIVE 1
/** Forbid abbreviations */
#define PREFIXMATCH_NOABBREV 2
/** Allow matching fewer words, if unambiguous */
#define PREFIXMATCH_MULTI_PARTIAL 4
enum pm_test_result {
PM_TEST_NO_MATCH = 0,
PM_TEST_MATCH = 1,
PM_TEST_MATCH_MULTI_PARTIAL = 2,
};
/**
* Recognize (optionally abbreviated) input
*
* @param[in] value - tested value
* @param[in] options - options to match against
* @param[in] flags - matching options (bitmask) - accepts PREFIXMATCH_CASE_SENSITIVE and PREFIXMATCH_NOABBREV
* @return index of the matched option, -1 on mismatch or ambiguous match
*/
int prefix_match(const char *value, const char **options, int flags);
/**
* Recognize input consisting of one or more (optionally abbreviated) words
*
* @param[in] value - tested value
* @param[in] options - options to match against, multi-word options separated by the listed delimiters
* @param[in] delims - string with a list of possible delimiters (like for strtok)
* @param[in] flags - matching options (bitmask) - accepts all options
* @return index of the matched option, -1 on mismatch or ambiguous match
*/
int prefix_multipart_match(const char *restrict value, const char **options, const char* restrict delims, int flags);
// useful internal functions exported for possible re-use
/**
* Test if two word sentences match, with individual words optionally allowed to be abbreviated.
*
* @internal
* @param[in] tested - tested (optionally abbreviated) sentence
* @param[in] full - full sentence
* @param[in] delims - list of possible delimiters, same may be used for both sentences
* @param[in] flags - matching options (bitmask) - accepts all options
* @return 1-match; 0-no match; 2-partial (some words) match, if the PREFIXMATCH_MULTI_PARTIAL flag is set
*/
enum pm_test_result prefix_multipart_test(const char *restrict tested, const char* restrict full, const char *restrict delims, int flags);
/**
* Count words in a "sentence", delimited by any of the given set of delimiters.
*
* @internal
* @param[in] sentence - one or multi-word string
* @param[in] delims - delimiters accepted
* @return number of words
*/
size_t pm_count_words(const char * restrict sentence, const char * restrict delims);
/**
* Measure word length
*
* @internal
* @param[in] word - start of a word that ends with either one of the delimiters, or a null byte.
* @param[in] delims - delimiters accepted
* @return word length
*/
size_t pm_word_len(const char * restrict word, const char * restrict delims);
/**
* Skip N words in a sentence.
*
* @param[in] sentence - one or multi-word string
* @param[in] delims - delimiters accepted
* @param[in] skip - how many words to skip
* @return pointer to the first byte after the last skipped word
*/
const char *pm_skip_words(const char * restrict sentence, const char * restrict delims, size_t skip);
#endif //_PREFIX_MATCH_H
@@ -0,0 +1,213 @@
/**
* 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