[dpdk-dev] [RFC] cmdline: rework as a wrapper to libedit

Jim Thompson jim at netgate.com
Thu Nov 16 17:53:28 CET 2017


How does this fit with all the work that Keith Wiles just discussed at DPDK Summit?

https://dpdk17.sched.com/event/Cqv3/new-command-line-interface-for-dpdk <https://dpdk17.sched.com/event/Cqv3/new-command-line-interface-for-dpdk>

Jim

> On Nov 9, 2017, at 7:43 AM, Adrien Mazarguil <adrien.mazarguil at 6wind.com> wrote:
> 
> This patch removes all code associated with symbols not internally relied
> on by other DPDK components, makes struct cmdline opaque and then proceeds
> to re-implement the remaining functionality as a wrapper to the editline
> library (also known as libedit) [1].
> 
> Besides adding a new external dependency to its users, its large impact on
> librte_cmdline's API/ABI also warrants a major version number bump.
> 
> While librte_cmdline served DPDK well all these years as a small, easy to
> use and self-sufficient interactive command-line handler, it started to
> show its limits with testpmd's flow (rte_flow) command, which required
> support for dynamic tokens and very long commands.
> 
> This is the main motivation behind this rework. Long commands often need to
> be displayed on multiple lines, which are not properly supported by
> librte_cmdline's limited terminal handling capabilities, resulting in a
> rather frustrating user experience.
> 
> Testpmd being one of the main tools used by PMD developers and given flow
> command lines won't get any shorter, this issue had to be addressed.
> 
> Three options were considered:
> 
> - Fixing and enhancing librte_cmdline.
> 
>  The amount of work necessary to add support for edition on multiple lines
>  was deemed significant and the result would still have lacked in some
>  areas, such as working backspace/delete keys in all terminals (i.e. full
>  termcap support).
> 
> - Making testpmd directly rely on a more capable library.
> 
>  All testpmd commands rely on the cmdline_parse interface provided by
>  librte_cmdline. This approach would have required either a complete
>  rewrite or importing the missing bits from librte_cmdline to wrap them
>  around the new library, which naturally led to...
> 
> - Converting librte_cmdline as a wrapper to a more capable library.
> 
>  Let's be honest, interactive command line handling isn't what makes DPDK
>  shine. It's also far removed from its core functionality, but is still
>  necessary in order to easily implement test and example programs; the
>  cmdline_parse interface is particularly good at this.
> 
>  DPDK actually only relies on cmdline_parse. By removing all the other
>  unused interfaces, implementing what remains on top of a different
>  terminal-handling library would be quick and easy.
> 
> This last approach was chosen for the stated reasons. Libedit is
> well-known, BSD-licensed, widely available [2], used by many projects, does
> everything needed and more [3].
> 
> This rework results in the following changes:
> 
> - Removed circular buffer management interface for command history
>  (cmdline_cirbuf.c), command history being handled by libedit.
> - Removed raw command-line interpreter (cmdline_rdline.c).
> - Removed raw terminal handler (cmdline_vt100.c).
> - Removed all test/example code for the above.
> - Re-implemented high level interactive and non-interactive command-line
>  handlers (cmdline.c and cmdline_socket.c) on top of libedit using its
>  native interface, not its readline compatibility layer.
> - Made struct cmdline opaque so that applications relying on librte_cmdline
>  do not need to include any libedit headers.
> - The only visible change for most applications besides being linked to
>  libedit is they do not have to include cmdline_rdline.h anymore.
> 
> As an added bonus, terminal resizing is now automatically handled.
> 
> In the future, cmdline_parse could use libedit's advanced tokenizer as
> well to interpret quoted strings and escape sequences.
> 
> [1] http://thrysoee.dk/editline/
> [2] It usually goes by the name "libedit" in Linux distributions.
> [3] http://netbsd.gw.com/cgi-bin/man-cgi?editline++NetBSD-current
> 
> Signed-off-by: Adrien Mazarguil <adrien.mazarguil at 6wind.com>
> ---
> app/test-pmd/cmdline.c                          |    1 -
> examples/bond/main.c                            |    1 -
> examples/cmdline/commands.c                     |    1 -
> examples/cmdline/main.c                         |    1 -
> .../ip_pipeline/pipeline/pipeline_common_fe.c   |    1 -
> .../ip_pipeline/pipeline/pipeline_firewall.c    |    1 -
> .../pipeline/pipeline_flow_actions.c            |    1 -
> .../pipeline/pipeline_flow_classification.c     |    1 -
> examples/ip_pipeline/thread_fe.c                |    1 -
> examples/multi_process/simple_mp/main.c         |    1 -
> examples/multi_process/simple_mp/mp_commands.c  |    1 -
> examples/qos_sched/cmdline.c                    |    1 -
> examples/quota_watermark/qwctl/commands.c       |    1 -
> examples/quota_watermark/qwctl/qwctl.c          |    1 -
> .../guest_cli/vm_power_cli_guest.c              |    1 -
> examples/vm_power_manager/vm_power_cli.c        |    1 -
> lib/librte_cmdline/Makefile                     |   10 +-
> lib/librte_cmdline/cmdline.c                    |  385 +++--
> lib/librte_cmdline/cmdline.h                    |   22 +-
> lib/librte_cmdline/cmdline_cirbuf.c             |  466 ------
> lib/librte_cmdline/cmdline_cirbuf.h             |  245 ----
> lib/librte_cmdline/cmdline_parse.c              |    7 +-
> lib/librte_cmdline/cmdline_rdline.c             |  697 ---------
> lib/librte_cmdline/cmdline_rdline.h             |  255 ----
> lib/librte_cmdline/cmdline_socket.c             |   36 +-
> lib/librte_cmdline/cmdline_vt100.c              |  185 ---
> lib/librte_cmdline/cmdline_vt100.h              |  153 --
> lib/librte_cmdline/rte_cmdline_version.map      |   41 +-
> mk/rte.app.mk                                   |    2 +
> test/cmdline_test/cmdline_test.c                |    1 -
> test/cmdline_test/commands.c                    |   69 -
> test/test/Makefile                              |    1 -
> test/test/commands.c                            |    1 -
> test/test/test.c                                |    1 -
> test/test/test_cmdline.c                        |    9 -
> test/test/test_cmdline.h                        |    6 -
> test/test/test_cmdline_cirbuf.c                 | 1330 ------------------
> test/test/test_cmdline_lib.c                    |  117 +-
> 38 files changed, 293 insertions(+), 3762 deletions(-)
> 
> diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
> index f71d963..9fe625c 100644
> --- a/app/test-pmd/cmdline.c
> +++ b/app/test-pmd/cmdline.c
> @@ -77,7 +77,6 @@
> #include <rte_flow.h>
> #include <rte_gro.h>
> 
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_num.h>
> #include <cmdline_parse_string.h>
> diff --git a/examples/bond/main.c b/examples/bond/main.c
> index 8e3b1f3..d903314 100644
> --- a/examples/bond/main.c
> +++ b/examples/bond/main.c
> @@ -71,7 +71,6 @@
> #include <rte_arp.h>
> #include <rte_spinlock.h>
> 
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_num.h>
> #include <cmdline_parse_string.h>
> diff --git a/examples/cmdline/commands.c b/examples/cmdline/commands.c
> index f3ba247..e8fa7f0 100644
> --- a/examples/cmdline/commands.c
> +++ b/examples/cmdline/commands.c
> @@ -74,7 +74,6 @@
> 	#endif
> #endif
> 
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_ipaddr.h>
> #include <cmdline_parse_num.h>
> diff --git a/examples/cmdline/main.c b/examples/cmdline/main.c
> index c6de944..c229f50 100644
> --- a/examples/cmdline/main.c
> +++ b/examples/cmdline/main.c
> @@ -65,7 +65,6 @@
> #include <termios.h>
> #include <sys/queue.h>
> 
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_socket.h>
> #include <cmdline.h>
> diff --git a/examples/ip_pipeline/pipeline/pipeline_common_fe.c b/examples/ip_pipeline/pipeline/pipeline_common_fe.c
> index 7521187..f1df197 100644
> --- a/examples/ip_pipeline/pipeline/pipeline_common_fe.c
> +++ b/examples/ip_pipeline/pipeline/pipeline_common_fe.c
> @@ -37,7 +37,6 @@
> 
> #include <rte_common.h>
> #include <rte_malloc.h>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_num.h>
> #include <cmdline_parse_string.h>
> diff --git a/examples/ip_pipeline/pipeline/pipeline_firewall.c b/examples/ip_pipeline/pipeline/pipeline_firewall.c
> index a82e552..e49d9ca 100644
> --- a/examples/ip_pipeline/pipeline/pipeline_firewall.c
> +++ b/examples/ip_pipeline/pipeline/pipeline_firewall.c
> @@ -41,7 +41,6 @@
> #include <rte_common.h>
> #include <rte_hexdump.h>
> #include <rte_malloc.h>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_num.h>
> #include <cmdline_parse_string.h>
> diff --git a/examples/ip_pipeline/pipeline/pipeline_flow_actions.c b/examples/ip_pipeline/pipeline/pipeline_flow_actions.c
> index 349db6b..0f680db 100644
> --- a/examples/ip_pipeline/pipeline/pipeline_flow_actions.c
> +++ b/examples/ip_pipeline/pipeline/pipeline_flow_actions.c
> @@ -40,7 +40,6 @@
> #include <rte_common.h>
> #include <rte_hexdump.h>
> #include <rte_malloc.h>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_num.h>
> #include <cmdline_parse_string.h>
> diff --git a/examples/ip_pipeline/pipeline/pipeline_flow_classification.c b/examples/ip_pipeline/pipeline/pipeline_flow_classification.c
> index 70b1938..b9e4ed5 100644
> --- a/examples/ip_pipeline/pipeline/pipeline_flow_classification.c
> +++ b/examples/ip_pipeline/pipeline/pipeline_flow_classification.c
> @@ -40,7 +40,6 @@
> #include <rte_common.h>
> #include <rte_hexdump.h>
> #include <rte_malloc.h>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_num.h>
> #include <cmdline_parse_string.h>
> diff --git a/examples/ip_pipeline/thread_fe.c b/examples/ip_pipeline/thread_fe.c
> index 4590c2b..4f54094 100644
> --- a/examples/ip_pipeline/thread_fe.c
> +++ b/examples/ip_pipeline/thread_fe.c
> @@ -1,7 +1,6 @@
> #include <rte_common.h>
> #include <rte_ring.h>
> #include <rte_malloc.h>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_num.h>
> #include <cmdline_parse_string.h>
> diff --git a/examples/multi_process/simple_mp/main.c b/examples/multi_process/simple_mp/main.c
> index 62537b0..c0fc6ea 100644
> --- a/examples/multi_process/simple_mp/main.c
> +++ b/examples/multi_process/simple_mp/main.c
> @@ -64,7 +64,6 @@
> #include <rte_ring.h>
> #include <rte_log.h>
> #include <rte_mempool.h>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_string.h>
> #include <cmdline_socket.h>
> diff --git a/examples/multi_process/simple_mp/mp_commands.c b/examples/multi_process/simple_mp/mp_commands.c
> index ef6dc58..264dea2 100644
> --- a/examples/multi_process/simple_mp/mp_commands.c
> +++ b/examples/multi_process/simple_mp/mp_commands.c
> @@ -54,7 +54,6 @@
> #include <rte_mempool.h>
> #include <rte_string_fns.h>
> 
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_string.h>
> #include <cmdline_socket.h>
> diff --git a/examples/qos_sched/cmdline.c b/examples/qos_sched/cmdline.c
> index b62d165..c2a4f6b 100644
> --- a/examples/qos_sched/cmdline.c
> +++ b/examples/qos_sched/cmdline.c
> @@ -36,7 +36,6 @@
> #include <inttypes.h>
> #include <string.h>
> 
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_num.h>
> #include <cmdline_parse_string.h>
> diff --git a/examples/quota_watermark/qwctl/commands.c b/examples/quota_watermark/qwctl/commands.c
> index 5cac0e1..a30a35c 100644
> --- a/examples/quota_watermark/qwctl/commands.c
> +++ b/examples/quota_watermark/qwctl/commands.c
> @@ -36,7 +36,6 @@
> #include <string.h>
> #include <termios.h>
> 
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_num.h>
> #include <cmdline_parse_string.h>
> diff --git a/examples/quota_watermark/qwctl/qwctl.c b/examples/quota_watermark/qwctl/qwctl.c
> index 18ec17a..2831667 100644
> --- a/examples/quota_watermark/qwctl/qwctl.c
> +++ b/examples/quota_watermark/qwctl/qwctl.c
> @@ -42,7 +42,6 @@
> #include <rte_log.h>
> #include <rte_memzone.h>
> 
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_socket.h>
> #include <cmdline.h>
> diff --git a/examples/vm_power_manager/guest_cli/vm_power_cli_guest.c b/examples/vm_power_manager/guest_cli/vm_power_cli_guest.c
> index 63f711e..83cd215 100644
> --- a/examples/vm_power_manager/guest_cli/vm_power_cli_guest.c
> +++ b/examples/vm_power_manager/guest_cli/vm_power_cli_guest.c
> @@ -37,7 +37,6 @@
> #include <stdio.h>
> #include <termios.h>
> 
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_string.h>
> #include <cmdline_parse_num.h>
> diff --git a/examples/vm_power_manager/vm_power_cli.c b/examples/vm_power_manager/vm_power_cli.c
> index 6f234fb..d013715 100644
> --- a/examples/vm_power_manager/vm_power_cli.c
> +++ b/examples/vm_power_manager/vm_power_cli.c
> @@ -39,7 +39,6 @@
> #include <termios.h>
> #include <errno.h>
> 
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_string.h>
> #include <cmdline_parse_num.h>
> diff --git a/lib/librte_cmdline/Makefile b/lib/librte_cmdline/Makefile
> index 2c48e62..35c8972 100644
> --- a/lib/librte_cmdline/Makefile
> +++ b/lib/librte_cmdline/Makefile
> @@ -38,28 +38,24 @@ CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3
> 
> EXPORT_MAP := rte_cmdline_version.map
> 
> -LIBABIVER := 2
> +LIBABIVER := 3
> 
> # all source are stored in SRCS-y
> SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) := cmdline.c
> -SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_cirbuf.c
> SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_parse.c
> SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_parse_etheraddr.c
> SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_parse_ipaddr.c
> SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_parse_num.c
> SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_parse_string.c
> -SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_rdline.c
> -SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_vt100.c
> SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_socket.c
> SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_parse_portlist.c
> 
> -CFLAGS += -D_GNU_SOURCE
> LDLIBS += -lrte_eal
> 
> # install includes
> INCS := cmdline.h cmdline_parse.h cmdline_parse_num.h cmdline_parse_ipaddr.h
> -INCS += cmdline_parse_etheraddr.h cmdline_parse_string.h cmdline_rdline.h
> -INCS += cmdline_vt100.h cmdline_socket.h cmdline_cirbuf.h cmdline_parse_portlist.h
> +INCS += cmdline_parse_etheraddr.h cmdline_parse_string.h
> +INCS += cmdline_socket.h cmdline_parse_portlist.h
> SYMLINK-$(CONFIG_RTE_LIBRTE_CMDLINE)-include := $(INCS)
> 
> include $(RTE_SDK)/mk/rte.lib.mk
> diff --git a/lib/librte_cmdline/cmdline.c b/lib/librte_cmdline/cmdline.c
> index d749165..1c19546 100644
> --- a/lib/librte_cmdline/cmdline.c
> +++ b/lib/librte_cmdline/cmdline.c
> @@ -58,79 +58,181 @@
>  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>  */
> 
> +#include <ctype.h>
> +#include <histedit.h>
> +#include <stdint.h>
> #include <stdio.h>
> #include <string.h>
> #include <unistd.h>
> #include <stdlib.h>
> #include <stdarg.h>
> -#include <inttypes.h>
> #include <fcntl.h>
> #include <poll.h>
> #include <errno.h>
> -#include <termios.h>
> -#include <netinet/in.h>
> -
> -#include <rte_string_fns.h>
> 
> #include "cmdline_parse.h"
> -#include "cmdline_rdline.h"
> #include "cmdline.h"
> 
> -static void
> -cmdline_valid_buffer(struct rdline *rdl, const char *buf,
> -		     __attribute__((unused)) unsigned int size)
> +struct cmdline {
> +	char *line;
> +	FILE *f_in;
> +	FILE *f_out;
> +	cmdline_parse_ctx_t *ctx;
> +	EditLine *el;
> +	History *hist;
> +	HistEvent histev;
> +	uint32_t eof:1;
> +	uint32_t error:1;
> +	char prompt[RDLINE_PROMPT_SIZE];
> +};
> +
> +void
> +cmdline_set_prompt(struct cmdline *cl, const char *prompt)
> {
> -	struct cmdline *cl = rdl->opaque;
> -	int ret;
> -	ret = cmdline_parse(cl, buf);
> -	if (ret == CMDLINE_PARSE_AMBIGUOUS)
> -		cmdline_printf(cl, "Ambiguous command\n");
> -	else if (ret == CMDLINE_PARSE_NOMATCH)
> -		cmdline_printf(cl, "Command not found\n");
> -	else if (ret == CMDLINE_PARSE_BAD_ARGS)
> -		cmdline_printf(cl, "Bad arguments\n");
> +	if (!cl || !prompt)
> +		return;
> +	snprintf(cl->prompt, sizeof(cl->prompt), "%s", prompt);
> }
> 
> -static int
> -cmdline_complete_buffer(struct rdline *rdl, const char *buf,
> -			char *dstbuf, unsigned int dstsize,
> -			int *state)
> +void *
> +cmdline_ctx_get(struct cmdline *cl)
> {
> -	struct cmdline *cl = rdl->opaque;
> -	return cmdline_complete(cl, buf, state, dstbuf, dstsize);
> +	if (!cl)
> +		return NULL;
> +	return cl->ctx;
> }
> 
> -int
> -cmdline_write_char(struct rdline *rdl, char c)
> +static char *
> +cmdline_el_prompt(EditLine *el)
> {
> -	int ret = -1;
> 	struct cmdline *cl;
> 
> -	if (!rdl)
> -		return -1;
> -
> -	cl = rdl->opaque;
> +	if (el_get(el, EL_CLIENTDATA, &cl))
> +		return NULL;
> +	return cl->prompt;
> +}
> 
> -	if (cl->s_out >= 0)
> -		ret = write(cl->s_out, &c, 1);
> +static unsigned char
> +cmdline_el_execute(EditLine *el, int c)
> +{
> +	const LineInfo *li = el_line(el);
> +	size_t len = li->lastchar - li->buffer;
> +	char *line;
> +	struct cmdline *cl;
> +	int ret;
> 
> -	return ret;
> +	(void)c;
> +	if (el_get(el, EL_CLIENTDATA, &cl))
> +		return CC_FATAL;
> +	line = realloc(cl->line, len + 2);
> +	if (!line) {
> +		cl->error = 1;
> +		return CC_FATAL;
> +	}
> +	cl->line = line;
> +	memcpy(line, li->buffer, len);
> +	line[len] = '\n';
> +	line[len + 1] = '\0';
> +	fputs("\r\n", cl->f_out);
> +	ret = cmdline_parse(cl, line);
> +	if (ret == CMDLINE_PARSE_AMBIGUOUS)
> +		fprintf(cl->f_out, "Ambiguous command\r\n");
> +	else if (ret == CMDLINE_PARSE_NOMATCH)
> +		fprintf(cl->f_out, "Command not found\r\n");
> +	else if (ret == CMDLINE_PARSE_BAD_ARGS)
> +		fprintf(cl->f_out, "Bad arguments\r\n");
> +	if (cl->error)
> +		return CC_FATAL;
> +	if (cl->eof)
> +		return CC_EOF;
> +	if (len) {
> +		line[len] = '\0';
> +		history(cl->hist, &cl->histev, H_ENTER, line);
> +	}
> +	return CC_NEWLINE;
> }
> 
> +static unsigned char
> +cmdline_el_complete(EditLine *el, int c)
> +{
> +	const LineInfo *li = el_line(el);
> +	size_t pos = li->cursor - li->buffer;
> +	char *line;
> +	struct cmdline *cl;
> +	char complete_buf[RDLINE_COMPLETE_SIZE];
> +	int complete_state;
> +	int ret;
> 
> -void
> -cmdline_set_prompt(struct cmdline *cl, const char *prompt)
> +	if (el_get(el, EL_CLIENTDATA, &cl))
> +		return CC_FATAL;
> +	line = realloc(cl->line, pos + 1);
> +	if (!line) {
> +		cl->error = 1;
> +		return CC_FATAL;
> +	}
> +	cl->line = line;
> +	memcpy(line, li->buffer, pos);
> +	line[pos] = '\0';
> +	if (c == '\t')
> +		complete_state = 0;
> +	else
> +		complete_state = -1;
> +	/* see in parse.h for help on complete() */
> +	ret = cmdline_complete(cl, line, &complete_state,
> +			       complete_buf, sizeof(complete_buf));
> +	/* no completion or error */
> +	if (ret <= 0)
> +		return CC_ARGHACK;
> +	/* string must be NUL-terminated */
> +	if (strnlen(complete_buf, sizeof(complete_buf)) == sizeof(complete_buf))
> +		return CC_ERROR;
> +	/* add chars */
> +	if (ret == CMDLINE_PARSE_COMPLETED_BUFFER) {
> +		/* if in the middle of a token, remove its suffix first */
> +		for (pos = 0; li->cursor + pos != li->lastchar; pos++)
> +			if (isblank(li->cursor[pos]))
> +				break;
> +		el_cursor(el, pos);
> +		el_deletestr(el, pos);
> +		if (el_insertstr(el, complete_buf))
> +			return CC_ERROR;
> +		return CC_REFRESH;
> +	}
> +	/* choice */
> +	fputs("\r\n", cl->f_out);
> +	while (ret) {
> +		fputc(' ', cl->f_out);
> +		fputs(complete_buf, cl->f_out);
> +		fputs("\r\n", cl->f_out);
> +		ret = cmdline_complete(cl, line, &complete_state,
> +				       complete_buf, sizeof(complete_buf));
> +	}
> +	el_set(el, EL_REFRESH);
> +	return CC_REDISPLAY;
> +}
> +
> +static unsigned char
> +cmdline_el_delete_next_char_or_eof(EditLine *el, int c)
> {
> -	if (!cl || !prompt)
> -		return;
> -	snprintf(cl->prompt, sizeof(cl->prompt), "%s", prompt);
> +	const LineInfo *li = el_line(el);
> +	struct cmdline *cl;
> +
> +	(void)c;
> +	if (el_get(el, EL_CLIENTDATA, &cl))
> +		return CC_FATAL;
> +	if (li->buffer == li->lastchar) {
> +		cl->eof = 1;
> +		return CC_EOF;
> +	}
> +	el_cursor(el, 1);
> +	el_deletestr(el, 1);
> +	return CC_REFRESH;
> }
> 
> struct cmdline *
> cmdline_new(cmdline_parse_ctx_t *ctx, const char *prompt, int s_in, int s_out)
> {
> 	struct cmdline *cl;
> -	int ret;
> 
> 	if (!ctx || !prompt)
> 		return NULL;
> @@ -139,36 +241,89 @@ cmdline_new(cmdline_parse_ctx_t *ctx, const char *prompt, int s_in, int s_out)
> 	if (cl == NULL)
> 		return NULL;
> 	memset(cl, 0, sizeof(struct cmdline));
> -	cl->s_in = s_in;
> -	cl->s_out = s_out;
> +	cl->line = NULL;
> +	s_in = dup(s_in);
> +	s_out = s_out != -1 ? dup(s_out) : open("/dev/null", O_WRONLY);
> +	if (s_in == -1 || s_out == -1)
> +		goto error;
> +	cl->f_in = fdopen(s_in, "rb");
> +	cl->f_out = fdopen(s_out, "wb");
> +	if (!cl->f_in || !cl->f_out)
> +		goto error;
> 	cl->ctx = ctx;
> -
> -	ret = rdline_init(&cl->rdl, cmdline_write_char, cmdline_valid_buffer,
> -			cmdline_complete_buffer);
> -	if (ret != 0) {
> -		free(cl);
> -		return NULL;
> -	}
> -
> -	cl->rdl.opaque = cl;
> +	cl->el = el_init("dpdk", cl->f_in, cl->f_out, stderr);
> +	if (!cl->el)
> +		goto error;
> +	if (el_set(cl->el, EL_CLIENTDATA, cl))
> +		goto error;
> 	cmdline_set_prompt(cl, prompt);
> -	rdline_newline(&cl->rdl, cl->prompt);
> -
> +	if (el_set(cl->el, EL_PROMPT, cmdline_el_prompt))
> +		goto error;
> +	if (el_set(cl->el, EL_EDITOR, "emacs"))
> +		goto error;
> +	if (el_set(cl->el, EL_SIGNAL, 1))
> +		goto error;
> +	cl->hist = history_init();
> +	if (!cl->hist)
> +		goto error;
> +	if (history(cl->hist, &cl->histev, H_SETSIZE,
> +		    RDLINE_HISTORY_MAX_LINE) < 0)
> +		goto error;
> +	if (history(cl->hist, &cl->histev, H_SETUNIQUE, 1))
> +		goto error;
> +	if (el_set(cl->el, EL_HIST, history, cl->hist))
> +		goto error;
> +	if (el_set(cl->el, EL_ADDFN, "ed-execute", "Execute command",
> +		   cmdline_el_execute))
> +		goto error;
> +	if (el_set(cl->el, EL_BIND, "^J", "ed-execute", NULL))
> +		goto error;
> +	if (el_set(cl->el, EL_BIND, "^M", "ed-execute", NULL))
> +		goto error;
> +	if (el_set(cl->el, EL_ADDFN, "ed-complete", "Complete argument",
> +		   cmdline_el_complete))
> +		goto error;
> +	if (el_set(cl->el, EL_BIND, "^I", "ed-complete", NULL))
> +		goto error;
> +	if (el_set(cl->el, EL_BIND, "?", "ed-complete", NULL))
> +		goto error;
> +	if (el_set(cl->el, EL_ADDFN, "ed-delete-next-char-or-eof",
> +		   "Delete next character or assume EOF",
> +		   cmdline_el_delete_next_char_or_eof))
> +		goto error;
> +	if (el_set(cl->el, EL_BIND, "^D",
> +		   "ed-delete-next-char-or-eof", NULL))
> +		goto error;
> +	if (el_set(cl->el, EL_BIND, "^W", "ed-delete-prev-word", NULL))
> +		goto error;
> 	return cl;
> +error:
> +	if (cl->hist)
> +		history_end(cl->hist);
> +	if (cl->el)
> +		el_end(cl->el);
> +	if (cl->f_out)
> +		fclose(cl->f_out);
> +	else if (s_out != -1)
> +		close(s_out);
> +	if (cl->f_in)
> +		fclose(cl->f_in);
> +	else if (s_in != -1)
> +		close(s_in);
> +	free(cl);
> +	return NULL;
> }
> 
> void
> cmdline_free(struct cmdline *cl)
> {
> -	dprintf("called\n");
> -
> 	if (!cl)
> 		return;
> -
> -	if (cl->s_in > 2)
> -		close(cl->s_in);
> -	if (cl->s_out != cl->s_in && cl->s_out > 2)
> -		close(cl->s_out);
> +	history_end(cl->hist);
> +	el_end(cl->el);
> +	fclose(cl->f_out);
> +	fclose(cl->f_in);
> +	free(cl->line);
> 	free(cl);
> }
> 
> @@ -180,70 +335,23 @@ cmdline_printf(const struct cmdline *cl, const char *fmt, ...)
> 	if (!cl || !fmt)
> 		return;
> 
> -#ifdef _GNU_SOURCE
> -	if (cl->s_out < 0)
> -		return;
> -	va_start(ap, fmt);
> -	vdprintf(cl->s_out, fmt, ap);
> -	va_end(ap);
> -#else
> -	int ret;
> -	char *buf;
> -
> -	if (cl->s_out < 0)
> -		return;
> -
> -	buf = malloc(BUFSIZ);
> -	if (buf == NULL)
> -		return;
> 	va_start(ap, fmt);
> -	ret = vsnprintf(buf, BUFSIZ, fmt, ap);
> +	vfprintf(cl->f_out, fmt, ap);
> 	va_end(ap);
> -	if (ret < 0) {
> -		free(buf);
> -		return;
> -	}
> -	if (ret >= BUFSIZ)
> -		ret = BUFSIZ - 1;
> -	ret = write(cl->s_out, buf, ret);
> -	(void)ret;
> -	free(buf);
> -#endif
> }
> 
> int
> cmdline_in(struct cmdline *cl, const char *buf, int size)
> {
> -	const char *history, *buffer;
> -	size_t histlen, buflen;
> -	int ret = 0;
> -	int i, same;
> +	int i;
> 
> 	if (!cl || !buf)
> 		return -1;
> 
> 	for (i=0; i<size; i++) {
> -		ret = rdline_char_in(&cl->rdl, buf[i]);
> -
> -		if (ret == RDLINE_RES_VALIDATED) {
> -			buffer = rdline_get_buffer(&cl->rdl);
> -			history = rdline_get_history_item(&cl->rdl, 0);
> -			if (history) {
> -				histlen = strnlen(history, RDLINE_BUF_SIZE);
> -				same = !memcmp(buffer, history, histlen) &&
> -					buffer[histlen] == '\n';
> -			}
> -			else
> -				same = 0;
> -			buflen = strnlen(buffer, RDLINE_BUF_SIZE);
> -			if (buflen > 1 && !same)
> -				rdline_add_history(&cl->rdl, buffer);
> -			rdline_newline(&cl->rdl, cl->prompt);
> -		}
> -		else if (ret == RDLINE_RES_EOF)
> -			return -1;
> -		else if (ret == RDLINE_RES_EXITED)
> -			return -1;
> +		char tmp[2] = { buf[i], '\0' };
> +
> +		el_push(cl->el, tmp);
> 	}
> 	return i;
> }
> @@ -253,7 +361,7 @@ cmdline_quit(struct cmdline *cl)
> {
> 	if (!cl)
> 		return;
> -	rdline_quit(&cl->rdl);
> +	cl->eof = 1;
> }
> 
> int
> @@ -261,48 +369,49 @@ cmdline_poll(struct cmdline *cl)
> {
> 	struct pollfd pfd;
> 	int status;
> -	ssize_t read_status;
> -	char c;
> +	int read_status;
> +	int flags;
> 
> 	if (!cl)
> 		return -EINVAL;
> -	else if (cl->rdl.status == RDLINE_EXITED)
> +	else if (cl->error)
> +		return RDLINE_ERROR;
> +	else if (cl->eof)
> 		return RDLINE_EXITED;
> 
> -	pfd.fd = cl->s_in;
> +	pfd.fd = fileno(cl->f_in);
> 	pfd.events = POLLIN;
> 	pfd.revents = 0;
> 
> 	status = poll(&pfd, 1, 0);
> 	if (status < 0)
> -		return status;
> -	else if (status > 0) {
> -		c = -1;
> -		read_status = read(cl->s_in, &c, 1);
> -		if (read_status < 0)
> -			return read_status;
> -
> -		status = cmdline_in(cl, &c, 1);
> -		if (status < 0 && cl->rdl.status != RDLINE_EXITED)
> -			return status;
> -	}
> -
> -	return cl->rdl.status;
> +		return RDLINE_ERROR;
> +	if (!status)
> +		return RDLINE_RUNNING;
> +	flags = fcntl(pfd.fd, F_GETFL);
> +	if (!(flags & O_NONBLOCK))
> +		fcntl(pfd.fd, F_SETFL, flags | O_NONBLOCK);
> +	if (!el_gets(cl->el, &read_status) && read_status == -1)
> +		cl->error = 1;
> +	if (!(flags & O_NONBLOCK))
> +		fcntl(pfd.fd, F_SETFL, flags);
> +	return cl->error ? RDLINE_ERROR :
> +		cl->eof ? RDLINE_EXITED :
> +		RDLINE_RUNNING;
> }
> 
> void
> cmdline_interact(struct cmdline *cl)
> {
> -	char c;
> -
> 	if (!cl)
> 		return;
> 
> -	c = -1;
> -	while (1) {
> -		if (read(cl->s_in, &c, 1) <= 0)
> -			break;
> -		if (cmdline_in(cl, &c, 1) < 0)
> -			break;
> +	while (!cl->error && !cl->eof) {
> +		int read_status;
> +
> +		if (el_gets(cl->el, &read_status))
> +			continue;
> +		if (read_status == -1)
> +			cl->error = 1;
> 	}
> }
> diff --git a/lib/librte_cmdline/cmdline.h b/lib/librte_cmdline/cmdline.h
> index 65d73b0..4507268 100644
> --- a/lib/librte_cmdline/cmdline.h
> +++ b/lib/librte_cmdline/cmdline.h
> @@ -61,8 +61,6 @@
> #ifndef _CMDLINE_H_
> #define _CMDLINE_H_
> 
> -#include <termios.h>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> 
> /**
> @@ -75,22 +73,26 @@
> extern "C" {
> #endif
> 
> -struct cmdline {
> -	int s_in;
> -	int s_out;
> -	cmdline_parse_ctx_t *ctx;
> -	struct rdline rdl;
> -	char prompt[RDLINE_PROMPT_SIZE];
> -	struct termios oldterm;
> +#define RDLINE_PROMPT_SIZE 32
> +#define RDLINE_HISTORY_MAX_LINE 64
> +#define RDLINE_COMPLETE_SIZE 128
> +
> +enum rdline_status {
> +	RDLINE_ERROR = -1,
> +	RDLINE_INIT,
> +	RDLINE_RUNNING,
> +	RDLINE_EXITED,
> };
> 
> +struct cmdline;
> +
> +void *cmdline_ctx_get(struct cmdline *cl);
> struct cmdline *cmdline_new(cmdline_parse_ctx_t *ctx, const char *prompt, int s_in, int s_out);
> void cmdline_set_prompt(struct cmdline *cl, const char *prompt);
> void cmdline_free(struct cmdline *cl);
> void cmdline_printf(const struct cmdline *cl, const char *fmt, ...)
> 	__attribute__((format(printf,2,3)));
> int cmdline_in(struct cmdline *cl, const char *buf, int size);
> -int cmdline_write_char(struct rdline *rdl, char c);
> 
> /**
>  * This function is nonblocking equivalent of ``cmdline_interact()``. It polls
> diff --git a/lib/librte_cmdline/cmdline_cirbuf.c b/lib/librte_cmdline/cmdline_cirbuf.c
> deleted file mode 100644
> index f506f88..0000000
> --- a/lib/librte_cmdline/cmdline_cirbuf.c
> +++ /dev/null
> @@ -1,466 +0,0 @@
> -/*-
> - *   BSD LICENSE
> - *
> - *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> - *   All rights reserved.
> - *
> - *   Redistribution and use in source and binary forms, with or without
> - *   modification, are permitted provided that the following conditions
> - *   are met:
> - *
> - *     * Redistributions of source code must retain the above copyright
> - *       notice, this list of conditions and the following disclaimer.
> - *     * Redistributions in binary form must reproduce the above copyright
> - *       notice, this list of conditions and the following disclaimer in
> - *       the documentation and/or other materials provided with the
> - *       distribution.
> - *     * Neither the name of Intel Corporation nor the names of its
> - *       contributors may be used to endorse or promote products derived
> - *       from this software without specific prior written permission.
> - *
> - *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> - *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> - *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> - *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> - *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> - *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> - *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> - *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> - *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -/*
> - * Copyright (c) 2009, Olivier MATZ <zer0 at droids-corp.org>
> - * All rights reserved.
> - * Redistribution and use in source and binary forms, with or without
> - * modification, are permitted provided that the following conditions are met:
> - *
> - *     * Redistributions of source code must retain the above copyright
> - *       notice, this list of conditions and the following disclaimer.
> - *     * Redistributions in binary form must reproduce the above copyright
> - *       notice, this list of conditions and the following disclaimer in the
> - *       documentation and/or other materials provided with the distribution.
> - *     * Neither the name of the University of California, Berkeley nor the
> - *       names of its contributors may be used to endorse or promote products
> - *       derived from this software without specific prior written permission.
> - *
> - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
> - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
> - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
> - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -#include <string.h>
> -#include <errno.h>
> -#include <stdio.h>
> -
> -#include "cmdline_cirbuf.h"
> -
> -
> -int
> -cirbuf_init(struct cirbuf *cbuf, char *buf, unsigned int start, unsigned int maxlen)
> -{
> -	if (!cbuf || !buf)
> -		return -EINVAL;
> -	cbuf->maxlen = maxlen;
> -	cbuf->len = 0;
> -	cbuf->start = start;
> -	cbuf->end = start;
> -	cbuf->buf = buf;
> -	return 0;
> -}
> -
> -/* multiple add */
> -
> -int
> -cirbuf_add_buf_head(struct cirbuf *cbuf, const char *c, unsigned int n)
> -{
> -	unsigned int e;
> -
> -	if (!cbuf || !c || !n || n > CIRBUF_GET_FREELEN(cbuf))
> -		return -EINVAL;
> -
> -	e = CIRBUF_IS_EMPTY(cbuf) ? 1 : 0;
> -
> -	if (n < cbuf->start + e) {
> -		dprintf("s[%d] -> d[%d] (%d)\n", 0, cbuf->start - n + e, n);
> -		memcpy(cbuf->buf + cbuf->start - n + e, c, n);
> -	}
> -	else {
> -		dprintf("s[%d] -> d[%d] (%d)\n", + n - (cbuf->start + e), 0,
> -			cbuf->start + e);
> -		dprintf("s[%d] -> d[%d] (%d)\n", cbuf->maxlen - n +
> -			(cbuf->start + e), 0, n - (cbuf->start + e));
> -		memcpy(cbuf->buf, c  + n - (cbuf->start + e) , cbuf->start + e);
> -		memcpy(cbuf->buf + cbuf->maxlen - n + (cbuf->start + e), c,
> -		       n - (cbuf->start + e));
> -	}
> -	cbuf->len += n;
> -	cbuf->start += (cbuf->maxlen - n + e);
> -	cbuf->start %= cbuf->maxlen;
> -	return n;
> -}
> -
> -/* multiple add */
> -
> -int
> -cirbuf_add_buf_tail(struct cirbuf *cbuf, const char *c, unsigned int n)
> -{
> -	unsigned int e;
> -
> -	if (!cbuf || !c || !n || n > CIRBUF_GET_FREELEN(cbuf))
> -		return -EINVAL;
> -
> -	e = CIRBUF_IS_EMPTY(cbuf) ? 1 : 0;
> -
> -	if (n < cbuf->maxlen - cbuf->end - 1 + e) {
> -		dprintf("s[%d] -> d[%d] (%d)\n", 0, cbuf->end + !e, n);
> -		memcpy(cbuf->buf + cbuf->end + !e, c, n);
> -	}
> -	else {
> -		dprintf("s[%d] -> d[%d] (%d)\n", cbuf->end + !e, 0,
> -			cbuf->maxlen - cbuf->end - 1 + e);
> -		dprintf("s[%d] -> d[%d] (%d)\n", cbuf->maxlen - cbuf->end - 1 +
> -			e, 0, n - cbuf->maxlen + cbuf->end + 1 - e);
> -		memcpy(cbuf->buf + cbuf->end + !e, c, cbuf->maxlen -
> -		       cbuf->end - 1 + e);
> -		memcpy(cbuf->buf, c + cbuf->maxlen - cbuf->end - 1 + e,
> -		       n - cbuf->maxlen + cbuf->end + 1 - e);
> -	}
> -	cbuf->len += n;
> -	cbuf->end += n - e;
> -	cbuf->end %= cbuf->maxlen;
> -	return n;
> -}
> -
> -/* add at head */
> -
> -static inline void
> -__cirbuf_add_head(struct cirbuf * cbuf, char c)
> -{
> -	if (!CIRBUF_IS_EMPTY(cbuf)) {
> -		cbuf->start += (cbuf->maxlen - 1);
> -		cbuf->start %= cbuf->maxlen;
> -	}
> -	cbuf->buf[cbuf->start] = c;
> -	cbuf->len ++;
> -}
> -
> -int
> -cirbuf_add_head_safe(struct cirbuf * cbuf, char c)
> -{
> -	if (cbuf && !CIRBUF_IS_FULL(cbuf)) {
> -		__cirbuf_add_head(cbuf, c);
> -		return 0;
> -	}
> -	return -EINVAL;
> -}
> -
> -void
> -cirbuf_add_head(struct cirbuf * cbuf, char c)
> -{
> -	__cirbuf_add_head(cbuf, c);
> -}
> -
> -/* add at tail */
> -
> -static inline void
> -__cirbuf_add_tail(struct cirbuf * cbuf, char c)
> -{
> -	if (!CIRBUF_IS_EMPTY(cbuf)) {
> -		cbuf->end ++;
> -		cbuf->end %= cbuf->maxlen;
> -	}
> -	cbuf->buf[cbuf->end] = c;
> -	cbuf->len ++;
> -}
> -
> -int
> -cirbuf_add_tail_safe(struct cirbuf * cbuf, char c)
> -{
> -	if (cbuf && !CIRBUF_IS_FULL(cbuf)) {
> -		__cirbuf_add_tail(cbuf, c);
> -		return 0;
> -	}
> -	return -EINVAL;
> -}
> -
> -void
> -cirbuf_add_tail(struct cirbuf * cbuf, char c)
> -{
> -	__cirbuf_add_tail(cbuf, c);
> -}
> -
> -
> -static inline void
> -__cirbuf_shift_left(struct cirbuf *cbuf)
> -{
> -	unsigned int i;
> -	char tmp = cbuf->buf[cbuf->start];
> -
> -	for (i=0 ; i<cbuf->len ; i++) {
> -		cbuf->buf[(cbuf->start+i)%cbuf->maxlen] =
> -			cbuf->buf[(cbuf->start+i+1)%cbuf->maxlen];
> -	}
> -	cbuf->buf[(cbuf->start-1+cbuf->maxlen)%cbuf->maxlen] = tmp;
> -	cbuf->start += (cbuf->maxlen - 1);
> -	cbuf->start %= cbuf->maxlen;
> -	cbuf->end += (cbuf->maxlen - 1);
> -	cbuf->end %= cbuf->maxlen;
> -}
> -
> -static inline void
> -__cirbuf_shift_right(struct cirbuf *cbuf)
> -{
> -	unsigned int i;
> -	char tmp = cbuf->buf[cbuf->end];
> -
> -	for (i=0 ; i<cbuf->len ; i++) {
> -		cbuf->buf[(cbuf->end+cbuf->maxlen-i)%cbuf->maxlen] =
> -			cbuf->buf[(cbuf->end+cbuf->maxlen-i-1)%cbuf->maxlen];
> -	}
> -	cbuf->buf[(cbuf->end+1)%cbuf->maxlen] = tmp;
> -	cbuf->start += 1;
> -	cbuf->start %= cbuf->maxlen;
> -	cbuf->end += 1;
> -	cbuf->end %= cbuf->maxlen;
> -}
> -
> -/* XXX we could do a better algorithm here... */
> -int
> -cirbuf_align_left(struct cirbuf * cbuf)
> -{
> -	if (!cbuf)
> -		return -EINVAL;
> -
> -	if (cbuf->start < cbuf->maxlen/2) {
> -		while (cbuf->start != 0) {
> -			__cirbuf_shift_left(cbuf);
> -		}
> -	}
> -	else {
> -		while (cbuf->start != 0) {
> -			__cirbuf_shift_right(cbuf);
> -		}
> -	}
> -
> -	return 0;
> -}
> -
> -/* XXX we could do a better algorithm here... */
> -int
> -cirbuf_align_right(struct cirbuf * cbuf)
> -{
> -	if (!cbuf)
> -		return -EINVAL;
> -
> -	if (cbuf->start >= cbuf->maxlen/2) {
> -		while (cbuf->end != cbuf->maxlen-1) {
> -			__cirbuf_shift_left(cbuf);
> -		}
> -	}
> -	else {
> -		while (cbuf->start != cbuf->maxlen-1) {
> -			__cirbuf_shift_right(cbuf);
> -		}
> -	}
> -
> -	return 0;
> -}
> -
> -/* buffer del */
> -
> -int
> -cirbuf_del_buf_head(struct cirbuf *cbuf, unsigned int size)
> -{
> -	if (!cbuf || !size || size > CIRBUF_GET_LEN(cbuf))
> -		return -EINVAL;
> -
> -	cbuf->len -= size;
> -	if (CIRBUF_IS_EMPTY(cbuf)) {
> -		cbuf->start += size - 1;
> -		cbuf->start %= cbuf->maxlen;
> -	}
> -	else {
> -		cbuf->start += size;
> -		cbuf->start %= cbuf->maxlen;
> -	}
> -	return 0;
> -}
> -
> -/* buffer del */
> -
> -int
> -cirbuf_del_buf_tail(struct cirbuf *cbuf, unsigned int size)
> -{
> -	if (!cbuf || !size || size > CIRBUF_GET_LEN(cbuf))
> -		return -EINVAL;
> -
> -	cbuf->len -= size;
> -	if (CIRBUF_IS_EMPTY(cbuf)) {
> -		cbuf->end  += (cbuf->maxlen - size + 1);
> -		cbuf->end %= cbuf->maxlen;
> -	}
> -	else {
> -		cbuf->end  += (cbuf->maxlen - size);
> -		cbuf->end %= cbuf->maxlen;
> -	}
> -	return 0;
> -}
> -
> -/* del at head */
> -
> -static inline void
> -__cirbuf_del_head(struct cirbuf * cbuf)
> -{
> -	cbuf->len --;
> -	if (!CIRBUF_IS_EMPTY(cbuf)) {
> -		cbuf->start ++;
> -		cbuf->start %= cbuf->maxlen;
> -	}
> -}
> -
> -int
> -cirbuf_del_head_safe(struct cirbuf * cbuf)
> -{
> -	if (cbuf && !CIRBUF_IS_EMPTY(cbuf)) {
> -		__cirbuf_del_head(cbuf);
> -		return 0;
> -	}
> -	return -EINVAL;
> -}
> -
> -void
> -cirbuf_del_head(struct cirbuf * cbuf)
> -{
> -	__cirbuf_del_head(cbuf);
> -}
> -
> -/* del at tail */
> -
> -static inline void
> -__cirbuf_del_tail(struct cirbuf * cbuf)
> -{
> -	cbuf->len --;
> -	if (!CIRBUF_IS_EMPTY(cbuf)) {
> -		cbuf->end  += (cbuf->maxlen - 1);
> -		cbuf->end %= cbuf->maxlen;
> -	}
> -}
> -
> -int
> -cirbuf_del_tail_safe(struct cirbuf * cbuf)
> -{
> -	if (cbuf && !CIRBUF_IS_EMPTY(cbuf)) {
> -		__cirbuf_del_tail(cbuf);
> -		return 0;
> -	}
> -	return -EINVAL;
> -}
> -
> -void
> -cirbuf_del_tail(struct cirbuf * cbuf)
> -{
> -	__cirbuf_del_tail(cbuf);
> -}
> -
> -/* convert to buffer */
> -
> -int
> -cirbuf_get_buf_head(struct cirbuf *cbuf, char *c, unsigned int size)
> -{
> -	unsigned int n;
> -
> -	if (!cbuf || !c)
> -		return -EINVAL;
> -
> -	n = (size < CIRBUF_GET_LEN(cbuf)) ? size : CIRBUF_GET_LEN(cbuf);
> -
> -	if (!n)
> -		return 0;
> -
> -	if (cbuf->start <= cbuf->end) {
> -		dprintf("s[%d] -> d[%d] (%d)\n", cbuf->start, 0, n);
> -		memcpy(c, cbuf->buf + cbuf->start , n);
> -	}
> -	else {
> -		/* check if we need to go from end to the beginning */
> -		if (n <= cbuf->maxlen - cbuf->start) {
> -			dprintf("s[%d] -> d[%d] (%d)\n", 0, cbuf->start, n);
> -			memcpy(c, cbuf->buf + cbuf->start , n);
> -		}
> -		else {
> -			dprintf("s[%d] -> d[%d] (%d)\n", cbuf->start, 0,
> -				cbuf->maxlen - cbuf->start);
> -			dprintf("s[%d] -> d[%d] (%d)\n", 0, cbuf->maxlen - cbuf->start,
> -				n - cbuf->maxlen + cbuf->start);
> -			memcpy(c, cbuf->buf + cbuf->start , cbuf->maxlen - cbuf->start);
> -			memcpy(c + cbuf->maxlen - cbuf->start, cbuf->buf,
> -				   n - cbuf->maxlen + cbuf->start);
> -		}
> -	}
> -	return n;
> -}
> -
> -/* convert to buffer */
> -
> -int
> -cirbuf_get_buf_tail(struct cirbuf *cbuf, char *c, unsigned int size)
> -{
> -	unsigned int n;
> -
> -	if (!cbuf || !c)
> -		return -EINVAL;
> -
> -	n = (size < CIRBUF_GET_LEN(cbuf)) ? size : CIRBUF_GET_LEN(cbuf);
> -
> -	if (!n)
> -		return 0;
> -
> -	if (cbuf->start <= cbuf->end) {
> -		dprintf("s[%d] -> d[%d] (%d)\n", cbuf->end - n + 1, 0, n);
> -		memcpy(c, cbuf->buf + cbuf->end - n + 1, n);
> -	}
> -	else {
> -		/* check if we need to go from end to the beginning */
> -		if (n <= cbuf->end + 1) {
> -			dprintf("s[%d] -> d[%d] (%d)\n", 0, cbuf->end - n + 1, n);
> -			memcpy(c, cbuf->buf + cbuf->end - n + 1, n);
> -		}
> -		else {
> -			dprintf("s[%d] -> d[%d] (%d)\n", 0,
> -				cbuf->maxlen - cbuf->start, cbuf->end + 1);
> -			dprintf("s[%d] -> d[%d] (%d)\n",
> -				cbuf->maxlen - n + cbuf->end + 1, 0, n - cbuf->end - 1);
> -			memcpy(c + cbuf->maxlen - cbuf->start,
> -					       cbuf->buf, cbuf->end + 1);
> -			memcpy(c, cbuf->buf + cbuf->maxlen - n + cbuf->end +1,
> -				   n - cbuf->end - 1);
> -		}
> -	}
> -	return n;
> -}
> -
> -/* get head or get tail */
> -
> -char
> -cirbuf_get_head(struct cirbuf * cbuf)
> -{
> -	return cbuf->buf[cbuf->start];
> -}
> -
> -/* get head or get tail */
> -
> -char
> -cirbuf_get_tail(struct cirbuf * cbuf)
> -{
> -	return cbuf->buf[cbuf->end];
> -}
> diff --git a/lib/librte_cmdline/cmdline_cirbuf.h b/lib/librte_cmdline/cmdline_cirbuf.h
> deleted file mode 100644
> index 6321dec..0000000
> --- a/lib/librte_cmdline/cmdline_cirbuf.h
> +++ /dev/null
> @@ -1,245 +0,0 @@
> -/*-
> - *   BSD LICENSE
> - *
> - *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> - *   All rights reserved.
> - *
> - *   Redistribution and use in source and binary forms, with or without
> - *   modification, are permitted provided that the following conditions
> - *   are met:
> - *
> - *     * Redistributions of source code must retain the above copyright
> - *       notice, this list of conditions and the following disclaimer.
> - *     * Redistributions in binary form must reproduce the above copyright
> - *       notice, this list of conditions and the following disclaimer in
> - *       the documentation and/or other materials provided with the
> - *       distribution.
> - *     * Neither the name of Intel Corporation nor the names of its
> - *       contributors may be used to endorse or promote products derived
> - *       from this software without specific prior written permission.
> - *
> - *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> - *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> - *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> - *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> - *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> - *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> - *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> - *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> - *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -/*
> - * Copyright (c) 2009, Olivier MATZ <zer0 at droids-corp.org>
> - * All rights reserved.
> - * Redistribution and use in source and binary forms, with or without
> - * modification, are permitted provided that the following conditions are met:
> - *
> - *     * Redistributions of source code must retain the above copyright
> - *       notice, this list of conditions and the following disclaimer.
> - *     * Redistributions in binary form must reproduce the above copyright
> - *       notice, this list of conditions and the following disclaimer in the
> - *       documentation and/or other materials provided with the distribution.
> - *     * Neither the name of the University of California, Berkeley nor the
> - *       names of its contributors may be used to endorse or promote products
> - *       derived from this software without specific prior written permission.
> - *
> - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
> - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
> - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
> - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -#ifndef _CIRBUF_H_
> -#define _CIRBUF_H_
> -
> -#ifdef __cplusplus
> -extern "C" {
> -#endif
> -
> -/**
> - * This structure is the header of a cirbuf type.
> - */
> -struct cirbuf {
> -	unsigned int maxlen;    /**< total len of the fifo (number of elements) */
> -	unsigned int start;     /**< indice of the first elt */
> -	unsigned int end;       /**< indice of the last elt */
> -	unsigned int len;       /**< current len of fifo */
> -	char *buf;
> -};
> -
> -#ifdef RTE_LIBRTE_CMDLINE_DEBUG
> -#define dprintf_(fmt, ...) printf("line %3.3d - " fmt "%.0s", __LINE__, __VA_ARGS__)
> -#define dprintf(...) dprintf_(__VA_ARGS__, "dummy")
> -#else
> -#define dprintf(...) (void)0
> -#endif
> -
> -
> -/**
> - * Init the circular buffer
> - */
> -int cirbuf_init(struct cirbuf *cbuf, char *buf, unsigned int start, unsigned int maxlen);
> -
> -
> -/**
> - * Return 1 if the circular buffer is full
> - */
> -#define CIRBUF_IS_FULL(cirbuf) ((cirbuf)->maxlen == (cirbuf)->len)
> -
> -/**
> - * Return 1 if the circular buffer is empty
> - */
> -#define CIRBUF_IS_EMPTY(cirbuf) ((cirbuf)->len == 0)
> -
> -/**
> - * return current size of the circular buffer (number of used elements)
> - */
> -#define CIRBUF_GET_LEN(cirbuf) ((cirbuf)->len)
> -
> -/**
> - * return size of the circular buffer (used + free elements)
> - */
> -#define CIRBUF_GET_MAXLEN(cirbuf) ((cirbuf)->maxlen)
> -
> -/**
> - * return the number of free elts
> - */
> -#define CIRBUF_GET_FREELEN(cirbuf) ((cirbuf)->maxlen - (cirbuf)->len)
> -
> -/**
> - * Iterator for a circular buffer
> - *   c: struct cirbuf pointer
> - *   i: an integer type internally used in the macro
> - *   e: char that takes the value for each iteration
> - */
> -#define CIRBUF_FOREACH(c, i, e)                                 \
> -	for ( i=0, e=(c)->buf[(c)->start] ;                     \
> -		i<((c)->len) ;                                  \
> -		i ++,  e=(c)->buf[((c)->start+i)%((c)->maxlen)])
> -
> -
> -/**
> - * Add a character at head of the circular buffer. Return 0 on success, or
> - * a negative value on error.
> - */
> -int cirbuf_add_head_safe(struct cirbuf *cbuf, char c);
> -
> -/**
> - * Add a character at head of the circular buffer. You _must_ check that you
> - * have enough free space in the buffer before calling this func.
> - */
> -void cirbuf_add_head(struct cirbuf *cbuf, char c);
> -
> -/**
> - * Add a character at tail of the circular buffer. Return 0 on success, or
> - * a negative value on error.
> - */
> -int cirbuf_add_tail_safe(struct cirbuf *cbuf, char c);
> -
> -/**
> - * Add a character at tail of the circular buffer. You _must_ check that you
> - * have enough free space in the buffer before calling this func.
> - */
> -void cirbuf_add_tail(struct cirbuf *cbuf, char c);
> -
> -/**
> - * Remove a char at the head of the circular buffer. Return 0 on
> - * success, or a negative value on error.
> - */
> -int cirbuf_del_head_safe(struct cirbuf *cbuf);
> -
> -/**
> - * Remove a char at the head of the circular buffer. You _must_ check
> - * that buffer is not empty before calling the function.
> - */
> -void cirbuf_del_head(struct cirbuf *cbuf);
> -
> -/**
> - * Remove a char at the tail of the circular buffer. Return 0 on
> - * success, or a negative value on error.
> - */
> -int cirbuf_del_tail_safe(struct cirbuf *cbuf);
> -
> -/**
> - * Remove a char at the tail of the circular buffer. You _must_ check
> - * that buffer is not empty before calling the function.
> - */
> -void cirbuf_del_tail(struct cirbuf *cbuf);
> -
> -/**
> - * Return the head of the circular buffer. You _must_ check that
> - * buffer is not empty before calling the function.
> - */
> -char cirbuf_get_head(struct cirbuf *cbuf);
> -
> -/**
> - * Return the tail of the circular buffer. You _must_ check that
> - * buffer is not empty before calling the function.
> - */
> -char cirbuf_get_tail(struct cirbuf *cbuf);
> -
> -/**
> - * Add a buffer at head of the circular buffer. 'c' is a pointer to a
> - * buffer, and n is the number of char to add. Return the number of
> - * copied bytes on success, or a negative value on error.
> - */
> -int cirbuf_add_buf_head(struct cirbuf *cbuf, const char *c, unsigned int n);
> -
> -/**
> - * Add a buffer at tail of the circular buffer. 'c' is a pointer to a
> - * buffer, and n is the number of char to add. Return the number of
> - * copied bytes on success, or a negative value on error.
> - */
> -int cirbuf_add_buf_tail(struct cirbuf *cbuf, const char *c, unsigned int n);
> -
> -/**
> - * Remove chars at the head of the circular buffer. Return 0 on
> - * success, or a negative value on error.
> - */
> -int cirbuf_del_buf_head(struct cirbuf *cbuf, unsigned int size);
> -
> -/**
> - * Remove chars at the tail of the circular buffer. Return 0 on
> - * success, or a negative value on error.
> - */
> -int cirbuf_del_buf_tail(struct cirbuf *cbuf, unsigned int size);
> -
> -/**
> - * Copy a maximum of 'size' characters from the head of the circular
> - * buffer to a flat one pointed by 'c'. Return the number of copied
> - * chars.
> - */
> -int cirbuf_get_buf_head(struct cirbuf *cbuf, char *c, unsigned int size);
> -
> -/**
> - * Copy a maximum of 'size' characters from the tail of the circular
> - * buffer to a flat one pointed by 'c'. Return the number of copied
> - * chars.
> - */
> -int cirbuf_get_buf_tail(struct cirbuf *cbuf, char *c, unsigned int size);
> -
> -
> -/**
> - * Set the start of the data to the index 0 of the internal buffer.
> - */
> -int cirbuf_align_left(struct cirbuf *cbuf);
> -
> -/**
> - * Set the end of the data to the last index of the internal buffer.
> - */
> -int cirbuf_align_right(struct cirbuf *cbuf);
> -
> -#ifdef __cplusplus
> -}
> -#endif
> -
> -#endif /* _CIRBUF_H_ */
> diff --git a/lib/librte_cmdline/cmdline_parse.c b/lib/librte_cmdline/cmdline_parse.c
> index 3e12ee5..0cc0b57 100644
> --- a/lib/librte_cmdline/cmdline_parse.c
> +++ b/lib/librte_cmdline/cmdline_parse.c
> @@ -70,7 +70,6 @@
> 
> #include <rte_string_fns.h>
> 
> -#include "cmdline_rdline.h"
> #include "cmdline_parse.h"
> #include "cmdline.h"
> 
> @@ -267,7 +266,7 @@ cmdline_parse(struct cmdline *cl, const char * buf)
> 	if (!cl || !buf)
> 		return CMDLINE_PARSE_BAD_ARGS;
> 
> -	ctx = cl->ctx;
> +	ctx = cmdline_ctx_get(cl);
> 
> 	/*
> 	 * - look if the buffer contains at least one line
> @@ -386,7 +385,7 @@ cmdline_complete(struct cmdline *cl, const char *buf, int *state,
> 	if (!cl || !buf || !state || !dst)
> 		return -1;
> 
> -	ctx = cl->ctx;
> +	ctx = cmdline_ctx_get(cl);
> 
> 	debug_printf("%s called\n", __func__);
> 	memset(&token_hdr, 0, sizeof(token_hdr));
> @@ -398,7 +397,7 @@ cmdline_complete(struct cmdline *cl, const char *buf, int *state,
> 		if (isblank2(buf[i]) && !isblank2(buf[i+1]))
> 			partial_tok = buf+i+1;
> 	}
> -	partial_tok_len = strnlen(partial_tok, RDLINE_BUF_SIZE);
> +	partial_tok_len = strlen(partial_tok);
> 
> 	/* first call -> do a first pass */
> 	if (*state <= 0) {
> diff --git a/lib/librte_cmdline/cmdline_rdline.c b/lib/librte_cmdline/cmdline_rdline.c
> deleted file mode 100644
> index 1ef2258..0000000
> --- a/lib/librte_cmdline/cmdline_rdline.c
> +++ /dev/null
> @@ -1,697 +0,0 @@
> -/*-
> - *   BSD LICENSE
> - *
> - *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> - *   All rights reserved.
> - *
> - *   Redistribution and use in source and binary forms, with or without
> - *   modification, are permitted provided that the following conditions
> - *   are met:
> - *
> - *     * Redistributions of source code must retain the above copyright
> - *       notice, this list of conditions and the following disclaimer.
> - *     * Redistributions in binary form must reproduce the above copyright
> - *       notice, this list of conditions and the following disclaimer in
> - *       the documentation and/or other materials provided with the
> - *       distribution.
> - *     * Neither the name of Intel Corporation nor the names of its
> - *       contributors may be used to endorse or promote products derived
> - *       from this software without specific prior written permission.
> - *
> - *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> - *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> - *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> - *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> - *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> - *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> - *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> - *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> - *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -/*
> - * Copyright (c) 2009, Olivier MATZ <zer0 at droids-corp.org>
> - * All rights reserved.
> - * Redistribution and use in source and binary forms, with or without
> - * modification, are permitted provided that the following conditions are met:
> - *
> - *     * Redistributions of source code must retain the above copyright
> - *       notice, this list of conditions and the following disclaimer.
> - *     * Redistributions in binary form must reproduce the above copyright
> - *       notice, this list of conditions and the following disclaimer in the
> - *       documentation and/or other materials provided with the distribution.
> - *     * Neither the name of the University of California, Berkeley nor the
> - *       names of its contributors may be used to endorse or promote products
> - *       derived from this software without specific prior written permission.
> - *
> - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
> - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
> - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
> - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -#include <stdlib.h>
> -#include <stdio.h>
> -#include <stdint.h>
> -#include <string.h>
> -#include <stdarg.h>
> -#include <errno.h>
> -#include <ctype.h>
> -
> -#include "cmdline_cirbuf.h"
> -#include "cmdline_rdline.h"
> -
> -static void rdline_puts(struct rdline *rdl, const char *buf);
> -static void rdline_miniprintf(struct rdline *rdl,
> -			      const char *buf, unsigned int val);
> -
> -static void rdline_remove_old_history_item(struct rdline *rdl);
> -static void rdline_remove_first_history_item(struct rdline *rdl);
> -static unsigned int rdline_get_history_size(struct rdline *rdl);
> -
> -
> -/* isblank() needs _XOPEN_SOURCE >= 600 || _ISOC99_SOURCE, so use our
> - * own. */
> -static int
> -isblank2(char c)
> -{
> -	if (c == ' ' ||
> -	    c == '\t' )
> -		return 1;
> -	return 0;
> -}
> -
> -int
> -rdline_init(struct rdline *rdl,
> -		 rdline_write_char_t *write_char,
> -		 rdline_validate_t *validate,
> -		 rdline_complete_t *complete)
> -{
> -	if (!rdl || !write_char || !validate || !complete)
> -		return -EINVAL;
> -	memset(rdl, 0, sizeof(*rdl));
> -	rdl->validate = validate;
> -	rdl->complete = complete;
> -	rdl->write_char = write_char;
> -	rdl->status = RDLINE_INIT;
> -	return cirbuf_init(&rdl->history, rdl->history_buf, 0, RDLINE_HISTORY_BUF_SIZE);
> -}
> -
> -void
> -rdline_newline(struct rdline *rdl, const char *prompt)
> -{
> -	unsigned int i;
> -
> -	if (!rdl || !prompt)
> -		return;
> -
> -	vt100_init(&rdl->vt100);
> -	cirbuf_init(&rdl->left, rdl->left_buf, 0, RDLINE_BUF_SIZE);
> -	cirbuf_init(&rdl->right, rdl->right_buf, 0, RDLINE_BUF_SIZE);
> -
> -	rdl->prompt_size = strnlen(prompt, RDLINE_PROMPT_SIZE-1);
> -	if (prompt != rdl->prompt)
> -		memcpy(rdl->prompt, prompt, rdl->prompt_size);
> -	rdl->prompt[RDLINE_PROMPT_SIZE-1] = '\0';
> -
> -	for (i=0 ; i<rdl->prompt_size ; i++)
> -		rdl->write_char(rdl, rdl->prompt[i]);
> -	rdl->status = RDLINE_RUNNING;
> -
> -	rdl->history_cur_line = -1;
> -}
> -
> -void
> -rdline_stop(struct rdline *rdl)
> -{
> -	if (!rdl)
> -		return;
> -	rdl->status = RDLINE_INIT;
> -}
> -
> -void
> -rdline_quit(struct rdline *rdl)
> -{
> -	if (!rdl)
> -		return;
> -	rdl->status = RDLINE_EXITED;
> -}
> -
> -void
> -rdline_restart(struct rdline *rdl)
> -{
> -	if (!rdl)
> -		return;
> -	rdl->status = RDLINE_RUNNING;
> -}
> -
> -void
> -rdline_reset(struct rdline *rdl)
> -{
> -	if (!rdl)
> -		return;
> -	vt100_init(&rdl->vt100);
> -	cirbuf_init(&rdl->left, rdl->left_buf, 0, RDLINE_BUF_SIZE);
> -	cirbuf_init(&rdl->right, rdl->right_buf, 0, RDLINE_BUF_SIZE);
> -
> -	rdl->status = RDLINE_RUNNING;
> -
> -	rdl->history_cur_line = -1;
> -}
> -
> -const char *
> -rdline_get_buffer(struct rdline *rdl)
> -{
> -	if (!rdl)
> -		return NULL;
> -	unsigned int len_l, len_r;
> -	cirbuf_align_left(&rdl->left);
> -	cirbuf_align_left(&rdl->right);
> -
> -	len_l = CIRBUF_GET_LEN(&rdl->left);
> -	len_r = CIRBUF_GET_LEN(&rdl->right);
> -	memcpy(rdl->left_buf+len_l, rdl->right_buf, len_r);
> -
> -	rdl->left_buf[len_l + len_r] = '\n';
> -	rdl->left_buf[len_l + len_r + 1] = '\0';
> -	return rdl->left_buf;
> -}
> -
> -static void
> -display_right_buffer(struct rdline *rdl, int force)
> -{
> -	unsigned int i;
> -	char tmp;
> -
> -	if (!force && CIRBUF_IS_EMPTY(&rdl->right))
> -		return;
> -
> -	rdline_puts(rdl, vt100_clear_right);
> -	CIRBUF_FOREACH(&rdl->right, i, tmp) {
> -		rdl->write_char(rdl, tmp);
> -	}
> -	if (!CIRBUF_IS_EMPTY(&rdl->right))
> -		rdline_miniprintf(rdl, vt100_multi_left,
> -				  CIRBUF_GET_LEN(&rdl->right));
> -}
> -
> -void
> -rdline_redisplay(struct rdline *rdl)
> -{
> -	unsigned int i;
> -	char tmp;
> -
> -	if (!rdl)
> -		return;
> -
> -	rdline_puts(rdl, vt100_home);
> -	for (i=0 ; i<rdl->prompt_size ; i++)
> -		rdl->write_char(rdl, rdl->prompt[i]);
> -	CIRBUF_FOREACH(&rdl->left, i, tmp) {
> -		rdl->write_char(rdl, tmp);
> -	}
> -	display_right_buffer(rdl, 1);
> -}
> -
> -int
> -rdline_char_in(struct rdline *rdl, char c)
> -{
> -	unsigned int i;
> -	int cmd;
> -	char tmp;
> -	char *buf;
> -
> -	if (!rdl)
> -		return -EINVAL;
> -
> -	if (rdl->status == RDLINE_EXITED)
> -		return RDLINE_RES_EXITED;
> -	if (rdl->status != RDLINE_RUNNING)
> -		return RDLINE_RES_NOT_RUNNING;
> -
> -	cmd = vt100_parser(&rdl->vt100, c);
> -	if (cmd == -2)
> -		return RDLINE_RES_SUCCESS;
> -
> -	if (cmd >= 0) {
> -		switch (cmd) {
> -		/* move caret 1 char to the left */
> -		case CMDLINE_KEY_CTRL_B:
> -		case CMDLINE_KEY_LEFT_ARR:
> -			if (CIRBUF_IS_EMPTY(&rdl->left))
> -				break;
> -			tmp = cirbuf_get_tail(&rdl->left);
> -			cirbuf_del_tail(&rdl->left);
> -			cirbuf_add_head(&rdl->right, tmp);
> -			rdline_puts(rdl, vt100_left_arr);
> -			break;
> -
> -		/* move caret 1 char to the right */
> -		case CMDLINE_KEY_CTRL_F:
> -		case CMDLINE_KEY_RIGHT_ARR:
> -			if (CIRBUF_IS_EMPTY(&rdl->right))
> -				break;
> -			tmp = cirbuf_get_head(&rdl->right);
> -			cirbuf_del_head(&rdl->right);
> -			cirbuf_add_tail(&rdl->left, tmp);
> -			rdline_puts(rdl, vt100_right_arr);
> -			break;
> -
> -		/* move caret 1 word to the left */
> -		/* keyboard equivalent: Alt+B */
> -		case CMDLINE_KEY_WLEFT:
> -			while (! CIRBUF_IS_EMPTY(&rdl->left) &&
> -			       (tmp = cirbuf_get_tail(&rdl->left)) &&
> -			       isblank2(tmp)) {
> -				rdline_puts(rdl, vt100_left_arr);
> -				cirbuf_del_tail(&rdl->left);
> -				cirbuf_add_head(&rdl->right, tmp);
> -			}
> -			while (! CIRBUF_IS_EMPTY(&rdl->left) &&
> -			       (tmp = cirbuf_get_tail(&rdl->left)) &&
> -			       !isblank2(tmp)) {
> -				rdline_puts(rdl, vt100_left_arr);
> -				cirbuf_del_tail(&rdl->left);
> -				cirbuf_add_head(&rdl->right, tmp);
> -			}
> -			break;
> -
> -		/* move caret 1 word to the right */
> -		/* keyboard equivalent: Alt+F */
> -		case CMDLINE_KEY_WRIGHT:
> -			while (! CIRBUF_IS_EMPTY(&rdl->right) &&
> -			       (tmp = cirbuf_get_head(&rdl->right)) &&
> -			       isblank2(tmp)) {
> -				rdline_puts(rdl, vt100_right_arr);
> -				cirbuf_del_head(&rdl->right);
> -				cirbuf_add_tail(&rdl->left, tmp);
> -			}
> -			while (! CIRBUF_IS_EMPTY(&rdl->right) &&
> -			       (tmp = cirbuf_get_head(&rdl->right)) &&
> -			       !isblank2(tmp)) {
> -				rdline_puts(rdl, vt100_right_arr);
> -				cirbuf_del_head(&rdl->right);
> -				cirbuf_add_tail(&rdl->left, tmp);
> -			}
> -			break;
> -
> -		/* move caret to the left */
> -		case CMDLINE_KEY_CTRL_A:
> -			if (CIRBUF_IS_EMPTY(&rdl->left))
> -				break;
> -			rdline_miniprintf(rdl, vt100_multi_left,
> -						CIRBUF_GET_LEN(&rdl->left));
> -			while (! CIRBUF_IS_EMPTY(&rdl->left)) {
> -				tmp = cirbuf_get_tail(&rdl->left);
> -				cirbuf_del_tail(&rdl->left);
> -				cirbuf_add_head(&rdl->right, tmp);
> -			}
> -			break;
> -
> -		/* move caret to the right */
> -		case CMDLINE_KEY_CTRL_E:
> -			if (CIRBUF_IS_EMPTY(&rdl->right))
> -				break;
> -			rdline_miniprintf(rdl, vt100_multi_right,
> -						CIRBUF_GET_LEN(&rdl->right));
> -			while (! CIRBUF_IS_EMPTY(&rdl->right)) {
> -				tmp = cirbuf_get_head(&rdl->right);
> -				cirbuf_del_head(&rdl->right);
> -				cirbuf_add_tail(&rdl->left, tmp);
> -			}
> -			break;
> -
> -		/* delete 1 char from the left */
> -		case CMDLINE_KEY_BKSPACE:
> -			if(!cirbuf_del_tail_safe(&rdl->left)) {
> -				rdline_puts(rdl, vt100_bs);
> -				display_right_buffer(rdl, 1);
> -			}
> -			break;
> -
> -		/* delete 1 char from the right */
> -		case CMDLINE_KEY_SUPPR:
> -		case CMDLINE_KEY_CTRL_D:
> -			if (cmd == CMDLINE_KEY_CTRL_D &&
> -			    CIRBUF_IS_EMPTY(&rdl->left) &&
> -			    CIRBUF_IS_EMPTY(&rdl->right)) {
> -				return RDLINE_RES_EOF;
> -			}
> -			if (!cirbuf_del_head_safe(&rdl->right)) {
> -				display_right_buffer(rdl, 1);
> -			}
> -			break;
> -
> -		/* delete 1 word from the left */
> -		case CMDLINE_KEY_META_BKSPACE:
> -		case CMDLINE_KEY_CTRL_W:
> -			while (! CIRBUF_IS_EMPTY(&rdl->left) && isblank2(cirbuf_get_tail(&rdl->left))) {
> -				rdline_puts(rdl, vt100_bs);
> -				cirbuf_del_tail(&rdl->left);
> -			}
> -			while (! CIRBUF_IS_EMPTY(&rdl->left) && !isblank2(cirbuf_get_tail(&rdl->left))) {
> -				rdline_puts(rdl, vt100_bs);
> -				cirbuf_del_tail(&rdl->left);
> -			}
> -			display_right_buffer(rdl, 1);
> -			break;
> -
> -		/* delete 1 word from the right */
> -		case CMDLINE_KEY_META_D:
> -			while (! CIRBUF_IS_EMPTY(&rdl->right) && isblank2(cirbuf_get_head(&rdl->right)))
> -				cirbuf_del_head(&rdl->right);
> -			while (! CIRBUF_IS_EMPTY(&rdl->right) && !isblank2(cirbuf_get_head(&rdl->right)))
> -				cirbuf_del_head(&rdl->right);
> -			display_right_buffer(rdl, 1);
> -			break;
> -
> -		/* set kill buffer to contents on the right side of caret */
> -		case CMDLINE_KEY_CTRL_K:
> -			cirbuf_get_buf_head(&rdl->right, rdl->kill_buf, RDLINE_BUF_SIZE);
> -			rdl->kill_size = CIRBUF_GET_LEN(&rdl->right);
> -			cirbuf_del_buf_head(&rdl->right, rdl->kill_size);
> -			rdline_puts(rdl, vt100_clear_right);
> -			break;
> -
> -		/* paste contents of kill buffer to the left side of caret */
> -		case CMDLINE_KEY_CTRL_Y:
> -			i=0;
> -			while(CIRBUF_GET_LEN(&rdl->right) + CIRBUF_GET_LEN(&rdl->left) <
> -			      RDLINE_BUF_SIZE &&
> -			      i < rdl->kill_size) {
> -				cirbuf_add_tail(&rdl->left, rdl->kill_buf[i]);
> -				rdl->write_char(rdl, rdl->kill_buf[i]);
> -				i++;
> -			}
> -			display_right_buffer(rdl, 0);
> -			break;
> -
> -		/* clear and newline */
> -		case CMDLINE_KEY_CTRL_C:
> -			rdline_puts(rdl, "\r\n");
> -			rdline_newline(rdl, rdl->prompt);
> -			break;
> -
> -		/* redisplay (helps when prompt is lost in other output) */
> -		case CMDLINE_KEY_CTRL_L:
> -			rdline_redisplay(rdl);
> -			break;
> -
> -		/* autocomplete */
> -		case CMDLINE_KEY_TAB:
> -		case CMDLINE_KEY_HELP:
> -			cirbuf_align_left(&rdl->left);
> -			rdl->left_buf[CIRBUF_GET_LEN(&rdl->left)] = '\0';
> -			if (rdl->complete) {
> -				char tmp_buf[BUFSIZ];
> -				int complete_state;
> -				int ret;
> -				unsigned int tmp_size;
> -
> -				if (cmd == CMDLINE_KEY_TAB)
> -					complete_state = 0;
> -				else
> -					complete_state = -1;
> -
> -				/* see in parse.h for help on complete() */
> -				ret = rdl->complete(rdl, rdl->left_buf,
> -						    tmp_buf, sizeof(tmp_buf),
> -						    &complete_state);
> -				/* no completion or error */
> -				if (ret <= 0) {
> -					return RDLINE_RES_COMPLETE;
> -				}
> -
> -				tmp_size = strnlen(tmp_buf, sizeof(tmp_buf));
> -				/* add chars */
> -				if (ret == RDLINE_RES_COMPLETE) {
> -					i=0;
> -					while(CIRBUF_GET_LEN(&rdl->right) + CIRBUF_GET_LEN(&rdl->left) <
> -					      RDLINE_BUF_SIZE &&
> -					      i < tmp_size) {
> -						cirbuf_add_tail(&rdl->left, tmp_buf[i]);
> -						rdl->write_char(rdl, tmp_buf[i]);
> -						i++;
> -					}
> -					display_right_buffer(rdl, 1);
> -					return RDLINE_RES_COMPLETE; /* ?? */
> -				}
> -
> -				/* choice */
> -				rdline_puts(rdl, "\r\n");
> -				while (ret) {
> -					rdl->write_char(rdl, ' ');
> -					for (i=0 ; tmp_buf[i] ; i++)
> -						rdl->write_char(rdl, tmp_buf[i]);
> -					rdline_puts(rdl, "\r\n");
> -					ret = rdl->complete(rdl, rdl->left_buf,
> -							    tmp_buf, sizeof(tmp_buf),
> -							    &complete_state);
> -				}
> -
> -				rdline_redisplay(rdl);
> -			}
> -			return RDLINE_RES_COMPLETE;
> -
> -		/* complete buffer */
> -		case CMDLINE_KEY_RETURN:
> -		case CMDLINE_KEY_RETURN2:
> -			rdline_get_buffer(rdl);
> -			rdl->status = RDLINE_INIT;
> -			rdline_puts(rdl, "\r\n");
> -			if (rdl->history_cur_line != -1)
> -				rdline_remove_first_history_item(rdl);
> -
> -			if (rdl->validate)
> -				rdl->validate(rdl, rdl->left_buf, CIRBUF_GET_LEN(&rdl->left)+2);
> -			/* user may have stopped rdline */
> -			if (rdl->status == RDLINE_EXITED)
> -				return RDLINE_RES_EXITED;
> -			return RDLINE_RES_VALIDATED;
> -
> -		/* previous element in history */
> -		case CMDLINE_KEY_UP_ARR:
> -		case CMDLINE_KEY_CTRL_P:
> -			if (rdl->history_cur_line == 0) {
> -				rdline_remove_first_history_item(rdl);
> -			}
> -			if (rdl->history_cur_line <= 0) {
> -				rdline_add_history(rdl, rdline_get_buffer(rdl));
> -				rdl->history_cur_line = 0;
> -			}
> -
> -			buf = rdline_get_history_item(rdl, rdl->history_cur_line + 1);
> -			if (!buf)
> -				break;
> -
> -			rdl->history_cur_line ++;
> -			vt100_init(&rdl->vt100);
> -			cirbuf_init(&rdl->left, rdl->left_buf, 0, RDLINE_BUF_SIZE);
> -			cirbuf_init(&rdl->right, rdl->right_buf, 0, RDLINE_BUF_SIZE);
> -			cirbuf_add_buf_tail(&rdl->left, buf, strnlen(buf, RDLINE_BUF_SIZE));
> -			rdline_redisplay(rdl);
> -			break;
> -
> -		/* next element in history */
> -		case CMDLINE_KEY_DOWN_ARR:
> -		case CMDLINE_KEY_CTRL_N:
> -			if (rdl->history_cur_line - 1 < 0)
> -				break;
> -
> -			rdl->history_cur_line --;
> -			buf = rdline_get_history_item(rdl, rdl->history_cur_line);
> -			if (!buf)
> -				break;
> -			vt100_init(&rdl->vt100);
> -			cirbuf_init(&rdl->left, rdl->left_buf, 0, RDLINE_BUF_SIZE);
> -			cirbuf_init(&rdl->right, rdl->right_buf, 0, RDLINE_BUF_SIZE);
> -			cirbuf_add_buf_tail(&rdl->left, buf, strnlen(buf, RDLINE_BUF_SIZE));
> -			rdline_redisplay(rdl);
> -
> -			break;
> -
> -
> -		default:
> -			break;
> -		}
> -
> -		return RDLINE_RES_SUCCESS;
> -	}
> -
> -	if (!isprint((int)c))
> -		return RDLINE_RES_SUCCESS;
> -
> -	/* standard chars */
> -	if (CIRBUF_GET_LEN(&rdl->left) + CIRBUF_GET_LEN(&rdl->right) >= RDLINE_BUF_SIZE)
> -		return RDLINE_RES_SUCCESS;
> -
> -	if (cirbuf_add_tail_safe(&rdl->left, c))
> -		return RDLINE_RES_SUCCESS;
> -
> -	rdl->write_char(rdl, c);
> -	display_right_buffer(rdl, 0);
> -
> -	return RDLINE_RES_SUCCESS;
> -}
> -
> -
> -/* HISTORY */
> -
> -static void
> -rdline_remove_old_history_item(struct rdline * rdl)
> -{
> -	char tmp;
> -
> -	while (! CIRBUF_IS_EMPTY(&rdl->history) ) {
> -		tmp = cirbuf_get_head(&rdl->history);
> -		cirbuf_del_head(&rdl->history);
> -		if (!tmp)
> -			break;
> -	}
> -}
> -
> -static void
> -rdline_remove_first_history_item(struct rdline * rdl)
> -{
> -	char tmp;
> -
> -	if ( CIRBUF_IS_EMPTY(&rdl->history) ) {
> -		return;
> -	}
> -	else {
> -		cirbuf_del_tail(&rdl->history);
> -	}
> -
> -	while (! CIRBUF_IS_EMPTY(&rdl->history) ) {
> -		tmp = cirbuf_get_tail(&rdl->history);
> -		if (!tmp)
> -			break;
> -		cirbuf_del_tail(&rdl->history);
> -	}
> -}
> -
> -static unsigned int
> -rdline_get_history_size(struct rdline * rdl)
> -{
> -	unsigned int i, tmp, ret=0;
> -
> -	CIRBUF_FOREACH(&rdl->history, i, tmp) {
> -		if (tmp == 0)
> -			ret ++;
> -	}
> -
> -	return ret;
> -}
> -
> -char *
> -rdline_get_history_item(struct rdline * rdl, unsigned int idx)
> -{
> -	unsigned int len, i, tmp;
> -
> -	if (!rdl)
> -		return NULL;
> -
> -	len = rdline_get_history_size(rdl);
> -	if ( idx >= len ) {
> -		return NULL;
> -	}
> -
> -	cirbuf_align_left(&rdl->history);
> -
> -	CIRBUF_FOREACH(&rdl->history, i, tmp) {
> -		if ( idx == len - 1) {
> -			return rdl->history_buf + i;
> -		}
> -		if (tmp == 0)
> -			len --;
> -	}
> -
> -	return NULL;
> -}
> -
> -int
> -rdline_add_history(struct rdline * rdl, const char * buf)
> -{
> -	unsigned int len, i;
> -
> -	if (!rdl || !buf)
> -		return -EINVAL;
> -
> -	len = strnlen(buf, RDLINE_BUF_SIZE);
> -	for (i=0; i<len ; i++) {
> -		if (buf[i] == '\n') {
> -			len = i;
> -			break;
> -		}
> -	}
> -
> -	if ( len >= RDLINE_HISTORY_BUF_SIZE )
> -		return -1;
> -
> -	while ( len >= CIRBUF_GET_FREELEN(&rdl->history) ) {
> -		rdline_remove_old_history_item(rdl);
> -	}
> -
> -	cirbuf_add_buf_tail(&rdl->history, buf, len);
> -	cirbuf_add_tail(&rdl->history, 0);
> -
> -	return 0;
> -}
> -
> -void
> -rdline_clear_history(struct rdline * rdl)
> -{
> -	if (!rdl)
> -		return;
> -	cirbuf_init(&rdl->history, rdl->history_buf, 0, RDLINE_HISTORY_BUF_SIZE);
> -}
> -
> -
> -/* STATIC USEFUL FUNCS */
> -
> -static void
> -rdline_puts(struct rdline * rdl, const char * buf)
> -{
> -	char c;
> -	while ( (c = *(buf++)) != '\0' ) {
> -		rdl->write_char(rdl, c);
> -	}
> -}
> -
> -/* a very very basic printf with one arg and one format 'u' */
> -static void
> -rdline_miniprintf(struct rdline *rdl, const char * buf, unsigned int val)
> -{
> -	char c, started=0, div=100;
> -
> -	while ( (c=*(buf++)) ) {
> -		if (c != '%') {
> -			rdl->write_char(rdl, c);
> -			continue;
> -		}
> -		c = *(buf++);
> -		if (c != 'u') {
> -			rdl->write_char(rdl, '%');
> -			rdl->write_char(rdl, c);
> -			continue;
> -		}
> -		/* val is never more than 255 */
> -		while (div) {
> -			c = (char)(val / div);
> -			if (c || started) {
> -				rdl->write_char(rdl, (char)(c+'0'));
> -				started = 1;
> -			}
> -			val %= div;
> -			div /= 10;
> -		}
> -	}
> -}
> diff --git a/lib/librte_cmdline/cmdline_rdline.h b/lib/librte_cmdline/cmdline_rdline.h
> deleted file mode 100644
> index 72e2dad..0000000
> --- a/lib/librte_cmdline/cmdline_rdline.h
> +++ /dev/null
> @@ -1,255 +0,0 @@
> -/*-
> - *   BSD LICENSE
> - *
> - *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> - *   All rights reserved.
> - *
> - *   Redistribution and use in source and binary forms, with or without
> - *   modification, are permitted provided that the following conditions
> - *   are met:
> - *
> - *     * Redistributions of source code must retain the above copyright
> - *       notice, this list of conditions and the following disclaimer.
> - *     * Redistributions in binary form must reproduce the above copyright
> - *       notice, this list of conditions and the following disclaimer in
> - *       the documentation and/or other materials provided with the
> - *       distribution.
> - *     * Neither the name of Intel Corporation nor the names of its
> - *       contributors may be used to endorse or promote products derived
> - *       from this software without specific prior written permission.
> - *
> - *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> - *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> - *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> - *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> - *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> - *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> - *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> - *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> - *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -/*
> - * Copyright (c) 2009, Olivier MATZ <zer0 at droids-corp.org>
> - * All rights reserved.
> - * Redistribution and use in source and binary forms, with or without
> - * modification, are permitted provided that the following conditions are met:
> - *
> - *     * Redistributions of source code must retain the above copyright
> - *       notice, this list of conditions and the following disclaimer.
> - *     * Redistributions in binary form must reproduce the above copyright
> - *       notice, this list of conditions and the following disclaimer in the
> - *       documentation and/or other materials provided with the distribution.
> - *     * Neither the name of the University of California, Berkeley nor the
> - *       names of its contributors may be used to endorse or promote products
> - *       derived from this software without specific prior written permission.
> - *
> - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
> - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
> - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
> - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -#ifndef _RDLINE_H_
> -#define _RDLINE_H_
> -
> -/**
> - * This file is a small equivalent to the GNU readline library, but it
> - * was originally designed for small systems, like Atmel AVR
> - * microcontrollers (8 bits). Indeed, we don't use any malloc that is
> - * sometimes not implemented (or just not recommended) on such
> - * systems.
> - *
> - * Obviously, it does not support as many things as the GNU readline,
> - * but at least it supports some interesting features like a kill
> - * buffer and a command history.
> - *
> - * It also have a feature that does not have the GNU readline (as far
> - * as I know): we can have several instances of it running at the same
> - * time, even on a monothread program, since it works with callbacks.
> - *
> - * The lib is designed for a client-side or a server-side use:
> - * - server-side: the server receives all data from a socket, including
> - *   control chars, like arrows, tabulations, ... The client is
> - *   very simple, it can be a telnet or a minicom through a serial line.
> - * - client-side: the client receives its data through its stdin for
> - *   instance.
> - */
> -
> -#include <stdio.h>
> -#include <cmdline_cirbuf.h>
> -#include <cmdline_vt100.h>
> -
> -#ifdef __cplusplus
> -extern "C" {
> -#endif
> -
> -/* configuration */
> -#define RDLINE_BUF_SIZE 512
> -#define RDLINE_PROMPT_SIZE  32
> -#define RDLINE_VT100_BUF_SIZE  8
> -#define RDLINE_HISTORY_BUF_SIZE BUFSIZ
> -#define RDLINE_HISTORY_MAX_LINE 64
> -
> -enum rdline_status {
> -	RDLINE_INIT,
> -	RDLINE_RUNNING,
> -	RDLINE_EXITED
> -};
> -
> -struct rdline;
> -
> -typedef int (rdline_write_char_t)(struct rdline *rdl, char);
> -typedef void (rdline_validate_t)(struct rdline *rdl,
> -				 const char *buf, unsigned int size);
> -typedef int (rdline_complete_t)(struct rdline *rdl, const char *buf,
> -				char *dstbuf, unsigned int dstsize,
> -				int *state);
> -
> -struct rdline {
> -	enum rdline_status status;
> -	/* rdline bufs */
> -	struct cirbuf left;
> -	struct cirbuf right;
> -	char left_buf[RDLINE_BUF_SIZE+2]; /* reserve 2 chars for the \n\0 */
> -	char right_buf[RDLINE_BUF_SIZE];
> -
> -	char prompt[RDLINE_PROMPT_SIZE];
> -	unsigned int prompt_size;
> -
> -	char kill_buf[RDLINE_BUF_SIZE];
> -	unsigned int kill_size;
> -
> -	/* history */
> -	struct cirbuf history;
> -	char history_buf[RDLINE_HISTORY_BUF_SIZE];
> -	int history_cur_line;
> -
> -	/* callbacks and func pointers */
> -	rdline_write_char_t *write_char;
> -	rdline_validate_t *validate;
> -	rdline_complete_t *complete;
> -
> -	/* vt100 parser */
> -	struct cmdline_vt100 vt100;
> -
> -	/* opaque pointer */
> -	void *opaque;
> -};
> -
> -/**
> - * Init fields for a struct rdline. Call this only once at the beginning
> - * of your program.
> - * \param rdl A pointer to an uninitialized struct rdline
> - * \param write_char The function used by the function to write a character
> - * \param validate A pointer to the function to execute when the
> - *                 user validates the buffer.
> - * \param complete A pointer to the function to execute when the
> - *                 user completes the buffer.
> - */
> -int rdline_init(struct rdline *rdl,
> -		 rdline_write_char_t *write_char,
> -		 rdline_validate_t *validate,
> -		 rdline_complete_t *complete);
> -
> -
> -/**
> - * Init the current buffer, and display a prompt.
> - * \param rdl A pointer to a struct rdline
> - * \param prompt A string containing the prompt
> - */
> -void rdline_newline(struct rdline *rdl, const char *prompt);
> -
> -/**
> - * Call it and all received chars will be ignored.
> - * \param rdl A pointer to a struct rdline
> - */
> -void rdline_stop(struct rdline *rdl);
> -
> -/**
> - * Same than rdline_stop() except that next calls to rdline_char_in()
> - * will return RDLINE_RES_EXITED.
> - * \param rdl A pointer to a struct rdline
> - */
> -void rdline_quit(struct rdline *rdl);
> -
> -/**
> - * Restart after a call to rdline_stop() or rdline_quit()
> - * \param rdl A pointer to a struct rdline
> - */
> -void rdline_restart(struct rdline *rdl);
> -
> -/**
> - * Redisplay the current buffer
> - * \param rdl A pointer to a struct rdline
> - */
> -void rdline_redisplay(struct rdline *rdl);
> -
> -/**
> - * Reset the current buffer and setup for a new line.
> - *  \param rdl A pointer to a struct rdline
> - */
> -void rdline_reset(struct rdline *rdl);
> -
> -
> -/* return status for rdline_char_in() */
> -#define RDLINE_RES_SUCCESS       0
> -#define RDLINE_RES_VALIDATED     1
> -#define RDLINE_RES_COMPLETE      2
> -#define RDLINE_RES_NOT_RUNNING  -1
> -#define RDLINE_RES_EOF          -2
> -#define RDLINE_RES_EXITED       -3
> -
> -/**
> - * append a char to the readline buffer.
> - * Return RDLINE_RES_VALIDATE when the line has been validated.
> - * Return RDLINE_RES_COMPLETE when the user asked to complete the buffer.
> - * Return RDLINE_RES_NOT_RUNNING if it is not running.
> - * Return RDLINE_RES_EOF if EOF (ctrl-d on an empty line).
> - * Else return RDLINE_RES_SUCCESS.
> - * XXX error case when the buffer is full ?
> - *
> - * \param rdl A pointer to a struct rdline
> - * \param c The character to append
> - */
> -int rdline_char_in(struct rdline *rdl, char c);
> -
> -/**
> - * Return the current buffer, terminated by '\0'.
> - * \param rdl A pointer to a struct rdline
> - */
> -const char *rdline_get_buffer(struct rdline *rdl);
> -
> -
> -/**
> - * Add the buffer to history.
> - * return < 0 on error.
> - * \param rdl A pointer to a struct rdline
> - * \param buf A buffer that is terminated by '\0'
> - */
> -int rdline_add_history(struct rdline *rdl, const char *buf);
> -
> -/**
> - * Clear current history
> - * \param rdl A pointer to a struct rdline
> - */
> -void rdline_clear_history(struct rdline *rdl);
> -
> -/**
> - * Get the i-th history item
> - */
> -char *rdline_get_history_item(struct rdline *rdl, unsigned int i);
> -
> -#ifdef __cplusplus
> -}
> -#endif
> -
> -#endif /* _RDLINE_H_ */
> diff --git a/lib/librte_cmdline/cmdline_socket.c b/lib/librte_cmdline/cmdline_socket.c
> index 3fc243b..11524b5 100644
> --- a/lib/librte_cmdline/cmdline_socket.c
> +++ b/lib/librte_cmdline/cmdline_socket.c
> @@ -58,23 +58,18 @@
>  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>  */
> 
> -#include <stdio.h>
> -#include <string.h>
> +#include <stddef.h>
> #include <unistd.h>
> -#include <stdlib.h>
> -#include <stdarg.h>
> -#include <inttypes.h>
> #include <fcntl.h>
> -#include <termios.h>
> 
> #include "cmdline_parse.h"
> -#include "cmdline_rdline.h"
> #include "cmdline_socket.h"
> #include "cmdline.h"
> 
> struct cmdline *
> cmdline_file_new(cmdline_parse_ctx_t *ctx, const char *prompt, const char *path)
> {
> +	struct cmdline *cl;
> 	int fd;
> 
> 	/* everything else is checked in cmdline_new() */
> @@ -83,37 +78,22 @@ cmdline_file_new(cmdline_parse_ctx_t *ctx, const char *prompt, const char *path)
> 
> 	fd = open(path, O_RDONLY, 0);
> 	if (fd < 0) {
> -		dprintf("open() failed\n");
> 		return NULL;
> 	}
> -	return cmdline_new(ctx, prompt, fd, -1);
> +	cl = cmdline_new(ctx, prompt, fd, -1);
> +	/* cmdline_new() duplicates fd */
> +	close(fd);
> +	return cl;
> }
> 
> struct cmdline *
> cmdline_stdin_new(cmdline_parse_ctx_t *ctx, const char *prompt)
> {
> -	struct cmdline *cl;
> -	struct termios oldterm, term;
> -
> -	tcgetattr(0, &oldterm);
> -	memcpy(&term, &oldterm, sizeof(term));
> -	term.c_lflag &= ~(ICANON | ECHO | ISIG);
> -	tcsetattr(0, TCSANOW, &term);
> -	setbuf(stdin, NULL);
> -
> -	cl = cmdline_new(ctx, prompt, 0, 1);
> -
> -	if (cl)
> -		memcpy(&cl->oldterm, &oldterm, sizeof(term));
> -
> -	return cl;
> +	return cmdline_new(ctx, prompt, 0, 1);
> }
> 
> void
> cmdline_stdin_exit(struct cmdline *cl)
> {
> -	if (!cl)
> -		return;
> -
> -	tcsetattr(fileno(stdin), TCSANOW, &cl->oldterm);
> +	cmdline_free(cl);
> }
> diff --git a/lib/librte_cmdline/cmdline_vt100.c b/lib/librte_cmdline/cmdline_vt100.c
> deleted file mode 100644
> index a253e8b..0000000
> --- a/lib/librte_cmdline/cmdline_vt100.c
> +++ /dev/null
> @@ -1,185 +0,0 @@
> -/*-
> - *   BSD LICENSE
> - *
> - *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> - *   All rights reserved.
> - *
> - *   Redistribution and use in source and binary forms, with or without
> - *   modification, are permitted provided that the following conditions
> - *   are met:
> - *
> - *     * Redistributions of source code must retain the above copyright
> - *       notice, this list of conditions and the following disclaimer.
> - *     * Redistributions in binary form must reproduce the above copyright
> - *       notice, this list of conditions and the following disclaimer in
> - *       the documentation and/or other materials provided with the
> - *       distribution.
> - *     * Neither the name of Intel Corporation nor the names of its
> - *       contributors may be used to endorse or promote products derived
> - *       from this software without specific prior written permission.
> - *
> - *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> - *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> - *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> - *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> - *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> - *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> - *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> - *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> - *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -/*
> - * Copyright (c) 2009, Olivier MATZ <zer0 at droids-corp.org>
> - * All rights reserved.
> - * Redistribution and use in source and binary forms, with or without
> - * modification, are permitted provided that the following conditions are met:
> - *
> - *     * Redistributions of source code must retain the above copyright
> - *       notice, this list of conditions and the following disclaimer.
> - *     * Redistributions in binary form must reproduce the above copyright
> - *       notice, this list of conditions and the following disclaimer in the
> - *       documentation and/or other materials provided with the distribution.
> - *     * Neither the name of the University of California, Berkeley nor the
> - *       names of its contributors may be used to endorse or promote products
> - *       derived from this software without specific prior written permission.
> - *
> - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
> - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
> - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
> - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -#include <stdlib.h>
> -#include <stdint.h>
> -#include <stdio.h>
> -#include <string.h>
> -#include <stdarg.h>
> -#include <ctype.h>
> -#include <termios.h>
> -
> -#include "cmdline_vt100.h"
> -
> -const char *cmdline_vt100_commands[] = {
> -	vt100_up_arr,
> -	vt100_down_arr,
> -	vt100_right_arr,
> -	vt100_left_arr,
> -	"\177",
> -	"\n",
> -	"\001",
> -	"\005",
> -	"\013",
> -	"\031",
> -	"\003",
> -	"\006",
> -	"\002",
> -	vt100_suppr,
> -	vt100_tab,
> -	"\004",
> -	"\014",
> -	"\r",
> -	"\033\177",
> -	vt100_word_left,
> -	vt100_word_right,
> -	"?",
> -	"\027",
> -	"\020",
> -	"\016",
> -	"\033\144",
> -};
> -
> -void
> -vt100_init(struct cmdline_vt100 *vt)
> -{
> -	if (!vt)
> -		return;
> -	vt->state = CMDLINE_VT100_INIT;
> -}
> -
> -
> -static int
> -match_command(char *buf, unsigned int size)
> -{
> -	const char *cmd;
> -	size_t cmdlen;
> -	unsigned int i = 0;
> -
> -	for (i=0 ; i<sizeof(cmdline_vt100_commands)/sizeof(const char *) ; i++) {
> -		cmd = *(cmdline_vt100_commands + i);
> -
> -		cmdlen = strnlen(cmd, CMDLINE_VT100_BUF_SIZE);
> -		if (size == cmdlen &&
> -		    !strncmp(buf, cmd, cmdlen)) {
> -			return i;
> -		}
> -	}
> -
> -	return -1;
> -}
> -
> -int
> -vt100_parser(struct cmdline_vt100 *vt, char ch)
> -{
> -	unsigned int size;
> -	uint8_t c = (uint8_t) ch;
> -
> -	if (!vt)
> -		return -1;
> -
> -	if (vt->bufpos >= CMDLINE_VT100_BUF_SIZE) {
> -		vt->state = CMDLINE_VT100_INIT;
> -		vt->bufpos = 0;
> -	}
> -
> -	vt->buf[vt->bufpos++] = c;
> -	size = vt->bufpos;
> -
> -	switch (vt->state) {
> -	case CMDLINE_VT100_INIT:
> -		if (c == 033) {
> -			vt->state = CMDLINE_VT100_ESCAPE;
> -		}
> -		else {
> -			vt->bufpos = 0;
> -			goto match_command;
> -		}
> -		break;
> -
> -	case CMDLINE_VT100_ESCAPE:
> -		if (c == 0133) {
> -			vt->state = CMDLINE_VT100_ESCAPE_CSI;
> -		}
> -		else if (c >= 060 && c <= 0177) { /* XXX 0177 ? */
> -			vt->bufpos = 0;
> -			vt->state = CMDLINE_VT100_INIT;
> -			goto match_command;
> -		}
> -		break;
> -
> -	case CMDLINE_VT100_ESCAPE_CSI:
> -		if (c >= 0100 && c <= 0176) {
> -			vt->bufpos = 0;
> -			vt->state = CMDLINE_VT100_INIT;
> -			goto match_command;
> -		}
> -		break;
> -
> -	default:
> -		vt->bufpos = 0;
> -		break;
> -	}
> -
> -	return -2;
> -
> - match_command:
> -	return match_command(vt->buf, size);
> -}
> diff --git a/lib/librte_cmdline/cmdline_vt100.h b/lib/librte_cmdline/cmdline_vt100.h
> deleted file mode 100644
> index 963add8..0000000
> --- a/lib/librte_cmdline/cmdline_vt100.h
> +++ /dev/null
> @@ -1,153 +0,0 @@
> -/*-
> - *   BSD LICENSE
> - *
> - *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> - *   All rights reserved.
> - *
> - *   Redistribution and use in source and binary forms, with or without
> - *   modification, are permitted provided that the following conditions
> - *   are met:
> - *
> - *     * Redistributions of source code must retain the above copyright
> - *       notice, this list of conditions and the following disclaimer.
> - *     * Redistributions in binary form must reproduce the above copyright
> - *       notice, this list of conditions and the following disclaimer in
> - *       the documentation and/or other materials provided with the
> - *       distribution.
> - *     * Neither the name of Intel Corporation nor the names of its
> - *       contributors may be used to endorse or promote products derived
> - *       from this software without specific prior written permission.
> - *
> - *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> - *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> - *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> - *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> - *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> - *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> - *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> - *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> - *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -/*
> - * Copyright (c) 2009, Olivier MATZ <zer0 at droids-corp.org>
> - * All rights reserved.
> - * Redistribution and use in source and binary forms, with or without
> - * modification, are permitted provided that the following conditions are met:
> - *
> - *     * Redistributions of source code must retain the above copyright
> - *       notice, this list of conditions and the following disclaimer.
> - *     * Redistributions in binary form must reproduce the above copyright
> - *       notice, this list of conditions and the following disclaimer in the
> - *       documentation and/or other materials provided with the distribution.
> - *     * Neither the name of the University of California, Berkeley nor the
> - *       names of its contributors may be used to endorse or promote products
> - *       derived from this software without specific prior written permission.
> - *
> - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
> - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
> - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
> - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -#ifndef _CMDLINE_VT100_H_
> -#define _CMDLINE_VT100_H_
> -
> -#include <stdint.h>
> -
> -#ifdef __cplusplus
> -extern "C" {
> -#endif
> -
> -#define vt100_bell         "\007"
> -#define vt100_bs           "\010"
> -#define vt100_bs_clear     "\010 \010"
> -#define vt100_tab          "\011"
> -#define vt100_crnl         "\012\015"
> -#define vt100_clear_right  "\033[0K"
> -#define vt100_clear_left   "\033[1K"
> -#define vt100_clear_down   "\033[0J"
> -#define vt100_clear_up     "\033[1J"
> -#define vt100_clear_line   "\033[2K"
> -#define vt100_clear_screen "\033[2J"
> -#define vt100_up_arr       "\033\133\101"
> -#define vt100_down_arr     "\033\133\102"
> -#define vt100_right_arr    "\033\133\103"
> -#define vt100_left_arr     "\033\133\104"
> -#define vt100_multi_right  "\033\133%uC"
> -#define vt100_multi_left   "\033\133%uD"
> -#define vt100_suppr        "\033\133\063\176"
> -#define vt100_home         "\033M\033E"
> -#define vt100_word_left    "\033\142"
> -#define vt100_word_right   "\033\146"
> -
> -/* Result of parsing : it must be synchronized with
> - * cmdline_vt100_commands[] in vt100.c */
> -#define CMDLINE_KEY_UP_ARR 0
> -#define CMDLINE_KEY_DOWN_ARR 1
> -#define CMDLINE_KEY_RIGHT_ARR 2
> -#define CMDLINE_KEY_LEFT_ARR 3
> -#define CMDLINE_KEY_BKSPACE 4
> -#define CMDLINE_KEY_RETURN 5
> -#define CMDLINE_KEY_CTRL_A 6
> -#define CMDLINE_KEY_CTRL_E 7
> -#define CMDLINE_KEY_CTRL_K 8
> -#define CMDLINE_KEY_CTRL_Y 9
> -#define CMDLINE_KEY_CTRL_C 10
> -#define CMDLINE_KEY_CTRL_F 11
> -#define CMDLINE_KEY_CTRL_B 12
> -#define CMDLINE_KEY_SUPPR 13
> -#define CMDLINE_KEY_TAB 14
> -#define CMDLINE_KEY_CTRL_D 15
> -#define CMDLINE_KEY_CTRL_L 16
> -#define CMDLINE_KEY_RETURN2 17
> -#define CMDLINE_KEY_META_BKSPACE 18
> -#define CMDLINE_KEY_WLEFT 19
> -#define CMDLINE_KEY_WRIGHT 20
> -#define CMDLINE_KEY_HELP 21
> -#define CMDLINE_KEY_CTRL_W 22
> -#define CMDLINE_KEY_CTRL_P 23
> -#define CMDLINE_KEY_CTRL_N 24
> -#define CMDLINE_KEY_META_D 25
> -
> -extern const char *cmdline_vt100_commands[];
> -
> -enum cmdline_vt100_parser_state {
> -	CMDLINE_VT100_INIT,
> -	CMDLINE_VT100_ESCAPE,
> -	CMDLINE_VT100_ESCAPE_CSI
> -};
> -
> -#define CMDLINE_VT100_BUF_SIZE 8
> -struct cmdline_vt100 {
> -	uint8_t bufpos;
> -	char buf[CMDLINE_VT100_BUF_SIZE];
> -	enum cmdline_vt100_parser_state state;
> -};
> -
> -/**
> - * Init
> - */
> -void vt100_init(struct cmdline_vt100 *vt);
> -
> -/**
> - * Input a new character.
> - * Return -1 if the character is not part of a control sequence
> - * Return -2 if c is not the last char of a control sequence
> - * Else return the index in vt100_commands[]
> - */
> -int vt100_parser(struct cmdline_vt100 *vt, char c);
> -
> -#ifdef __cplusplus
> -}
> -#endif
> -
> -#endif
> diff --git a/lib/librte_cmdline/rte_cmdline_version.map b/lib/librte_cmdline/rte_cmdline_version.map
> index 04bcb38..3133199 100644
> --- a/lib/librte_cmdline/rte_cmdline_version.map
> +++ b/lib/librte_cmdline/rte_cmdline_version.map
> @@ -1,25 +1,6 @@
> DPDK_2.0 {
> 	global:
> 
> -	cirbuf_add_buf_head;
> -	cirbuf_add_buf_tail;
> -	cirbuf_add_head;
> -	cirbuf_add_head_safe;
> -	cirbuf_add_tail;
> -	cirbuf_add_tail_safe;
> -	cirbuf_align_left;
> -	cirbuf_align_right;
> -	cirbuf_del_buf_head;
> -	cirbuf_del_buf_tail;
> -	cirbuf_del_head;
> -	cirbuf_del_head_safe;
> -	cirbuf_del_tail;
> -	cirbuf_del_tail_safe;
> -	cirbuf_get_buf_head;
> -	cirbuf_get_buf_tail;
> -	cirbuf_get_head;
> -	cirbuf_get_tail;
> -	cirbuf_init;
> 	cmdline_complete;
> 	cmdline_complete_get_elt_string;
> 	cmdline_complete_get_nb_string;
> @@ -50,21 +31,6 @@ DPDK_2.0 {
> 	cmdline_token_num_ops;
> 	cmdline_token_portlist_ops;
> 	cmdline_token_string_ops;
> -	cmdline_write_char;
> -	rdline_add_history;
> -	rdline_char_in;
> -	rdline_clear_history;
> -	rdline_get_buffer;
> -	rdline_get_history_item;
> -	rdline_init;
> -	rdline_newline;
> -	rdline_quit;
> -	rdline_redisplay;
> -	rdline_reset;
> -	rdline_restart;
> -	rdline_stop;
> -	vt100_init;
> -	vt100_parser;
> 
> 	local: *;
> };
> @@ -75,3 +41,10 @@ DPDK_2.1 {
> 	cmdline_poll;
> 
> } DPDK_2.0;
> +
> +DPDK_18.02 {
> +	global:
> +
> +	cmdline_ctx_get;
> +
> +} DPDK_2.1;
> diff --git a/mk/rte.app.mk b/mk/rte.app.mk
> index 6a6a745..504bb4e 100644
> --- a/mk/rte.app.mk
> +++ b/mk/rte.app.mk
> @@ -102,6 +102,8 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_RING)           += -lrte_ring
> _LDLIBS-$(CONFIG_RTE_LIBRTE_PCI)            += -lrte_pci
> _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)            += -lrte_eal
> _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += -lrte_cmdline
> +
> +_LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE)        += $(shell pkg-config --libs libedit)
> _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER)        += -lrte_reorder
> _LDLIBS-$(CONFIG_RTE_LIBRTE_SCHED)          += -lrte_sched
> 
> diff --git a/test/cmdline_test/cmdline_test.c b/test/cmdline_test/cmdline_test.c
> index 716b5f1..595efa5 100644
> --- a/test/cmdline_test/cmdline_test.c
> +++ b/test/cmdline_test/cmdline_test.c
> @@ -41,7 +41,6 @@
> #include <ctype.h>
> #include <sys/queue.h>
> 
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_socket.h>
> #include <cmdline.h>
> diff --git a/test/cmdline_test/commands.c b/test/cmdline_test/commands.c
> index 404f51a..8481af9 100644
> --- a/test/cmdline_test/commands.c
> +++ b/test/cmdline_test/commands.c
> @@ -36,7 +36,6 @@
> #include <termios.h>
> #include <inttypes.h>
> 
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_string.h>
> #include <cmdline_parse_num.h>
> @@ -306,72 +305,6 @@ cmdline_parse_inst_t cmd_ambig_2 = {
> 
> 
> 
> -/*** get_history_bufsize ***/
> -/* command that displays total space in history buffer
> - * this will be useful for testing history (to fill it up just enough to
> - * remove the last entry, we need to know how big it is).
> - */
> -
> -struct cmd_get_history_bufsize_result {
> -	cmdline_fixed_string_t str;
> -};
> -
> -static void
> -cmd_get_history_bufsize_parsed(__attribute__((unused)) void *parsed_result,
> -		struct cmdline *cl,
> -		__attribute__((unused)) void *data)
> -{
> -	cmdline_printf(cl, "History buffer size: %zu\n",
> -			sizeof(cl->rdl.history_buf));
> -}
> -
> -cmdline_parse_token_string_t cmd_get_history_bufsize_tok =
> -	TOKEN_STRING_INITIALIZER(struct cmd_get_history_bufsize_result, str,
> -				 "get_history_bufsize");
> -
> -cmdline_parse_inst_t cmd_get_history_bufsize = {
> -	.f = cmd_get_history_bufsize_parsed,  /* function to call */
> -	.data = NULL,      /* 2nd arg of func */
> -	.help_str = "command that displays total space in history buffer",
> -	.tokens = {        /* token list, NULL terminated */
> -		(void *)&cmd_get_history_bufsize_tok,
> -		NULL,
> -	},
> -};
> -
> -
> -
> -/*** clear_history ***/
> -/* clears history buffer */
> -
> -struct cmd_clear_history_result {
> -	cmdline_fixed_string_t str;
> -};
> -
> -static void
> -cmd_clear_history_parsed(__attribute__((unused)) void *parsed_result,
> -		struct cmdline *cl,
> -		__attribute__((unused)) void *data)
> -{
> -	rdline_clear_history(&cl->rdl);
> -}
> -
> -cmdline_parse_token_string_t cmd_clear_history_tok =
> -	TOKEN_STRING_INITIALIZER(struct cmd_clear_history_result, str,
> -				 "clear_history");
> -
> -cmdline_parse_inst_t cmd_clear_history = {
> -	.f = cmd_clear_history_parsed,  /* function to call */
> -	.data = NULL,      /* 2nd arg of func */
> -	.help_str = "clear command history",
> -	.tokens = {        /* token list, NULL terminated */
> -		(void *)&cmd_clear_history_tok,
> -		NULL,
> -	},
> -};
> -
> -
> -
> /****************/
> 
> cmdline_parse_ctx_t main_ctx[] = {
> @@ -381,8 +314,6 @@ cmdline_parse_ctx_t main_ctx[] = {
> 		(cmdline_parse_inst_t *)&cmd_single,
> 		(cmdline_parse_inst_t *)&cmd_single_long,
> 		(cmdline_parse_inst_t *)&cmd_num,
> -		(cmdline_parse_inst_t *)&cmd_get_history_bufsize,
> -		(cmdline_parse_inst_t *)&cmd_clear_history,
> 		(cmdline_parse_inst_t *)&cmd_autocomplete_1,
> 		(cmdline_parse_inst_t *)&cmd_autocomplete_2,
> 	NULL,
> diff --git a/test/test/Makefile b/test/test/Makefile
> index bb54c98..49e907c 100644
> --- a/test/test/Makefile
> +++ b/test/test/Makefile
> @@ -164,7 +164,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += test_cmdline_num.c
> SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += test_cmdline_etheraddr.c
> SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += test_cmdline_portlist.c
> SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += test_cmdline_ipaddr.c
> -SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += test_cmdline_cirbuf.c
> SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += test_cmdline_string.c
> SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += test_cmdline_lib.c
> 
> diff --git a/test/test/commands.c b/test/test/commands.c
> index 4097a33..21a4a06 100644
> --- a/test/test/commands.c
> +++ b/test/test/commands.c
> @@ -66,7 +66,6 @@
> #include <rte_mbuf.h>
> #include <rte_devargs.h>
> 
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_ipaddr.h>
> #include <cmdline_parse_num.h>
> diff --git a/test/test/test.c b/test/test/test.c
> index 0e6ff7c..6f48892 100644
> --- a/test/test/test.c
> +++ b/test/test/test.c
> @@ -42,7 +42,6 @@
> #include <sys/queue.h>
> 
> #ifdef RTE_LIBRTE_CMDLINE
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_socket.h>
> #include <cmdline.h>
> diff --git a/test/test/test_cmdline.c b/test/test/test_cmdline.c
> index 38c7256..056b569 100644
> --- a/test/test/test_cmdline.c
> +++ b/test/test/test_cmdline.c
> @@ -74,15 +74,6 @@ test_cmdline(void)
> 		return -1;
> 	if (test_parse_string_invalid_param() < 0)
> 		return -1;
> -	printf("Testing circular buffer...\n");
> -	if (test_cirbuf_char() < 0)
> -		return -1;
> -	if (test_cirbuf_string() < 0)
> -		return -1;
> -	if (test_cirbuf_align() < 0)
> -		return -1;
> -	if (test_cirbuf_invalid_param() < 0)
> -		return -1;
> 	printf("Testing library functions...\n");
> 	if (test_cmdline_lib() < 0)
> 		return -1;
> diff --git a/test/test/test_cmdline.h b/test/test/test_cmdline.h
> index 0ee91c1..b55caa9 100644
> --- a/test/test/test_cmdline.h
> +++ b/test/test/test_cmdline.h
> @@ -61,12 +61,6 @@ int test_parse_string_valid(void);
> int test_parse_string_invalid_data(void);
> int test_parse_string_invalid_param(void);
> 
> -/* cmdline_cirbuf tests */
> -int test_cirbuf_invalid_param(void);
> -int test_cirbuf_char(void);
> -int test_cirbuf_string(void);
> -int test_cirbuf_align(void);
> -
> /* test the rest of the library */
> int test_cmdline_lib(void);
> 
> diff --git a/test/test/test_cmdline_cirbuf.c b/test/test/test_cmdline_cirbuf.c
> deleted file mode 100644
> index 2c32145..0000000
> --- a/test/test/test_cmdline_cirbuf.c
> +++ /dev/null
> @@ -1,1330 +0,0 @@
> -/*-
> - *   BSD LICENSE
> - *
> - *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> - *   All rights reserved.
> - *
> - *   Redistribution and use in source and binary forms, with or without
> - *   modification, are permitted provided that the following conditions
> - *   are met:
> - *
> - *     * Redistributions of source code must retain the above copyright
> - *       notice, this list of conditions and the following disclaimer.
> - *     * Redistributions in binary form must reproduce the above copyright
> - *       notice, this list of conditions and the following disclaimer in
> - *       the documentation and/or other materials provided with the
> - *       distribution.
> - *     * Neither the name of Intel Corporation nor the names of its
> - *       contributors may be used to endorse or promote products derived
> - *       from this software without specific prior written permission.
> - *
> - *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> - *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> - *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> - *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> - *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> - *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> - *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> - *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> - *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -#include <stdio.h>
> -#include <stdlib.h>
> -#include <string.h>
> -
> -#include <rte_string_fns.h>
> -
> -#include <cmdline_cirbuf.h>
> -
> -#include "test_cmdline.h"
> -
> -/* different length strings */
> -#define CIRBUF_STR_HEAD " HEAD"
> -#define CIRBUF_STR_TAIL "TAIL"
> -
> -/* miscellaneous tests - they make bullseye happy */
> -static int
> -test_cirbuf_string_misc(void)
> -{
> -	struct cirbuf cb;
> -	char buf[CMDLINE_TEST_BUFSIZE];
> -	char tmp[CMDLINE_TEST_BUFSIZE];
> -
> -	/* initialize buffers */
> -	memset(buf, 0, sizeof(buf));
> -	memset(tmp, 0, sizeof(tmp));
> -
> -	/*
> -	 * initialize circular buffer
> -	 */
> -	if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> -		printf("Error: failed to initialize circular buffer!\n");
> -		return -1;
> -	}
> -
> -	/*
> -	 * add strings to head and tail, but read only tail
> -	 * this results in read operation that does not transcend
> -	 * from buffer end to buffer beginning (in other words,
> -	 * strlen <= cb->maxlen - cb->end)
> -	 */
> -
> -	/* add string to head */
> -	if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD))
> -			!= (sizeof(CIRBUF_STR_HEAD))) {
> -		printf("Error: failed to add string to head!\n");
> -		return -1;
> -	}
> -	/* add string to tail */
> -	if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL))
> -			!= (sizeof(CIRBUF_STR_TAIL))) {
> -		printf("Error: failed to add string to head!\n");
> -		return -1;
> -	}
> -	/* read string from tail */
> -	if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_TAIL))
> -			!= (sizeof(CIRBUF_STR_TAIL))) {
> -		printf("Error: failed to get string from tail!\n");
> -		return -1;
> -	}
> -	/* verify string */
> -	if (strncmp(tmp, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) != 0) {
> -		printf("Error: tail strings do not match!\n");
> -		return -1;
> -	}
> -	/* clear buffers */
> -	memset(tmp, 0, sizeof(tmp));
> -	memset(buf, 0, sizeof(buf));
> -
> -
> -
> -	/*
> -	 * add a string to buffer when start/end is at end of buffer
> -	 */
> -
> -	/*
> -	 * reinitialize circular buffer with start at the end of cirbuf
> -	 */
> -	if (cirbuf_init(&cb, buf, CMDLINE_TEST_BUFSIZE - 2, sizeof(buf)) < 0) {
> -		printf("Error: failed to reinitialize circular buffer!\n");
> -		return -1;
> -	}
> -
> -
> -	/* add string to tail */
> -	if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL))
> -			!= (sizeof(CIRBUF_STR_TAIL))) {
> -		printf("Error: failed to add string to tail!\n");
> -		return -1;
> -	}
> -	/* read string from tail */
> -	if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_TAIL))
> -			!= (sizeof(CIRBUF_STR_TAIL))) {
> -		printf("Error: failed to get string from tail!\n");
> -		return -1;
> -	}
> -	/* verify string */
> -	if (strncmp(tmp, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) != 0) {
> -		printf("Error: tail strings do not match!\n");
> -		return -1;
> -	}
> -	/* clear tmp buffer */
> -	memset(tmp, 0, sizeof(tmp));
> -
> -
> -	/* add string to head */
> -	if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD))
> -			!= (sizeof(CIRBUF_STR_HEAD))) {
> -		printf("Error: failed to add string to head!\n");
> -		return -1;
> -	}
> -	/* read string from tail */
> -	if (cirbuf_get_buf_head(&cb, tmp, sizeof(CIRBUF_STR_HEAD))
> -			!= (sizeof(CIRBUF_STR_HEAD))) {
> -		printf("Error: failed to get string from head!\n");
> -		return -1;
> -	}
> -	/* verify string */
> -	if (strncmp(tmp, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) != 0) {
> -		printf("Error: headstrings do not match!\n");
> -		return -1;
> -	}
> -
> -	return 0;
> -}
> -
> -/* test adding and deleting strings */
> -static int
> -test_cirbuf_string_add_del(void)
> -{
> -	struct cirbuf cb;
> -	char buf[CMDLINE_TEST_BUFSIZE];
> -	char tmp[CMDLINE_TEST_BUFSIZE];
> -
> -	/* initialize buffers */
> -	memset(buf, 0, sizeof(buf));
> -	memset(tmp, 0, sizeof(tmp));
> -
> -	/*
> -	 * initialize circular buffer
> -	 */
> -	if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> -		printf("Error: failed to initialize circular buffer!\n");
> -		return -1;
> -	}
> -
> -	/* add string to head */
> -	if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD))
> -			!= (sizeof(CIRBUF_STR_HEAD))) {
> -		printf("Error: failed to add string to head!\n");
> -		return -1;
> -	}
> -	/* read string from head */
> -	if (cirbuf_get_buf_head(&cb, tmp, sizeof(CIRBUF_STR_HEAD))
> -			!= (sizeof(CIRBUF_STR_HEAD))) {
> -		printf("Error: failed to get string from head!\n");
> -		return -1;
> -	}
> -	/* verify string */
> -	if (strncmp(tmp, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) != 0) {
> -		printf("Error: head strings do not match!\n");
> -		return -1;
> -	}
> -	/* clear tmp buffer */
> -	memset(tmp, 0, sizeof(tmp));
> -	/* read string from tail */
> -	if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_HEAD))
> -			!= (sizeof(CIRBUF_STR_HEAD))) {
> -		printf("Error: failed to get string from head!\n");
> -		return -1;
> -	}
> -	/* verify string */
> -	if (strncmp(tmp, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) != 0) {
> -		printf("Error: head strings do not match!\n");
> -		return -1;
> -	}
> -	/* delete string from head*/
> -	if (cirbuf_del_buf_head(&cb, sizeof(CIRBUF_STR_HEAD)) < 0) {
> -		printf("Error: failed to delete string from head!\n");
> -		return -1;
> -	}
> -	/* verify string was deleted */
> -	if (cirbuf_del_head_safe(&cb) == 0) {
> -		printf("Error: buffer should have been empty!\n");
> -		return -1;
> -	}
> -	/* clear tmp buffer */
> -	memset(tmp, 0, sizeof(tmp));
> -
> -
> -
> -	/*
> -	 * reinitialize circular buffer
> -	 */
> -	memset(buf, 0, sizeof(buf));
> -	if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> -		printf("Error: failed to reinitialize circular buffer!\n");
> -		return -1;
> -	}
> -
> -	/* add string to tail */
> -	if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL))
> -			!= (sizeof(CIRBUF_STR_TAIL))) {
> -		printf("Error: failed to add string to tail!\n");
> -		return -1;
> -	}
> -	/* get string from tail */
> -	if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_TAIL))
> -			!= (sizeof(CIRBUF_STR_TAIL))) {
> -		printf("Error: failed to get string from tail!\n");
> -		return -1;
> -	}
> -	/* verify string */
> -	if (strncmp(tmp, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) != 0) {
> -		printf("Error: tail strings do not match!\n");
> -		return -1;
> -	}
> -	/* clear tmp buffer */
> -	memset(tmp, 0, sizeof(tmp));
> -	/* get string from head */
> -	if (cirbuf_get_buf_head(&cb, tmp, sizeof(CIRBUF_STR_TAIL))
> -			!= (sizeof(CIRBUF_STR_TAIL))) {
> -		printf("Error: failed to get string from tail!\n");
> -		return -1;
> -	}
> -	/* verify string */
> -	if (strncmp(tmp, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) != 0) {
> -		printf("Error: tail strings do not match!\n");
> -		return -1;
> -	}
> -	/* delete string from tail */
> -	if (cirbuf_del_buf_tail(&cb, sizeof(CIRBUF_STR_TAIL)) < 0) {
> -		printf("Error: failed to delete string from tail!\n");
> -		return -1;
> -	}
> -	/* verify string was deleted */
> -	if (cirbuf_del_tail_safe(&cb) == 0) {
> -		printf("Error: buffer should have been empty!\n");
> -		return -1;
> -	}
> -
> -	return 0;
> -}
> -
> -/* test adding from head and deleting from tail, and vice versa */
> -static int
> -test_cirbuf_string_add_del_reverse(void)
> -{
> -	struct cirbuf cb;
> -	char buf[CMDLINE_TEST_BUFSIZE];
> -	char tmp[CMDLINE_TEST_BUFSIZE];
> -
> -	/* initialize buffers */
> -	memset(buf, 0, sizeof(buf));
> -	memset(tmp, 0, sizeof(tmp));
> -
> -	/*
> -	 * initialize circular buffer
> -	 */
> -	if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> -		printf("Error: failed to initialize circular buffer!\n");
> -		return -1;
> -	}
> -
> -	/* add string to head */
> -	if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD))
> -			!= (sizeof(CIRBUF_STR_HEAD))) {
> -		printf("Error: failed to add string to head!\n");
> -		return -1;
> -	}
> -	/* delete string from tail */
> -	if (cirbuf_del_buf_tail(&cb, sizeof(CIRBUF_STR_HEAD)) < 0) {
> -		printf("Error: failed to delete string from tail!\n");
> -		return -1;
> -	}
> -	/* verify string was deleted */
> -	if (cirbuf_del_tail_safe(&cb) == 0) {
> -		printf("Error: buffer should have been empty!\n");
> -		return -1;
> -	}
> -	/* clear tmp buffer */
> -	memset(tmp, 0, sizeof(tmp));
> -
> -	/*
> -	 * reinitialize circular buffer
> -	 */
> -	memset(buf, 0, sizeof(buf));
> -	if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> -		printf("Error: failed to reinitialize circular buffer!\n");
> -		return -1;
> -	}
> -
> -	/* add string to tail */
> -	if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL))
> -			!= (sizeof(CIRBUF_STR_TAIL))) {
> -		printf("Error: failed to add string to tail!\n");
> -		return -1;
> -	}
> -	/* delete string from head */
> -	if (cirbuf_del_buf_head(&cb, sizeof(CIRBUF_STR_TAIL)) < 0) {
> -		printf("Error: failed to delete string from head!\n");
> -		return -1;
> -	}
> -	/* verify string was deleted */
> -	if (cirbuf_del_head_safe(&cb) == 0) {
> -		printf("Error: buffer should have been empty!\n");
> -		return -1;
> -	}
> -
> -	return 0;
> -}
> -
> -/* try to write more than available */
> -static int
> -test_cirbuf_string_add_boundaries(void)
> -{
> -	struct cirbuf cb;
> -	char buf[CMDLINE_TEST_BUFSIZE];
> -	unsigned i;
> -
> -	/* initialize buffers */
> -	memset(buf, 0, sizeof(buf));
> -
> -	/*
> -	 * initialize circular buffer
> -	 */
> -	if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> -		printf("Error: failed to initialize circular buffer!\n");
> -		return -1;
> -	}
> -
> -	/* fill the buffer from tail */
> -	for (i = 0; i < CMDLINE_TEST_BUFSIZE - sizeof(CIRBUF_STR_TAIL) + 1; i++)
> -		cirbuf_add_tail_safe(&cb, 't');
> -
> -	/* try adding a string to tail */
> -	if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL))
> -			> 0) {
> -		printf("Error: buffer should have been full!\n");
> -		return -1;
> -	}
> -	/* try adding a string to head */
> -	if (cirbuf_add_buf_head(&cb, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL))
> -			> 0) {
> -		printf("Error: buffer should have been full!\n");
> -		return -1;
> -	}
> -
> -	/*
> -	 * reinitialize circular buffer
> -	 */
> -	memset(buf, 0, sizeof(buf));
> -	if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> -		printf("Error: failed to reinitialize circular buffer!\n");
> -		return -1;
> -	}
> -
> -	/* fill the buffer from head */
> -	for (i = 0; i < CMDLINE_TEST_BUFSIZE - sizeof(CIRBUF_STR_HEAD) + 1; i++)
> -		cirbuf_add_head_safe(&cb, 'h');
> -
> -	/* try adding a string to head */
> -	if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD))
> -			> 0) {
> -		printf("Error: buffer should have been full!\n");
> -		return -1;
> -	}
> -	/* try adding a string to tail */
> -	if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD))
> -			> 0) {
> -		printf("Error: buffer should have been full!\n");
> -		return -1;
> -	}
> -
> -	return 0;
> -}
> -
> -/* try to read/delete more than written */
> -static int
> -test_cirbuf_string_get_del_boundaries(void)
> -{
> -	struct cirbuf cb;
> -	char buf[CMDLINE_TEST_BUFSIZE];
> -	char tmp[CMDLINE_TEST_BUFSIZE];
> -
> -	/* initialize buffers */
> -	memset(buf, 0, sizeof(buf));
> -	memset(tmp, 0, sizeof(tmp));
> -
> -	/*
> -	 * initialize circular buffer
> -	 */
> -	if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> -		printf("Error: failed to initialize circular buffer!\n");
> -		return -1;
> -	}
> -
> -
> -	/* add string to head */
> -	if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD))
> -				!= (sizeof(CIRBUF_STR_HEAD))) {
> -		printf("Error: failed to add string to head!\n");
> -		return -1;
> -	}
> -	/* read more than written (head) */
> -	if (cirbuf_get_buf_head(&cb, tmp, sizeof(CIRBUF_STR_HEAD) + 1)
> -			!= sizeof(CIRBUF_STR_HEAD)) {
> -		printf("Error: unexpected result when reading too much data!\n");
> -		return -1;
> -	}
> -	/* read more than written (tail) */
> -	if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_HEAD) + 1)
> -			!= sizeof(CIRBUF_STR_HEAD)) {
> -		printf("Error: unexpected result when reading too much data!\n");
> -		return -1;
> -	}
> -	/* delete more than written (head) */
> -	if (cirbuf_del_buf_head(&cb, sizeof(CIRBUF_STR_HEAD) + 1) == 0) {
> -		printf("Error: unexpected result when deleting too much data!\n");
> -		return -1;
> -	}
> -	/* delete more than written (tail) */
> -	if (cirbuf_del_buf_tail(&cb, sizeof(CIRBUF_STR_HEAD) + 1) == 0) {
> -		printf("Error: unexpected result when deleting too much data!\n");
> -		return -1;
> -	}
> -
> -	/*
> -	 * reinitialize circular buffer
> -	 */
> -	memset(buf, 0, sizeof(buf));
> -	if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> -		printf("Error: failed to reinitialize circular buffer!\n");
> -		return -1;
> -	}
> -
> -	/* add string to tail */
> -	if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL))
> -				!= (sizeof(CIRBUF_STR_TAIL))) {
> -		printf("Error: failed to add string to tail!\n");
> -		return -1;
> -	}
> -	/* read more than written (tail) */
> -	if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_TAIL) + 1)
> -			!= sizeof(CIRBUF_STR_TAIL)) {
> -		printf("Error: unexpected result when reading too much data!\n");
> -		return -1;
> -	}
> -	/* read more than written (head) */
> -	if (cirbuf_get_buf_head(&cb, tmp, sizeof(CIRBUF_STR_TAIL) + 1)
> -			!= sizeof(CIRBUF_STR_TAIL)) {
> -		printf("Error: unexpected result when reading too much data!\n");
> -		return -1;
> -	}
> -	/* delete more than written (tail) */
> -	if (cirbuf_del_buf_tail(&cb, sizeof(CIRBUF_STR_TAIL) + 1) == 0) {
> -		printf("Error: unexpected result when deleting too much data!\n");
> -		return -1;
> -	}
> -	/* delete more than written (head) */
> -	if (cirbuf_del_buf_tail(&cb, sizeof(CIRBUF_STR_TAIL) + 1) == 0) {
> -		printf("Error: unexpected result when deleting too much data!\n");
> -		return -1;
> -	}
> -
> -	return 0;
> -}
> -
> -/* try to read/delete less than written */
> -static int
> -test_cirbuf_string_get_del_partial(void)
> -{
> -	struct cirbuf cb;
> -	char buf[CMDLINE_TEST_BUFSIZE];
> -	char tmp[CMDLINE_TEST_BUFSIZE];
> -	char tmp2[CMDLINE_TEST_BUFSIZE];
> -
> -	/* initialize buffers */
> -	memset(buf, 0, sizeof(buf));
> -	memset(tmp, 0, sizeof(tmp));
> -	memset(tmp2, 0, sizeof(tmp));
> -
> -	snprintf(tmp2, sizeof(tmp2), "%s", CIRBUF_STR_HEAD);
> -
> -	/*
> -	 * initialize circular buffer
> -	 */
> -	if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> -		printf("Error: failed to initialize circular buffer!\n");
> -		return -1;
> -	}
> -
> -	/* add string to head */
> -	if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD))
> -				!= (sizeof(CIRBUF_STR_HEAD))) {
> -		printf("Error: failed to add string to head!\n");
> -		return -1;
> -	}
> -	/* read less than written (head) */
> -	if (cirbuf_get_buf_head(&cb, tmp, sizeof(CIRBUF_STR_HEAD) - 1)
> -			!= sizeof(CIRBUF_STR_HEAD) - 1) {
> -		printf("Error: unexpected result when reading from head!\n");
> -		return -1;
> -	}
> -	/* verify string */
> -	if (strncmp(tmp, tmp2, sizeof(CIRBUF_STR_HEAD) - 1) != 0) {
> -		printf("Error: strings mismatch!\n");
> -		return -1;
> -	}
> -	memset(tmp, 0, sizeof(tmp));
> -	/* read less than written (tail) */
> -	if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_HEAD) - 1)
> -			!= sizeof(CIRBUF_STR_HEAD) - 1) {
> -		printf("Error: unexpected result when reading from tail!\n");
> -		return -1;
> -	}
> -	/* verify string */
> -	if (strncmp(tmp, &tmp2[1], sizeof(CIRBUF_STR_HEAD) - 1) != 0) {
> -		printf("Error: strings mismatch!\n");
> -		return -1;
> -	}
> -
> -	/*
> -	 * verify correct deletion
> -	 */
> -
> -	/* clear buffer */
> -	memset(tmp, 0, sizeof(tmp));
> -
> -	/* delete less than written (head) */
> -	if (cirbuf_del_buf_head(&cb, 1) != 0) {
> -		printf("Error: delete from head failed!\n");
> -		return -1;
> -	}
> -	/* read from head */
> -	if (cirbuf_get_buf_head(&cb, tmp, sizeof(CIRBUF_STR_HEAD) - 1)
> -			!= sizeof(CIRBUF_STR_HEAD) - 1) {
> -		printf("Error: unexpected result when reading from head!\n");
> -		return -1;
> -	}
> -	/* since we deleted from head, first char should be deleted */
> -	if (strncmp(tmp, &tmp2[1], sizeof(CIRBUF_STR_HEAD) - 1) != 0) {
> -		printf("Error: strings mismatch!\n");
> -		return -1;
> -	}
> -	/* clear buffer */
> -	memset(tmp, 0, sizeof(tmp));
> -
> -	/* delete less than written (tail) */
> -	if (cirbuf_del_buf_tail(&cb, 1) != 0) {
> -		printf("Error: delete from tail failed!\n");
> -		return -1;
> -	}
> -	/* read from tail */
> -	if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_HEAD) - 2)
> -			!= sizeof(CIRBUF_STR_HEAD) - 2) {
> -		printf("Error: unexpected result when reading from head!\n");
> -		return -1;
> -	}
> -	/* since we deleted from tail, last char should be deleted */
> -	if (strncmp(tmp, &tmp2[1], sizeof(CIRBUF_STR_HEAD) - 2) != 0) {
> -		printf("Error: strings mismatch!\n");
> -		return -1;
> -	}
> -
> -	return 0;
> -}
> -
> -/* test cmdline_cirbuf char add/del functions */
> -static int
> -test_cirbuf_char_add_del(void)
> -{
> -	struct cirbuf cb;
> -	char buf[CMDLINE_TEST_BUFSIZE];
> -	char tmp[CMDLINE_TEST_BUFSIZE];
> -
> -	/* clear buffer */
> -	memset(buf, 0, sizeof(buf));
> -	memset(tmp, 0, sizeof(tmp));
> -
> -	/*
> -	 * initialize circular buffer
> -	 */
> -	if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> -		printf("Error: failed to initialize circular buffer!\n");
> -		return -1;
> -	}
> -
> -	/*
> -	 * try to delete something from cirbuf. since it's empty,
> -	 * these should fail.
> -	 */
> -	if (cirbuf_del_head_safe(&cb) == 0) {
> -		printf("Error: deleting from empty cirbuf head succeeded!\n");
> -		return -1;
> -	}
> -	if (cirbuf_del_tail_safe(&cb) == 0) {
> -		printf("Error: deleting from empty cirbuf tail succeeded!\n");
> -		return -1;
> -	}
> -
> -	/*
> -	 * add, verify and delete. these should pass.
> -	 */
> -	if (cirbuf_add_head_safe(&cb,'h') < 0) {
> -		printf("Error: adding to cirbuf head failed!\n");
> -		return -1;
> -	}
> -	if (cirbuf_get_head(&cb) != 'h') {
> -		printf("Error: wrong head content!\n");
> -		return -1;
> -	}
> -	if (cirbuf_del_head_safe(&cb) < 0) {
> -		printf("Error: deleting from cirbuf head failed!\n");
> -		return -1;
> -	}
> -	if (cirbuf_add_tail_safe(&cb,'t') < 0) {
> -		printf("Error: adding to cirbuf tail failed!\n");
> -		return -1;
> -	}
> -	if (cirbuf_get_tail(&cb) != 't') {
> -		printf("Error: wrong tail content!\n");
> -		return -1;
> -	}
> -	if (cirbuf_del_tail_safe(&cb) < 0) {
> -		printf("Error: deleting from cirbuf tail failed!\n");
> -		return -1;
> -	}
> -	/* do the same for unsafe versions. those are void. */
> -	cirbuf_add_head(&cb,'h');
> -	if (cirbuf_get_head(&cb) != 'h') {
> -		printf("Error: wrong head content!\n");
> -		return -1;
> -	}
> -	cirbuf_del_head(&cb);
> -
> -	/* test if char has been deleted. we can't call cirbuf_get_head
> -	 * because it's unsafe, but we can call cirbuf_get_buf_head.
> -	 */
> -	if (cirbuf_get_buf_head(&cb, tmp, 1) > 0) {
> -		printf("Error: buffer should have been empty!\n");
> -		return -1;
> -	}
> -
> -	cirbuf_add_tail(&cb,'t');
> -	if (cirbuf_get_tail(&cb) != 't') {
> -		printf("Error: wrong tail content!\n");
> -		return -1;
> -	}
> -	cirbuf_del_tail(&cb);
> -
> -	/* test if char has been deleted. we can't call cirbuf_get_tail
> -	 * because it's unsafe, but we can call cirbuf_get_buf_tail.
> -	 */
> -	if (cirbuf_get_buf_tail(&cb, tmp, 1) > 0) {
> -		printf("Error: buffer should have been empty!\n");
> -		return -1;
> -	}
> -
> -	return 0;
> -}
> -
> -/* test filling up buffer with chars */
> -static int
> -test_cirbuf_char_fill(void)
> -{
> -	struct cirbuf cb;
> -	char buf[CMDLINE_TEST_BUFSIZE];
> -	unsigned i;
> -
> -	/* clear buffer */
> -	memset(buf, 0, sizeof(buf));
> -
> -	/*
> -	 * initialize circular buffer
> -	 */
> -	if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> -		printf("Error: failed to initialize circular buffer!\n");
> -		return -1;
> -	}
> -
> -	/*
> -	 * fill the buffer from head or tail, verify contents, test boundaries
> -	 * and clear the buffer
> -	 */
> -
> -	/* fill the buffer from tail */
> -	for (i = 0; i < CMDLINE_TEST_BUFSIZE; i++)
> -		cirbuf_add_tail_safe(&cb, 't');
> -	/* verify that contents of the buffer are what they are supposed to be */
> -	for (i = 0; i < sizeof(buf); i++) {
> -		if (buf[i] != 't') {
> -			printf("Error: wrong content in buffer!\n");
> -			return -1;
> -		}
> -	}
> -	/* try to add to a full buffer from tail */
> -	if (cirbuf_add_tail_safe(&cb, 't') == 0) {
> -		printf("Error: buffer should have been full!\n");
> -		return -1;
> -	}
> -	/* try to add to a full buffer from head */
> -	if (cirbuf_add_head_safe(&cb, 'h') == 0) {
> -		printf("Error: buffer should have been full!\n");
> -		return -1;
> -	}
> -	/* delete buffer from tail */
> -	for(i = 0; i < CMDLINE_TEST_BUFSIZE; i++)
> -		cirbuf_del_tail_safe(&cb);
> -	/* try to delete from an empty buffer */
> -	if (cirbuf_del_tail_safe(&cb) >= 0) {
> -		printf("Error: buffer should have been empty!\n");
> -		return -1;
> -	}
> -
> -	/* fill the buffer from head */
> -	for (i = 0; i < CMDLINE_TEST_BUFSIZE; i++)
> -		cirbuf_add_head_safe(&cb, 'h');
> -	/* verify that contents of the buffer are what they are supposed to be */
> -	for (i = 0; i < sizeof(buf); i++) {
> -		if (buf[i] != 'h') {
> -			printf("Error: wrong content in buffer!\n");
> -			return -1;
> -		}
> -	}
> -	/* try to add to a full buffer from head */
> -	if (cirbuf_add_head_safe(&cb,'h') >= 0) {
> -		printf("Error: buffer should have been full!\n");
> -		return -1;
> -	}
> -	/* try to add to a full buffer from tail */
> -	if (cirbuf_add_tail_safe(&cb, 't') == 0) {
> -		printf("Error: buffer should have been full!\n");
> -		return -1;
> -	}
> -	/* delete buffer from head */
> -	for(i = 0; i < CMDLINE_TEST_BUFSIZE; i++)
> -		cirbuf_del_head_safe(&cb);
> -	/* try to delete from an empty buffer */
> -	if (cirbuf_del_head_safe(&cb) >= 0) {
> -		printf("Error: buffer should have been empty!\n");
> -		return -1;
> -	}
> -
> -	/*
> -	 * fill the buffer from both head and tail, with alternating characters,
> -	 * verify contents and clear the buffer
> -	 */
> -
> -	/* fill half of buffer from tail */
> -	for (i = 0; i < CMDLINE_TEST_BUFSIZE / 2; i++)
> -		cirbuf_add_tail_safe(&cb, (char) (i % 2 ? 't' : 'T'));
> -	/* fill other half of the buffer from head */
> -	for (i = 0; i < CMDLINE_TEST_BUFSIZE / 2; i++)
> -		cirbuf_add_head_safe(&cb, (char) (i % 2 ? 'H' : 'h')); /* added in reverse */
> -
> -	/* verify that contents of the buffer are what they are supposed to be */
> -	for (i = 0; i < sizeof(buf) / 2; i++) {
> -		if (buf[i] != (char) (i % 2 ? 't' : 'T')) {
> -			printf("Error: wrong content in buffer at %u!\n", i);
> -			return -1;
> -		}
> -	}
> -	for (i = sizeof(buf) / 2; i < sizeof(buf); i++) {
> -		if (buf[i] != (char) (i % 2 ? 'h' : 'H')) {
> -			printf("Error: wrong content in buffer %u!\n", i);
> -			return -1;
> -		}
> -	}
> -
> -	return 0;
> -}
> -
> -/* test left alignment */
> -static int
> -test_cirbuf_align_left(void)
> -{
> -#define HALF_OFFSET CMDLINE_TEST_BUFSIZE / 2
> -#define SMALL_OFFSET HALF_OFFSET / 2
> -/* resulting buffer lengths for each of the test cases */
> -#define LEN1 HALF_OFFSET - SMALL_OFFSET - 1
> -#define LEN2 HALF_OFFSET + SMALL_OFFSET + 2
> -#define LEN3 HALF_OFFSET - SMALL_OFFSET
> -#define LEN4 HALF_OFFSET + SMALL_OFFSET - 1
> -
> -	struct cirbuf cb;
> -	char buf[CMDLINE_TEST_BUFSIZE];
> -	char tmp[CMDLINE_TEST_BUFSIZE];
> -	unsigned i;
> -
> -	/*
> -	 * align left when start < end and start in left half
> -	 */
> -
> -	/*
> -	 * initialize circular buffer
> -	 */
> -	memset(buf, 0, sizeof(buf));
> -	if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> -		printf("Error: failed to initialize circular buffer!\n");
> -		return -1;
> -	}
> -
> -	/* push end into left half */
> -	for (i = 0; i < HALF_OFFSET - 1; i++)
> -		cirbuf_add_tail_safe(&cb, 't');
> -
> -	/* push start into left half < end */
> -	for (i = 0; i < SMALL_OFFSET; i++)
> -		cirbuf_del_head_safe(&cb);
> -
> -	/* align */
> -	if (cirbuf_align_left(&cb) < 0) {
> -		printf("Error: alignment failed!\n");
> -		return -1;
> -	}
> -
> -	/* verify result */
> -	if (cb.start != 0 || cb.len != LEN1 || cb.end != cb.len - 1) {
> -		printf("Error: buffer alignment is wrong!\n");
> -		return -1;
> -	}
> -
> -	/*
> -	 * align left when start > end and start in left half
> -	 */
> -
> -	/*
> -	 * reinitialize circular buffer
> -	 */
> -	memset(buf, 0, sizeof(buf));
> -	if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> -		printf("Error: failed to reinitialize circular buffer!\n");
> -		return -1;
> -	}
> -
> -	/* push start into left half */
> -	for (i = 0; i < HALF_OFFSET + 2; i++)
> -		cirbuf_add_head_safe(&cb, 'h');
> -
> -	/* push end into left half > start */
> -	for (i = 0; i < SMALL_OFFSET; i++)
> -		cirbuf_add_tail_safe(&cb, 't');
> -
> -	/* align */
> -	if (cirbuf_align_left(&cb) < 0) {
> -		printf("Error: alignment failed!\n");
> -		return -1;
> -	}
> -
> -	/* verify result */
> -	if (cb.start != 0 || cb.len != LEN2 || cb.end != cb.len - 1) {
> -		printf("Error: buffer alignment is wrong!");
> -		return -1;
> -	}
> -
> -	/*
> -	 * align left when start < end and start in right half
> -	 */
> -
> -	/*
> -	 * reinitialize circular buffer
> -	 */
> -	memset(buf, 0, sizeof(buf));
> -	if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> -		printf("Error: failed to reinitialize circular buffer!\n");
> -		return -1;
> -	}
> -
> -	/* push start into the right half */
> -	for (i = 0; i < HALF_OFFSET; i++)
> -		cirbuf_add_head_safe(&cb, 'h');
> -
> -	/* push end into left half > start */
> -	for (i = 0; i < SMALL_OFFSET; i++)
> -		cirbuf_del_tail_safe(&cb);
> -
> -	/* align */
> -	if (cirbuf_align_left(&cb) < 0) {
> -		printf("Error: alignment failed!\n");
> -		return -1;
> -	}
> -
> -	/* verify result */
> -	if (cb.start != 0 || cb.len != LEN3 || cb.end != cb.len - 1) {
> -		printf("Error: buffer alignment is wrong!");
> -		return -1;
> -	}
> -
> -	/*
> -	 * align left when start > end and start in right half
> -	 */
> -
> -	/*
> -	 * reinitialize circular buffer
> -	 */
> -	memset(buf, 0, sizeof(buf));
> -	if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> -		printf("Error: failed to reinitialize circular buffer!\n");
> -		return -1;
> -	}
> -
> -	/* push start into the right half */
> -	for (i = 0; i < HALF_OFFSET - 1; i++)
> -		cirbuf_add_head_safe(&cb, 'h');
> -
> -	/* push end into left half < start */
> -	for (i = 0; i < SMALL_OFFSET; i++)
> -		cirbuf_add_tail_safe(&cb, 't');
> -
> -	/* align */
> -	if (cirbuf_align_left(&cb) < 0) {
> -		printf("Error: alignment failed!\n");
> -		return -1;
> -	}
> -
> -	/* verify result */
> -	if (cb.start != 0 || cb.len != LEN4 ||
> -			cb.end != cb.len - 1) {
> -		printf("Error: buffer alignment is wrong!");
> -		return -1;
> -	}
> -
> -	/*
> -	 * Verify that alignment doesn't corrupt data
> -	 */
> -
> -	/*
> -	 * reinitialize circular buffer
> -	 */
> -	memset(buf, 0, sizeof(buf));
> -	if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> -		printf("Error: failed to reinitialize circular buffer!\n");
> -		return -1;
> -	}
> -
> -	/* add string to tail and head */
> -	if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD,
> -			sizeof(CIRBUF_STR_HEAD)) < 0 || cirbuf_add_buf_tail(&cb,
> -					CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) < 0) {
> -		printf("Error: failed to add strings!\n");
> -		return -1;
> -	}
> -
> -	/* align */
> -	if (cirbuf_align_left(&cb) < 0) {
> -		printf("Error: alignment failed!\n");
> -		return -1;
> -	}
> -
> -	/* get string from head */
> -	if (cirbuf_get_buf_head(&cb, tmp,
> -			sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) < 0) {
> -		printf("Error: failed to read string from head!\n");
> -		return -1;
> -	}
> -
> -	/* verify string */
> -	if (strncmp(tmp, CIRBUF_STR_HEAD "\0" CIRBUF_STR_TAIL,
> -			sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) != 0) {
> -		printf("Error: strings mismatch!\n");
> -		return -1;
> -	}
> -
> -	/* reset tmp buffer */
> -	memset(tmp, 0, sizeof(tmp));
> -
> -	/* get string from tail */
> -	if (cirbuf_get_buf_tail(&cb, tmp,
> -			sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) < 0) {
> -		printf("Error: failed to read string from head!\n");
> -		return -1;
> -	}
> -
> -	/* verify string */
> -	if (strncmp(tmp, CIRBUF_STR_HEAD "\0" CIRBUF_STR_TAIL,
> -			sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) != 0) {
> -		printf("Error: strings mismatch!\n");
> -		return -1;
> -	}
> -
> -	return 0;
> -}
> -
> -/* test right alignment */
> -static int
> -test_cirbuf_align_right(void)
> -{
> -#define END_OFFSET CMDLINE_TEST_BUFSIZE - 1
> -	struct cirbuf cb;
> -	char buf[CMDLINE_TEST_BUFSIZE];
> -	char tmp[CMDLINE_TEST_BUFSIZE];
> -	unsigned i;
> -
> -
> -	/*
> -	 * align right when start < end and start in left half
> -	 */
> -
> -	/*
> -	 * initialize circular buffer
> -	 */
> -	memset(buf, 0, sizeof(buf));
> -	if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> -		printf("Error: failed to initialize circular buffer!\n");
> -		return -1;
> -	}
> -
> -	/* push end into left half */
> -	for (i = 0; i < HALF_OFFSET - 1; i++)
> -		cirbuf_add_tail_safe(&cb, 't');
> -
> -	/* push start into left half < end */
> -	for (i = 0; i < SMALL_OFFSET; i++)
> -		cirbuf_del_head_safe(&cb);
> -
> -	/* align */
> -	cirbuf_align_right(&cb);
> -
> -	/* verify result */
> -	if (cb.start != END_OFFSET || cb.len != LEN1 || cb.end != cb.len - 2) {
> -		printf("Error: buffer alignment is wrong!\n");
> -		return -1;
> -	}
> -
> -	/*
> -	 * align right when start > end and start in left half
> -	 */
> -
> -	/*
> -	 * reinitialize circular buffer
> -	 */
> -	memset(buf, 0, sizeof(buf));
> -	if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> -		printf("Error: failed to reinitialize circular buffer!\n");
> -		return -1;
> -	}
> -
> -	/* push start into left half */
> -	for (i = 0; i < HALF_OFFSET + 2; i++)
> -		cirbuf_add_head_safe(&cb, 'h');
> -
> -	/* push end into left half > start */
> -	for (i = 0; i < SMALL_OFFSET; i++)
> -		cirbuf_add_tail_safe(&cb, 't');
> -
> -	/* align */
> -	cirbuf_align_right(&cb);
> -
> -	/* verify result */
> -	if (cb.start != END_OFFSET || cb.len != LEN2 || cb.end != cb.len - 2) {
> -		printf("Error: buffer alignment is wrong!");
> -		return -1;
> -	}
> -
> -	/*
> -	 * align right when start < end and start in right half
> -	 */
> -
> -	/*
> -	 * reinitialize circular buffer
> -	 */
> -	memset(buf, 0, sizeof(buf));
> -	if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> -		printf("Error: failed to reinitialize circular buffer!\n");
> -		return -1;
> -	}
> -
> -	/* push start into the right half */
> -	for (i = 0; i < HALF_OFFSET; i++)
> -		cirbuf_add_head_safe(&cb, 'h');
> -
> -	/* push end into left half > start */
> -	for (i = 0; i < SMALL_OFFSET; i++)
> -		cirbuf_del_tail_safe(&cb);
> -
> -	/* align */
> -	cirbuf_align_right(&cb);
> -
> -	/* verify result */
> -	if (cb.end != END_OFFSET || cb.len != LEN3 || cb.start != cb.end - cb.len + 1) {
> -		printf("Error: buffer alignment is wrong!");
> -		return -1;
> -	}
> -
> -	/*
> -	 * align right when start > end and start in right half
> -	 */
> -
> -	/*
> -	 * reinitialize circular buffer
> -	 */
> -	memset(buf, 0, sizeof(buf));
> -	if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> -		printf("Error: failed to reinitialize circular buffer!\n");
> -		return -1;
> -	}
> -
> -	/* push start into the right half */
> -	for (i = 0; i < HALF_OFFSET - 1; i++)
> -		cirbuf_add_head_safe(&cb, 'h');
> -
> -	/* push end into left half < start */
> -	for (i = 0; i < SMALL_OFFSET; i++)
> -		cirbuf_add_tail_safe(&cb, 't');
> -
> -	/* align */
> -	cirbuf_align_right(&cb);
> -
> -	/* verify result */
> -	if (cb.end != END_OFFSET || cb.len != LEN4 || cb.start != cb.end - cb.len + 1) {
> -		printf("Error: buffer alignment is wrong!");
> -		return -1;
> -	}
> -
> -	/*
> -	 * Verify that alignment doesn't corrupt data
> -	 */
> -
> -	/*
> -	 * reinitialize circular buffer
> -	 */
> -	memset(buf, 0, sizeof(buf));
> -	if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> -		printf("Error: failed to reinitialize circular buffer!\n");
> -		return -1;
> -	}
> -
> -	/* add string to tail and head */
> -	if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_TAIL,
> -			sizeof(CIRBUF_STR_TAIL)) < 0 || cirbuf_add_buf_head(&cb,
> -					CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) < 0) {
> -		printf("Error: failed to add strings!\n");
> -		return -1;
> -	}
> -
> -	/* align */
> -	if (cirbuf_align_right(&cb) < 0) {
> -		printf("Error: alignment failed!\n");
> -		return -1;
> -	}
> -
> -	/* get string from head */
> -	if (cirbuf_get_buf_head(&cb, tmp,
> -			sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) < 0) {
> -		printf("Error: failed to read string from head!\n");
> -		return -1;
> -	}
> -
> -	/* verify string */
> -	if (strncmp(tmp, CIRBUF_STR_HEAD "\0" CIRBUF_STR_TAIL,
> -			sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) != 0) {
> -		printf("Error: strings mismatch!\n");
> -		return -1;
> -	}
> -
> -	/* reset tmp buffer */
> -	memset(tmp, 0, sizeof(tmp));
> -
> -	/* get string from tail */
> -	if (cirbuf_get_buf_tail(&cb, tmp,
> -			sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) < 0) {
> -		printf("Error: failed to read string from head!\n");
> -		return -1;
> -	}
> -	/* verify string */
> -	if (strncmp(tmp, CIRBUF_STR_HEAD "\0" CIRBUF_STR_TAIL,
> -			sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) != 0) {
> -		printf("Error: strings mismatch!\n");
> -		return -1;
> -	}
> -
> -	return 0;
> -}
> -
> -/* call functions with invalid parameters */
> -int
> -test_cirbuf_invalid_param(void)
> -{
> -	struct cirbuf cb;
> -	char buf[CMDLINE_TEST_BUFSIZE];
> -
> -	/* null cirbuf */
> -	if (cirbuf_init(0, buf, 0, sizeof(buf)) == 0)
> -		return -1;
> -	/* null buffer */
> -	if (cirbuf_init(&cb, 0, 0, sizeof(buf)) == 0)
> -		return -1;
> -	/* null cirbuf */
> -	if (cirbuf_add_head_safe(0, 'h') == 0)
> -		return -1;
> -	if (cirbuf_add_tail_safe(0, 't') == 0)
> -		return -1;
> -	if (cirbuf_del_head_safe(0) == 0)
> -		return -1;
> -	if (cirbuf_del_tail_safe(0) == 0)
> -		return -1;
> -	/* null buffer */
> -	if (cirbuf_add_buf_head(&cb, 0, 0) == 0)
> -		return -1;
> -	if (cirbuf_add_buf_tail(&cb, 0, 0) == 0)
> -		return -1;
> -	/* null cirbuf */
> -	if (cirbuf_add_buf_head(0, buf, 0) == 0)
> -		return -1;
> -	if (cirbuf_add_buf_tail(0, buf, 0) == 0)
> -		return -1;
> -	/* null size */
> -	if (cirbuf_add_buf_head(&cb, buf, 0) == 0)
> -		return -1;
> -	if (cirbuf_add_buf_tail(&cb, buf, 0) == 0)
> -		return -1;
> -	/* null cirbuf */
> -	if (cirbuf_del_buf_head(0, 0) == 0)
> -		return -1;
> -	if (cirbuf_del_buf_tail(0, 0) == 0)
> -		return -1;
> -	/* null size */
> -	if (cirbuf_del_buf_head(&cb, 0) == 0)
> -		return -1;
> -	if (cirbuf_del_buf_tail(&cb, 0) == 0)
> -		return -1;
> -	/* null cirbuf */
> -	if (cirbuf_get_buf_head(0, 0, 0) == 0)
> -		return -1;
> -	if (cirbuf_get_buf_tail(0, 0, 0) == 0)
> -		return -1;
> -	/* null buffer */
> -	if (cirbuf_get_buf_head(&cb, 0, 0) == 0)
> -		return -1;
> -	if (cirbuf_get_buf_tail(&cb, 0, 0) == 0)
> -		return -1;
> -	/* null size, this is valid but should return 0 */
> -	if (cirbuf_get_buf_head(&cb, buf, 0) != 0)
> -		return -1;
> -	if (cirbuf_get_buf_tail(&cb, buf, 0) != 0)
> -		return -1;
> -	/* null cirbuf */
> -	if (cirbuf_align_left(0) == 0)
> -		return -1;
> -	if (cirbuf_align_right(0) == 0)
> -		return -1;
> -
> -	return 0;
> -}
> -
> -/* test cmdline_cirbuf char functions */
> -int
> -test_cirbuf_char(void)
> -{
> -	int ret;
> -
> -	ret = test_cirbuf_char_add_del();
> -	if (ret < 0)
> -		return -1;
> -
> -	ret = test_cirbuf_char_fill();
> -	if (ret < 0)
> -		return -1;
> -
> -	return 0;
> -}
> -
> -/* test cmdline_cirbuf string functions */
> -int
> -test_cirbuf_string(void)
> -{
> -	if (test_cirbuf_string_add_del() < 0)
> -		return -1;
> -
> -	if (test_cirbuf_string_add_del_reverse() < 0)
> -		return -1;
> -
> -	if (test_cirbuf_string_add_boundaries() < 0)
> -		return -1;
> -
> -	if (test_cirbuf_string_get_del_boundaries() < 0)
> -		return -1;
> -
> -	if (test_cirbuf_string_get_del_partial() < 0)
> -		return -1;
> -
> -	if (test_cirbuf_string_misc() < 0)
> -		return -1;
> -
> -	return 0;
> -}
> -
> -/* test cmdline_cirbuf align functions */
> -int
> -test_cirbuf_align(void)
> -{
> -	if (test_cirbuf_align_left() < 0)
> -		return -1;
> -	if (test_cirbuf_align_right() < 0)
> -		return -1;
> -	return 0;
> -}
> diff --git a/test/test/test_cmdline_lib.c b/test/test/test_cmdline_lib.c
> index 65b823a..93a80d0 100644
> --- a/test/test/test_cmdline_lib.c
> +++ b/test/test/test_cmdline_lib.c
> @@ -41,8 +41,6 @@
> #include <ctype.h>
> #include <sys/queue.h>
> 
> -#include <cmdline_vt100.h>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_socket.h>
> #include <cmdline.h>
> @@ -50,113 +48,41 @@
> #include "test_cmdline.h"
> 
> /****************************************************************/
> -/* static functions required for some tests */
> -static void
> -valid_buffer(__attribute__((unused))struct rdline *rdl,
> -			__attribute__((unused))const char *buf,
> -			__attribute__((unused)) unsigned int size)
> -{
> -}
> -
> -static int
> -complete_buffer(__attribute__((unused)) struct rdline *rdl,
> -			__attribute__((unused)) const char *buf,
> -			__attribute__((unused)) char *dstbuf,
> -			__attribute__((unused)) unsigned int dstsize,
> -			__attribute__((unused)) int *state)
> -{
> -	return 0;
> -}
> -
> -/****************************************************************/
> 
> static int
> test_cmdline_parse_fns(void)
> {
> -	struct cmdline cl;
> +	struct cmdline *cl;
> 	int i = 0;
> 	char dst[CMDLINE_TEST_BUFSIZE];
> 
> +	cl = cmdline_new(NULL, "prompt", 0, 1);
> +	if (!cl)
> +		goto error;
> 	if (cmdline_parse(NULL, "buffer") >= 0)
> 		goto error;
> -	if (cmdline_parse(&cl, NULL) >= 0)
> +	if (cmdline_parse(cl, NULL) >= 0)
> 		goto error;
> 
> 	if (cmdline_complete(NULL, "buffer", &i, dst, sizeof(dst)) >= 0)
> 		goto error;
> -	if (cmdline_complete(&cl, NULL, &i, dst, sizeof(dst)) >= 0)
> +	if (cmdline_complete(cl, NULL, &i, dst, sizeof(dst)) >= 0)
> 		goto error;
> -	if (cmdline_complete(&cl, "buffer", NULL, dst, sizeof(dst)) >= 0)
> +	if (cmdline_complete(cl, "buffer", NULL, dst, sizeof(dst)) >= 0)
> 		goto error;
> -	if (cmdline_complete(&cl, "buffer", &i, NULL, sizeof(dst)) >= 0)
> +	if (cmdline_complete(cl, "buffer", &i, NULL, sizeof(dst)) >= 0)
> 		goto error;
> 
> 	return 0;
> 
> error:
> +	if (cl)
> +		cmdline_free(cl);
> 	printf("Error: function accepted null parameter!\n");
> 	return -1;
> }
> 
> static int
> -test_cmdline_rdline_fns(void)
> -{
> -	struct rdline rdl;
> -	rdline_write_char_t *wc = &cmdline_write_char;
> -	rdline_validate_t *v = &valid_buffer;
> -	rdline_complete_t *c = &complete_buffer;
> -
> -	if (rdline_init(NULL, wc, v, c) >= 0)
> -		goto error;
> -	if (rdline_init(&rdl, NULL, v, c) >= 0)
> -		goto error;
> -	if (rdline_init(&rdl, wc, NULL, c) >= 0)
> -		goto error;
> -	if (rdline_init(&rdl, wc, v, NULL) >= 0)
> -		goto error;
> -	if (rdline_char_in(NULL, 0) >= 0)
> -		goto error;
> -	if (rdline_get_buffer(NULL) != NULL)
> -		goto error;
> -	if (rdline_add_history(NULL, "history") >= 0)
> -		goto error;
> -	if (rdline_add_history(&rdl, NULL) >= 0)
> -		goto error;
> -	if (rdline_get_history_item(NULL, 0) != NULL)
> -		goto error;
> -
> -	/* void functions */
> -	rdline_newline(NULL, "prompt");
> -	rdline_newline(&rdl, NULL);
> -	rdline_stop(NULL);
> -	rdline_quit(NULL);
> -	rdline_restart(NULL);
> -	rdline_redisplay(NULL);
> -	rdline_reset(NULL);
> -	rdline_clear_history(NULL);
> -
> -	return 0;
> -
> -error:
> -	printf("Error: function accepted null parameter!\n");
> -	return -1;
> -}
> -
> -static int
> -test_cmdline_vt100_fns(void)
> -{
> -	if (vt100_parser(NULL, 0) >= 0) {
> -		printf("Error: function accepted null parameter!\n");
> -		return -1;
> -	}
> -
> -	/* void functions */
> -	vt100_init(NULL);
> -
> -	return 0;
> -}
> -
> -static int
> test_cmdline_socket_fns(void)
> {
> 	cmdline_parse_ctx_t ctx;
> @@ -193,7 +119,7 @@ static int
> test_cmdline_fns(void)
> {
> 	cmdline_parse_ctx_t ctx;
> -	struct cmdline cl, *tmp;
> +	struct cmdline *tmp;
> 
> 	memset(&ctx, 0, sizeof(ctx));
> 	tmp = cmdline_new(&ctx, "test", -1, -1);
> @@ -206,10 +132,6 @@ test_cmdline_fns(void)
> 		goto error;
> 	if (cmdline_in(NULL, "buffer", CMDLINE_TEST_BUFSIZE) >= 0)
> 		goto error;
> -	if (cmdline_in(&cl, NULL, CMDLINE_TEST_BUFSIZE) >= 0)
> -		goto error;
> -	if (cmdline_write_char(NULL, 0) >= 0)
> -		goto error;
> 
> 	/* void functions */
> 	cmdline_set_prompt(NULL, "prompt");
> @@ -220,16 +142,6 @@ test_cmdline_fns(void)
> 	cmdline_interact(NULL);
> 	cmdline_quit(NULL);
> 
> -	/* check if void calls change anything when they should fail */
> -	cl = *tmp;
> -
> -	cmdline_printf(&cl, NULL);
> -	if (memcmp(&cl, tmp, sizeof(cl))) goto mismatch;
> -	cmdline_set_prompt(&cl, NULL);
> -	if (memcmp(&cl, tmp, sizeof(cl))) goto mismatch;
> -	cmdline_in(&cl, NULL, CMDLINE_TEST_BUFSIZE);
> -	if (memcmp(&cl, tmp, sizeof(cl))) goto mismatch;
> -
> 	cmdline_free(tmp);
> 
> 	return 0;
> @@ -237,9 +149,6 @@ test_cmdline_fns(void)
> error:
> 	printf("Error: function accepted null parameter!\n");
> 	return -1;
> -mismatch:
> -	printf("Error: data changed!\n");
> -	return -1;
> }
> 
> /* test library functions. the point of these tests is not so much to test
> @@ -251,10 +160,6 @@ test_cmdline_lib(void)
> {
> 	if (test_cmdline_parse_fns() < 0)
> 		return -1;
> -	if (test_cmdline_rdline_fns() < 0)
> -		return -1;
> -	if (test_cmdline_vt100_fns() < 0)
> -		return -1;
> 	if (test_cmdline_socket_fns() < 0)
> 		return -1;
> 	if (test_cmdline_fns() < 0)
> -- 
> 2.1.4



More information about the dev mailing list