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

#include <ctype.h>
#include <stdarg.h>
#include <stdlib.h>
#include <shell/shell.h>
#include <shell/shell_dummy.h>
#include "shell_utils.h"
#include "shell_ops.h"
#include "shell_wildcard.h"
#include "shell_vt100.h"
#include <atomic.h>

/* 2 == 1 char for cmd + 1 char for '\0' */
#if (CONFIG_SHELL_CMD_BUFF_SIZE < 2)
	#error too small CONFIG_SHELL_CMD_BUFF_SIZE
#endif

#if (CONFIG_SHELL_PRINTF_BUFF_SIZE < 1)
	#error too small SHELL_PRINTF_BUFF_SIZE
#endif

#define SHELL_MSG_COMMAND_NOT_FOUND	": command not found"
#define SHELL_MSG_TAB_OVERFLOWED	\
	"Tab function: commands counter overflowed.\r\n"

#define SHELL_INIT_OPTION_PRINTER	(NULL)

/* Initial cursor position is: (1, 1). */
#define SHELL_INITIAL_CURS_POS		(1u)

#define EXIT_HISTORY(shell)					\
		((shell)->ctx->internal.flags.history_exit)
#define EXIT_HISTORY_REQUEST(shell)				\
		((shell)->ctx->internal.flags.history_exit = 1)
#define EXIT_HISTORY_CLEAR(shell)				\
		((shell)->ctx->internal.flags.history_exit = 0)

static int shell_execute(const struct shell *shell);

extern const struct shell_cmd_entry __shell_root_cmds_start[0];
extern const struct shell_cmd_entry __shell_root_cmds_end[0];

static inline const struct shell_cmd_entry *shell_root_cmd_get(u32_t id)
{
	return &__shell_root_cmds_start[id];
}

static inline u32_t shell_root_cmd_count(void)
{
	return ((u8_t *)__shell_root_cmds_end -
			(u8_t *)__shell_root_cmds_start)/
				sizeof(struct shell_cmd_entry);
}

static inline void transport_buffer_flush(const struct shell *shell)
{
	shell_fprintf_buffer_flush(shell->fprintf_ctx);
}

static inline void help_flag_set(const struct shell *shell)
{
	shell->ctx->internal.flags.show_help = 1;
}
static inline void help_flag_clear(const struct shell *shell)
{
	shell->ctx->internal.flags.show_help = 0;
}

/* Function returns true if delete escape code shall be interpreted as
 * backspace.
 */
static inline bool flag_delete_mode_set(const struct shell *shell)
{
	return shell->ctx->internal.flags.mode_delete == 1 ? true : false;
}

static inline bool flag_processing_is_set(const struct shell *shell)
{
	return shell->ctx->internal.flags.processing == 1 ? true : false;
}

static inline void receive_state_change(const struct shell *shell,
					enum shell_receive_state state)
{
	shell->ctx->receive_state = state;
}

static void shell_cmd_buffer_clear(const struct shell *shell)
{
	shell->ctx->cmd_buff[0] = '\0'; /* clear command buffer */
	shell->ctx->cmd_buff_pos = 0;
	shell->ctx->cmd_buff_len = 0;
}

/* Function sends data stream to the shell instance. Each time before the
 * shell_write function is called, it must be ensured that IO buffer of fprintf
 * is flushed to avoid synchronization issues.
 * For that purpose, use function transport_buffer_flush(shell)
 */
static void shell_write(const struct shell *shell, const void *data,
			size_t length)
{
	__ASSERT_NO_MSG(shell && data);

	size_t offset = 0;
	size_t tmp_cnt;

	while (length) {
		int err = shell->iface->api->write(shell->iface,
				&((const u8_t *) data)[offset], length,
				&tmp_cnt);
		(void)err;
		__ASSERT_NO_MSG(err == 0);
		__ASSERT_NO_MSG(length >= tmp_cnt);
		offset += tmp_cnt;
		length -= tmp_cnt;
		if (tmp_cnt == 0 &&
		    (shell->ctx->state != SHELL_STATE_PANIC_MODE_ACTIVE)) {
			/* todo  semaphore pend*/
			if (IS_ENABLED(CONFIG_MULTITHREADING)) {
				k_poll(&shell->ctx->events[SHELL_SIGNAL_TXDONE],
				1, K_FOREVER);
			} else {
				/* Blocking wait in case of bare metal. */
				while (!shell->ctx->internal.flags.tx_rdy) {

				}
				shell->ctx->internal.flags.tx_rdy = 0;
			}
		}
	}
}

/* @brief Function shall be used to search commands.
 *
 * It moves the pointer entry to command of static command structure. If the
 * command cannot be found, the function will set entry to NULL.
 *
 *   @param command	Pointer to command which will be processed (no matter
 *			the root command).
 *   @param lvl		Level of the requested command.
 *   @param idx		Index of the requested command.
 *   @param entry	Pointer which points to subcommand[idx] after function
 *			execution.
 *   @param st_entry	Pointer to the structure where dynamic entry data can be
 *			stored.
 */
static void cmd_get(const struct shell_cmd_entry *command, size_t lvl,
		    size_t idx, const struct shell_static_entry **entry,
		    struct shell_static_entry *d_entry)
{
	__ASSERT_NO_MSG(entry != NULL);
	__ASSERT_NO_MSG(d_entry != NULL);
<commit_msg>shell: Fix TXDONE signal not being cleared<commit_after>/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <ctype.h>
#include <stdarg.h>
#include <stdlib.h>
#include <shell/shell.h>
#include <shell/shell_dummy.h>
#include "shell_utils.h"
#include "shell_ops.h"
#include "shell_wildcard.h"
#include "shell_vt100.h"
#include <atomic.h>

/* 2 == 1 char for cmd + 1 char for '\0' */
#if (CONFIG_SHELL_CMD_BUFF_SIZE < 2)
	#error too small CONFIG_SHELL_CMD_BUFF_SIZE
#endif

#if (CONFIG_SHELL_PRINTF_BUFF_SIZE < 1)
	#error too small SHELL_PRINTF_BUFF_SIZE
#endif

#define SHELL_MSG_COMMAND_NOT_FOUND	": command not found"
#define SHELL_MSG_TAB_OVERFLOWED	\
	"Tab function: commands counter overflowed.\r\n"

#define SHELL_INIT_OPTION_PRINTER	(NULL)

/* Initial cursor position is: (1, 1). */
#define SHELL_INITIAL_CURS_POS		(1u)

#define EXIT_HISTORY(shell)					\
		((shell)->ctx->internal.flags.history_exit)
#define EXIT_HISTORY_REQUEST(shell)				\
		((shell)->ctx->internal.flags.history_exit = 1)
#define EXIT_HISTORY_CLEAR(shell)				\
		((shell)->ctx->internal.flags.history_exit = 0)

static int shell_execute(const struct shell *shell);

extern const struct shell_cmd_entry __shell_root_cmds_start[0];
extern const struct shell_cmd_entry __shell_root_cmds_end[0];

static inline const struct shell_cmd_entry *shell_root_cmd_get(u32_t id)
{
	return &__shell_root_cmds_start[id];
}

static inline u32_t shell_root_cmd_count(void)
{
	return ((u8_t *)__shell_root_cmds_end -
			(u8_t *)__shell_root_cmds_start)/
				sizeof(struct shell_cmd_entry);
}

static inline void transport_buffer_flush(const struct shell *shell)
{
	shell_fprintf_buffer_flush(shell->fprintf_ctx);
}

static inline void help_flag_set(const struct shell *shell)
{
	shell->ctx->internal.flags.show_help = 1;
}
static inline void help_flag_clear(const struct shell *shell)
{
	shell->ctx->internal.flags.show_help = 0;
}

/* Function returns true if delete escape code shall be interpreted as
 * backspace.
 */
static inline bool flag_delete_mode_set(const struct shell *shell)
{
	return shell->ctx->internal.flags.mode_delete == 1 ? true : false;
}

static inline bool flag_processing_is_set(const struct shell *shell)
{
	return shell->ctx->internal.flags.processing == 1 ? true : false;
}

static inline void receive_state_change(const struct shell *shell,
					enum shell_receive_state state)
{
	shell->ctx->receive_state = state;
}

static void shell_cmd_buffer_clear(const struct shell *shell)
{
	shell->ctx->cmd_buff[0] = '\0'; /* clear command buffer */
	shell->ctx->cmd_buff_pos = 0;
	shell->ctx->cmd_buff_len = 0;
}

static void shell_pend_on_txdone(const struct shell *shell)
{
	if (IS_ENABLED(CONFIG_MULTITHREADING)) {
		k_poll(&shell->ctx->events[SHELL_SIGNAL_TXDONE], 1, K_FOREVER);
		k_poll_signal_reset(&shell->ctx->signals[SHELL_SIGNAL_TXDONE]);
	} else {
		/* Blocking wait in case of bare metal. */
		while (!shell->ctx->internal.flags.tx_rdy) {
		}
		shell->ctx->internal.flags.tx_rdy = 0;
	}
}

/* Function sends data stream to the shell instance. Each time before the
 * shell_write function is called, it must be ensured that IO buffer of fprintf
 * is flushed to avoid synchronization issues.
 * For that purpose, use function transport_buffer_flush(shell)
 */
static void shell_write(const struct shell *shell, const void *data,
			size_t length)
{
	__ASSERT_NO_MSG(shell && data);

	size_t offset = 0;
	size_t tmp_cnt;

	while (length) {
		int err = shell->iface->api->write(shell->iface,
				&((const u8_t *) data)[offset], length,
				&tmp_cnt);
		(void)err;
		__ASSERT_NO_MSG(err == 0);
		__ASSERT_NO_MSG(length >= tmp_cnt);
		offset += tmp_cnt;
		length -= tmp_cnt;
		if (tmp_cnt == 0 &&
		    (shell->ctx->state != SHELL_STATE_PANIC_MODE_ACTIVE)) {
			shell_pend_on_txdone(shell);
		}
	}
}

/* @brief Function shall be used to search commands.
 *
 * It moves the pointer entry to command of static command structure. If the
 * command cannot be found, the function will set entry to NULL.
 *
 *   @param command	Pointer to command which will be processed (no matter
 *			the root command).
 *   @param lvl		Level of the requested command.
 *   @param idx		Index of the requested command.
 *   @param entry	Pointer which points to subcommand[idx] after function
 *			execution.
 *   @param st_entry	Pointer to the structure where dynamic entry data can be
 *			stored.
 */
static void cmd_get(const struct shell_cmd_entry *command, size_t lvl,
		    size_t idx, const struct shell_static_entry **entry,
		    struct shell_static_entry *d_entry)
{
	__ASSERT_NO_MSG(entry != NULL);
	__ASSERT_NO_MSG(d_entry != NULL);

{'fraction_non_alphanumeric': 0.1109055289508054, 'fraction_numerical': 0.00914235959947758, 'mean_word_length': 4.569090909090909, 'pattern_counts': {'":': 2, '<': 19, '<?xml version=': 0, '>': 89, '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': '1265104', 'n_tokens_mistral': 3393, 'n_tokens_neox': 3188, 'n_words': 847}