コード例 #1
0
ファイル: shell.c プロジェクト: wuhaixiang/VoiceCode
void finsh_thread_entry(void* parameter)
{
    char ch;

	/* normal is echo mode */
	shell->echo_mode = 1;

    finsh_init(&shell->parser);
	rt_kprintf(FINSH_PROMPT);

	while (1)
	{
		/* wait receive */
		if (rt_sem_take(&shell->rx_sem, RT_WAITING_FOREVER) != RT_EOK) continue;

		/* read one character from device */
		while (rt_device_read(shell->device, 0, &ch, 1) == 1)
		{
			/* handle history key */
			#ifdef FINSH_USING_HISTORY
			if (finsh_handle_history(shell, ch) == RT_TRUE) continue;
			#endif

			/* handle CR key */
			if (ch == '\r')
			{
				char next;

				if (rt_device_read(shell->device, 0, &next, 1) == 1)
					ch = next;
				else ch = '\r';
			}
			/* handle tab key */
			else if (ch == '\t')
			{
				/* auto complete */
				finsh_auto_complete(&shell->line[0]);
				/* re-calculate position */
				shell->line_position = strlen(shell->line);
				continue;
			}
			/* handle backspace key */
			else if (ch == 0x7f || ch == 0x08)
			{
				if (shell->line_position != 0)
				{
					rt_kprintf("%c %c", ch, ch);
				}
				if (shell->line_position <= 0) shell->line_position = 0;
				else shell->line_position --;
				shell->line[shell->line_position] = 0;
				continue;
			}

			/* handle end of line, break */
			if (ch == '\r' || ch == '\n')
			{
				/* change to ';' and break */
				shell->line[shell->line_position] = ';';

				#ifdef FINSH_USING_HISTORY
				finsh_push_history(shell);
				#endif

				if (shell->line_position != 0) finsh_run_line(&shell->parser, shell->line);
				else rt_kprintf("\n");

				rt_kprintf(FINSH_PROMPT);
				memset(shell->line, 0, sizeof(shell->line));
				shell->line_position = 0;

				break;
			}

			/* it's a large line, discard it */
			if (shell->line_position >= FINSH_CMD_SIZE) shell->line_position = 0;

			/* normal character */
			shell->line[shell->line_position] = ch; ch = 0;
			if (shell->echo_mode) rt_kprintf("%c", shell->line[shell->line_position]);
			shell->line_position ++;
			shell->use_history = 0; /* it's a new command */
		} /* end of device read */
	}
}
コード例 #2
0
ファイル: shell.c プロジェクト: alandigi/rt-thread
void finsh_thread_entry(void* parameter)
{
    char ch;

	/* normal is echo mode */
	shell->echo_mode = 1;

    finsh_init(&shell->parser);
	rt_kprintf(FINSH_PROMPT);

	/* set console device as shell device */
	shell->device = rt_console_get_device();
	if (shell->device != RT_NULL)
	{
		rt_device_open(shell->device, RT_DEVICE_OFLAG_RDWR);
		rt_device_set_rx_indicate(shell->device, finsh_rx_ind);
	}

	while (1)
	{
		/* wait receive */
		if (rt_sem_take(&shell->rx_sem, RT_WAITING_FOREVER) != RT_EOK) continue;

		/* read one character from device */
		while (rt_device_read(shell->device, 0, &ch, 1) == 1)
		{
			/*
			 * handle control key
			 * up key  : 0x1b 0x5b 0x41
			 * down key: 0x1b 0x5b 0x42
			 * right key:0x1b 0x5b 0x43
			 * left key: 0x1b 0x5b 0x44
			 */
			if (ch == 0x1b)
			{
				shell->stat = WAIT_SPEC_KEY;
				continue;
			}
			else if (shell->stat == WAIT_SPEC_KEY)
			{
				if (ch == 0x5b)
				{
					shell->stat = WAIT_FUNC_KEY;
					continue;
				}

				shell->stat = WAIT_NORMAL;
			}
			else if (shell->stat == WAIT_FUNC_KEY)
			{
				shell->stat = WAIT_NORMAL;

				if (ch == 0x41) /* up key */
				{
#ifdef FINSH_USING_HISTORY
					/* prev history */
					if (shell->current_history > 0)
						shell->current_history --;
					else
					{
						shell->current_history = 0;
						continue;
					}

					/* copy the history command */
					memcpy(shell->line, &shell->cmd_history[shell->current_history][0],
						   FINSH_CMD_SIZE);
					shell->line_curpos = shell->line_position = strlen(shell->line);
					finsh_handle_history(shell);
#endif
					continue;
				}
				else if (ch == 0x42) /* down key */
				{
#ifdef FINSH_USING_HISTORY
					/* next history */
					if (shell->current_history < shell->history_count - 1)
						shell->current_history ++;
					else
					{
						/* set to the end of history */
						if (shell->history_count != 0)
							shell->current_history = shell->history_count - 1;
						else
							continue;
					}

					memcpy(shell->line, &shell->cmd_history[shell->current_history][0],
						   FINSH_CMD_SIZE);
					shell->line_curpos = shell->line_position = strlen(shell->line);
					finsh_handle_history(shell);
#endif
					continue;
				}
				else if (ch == 0x44) /* left key */
				{
					if (shell->line_curpos)
					{
						rt_kprintf("\b");
						shell->line_curpos --;
					}

					continue;
				}
				else if (ch == 0x43) /* right key */
				{
					if (shell->line_curpos < shell->line_position)
					{
						rt_kprintf("%c", shell->line[shell->line_curpos]);
						shell->line_curpos ++;
					}

					continue;
				}

			}

			/* handle CR key */
			if (ch == '\r')
			{
				char next;

				if (rt_device_read(shell->device, 0, &next, 1) == 1)
					ch = next;
				else ch = '\r';
			}
			/* handle tab key */
			else if (ch == '\t')
			{
				int i;
				/* move the cursor to the beginning of line */
				for (i = 0; i < shell->line_curpos; i++)
					rt_kprintf("\b");

				/* auto complete */
				finsh_auto_complete(&shell->line[0]);
				/* re-calculate position */
				shell->line_curpos = shell->line_position = strlen(shell->line);

				continue;
			}
			/* handle backspace key */
			else if (ch == 0x7f || ch == 0x08)
			{
				/* note that shell->line_curpos >= 0 */
				if (shell->line_curpos == 0)
					continue;

				shell->line_position--;
				shell->line_curpos--;

				if (shell->line_position > shell->line_curpos)
				{
					int i;

					rt_memmove(&shell->line[shell->line_curpos],
							   &shell->line[shell->line_curpos + 1],
							   shell->line_position - shell->line_curpos);
					shell->line[shell->line_position] = 0;

					rt_kprintf("\b%s  \b", &shell->line[shell->line_curpos]);

					/* move the cursor to the origin position */
					for (i = shell->line_curpos; i <= shell->line_position; i++)
						rt_kprintf("\b");
				}
				else
				{
					rt_kprintf("\b \b");
					shell->line[shell->line_position] = 0;
				}

				continue;
			}

			/* handle end of line, break */
			if (ch == '\r' || ch == '\n')
			{
#ifdef FINSH_USING_MSH
				if (msh_is_used() == RT_TRUE && shell->line_position != 0)
				{
					rt_kprintf("\n");
					msh_exec(shell->line, shell->line_position);
					#ifdef FINSH_USING_HISTORY
					finsh_push_history(shell);
					#endif
				}
				else
#endif
				{
					/* add ';' and run the command line */
					shell->line[shell->line_position] = ';';

					#ifdef FINSH_USING_HISTORY
					finsh_push_history(shell);
					#endif

					if (shell->line_position != 0) finsh_run_line(&shell->parser, shell->line);
					else rt_kprintf("\n");
				}

				rt_kprintf(FINSH_PROMPT);
				memset(shell->line, 0, sizeof(shell->line));
				shell->line_curpos = shell->line_position = 0;

				break;
			}

			/* it's a large line, discard it */
			if (shell->line_position >= FINSH_CMD_SIZE)
				shell->line_position = 0;

			/* normal character */
			if (shell->line_curpos < shell->line_position)
			{
				int i;

				rt_memmove(&shell->line[shell->line_curpos + 1],
						   &shell->line[shell->line_curpos],
						   shell->line_position - shell->line_curpos);
				shell->line[shell->line_curpos] = ch;
				if (shell->echo_mode)
					rt_kprintf("%s", &shell->line[shell->line_curpos]);

				/* move the cursor to new position */
				for (i = shell->line_curpos; i < shell->line_position; i++)
					rt_kprintf("\b");
			}
			else
			{
				shell->line[shell->line_position] = ch;
				rt_kprintf("%c", ch);
			}

			ch = 0;
			shell->line_position ++;
			shell->line_curpos++;
		} /* end of device read */
	}
}