<commit_before>/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#ifndef SHELL_H__
#define SHELL_H__

#include <zephyr.h>
#include <shell/shell_types.h>
#include <shell/shell_history.h>
#include <shell/shell_fprintf.h>
#include <shell/shell_log_backend.h>
#include <logging/log_instance.h>
#include <logging/log.h>
#include <sys/util.h>

#ifdef __cplusplus
extern "C" {
#endif

#define SHELL_RX_BUFF_SIZE 16

#ifndef CONFIG_SHELL_CMD_BUFF_SIZE
#define CONFIG_SHELL_CMD_BUFF_SIZE 0
#endif

#ifndef CONFIG_SHELL_PRINTF_BUFF_SIZE
#define CONFIG_SHELL_PRINTF_BUFF_SIZE 0
#endif

#ifndef CONFIG_SHELL_HISTORY_BUFFER
#define CONFIG_SHELL_HISTORY_BUFFER 0
#endif

#define SHELL_CMD_ROOT_LVL		(0u)

/**
 * @brief Shell API
 * @defgroup shell_api Shell API
 * @ingroup shell
 * @{
 */

struct shell_static_entry;

/**
 * @brief Shell dynamic command descriptor.
 *
 * @details Function shall fill the received shell_static_entry structure
 * with requested (idx) dynamic subcommand data. If there is more than
 * one dynamic subcommand available, the function shall ensure that the
 * returned commands: entry->syntax are sorted in alphabetical order.
 * If idx exceeds the available dynamic subcommands, the function must
 * write to entry->syntax NULL value. This will indicate to the shell
 * module that there are no more dynamic commands to read.
 */
typedef void (*shell_dynamic_get)(size_t idx,
				  struct shell_static_entry *entry);

/**
 * @brief Shell command descriptor.
 */
struct shell_cmd_entry {
	bool is_dynamic;
	union union_cmd_entry {
		/*!< Pointer to function returning dynamic commands.*/
		shell_dynamic_get dynamic_get;

		/*!< Pointer to array of static commands. */
		const struct shell_static_entry *entry;
	} u;
};

struct shell;

struct shell_static_args {
	u8_t mandatory; /*!< Number of mandatory arguments. */
	u8_t optional;  /*!< Number of optional arguments. */
};

/**
 * @brief Shell command handler prototype.
 *
 * @param shell Shell instance.
 * @param argc  Arguments count.
 * @param argv  Arguments.
 *
 * @retval 0 Successful command execution.
 * @retval 1 Help printed and command not executed.
 * @retval -EINVAL Argument validation failed.
 * @retval -ENOEXEC Command not executed.
 */
typedef int (*shell_cmd_handler)(const struct shell *shell,
				 size_t argc, char **argv);

/*
 * @brief Shell static command descriptor.
 */
struct shell_static_entry {
	const char *syntax;			/*!< Command syntax strings. */
	const char *help;			/*!< Command help string. */
	const struct shell_cmd_entry *subcmd;	/*!< Pointer to subcommand. */
	shell_cmd_handler handler;		/*!< Command handler. */
	struct shell_static_args args;		/*!< Command arguments. */
};

/**
 * @brief Macro for defining and adding a root command (level 0) with required
 * number of arguments.
 *
 * @note Each root command shall have unique syntax. If a command will be called
 * with wrong number of arguments shell will print an error message and command
 * handler will not be called.
 *
 * @param[in] syntax	Command syntax (for example: history).
 * @param[in] subcmd	Pointer to a subcommands array.
 * @param[in] help	Pointer to a command help string.
 * @param[in] handler	Pointer to a function handler.
 * @param[in] mandatory	Number of mandatory arguments.
 * @param[in] optional	Number of optional arguments.
 */
#define SHELL_CMD_ARG_REGISTER(syntax, subcmd, help, handler,		   \
			       mandatory, optional)			   \
	static const struct shell_static_entry UTIL_CAT(_shell_, syntax) = \
	SHELL_CMD_ARG(syntax, subcmd, help, handler, mandatory, optional); \
	static const struct shell_cmd_entry UTIL_CAT(shell_cmd_, syntax)   \
	__attribute__ ((section("."					   \
			STRINGIFY(UTIL_CAT(shell_root_cmd_, syntax)))))	   \
	__attribute__((used)) = {					   \
		.is_dynamic = false,					   \
		.u = {.entry = &UTIL_CAT(_shell_, syntax)}		   \
	}

/**
 * @brief Macro for defining and adding a conditional root command (level 0)
 * with required number of arguments.
 *
 * @see SHELL_CMD_ARG_REGISTER for details.
 *
 * Macro can be used to create a command which can be conditionally present.
 * It is and alternative to \#ifdefs around command registration and command
 * handler. If command is disabled handler and subcommands are removed from
 * the application.
 *
 * @param[in] flag	Compile time flag. Command is present only if flag
 *			exists and equals 1.
 * @param[in] syntax	Command syntax (for example: history).
 * @param[in] subcmd	Pointer to a subcommands array.
 * @param[in] help	Pointer to a command help string.
 * @param[in] handler	Pointer to a function handler.
 * @param[in] mandatory	Number of mandatory arguments.
 * @param[in] optional	Number of optional arguments.
 */
#define SHELL_COND_CMD_ARG_REGISTER(flag, syntax, subcmd, help, handler, \
					mandatory, optional) \
	COND_CODE_1(\
		flag, \
		(\
		SHELL_CMD_ARG_REGISTER(syntax, subcmd, help, handler, \
					mandatory, optional) \
		), \
		(\
		static shell_cmd_handler dummy_##syntax##handler \
			__attribute__((unused)) = handler;\
		static const struct shell_cmd_entry *dummy_subcmd_##syntax \
			__attribute__((unused)) = subcmd\
		)\
	)
/**
 * @brief Macro for defining and adding a root command (level 0) with
 * arguments.
 *
 * @note All root commands must have different name.
 *
 * @param[in] syntax	Command syntax (for example: history).
 * @param[in] subcmd	Pointer to a subcommands array.
 * @param[in] help	Pointer to a command help string.
 * @param[in] handler	Pointer to a function handler.<commit_msg>shell: Fix SHELL_COND_CMD_ARG_REGISTER macro with NULL handler<commit_after>/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#ifndef SHELL_H__
#define SHELL_H__

#include <zephyr.h>
#include <shell/shell_types.h>
#include <shell/shell_history.h>
#include <shell/shell_fprintf.h>
#include <shell/shell_log_backend.h>
#include <logging/log_instance.h>
#include <logging/log.h>
#include <sys/util.h>

#ifdef __cplusplus
extern "C" {
#endif

#define SHELL_RX_BUFF_SIZE 16

#ifndef CONFIG_SHELL_CMD_BUFF_SIZE
#define CONFIG_SHELL_CMD_BUFF_SIZE 0
#endif

#ifndef CONFIG_SHELL_PRINTF_BUFF_SIZE
#define CONFIG_SHELL_PRINTF_BUFF_SIZE 0
#endif

#ifndef CONFIG_SHELL_HISTORY_BUFFER
#define CONFIG_SHELL_HISTORY_BUFFER 0
#endif

#define SHELL_CMD_ROOT_LVL		(0u)

/**
 * @brief Shell API
 * @defgroup shell_api Shell API
 * @ingroup shell
 * @{
 */

struct shell_static_entry;

/**
 * @brief Shell dynamic command descriptor.
 *
 * @details Function shall fill the received shell_static_entry structure
 * with requested (idx) dynamic subcommand data. If there is more than
 * one dynamic subcommand available, the function shall ensure that the
 * returned commands: entry->syntax are sorted in alphabetical order.
 * If idx exceeds the available dynamic subcommands, the function must
 * write to entry->syntax NULL value. This will indicate to the shell
 * module that there are no more dynamic commands to read.
 */
typedef void (*shell_dynamic_get)(size_t idx,
				  struct shell_static_entry *entry);

/**
 * @brief Shell command descriptor.
 */
struct shell_cmd_entry {
	bool is_dynamic;
	union union_cmd_entry {
		/*!< Pointer to function returning dynamic commands.*/
		shell_dynamic_get dynamic_get;

		/*!< Pointer to array of static commands. */
		const struct shell_static_entry *entry;
	} u;
};

struct shell;

struct shell_static_args {
	u8_t mandatory; /*!< Number of mandatory arguments. */
	u8_t optional;  /*!< Number of optional arguments. */
};

/**
 * @brief Shell command handler prototype.
 *
 * @param shell Shell instance.
 * @param argc  Arguments count.
 * @param argv  Arguments.
 *
 * @retval 0 Successful command execution.
 * @retval 1 Help printed and command not executed.
 * @retval -EINVAL Argument validation failed.
 * @retval -ENOEXEC Command not executed.
 */
typedef int (*shell_cmd_handler)(const struct shell *shell,
				 size_t argc, char **argv);

/*
 * @brief Shell static command descriptor.
 */
struct shell_static_entry {
	const char *syntax;			/*!< Command syntax strings. */
	const char *help;			/*!< Command help string. */
	const struct shell_cmd_entry *subcmd;	/*!< Pointer to subcommand. */
	shell_cmd_handler handler;		/*!< Command handler. */
	struct shell_static_args args;		/*!< Command arguments. */
};

/**
 * @brief Macro for defining and adding a root command (level 0) with required
 * number of arguments.
 *
 * @note Each root command shall have unique syntax. If a command will be called
 * with wrong number of arguments shell will print an error message and command
 * handler will not be called.
 *
 * @param[in] syntax	Command syntax (for example: history).
 * @param[in] subcmd	Pointer to a subcommands array.
 * @param[in] help	Pointer to a command help string.
 * @param[in] handler	Pointer to a function handler.
 * @param[in] mandatory	Number of mandatory arguments.
 * @param[in] optional	Number of optional arguments.
 */
#define SHELL_CMD_ARG_REGISTER(syntax, subcmd, help, handler,		   \
			       mandatory, optional)			   \
	static const struct shell_static_entry UTIL_CAT(_shell_, syntax) = \
	SHELL_CMD_ARG(syntax, subcmd, help, handler, mandatory, optional); \
	static const struct shell_cmd_entry UTIL_CAT(shell_cmd_, syntax)   \
	__attribute__ ((section("."					   \
			STRINGIFY(UTIL_CAT(shell_root_cmd_, syntax)))))	   \
	__attribute__((used)) = {					   \
		.is_dynamic = false,					   \
		.u = {.entry = &UTIL_CAT(_shell_, syntax)}		   \
	}

/**
 * @brief Macro for defining and adding a conditional root command (level 0)
 * with required number of arguments.
 *
 * @see SHELL_CMD_ARG_REGISTER for details.
 *
 * Macro can be used to create a command which can be conditionally present.
 * It is and alternative to \#ifdefs around command registration and command
 * handler. If command is disabled handler and subcommands are removed from
 * the application.
 *
 * @param[in] flag	Compile time flag. Command is present only if flag
 *			exists and equals 1.
 * @param[in] syntax	Command syntax (for example: history).
 * @param[in] subcmd	Pointer to a subcommands array.
 * @param[in] help	Pointer to a command help string.
 * @param[in] handler	Pointer to a function handler.
 * @param[in] mandatory	Number of mandatory arguments.
 * @param[in] optional	Number of optional arguments.
 */
#define SHELL_COND_CMD_ARG_REGISTER(flag, syntax, subcmd, help, handler, \
					mandatory, optional) \
	COND_CODE_1(\
		flag, \
		(\
		SHELL_CMD_ARG_REGISTER(syntax, subcmd, help, handler, \
					mandatory, optional) \
		), \
		(\
		static shell_cmd_handler dummy_##syntax##_handler \
			__attribute__((unused)) = handler;\
		static const struct shell_cmd_entry *dummy_subcmd_##syntax \
			__attribute__((unused)) = subcmd\
		)\
	)
/**
 * @brief Macro for defining and adding a root command (level 0) with
 * arguments.
 *
 * @note All root commands must have different name.
 *
 * @param[in] syntax	Command syntax (for example: history).
 * @param[in] subcmd	Pointer to a subcommands array.
 * @param[in] help	Pointer to a command help string.
 * @param[in] handler	Pointer to a function handler.
{'fraction_non_alphanumeric': 0.09957058507783145, 'fraction_numerical': 0.003757380568974772, 'mean_word_length': 4.028789923526766, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5682041', 'n_tokens_mistral': 3625, 'n_tokens_neox': 3418, 'n_words': 1195}