simple CLI architecture

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
Hello, All!

    I'm trying to implement simple Command Line Interface (CLI) for our
design based on linux. I will use GCC as compiler. I don't need some special
features (like command line editing, commands history  etc.) by now,  just
simple and basic functionality:
1) enter command
2) parse command line
3) execute code related to command

Seems to be simple but I don't have any idea right now, that's why I ask for
you to help me out :)

With best regards, Roman Mashak.  E-mail: snipped-for-privacy@tusur.ru



Re: simple CLI architecture

Quoted text here. Click to load it

Perhaps the pseudo code below will help, I am not sure
I understand what you miss exactly.

You compile your C code, get an executable and run it in
a shell.

While(1)
{
   fgets(string, num, stdin); // get a newline from user input
   parse (string);            // Split your string into words
                              // Put them where you want (array)

   if (!strcmp ("cmd1", first_word))      cmd1_function();
   else if (!strcmp ("cmd2", first_word)) cmd2_function();
   ...
   else if (!strcmp ("Q", first_word))    exit();
}


Re: simple CLI architecture
Quoted text here. Click to load it

You might also consider putting the commands in an array, and searching
through the array for a matching command.  And you might check out the
GNU readline library as well for an easy way to support command line
editing, history buffer, and with a smidge of programming,
tab-completion for your command set.  Google is your friend.

Kelly

Re: simple CLI architecture
Quoted text here. Click to load it

I would suggest at LEAST backspace/backwards delete support would be useful.
However if you are using linux you should have this anyway, from the get
string function.

Quoted text here. Click to load it

Solution depends on how many commands you are going to support and how many
parameters. The simplest solution is spaghetti if .. then .. else statements
which is awkward to follow and actual code change to add another function.

Is your command line always

        <action> <parameter1> <parameter2>.....<parametern>

Get a string of the whole input line (knowing what max size is and watching
that user cannot input a line beyond that size).

Then ensure you have a table of strings that match the <action>, and a
matching table of the function calls. Important note are commands CAse
sensitive, if not always upper or lower case the table and what you match it
against from the input. The advantage of a table method is you can easily
add commands to the table with minimal hassle.

If white space (space, tab) are only used to separate <action> and
<parameters>, consider first scanning the command line to give a list of
parameter starting addresses, and a total number of parameters. Changing
spaces to NULL character unless you are using external commands.

Scan the <action> table for a string match on the first entry <action>, for
a match call the matching function (all functions must use the SAME structure
e.g. int func( int ) ). Preferably passing in number of parameters and
returning error code for invalid parameters or success. I often write these
type of table CLI with a table of structures for embedded work (debug monitor)
so that the table is a table of structures like

        string address          <action> to match
        mode                    Unit modes valid command for
        min arguments
        max arguments
        function address

This way some of the repetitive checks are done by one piece of code NOT
REPEATED in every other function.

In embedded work I make standard parameter parsing functions to convert
string parameters to various number formats with limits check parameters
so each function makes the call to convert and check the ranges of inputs
and return error codes  and values are stored to known variables. Also
reducing the duplication of some checks.

        e.g.   if( conv_hex( &parameter, min, max, mask, &result ) < SUCCESS )
                 error action
               else
                 next action

If your parameter string table always contains a pointer to the <action>
parameter then external functions (other programmes) can be called as well
either because you have reached the end of the table or you have a list of
allowed external functions and you have the ability to pass the complete
command line across.

The advantages of this approach is that a flexible method of adding
extra functions is created, that is easy to maintain, and all your
action functions have a common method of calling/return. This way you
add a function and you are only testing that function, not changes
to add the function as well. This method can be easily adapted for
tree level functions where the CLI is working like a menuing system.

Examples of this sort of code do exist on the web.

--
Paul Carpenter          | snipped-for-privacy@pcserviceselectronics.co.uk
<http://www.pcserviceselectronics.co.uk/ PC Services
We've slightly trimmed the long signature. Click to see the full one.
Re: simple CLI architecture
Hello, Paul!
You wrote  on Fri, 03 Jun 2005 09:00:56 +0100 (BST):

First of all, I'd like to thank everybody for advices.

 PC> Is your command line always

 PC>         <action> <parameter1> <parameter2>.....<parametern>
    yes. exactly.
 PC> Get a string of the whole input line (knowing what max size is and
 PC> watching that user cannot input a line beyond that size).

 PC> Then ensure you have a table of strings that match the <action>, and a
 PC> matching table of the function calls. Important note are commands CAse
 PC> sensitive, if not always upper or lower case the table and what you
 PC> match it against from the input. The advantage of a table method is you
 PC> can easily add commands to the table with minimal hassle.
    So, you recommend to make two tables (for example in the form of
arrays?):
1) table of strings ("show", "help", "conf" etc.)
2) table of matching functions. In this case - what is the key for matching?

 PC> If white space (space, tab) are only used to separate <action> and
 PC> <parameters>, consider first scanning the command line to give a list
 PC> of parameter starting addresses, and a total number of parameters.
 PC> Changing spaces to NULL character unless you are using external
 PC> commands.
    What os the reason of changing spaces into NULL character?
[skip]

 PC> The advantages of this approach is that a flexible method of adding
 PC> extra functions is created, that is easy to maintain, and all your
 PC> action functions have a common method of calling/return. This way you
 PC> add a function and you are only testing that function, not changes
 PC> to add the function as well. This method can be easily adapted for
 PC> tree level functions where the CLI is working like a menuing system.

 PC> Examples of this sort of code do exist on the web.
    I searched but didn't find yet, will try again.

With best regards, Roman Mashak.  E-mail: snipped-for-privacy@tusur.ru



Re: simple CLI architecture
Quoted text here. Click to load it

Do yourself and all your users a big favor. Use a predefined CLI
package. My favorite is embedded TCL.

This way, your CLI is up in a week, has full scripting and control language,
and has an off the shelf users manual.


Re: simple CLI architecture
Hello, Scott!
You wrote  on Fri, 03 Jun 2005 11:52:04 -0700:

 ??>> command 2) parse command line 3) execute code related to command Seems
 ??>> to be simple but I don't have any idea right now, that's why I ask for
 ??>> you to help me out :) With best regards, Roman Mashak.  E-mail:
 ??>> snipped-for-privacy@tusur.ru

 SM> Do yourself and all your users a big favor. Use a predefined CLI
 SM> package. My favorite is embedded TCL.
    What do you think about using flex+bison for my task? The only reason
that stops me is I don't know this well.

With best regards, Roman Mashak.  E-mail: snipped-for-privacy@tusur.ru



Site Timeline