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

Message ID 1510234868-31053-1-git-send-email-adrien.mazarguil@6wind.com (mailing list archive)
State Superseded, archived
Headers

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation fail Compilation issues

Commit Message

Adrien Mazarguil Nov. 9, 2017, 1:43 p.m. UTC
  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@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(-)
  

Comments

Wiles, Keith Nov. 15, 2017, 4:12 a.m. UTC | #1
> On Nov 9, 2017, at 5:43 AM, Adrien Mazarguil <adrien.mazarguil@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.
> 

I do agree that cmdline is getting pretty old and using libedit is one solution around the long commands, but it has a lot more problems IMO.

I do not agree it has severed DPDK well, just look at test-pmd and the hoops people have to jump thru to get a new command or variation of an existing command integrated into test-pmd it is very difficult. Also if you look at the command sets in test-pmd they are very odd in that similar commands can some times be set up completely different as cmdline is too rigid and difficult to use.

I had decided to not use the circular buffer code in cmdline as it did have a few problems for what I wanted and decided to write a standard gap buffer scheme used in most editors for lines. I had looked at libedit at one point decided I did not want another dependence for DPDK. I expect even my version does not solve the long line problem, but we can convert to libedit. (and toss my pretty code :-)

Fixing the long line problem is a very minor issue compared to everything else wrong with cmdline. I would suggest we look at CLI and improve it instead. We can add libedit to CLI and then finish testing the CLI with test-pmd. The first time I converted test-pmd I did remove and simplify the commands, but I was afraid that would cause a lot of problems for testing and scripts that people have written, but it is possible to fix these problems too.


I do not think fixing cmdline is the best answer and working to convert over to CLI is the better answer here.


Regards,
Keith
  
Olivier Matz Nov. 15, 2017, 8:04 a.m. UTC | #2
Hi,

On Wed, Nov 15, 2017 at 04:12:07AM +0000, Wiles, Keith wrote:
> 
> 
> > On Nov 9, 2017, at 5:43 AM, Adrien Mazarguil <adrien.mazarguil@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.
> > 
> 
> I do agree that cmdline is getting pretty old and using libedit is one solution around the long commands, but it has a lot more problems IMO.
> 
> I do not agree it has severed DPDK well, just look at test-pmd and the hoops people have to jump thru to get a new command or variation of an existing command integrated into test-pmd it is very difficult. Also if you look at the command sets in test-pmd they are very odd in that similar commands can some times be set up completely different as cmdline is too rigid and difficult to use.
> 
> I had decided to not use the circular buffer code in cmdline as it did have a few problems for what I wanted and decided to write a standard gap buffer scheme used in most editors for lines. I had looked at libedit at one point decided I did not want another dependence for DPDK. I expect even my version does not solve the long line problem, but we can convert to libedit. (and toss my pretty code :-)
> 
> Fixing the long line problem is a very minor issue compared to everything else wrong with cmdline. I would suggest we look at CLI and improve it instead. We can add libedit to CLI and then finish testing the CLI with test-pmd. The first time I converted test-pmd I did remove and simplify the commands, but I was afraid that would cause a lot of problems for testing and scripts that people have written, but it is possible to fix these problems too.
> 
> 
> I do not think fixing cmdline is the best answer and working to convert over to CLI is the better answer here.

On my side, I think this patch goes in the correct direction:
- it solves an issue of the command line library
- it replaces a specific dpdk code by a well-known library which is widely used

Olivier
  
Wiles, Keith Nov. 15, 2017, 4:31 p.m. UTC | #3
> On Nov 15, 2017, at 12:04 AM, Olivier MATZ <olivier.matz@6wind.com> wrote:

> 

> Hi,

> 

> On Wed, Nov 15, 2017 at 04:12:07AM +0000, Wiles, Keith wrote:

>> 

>> 

>>> On Nov 9, 2017, at 5:43 AM, Adrien Mazarguil <adrien.mazarguil@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.

>>> 

>> 

>> I do agree that cmdline is getting pretty old and using libedit is one solution around the long commands, but it has a lot more problems IMO.

>> 

>> I do not agree it has severed DPDK well, just look at test-pmd and the hoops people have to jump thru to get a new command or variation of an existing command integrated into test-pmd it is very difficult. Also if you look at the command sets in test-pmd they are very odd in that similar commands can some times be set up completely different as cmdline is too rigid and difficult to use.

>> 

>> I had decided to not use the circular buffer code in cmdline as it did have a few problems for what I wanted and decided to write a standard gap buffer scheme used in most editors for lines. I had looked at libedit at one point decided I did not want another dependence for DPDK. I expect even my version does not solve the long line problem, but we can convert to libedit. (and toss my pretty code :-)

>> 

>> Fixing the long line problem is a very minor issue compared to everything else wrong with cmdline. I would suggest we look at CLI and improve it instead. We can add libedit to CLI and then finish testing the CLI with test-pmd. The first time I converted test-pmd I did remove and simplify the commands, but I was afraid that would cause a lot of problems for testing and scripts that people have written, but it is possible to fix these problems too.

>> 

>> 

>> I do not think fixing cmdline is the best answer and working to convert over to CLI is the better answer here.

> 

> On my side, I think this patch goes in the correct direction:

> - it solves an issue of the command line library

> - it replaces a specific dpdk code by a well-known library which is widely used



We are ignoring the fact we are trying to patch something that is difficult to use and does not create a clean/simple design for the developer.

Just patching this with libedit now adds two more dependencies to the DPDK libedit and now ncurses. If we moved to CLI then we can fix the one thing we need fixed is the long command line and not require more dependencies to DPDK. Adding more dependencies to DPDK is going ti cause problems with the distro’s but I assume these are around. In Ubuntu 17.04 I had to pull in libedit and ncurses to use libedit.

> 

> Olivier


Regards,
Keith
  
Adrien Mazarguil Nov. 16, 2017, 9:23 a.m. UTC | #4
Hi Keith,

On Wed, Nov 15, 2017 at 04:12:07AM +0000, Wiles, Keith wrote:
> 
> 
> > On Nov 9, 2017, at 5:43 AM, Adrien Mazarguil <adrien.mazarguil@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.
> > 
> 
> I do agree that cmdline is getting pretty old and using libedit is one solution around the long commands, but it has a lot more problems IMO.

Before going further, I'd like to put emphasis on the fact this RFC is not
pushing to retain librte_cmdline over your librte_cli proposal. Rather, it
removes about 30% of its code and shifts the blame to an external library
without modifying user applications.

It started some time ago as a quick hack to improve user experience with the
flow command in testpmd using the least amount of time and effort, which I
only recently reformatted as a proper RFC in order to get feedback from the
community.

> I do not agree it has severed DPDK well, just look at test-pmd and the hoops people have to jump thru to get a new command or variation of an existing command integrated into test-pmd it is very difficult. Also if you look at the command sets in test-pmd they are very odd in that similar commands can some times be set up completely different as cmdline is too rigid and difficult to use.

Testpmd is indeed messy, but this is not librte_cmdline's fundamental fault
in my opinion, more likely the result of using a copy/paste approach to new
commands due to lack of time or interest in making things nicer than the
bare minimum to validate features. There's no design direction for it hence
the lack of uniformity in the command hierarchy.

> I had decided to not use the circular buffer code in cmdline as it did have a few problems for what I wanted and decided to write a standard gap buffer scheme used in most editors for lines. I had looked at libedit at one point decided I did not want another dependence for DPDK. I expect even my version does not solve the long line problem, but we can convert to libedit. (and toss my pretty code :-)

I'm not sure adding dependencies to DPDK is an issue anymore. Not in the
sense "there's so many of them already, no one will notice" but more with
the need to focus community efforts a bit more on what DPDK brings that
doesn't exist elsewhere.

How many DPDK contributors are experts in termcap handling and would care to
invest time in this area, compared to say, squeezing the last drop of
performance out of their employer's HW?

I understand you've invested a lot of effort in this but I think that even
if DPDK moves to librte_cli, the switch to libedit will be unavoidable.

Keep in mind every time some feature will be requested, someone will raise
the question "why not move to libedit instead?"

> Fixing the long line problem is a very minor issue compared to everything
> else wrong with cmdline.

I beg to differ on this point, however the reason may not be obvious if
you are not familiar with the flow command (the main reason behind this
RFC).

You should try it. It basically uses dynamic cmdline_parse tokens and help
strings which enables flexible arguments with contextual help (without
printing it for hundreds of unrelated commands) and more or less infinite
command lines. That was the only sane approach to interface rte_flow.

My point is there's already a case today for long lines support, it's not
minor given rte_flow is bound to replace a lot of the legacy APIs and
associated testpmd commands (flow_director_* to name a few).

> I would suggest we look at CLI and improve it instead. We can add libedit to CLI and then finish testing the CLI with test-pmd. The first time I converted test-pmd I did remove and simplify the commands, but I was afraid that would cause a lot of problems for testing and scripts that people have written, but it is possible to fix these problems too.
> 
> I do not think fixing cmdline is the best answer and working to convert over to CLI is the better answer here.

In truth I didn't do my homework. Before your reply I completely forgot
about the librte_cli proposal and related dpdk-draft-cli tree. It didn't
cross my mind to check it out before working on this RFC.

I'm now aware of how much effort you put in this and what it takes to
reorder and reimplement all testpmd commands. That's huge. It seems like
we're fighting unrelated battles though.

To summarize:

- You don't like librte_cmdline for various reasons and provide librte_cli
  as an alternative along a testpmd implementation. I assume the goal is to
  remove librte_cmdline once every application has switched.

- I don't mind librte_cmdline, but I don't expect it to grow nor to be used
  by applications outside test programs in DPDK itself, hence I choose to
  strip its unused parts and make the rest a wrapper to libedit without
  modifying applications.

Both are not incompatible, and since I think libedit will be unavoidable for
librte_cli, my approach can be seen as temporary until something replaces
librte_cmdline. In the meantime, users still benefit from much better
command line handling at no extra cost.
  
Wiles, Keith Nov. 16, 2017, 4:48 p.m. UTC | #5
> On Nov 16, 2017, at 1:23 AM, Adrien Mazarguil <adrien.mazarguil@6wind.com> wrote:
> 
> Hi Keith,
> 
> On Wed, Nov 15, 2017 at 04:12:07AM +0000, Wiles, Keith wrote:
>> 
>> 
>>> On Nov 9, 2017, at 5:43 AM, Adrien Mazarguil <adrien.mazarguil@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.
>>> 
>> 
>> I do agree that cmdline is getting pretty old and using libedit is one solution around the long commands, but it has a lot more problems IMO.
> 
> Before going further, I'd like to put emphasis on the fact this RFC is not
> pushing to retain librte_cmdline over your librte_cli proposal. Rather, it
> removes about 30% of its code and shifts the blame to an external library
> without modifying user applications.
> 
> It started some time ago as a quick hack to improve user experience with the
> flow command in testpmd using the least amount of time and effort, which I
> only recently reformatted as a proper RFC in order to get feedback from the
> community.
> 
>> I do not agree it has severed DPDK well, just look at test-pmd and the hoops people have to jump thru to get a new command or variation of an existing command integrated into test-pmd it is very difficult. Also if you look at the command sets in test-pmd they are very odd in that similar commands can some times be set up completely different as cmdline is too rigid and difficult to use.
> 
> Testpmd is indeed messy, but this is not librte_cmdline's fundamental fault
> in my opinion, more likely the result of using a copy/paste approach to new
> commands due to lack of time or interest in making things nicer than the
> bare minimum to validate features. There's no design direction for it hence
> the lack of uniformity in the command hierarchy.
> 
>> I had decided to not use the circular buffer code in cmdline as it did have a few problems for what I wanted and decided to write a standard gap buffer scheme used in most editors for lines. I had looked at libedit at one point decided I did not want another dependence for DPDK. I expect even my version does not solve the long line problem, but we can convert to libedit. (and toss my pretty code :-)
> 
> I'm not sure adding dependencies to DPDK is an issue anymore. Not in the
> sense "there's so many of them already, no one will notice" but more with
> the need to focus community efforts a bit more on what DPDK brings that
> doesn't exist elsewhere.
> 
> How many DPDK contributors are experts in termcap handling and would care to
> invest time in this area, compared to say, squeezing the last drop of
> performance out of their employer's HW?
> 
> I understand you've invested a lot of effort in this but I think that even
> if DPDK moves to librte_cli, the switch to libedit will be unavoidable.
> 
> Keep in mind every time some feature will be requested, someone will raise
> the question "why not move to libedit instead?"
> 
>> Fixing the long line problem is a very minor issue compared to everything
>> else wrong with cmdline.
> 
> I beg to differ on this point, however the reason may not be obvious if
> you are not familiar with the flow command (the main reason behind this
> RFC).
> 
> You should try it. It basically uses dynamic cmdline_parse tokens and help
> strings which enables flexible arguments with contextual help (without
> printing it for hundreds of unrelated commands) and more or less infinite
> command lines. That was the only sane approach to interface rte_flow.
> 
> My point is there's already a case today for long lines support, it's not
> minor given rte_flow is bound to replace a lot of the legacy APIs and
> associated testpmd commands (flow_director_* to name a few).
> 
>> I would suggest we look at CLI and improve it instead. We can add libedit to CLI and then finish testing the CLI with test-pmd. The first time I converted test-pmd I did remove and simplify the commands, but I was afraid that would cause a lot of problems for testing and scripts that people have written, but it is possible to fix these problems too.
>> 
>> I do not think fixing cmdline is the best answer and working to convert over to CLI is the better answer here.
> 
> In truth I didn't do my homework. Before your reply I completely forgot
> about the librte_cli proposal and related dpdk-draft-cli tree. It didn't
> cross my mind to check it out before working on this RFC.
> 
> I'm now aware of how much effort you put in this and what it takes to
> reorder and reimplement all testpmd commands. That's huge. It seems like
> we're fighting unrelated battles though.
> 
> To summarize:
> 
> - You don't like librte_cmdline for various reasons and provide librte_cli
>  as an alternative along a testpmd implementation. I assume the goal is to
>  remove librte_cmdline once every application has switched.
> 
> - I don't mind librte_cmdline, but I don't expect it to grow nor to be used
>  by applications outside test programs in DPDK itself, hence I choose to
>  strip its unused parts and make the rest a wrapper to libedit without
>  modifying applications.
> 
> Both are not incompatible, and since I think libedit will be unavoidable for
> librte_cli, my approach can be seen as temporary until something replaces
> librte_cmdline. In the meantime, users still benefit from much better
> command line handling at no extra cost.

OK, I understand your points and not to state your work was in vain, but it would have been better if we had applied the effort to the CLI. I do not agree per-say that libedit is required for CLI as the only feature we need is to handle long lines and their are easier ways to do then using libedit.

I was looking at the problem and I think we can handle long lines without libedit, I will try to put together an example soon.

For now we can accept your patch for cmdline as it does add the support without much effort.

> 
> -- 
> Adrien Mazarguil
> 6WIND

Regards,
Keith
  
Jim Thompson Nov. 16, 2017, 4:53 p.m. UTC | #6
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@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@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@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@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@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@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@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@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
  
Ferruh Yigit Nov. 16, 2017, 5:06 p.m. UTC | #7
On 11/16/2017 1:23 AM, Adrien Mazarguil wrote:
<...>

>> I do not agree it has severed DPDK well, just look at test-pmd and the hoops people have to jump thru to get a new command or variation of an existing command integrated into test-pmd it is very difficult. Also if you look at the command sets in test-pmd they are very odd in that similar commands can some times be set up completely different as cmdline is too rigid and difficult to use.
> 
> Testpmd is indeed messy, but this is not librte_cmdline's fundamental fault
> in my opinion, more likely the result of using a copy/paste approach to new
> commands due to lack of time or interest in making things nicer than the
> bare minimum to validate features. There's no design direction for it hence
> the lack of uniformity in the command hierarchy.

Unrelated to cmdline discussion +1 for this paragraph.
  
Wiles, Keith Nov. 16, 2017, 5:27 p.m. UTC | #8
> On Nov 16, 2017, at 9:06 AM, Yigit, Ferruh <ferruh.yigit@intel.com> wrote:
> 
> On 11/16/2017 1:23 AM, Adrien Mazarguil wrote:
> <...>
> 
>>> I do not agree it has severed DPDK well, just look at test-pmd and the hoops people have to jump thru to get a new command or variation of an existing command integrated into test-pmd it is very difficult. Also if you look at the command sets in test-pmd they are very odd in that similar commands can some times be set up completely different as cmdline is too rigid and difficult to use.
>> 
>> Testpmd is indeed messy, but this is not librte_cmdline's fundamental fault
>> in my opinion, more likely the result of using a copy/paste approach to new
>> commands due to lack of time or interest in making things nicer than the
>> bare minimum to validate features. There's no design direction for it hence
>> the lack of uniformity in the command hierarchy.
> 
> Unrelated to cmdline discussion +1 for this paragraph.

As a side note should CLI change the test-pmd commands to be more reasonable or maintain the current commands to not break testing. I would like to fix these commands with CLI, but as I have both built into test-pmd currently we can could keep the old cmdline commands and if you use the new CLI then it would be the new cleaner commands.

Regards,
Keith
  
Thomas Monjalon Nov. 16, 2017, 6:05 p.m. UTC | #9
16/11/2017 18:27, Wiles, Keith:
> 
> > On Nov 16, 2017, at 9:06 AM, Yigit, Ferruh <ferruh.yigit@intel.com> wrote:
> > 
> > On 11/16/2017 1:23 AM, Adrien Mazarguil wrote:
> > <...>
> > 
> >>> I do not agree it has severed DPDK well, just look at test-pmd and the hoops people have to jump thru to get a new command or variation of an existing command integrated into test-pmd it is very difficult. Also if you look at the command sets in test-pmd they are very odd in that similar commands can some times be set up completely different as cmdline is too rigid and difficult to use.
> >> 
> >> Testpmd is indeed messy, but this is not librte_cmdline's fundamental fault
> >> in my opinion, more likely the result of using a copy/paste approach to new
> >> commands due to lack of time or interest in making things nicer than the
> >> bare minimum to validate features. There's no design direction for it hence
> >> the lack of uniformity in the command hierarchy.
> > 
> > Unrelated to cmdline discussion +1 for this paragraph.
> 
> As a side note should CLI change the test-pmd commands to be more reasonable or maintain the current commands to not break testing. I would like to fix these commands with CLI, but as I have both built into test-pmd currently we can could keep the old cmdline commands and if you use the new CLI then it would be the new cleaner commands.

I think we must keep the existing testpmd commands for a while to not
disturb people using it integrated in their testing tools.
If we introduce a new set of commands, we can define a deadline for removal
of old commands.
  
Thomas Monjalon Nov. 16, 2017, 6:07 p.m. UTC | #10
16/11/2017 17:48, Wiles, Keith:
> For now we can accept your patch for cmdline as it does add the support without much effort.

I agree.
  

Patch

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@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@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@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@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@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@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)