readline: Update initial readline commit -- make option configurable. Add an interface to de-couple the readline implementation from NSH. Misc. updates for coding style
This commit is contained in:
parent
264b84860d
commit
766886310d
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* apps/include/readline.h
|
* apps/include/readline.h
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2011, 2013, 2015 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -63,6 +63,35 @@ extern "C"
|
|||||||
* Public Function Prototypes
|
* Public Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: readline_prompt
|
||||||
|
*
|
||||||
|
* If a prompt string is used by the application, then the application
|
||||||
|
* must provide the prompt string to readline by calling this function.
|
||||||
|
* This is needed only for tab completion in cases where is it necessary
|
||||||
|
* to reprint the prompt string.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* prompt - The prompt string.
|
||||||
|
*
|
||||||
|
* Returned values:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* The prompt string is statically allocated a global. readline will
|
||||||
|
* simply remember the pointer to the string. The string must stay
|
||||||
|
* allocated and available. Only one prompt string is supported. If
|
||||||
|
* there are multiple clients of readline, they must all share the same
|
||||||
|
* prompt string (with exceptions in the case of the kernel build).
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_READLINE_TABCOMPLETION
|
||||||
|
void readline_prompt(FAR const *prompt);
|
||||||
|
#else
|
||||||
|
# define readline_prompt(p)
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: readline
|
* Name: readline
|
||||||
*
|
*
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* apps/nshlib/nsh_init.c
|
* apps/nshlib/nsh_init.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2012, 2014 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2012, 2014-2015 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -103,4 +103,10 @@ void nsh_initialize(void)
|
|||||||
/* Bring up the network */
|
/* Bring up the network */
|
||||||
|
|
||||||
(void)nsh_netinit();
|
(void)nsh_netinit();
|
||||||
|
|
||||||
|
#ifdef CONFIG_READLINE_TABCOMPLETION
|
||||||
|
/* Configure the NSH prompt */
|
||||||
|
|
||||||
|
readline_prompt(g_nshprompt);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -20,4 +20,12 @@ config READLINE_ECHO
|
|||||||
already has local echo support or you need to suppress the back-channel
|
already has local echo support or you need to suppress the back-channel
|
||||||
responses for any other reason.
|
responses for any other reason.
|
||||||
|
|
||||||
|
config READLINE_TABCOMPLETION
|
||||||
|
bool "Tab completion"
|
||||||
|
default n
|
||||||
|
depends on BUILD_FLAT && BUILTIN
|
||||||
|
---help---
|
||||||
|
Build in support for Unix-style tab completion. This feature was
|
||||||
|
provided by Nghia.
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
@ -48,27 +48,11 @@
|
|||||||
|
|
||||||
#include <nuttx/ascii.h>
|
#include <nuttx/ascii.h>
|
||||||
#include <nuttx/vt100.h>
|
#include <nuttx/vt100.h>
|
||||||
|
#include <nuttx/binfmt/builtin.h>
|
||||||
|
|
||||||
#include <apps/readline.h>
|
#include <apps/readline.h>
|
||||||
#include "readline.h"
|
#include "readline.h"
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Pre-processor Definitions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Type Declarations
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Function Prototypes
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Public Data
|
|
||||||
****************************************************************************/
|
|
||||||
extern const char g_nshprompt[];
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Data
|
* Private Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -76,18 +60,155 @@ extern const char g_nshprompt[];
|
|||||||
|
|
||||||
static const char g_erasetoeol[] = VT100_CLEAREOL;
|
static const char g_erasetoeol[] = VT100_CLEAREOL;
|
||||||
|
|
||||||
|
#ifdef CONFIG_READLINE_TABCOMPLETION
|
||||||
|
/* Prompt string to present at the beginning of the line */
|
||||||
|
|
||||||
|
static const *char g_readline_prompt = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static void tab_completion(FAR struct rl_common_s *vtbl, char *buf, int *len);
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: tab_completion
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Nghia - Unix like tab completion, only for builtin apps
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* vtbl - vtbl used to access implementation specific interface
|
||||||
|
* buf - The user allocated buffer to be filled.
|
||||||
|
* buflen - the size of the buffer.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_READLINE_TABCOMPLETION
|
||||||
|
void tab_completion(FAR struct rl_common_s *vtbl, char *buf, int *nch)
|
||||||
|
{
|
||||||
|
FAR const char *name = NULL;
|
||||||
|
int num_matches = 0;
|
||||||
|
int matches[128];
|
||||||
|
int len = *nch;
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
if (len >= 1)
|
||||||
|
{
|
||||||
|
for (i = 0; (name = builtin_getname(i)) != NULL; i++)
|
||||||
|
{
|
||||||
|
if (!strncmp(buf, name, len))
|
||||||
|
{
|
||||||
|
matches[num_matches] = i;
|
||||||
|
num_matches++;
|
||||||
|
|
||||||
|
if (num_matches >= sizeof(matches) / sizeof(int))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_matches == 1)
|
||||||
|
{
|
||||||
|
name = builtin_getname(matches[0]);
|
||||||
|
|
||||||
|
int name_len = strlen(name);
|
||||||
|
|
||||||
|
for (j = len; j < name_len; j++)
|
||||||
|
{
|
||||||
|
buf[j] = name[j];
|
||||||
|
RL_PUTC(vtbl, name[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't remove extra characters after the completed word, if any */
|
||||||
|
|
||||||
|
if (len < name_len)
|
||||||
|
{
|
||||||
|
*nch = name_len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (num_matches > 1)
|
||||||
|
{
|
||||||
|
RL_PUTC(vtbl, '\n');
|
||||||
|
|
||||||
|
/* possible completion */
|
||||||
|
|
||||||
|
for (i = 0; i < num_matches; i++)
|
||||||
|
{
|
||||||
|
name = builtin_getname(matches[i]);
|
||||||
|
|
||||||
|
RL_PUTC(vtbl, ' ');
|
||||||
|
RL_PUTC(vtbl, ' ');
|
||||||
|
|
||||||
|
for (j = 0; j < strlen(name); j++)
|
||||||
|
{
|
||||||
|
RL_PUTC(vtbl, name[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
RL_PUTC(vtbl, '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Output the original prompt */
|
||||||
|
|
||||||
|
if (g_readline_prompt != NULL)
|
||||||
|
{
|
||||||
|
for (i = 0; i < strlen(g_readline_prompt); i++)
|
||||||
|
{
|
||||||
|
RL_PUTC(vtbl, g_readline_prompt[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
RL_PUTC(vtbl, buf[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: readline_prompt
|
||||||
|
*
|
||||||
|
* If a prompt string is used by the application, then the application
|
||||||
|
* must provide the prompt string to readline by calling this function.
|
||||||
|
* This is needed only for tab completion in cases where is it necessary
|
||||||
|
* to reprint the prompt string.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* prompt - The prompt string.
|
||||||
|
*
|
||||||
|
* Returned values:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* The prompt string is statically allocated a global. readline will
|
||||||
|
* simply remember the pointer to the string. The string must stay
|
||||||
|
* allocated and available. Only one prompt string is supported. If
|
||||||
|
* there are multiple clients of readline, they must all share the same
|
||||||
|
* prompt string (with exceptions in the case of the kernel build).
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_READLINE_TABCOMPLETION
|
||||||
|
void readline_prompt(FAR const *prompt)
|
||||||
|
{
|
||||||
|
g_readline_prompt = prompt;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: readline_common
|
* Name: readline_common
|
||||||
*
|
*
|
||||||
|
* Description:
|
||||||
* readline() reads in at most one less than 'buflen' characters from
|
* readline() reads in at most one less than 'buflen' characters from
|
||||||
* 'instream' and stores them into the buffer pointed to by 'buf'.
|
* 'instream' and stores them into the buffer pointed to by 'buf'.
|
||||||
* Characters are echoed on 'outstream'. Reading stops after an EOF or a
|
* Characters are echoed on 'outstream'. Reading stops after an EOF or a
|
||||||
@ -102,12 +223,11 @@ static void tab_completion(FAR struct rl_common_s *vtbl, char *buf, int *len);
|
|||||||
* different creature.
|
* different creature.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* buf - The user allocated buffer to be filled.
|
* vtbl - vtbl used to access implementation specific interface
|
||||||
* buflen - the size of the buffer.
|
* buf - The user allocated buffer to be filled.
|
||||||
* instream - The stream to read characters from
|
* buflen - the size of the buffer.
|
||||||
* outstream - The stream to each characters to.
|
|
||||||
*
|
*
|
||||||
* Returned values:
|
* Returned Value:
|
||||||
* On success, the (positive) number of bytes transferred is returned.
|
* On success, the (positive) number of bytes transferred is returned.
|
||||||
* EOF is returned to indicate either an end of file condition or a
|
* EOF is returned to indicate either an end of file condition or a
|
||||||
* failure.
|
* failure.
|
||||||
@ -285,88 +405,11 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl, FAR char *buf, int buflen)
|
|||||||
return nch;
|
return nch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef CONFIG_READLINE_TABCOMPLETION
|
||||||
else if (ch == '\t') /* Nghia - TAB character */
|
else if (ch == '\t') /* Nghia - TAB character */
|
||||||
{
|
{
|
||||||
tab_completion(vtbl, buf, &nch);
|
tab_completion(vtbl, buf, &nch);
|
||||||
}
|
}
|
||||||
}
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Nghia - Unix like tab completion, only for builtin apps
|
|
||||||
*/
|
|
||||||
void tab_completion(FAR struct rl_common_s *vtbl, char *buf, int *nch)
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
int num_matches = 0;
|
|
||||||
int matches[128];
|
|
||||||
FAR const char *name = NULL;
|
|
||||||
int len = *nch;
|
|
||||||
|
|
||||||
if (len >= 1)
|
|
||||||
{
|
|
||||||
for (i = 0; (name = builtin_getname(i)) != NULL; i++)
|
|
||||||
{
|
|
||||||
if (!strncmp(buf, name, len))
|
|
||||||
{
|
|
||||||
matches[num_matches] = i;
|
|
||||||
num_matches++;
|
|
||||||
|
|
||||||
if (num_matches >= sizeof(matches) / sizeof(int))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (num_matches == 1)
|
|
||||||
{
|
|
||||||
name = builtin_getname(matches[0]);
|
|
||||||
|
|
||||||
int name_len = strlen(name);
|
|
||||||
|
|
||||||
for (j = len; j < name_len; j++)
|
|
||||||
{
|
|
||||||
buf[j] = name[j];
|
|
||||||
RL_PUTC(vtbl, name[j]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// don't remove extra characters after the completed word, if any
|
|
||||||
if (len < name_len)
|
|
||||||
{
|
|
||||||
*nch = name_len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (num_matches > 1)
|
|
||||||
{
|
|
||||||
RL_PUTC(vtbl, '\n');
|
|
||||||
|
|
||||||
// possible completion
|
|
||||||
for (i = 0; i < num_matches; i++)
|
|
||||||
{
|
|
||||||
name = builtin_getname(matches[i]);
|
|
||||||
|
|
||||||
RL_PUTC(vtbl, ' ');
|
|
||||||
RL_PUTC(vtbl, ' ');
|
|
||||||
|
|
||||||
for (j = 0; j < strlen(name); j++)
|
|
||||||
{
|
|
||||||
RL_PUTC(vtbl, name[j]);
|
|
||||||
}
|
|
||||||
|
|
||||||
RL_PUTC(vtbl, '\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
// output the original prompt
|
|
||||||
for (i = 0; i < strlen(g_nshprompt); i++)
|
|
||||||
{
|
|
||||||
RL_PUTC(vtbl, g_nshprompt[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < len; i++)
|
|
||||||
{
|
|
||||||
RL_PUTC(vtbl, buf[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user