A vt100 command line interface and command parser module. More...
#include <terminal.h>

Classes | |
| class | cmdhandler |
| An array node containing a link to a specific command execution method. More... | |
| class | expandsource |
| An array node containing a link to a specific dynamic list method. More... | |
Public Types | |
| typedef value *(ctlclass::* | srcmethod )(const value &, int) |
| typedef int(ctlclass::* | hmethod )(const value &) |
Public Member Functions | |
| cli (ctlclass *p, file &in, file &out, int _size=4096, int _wsize=0) | |
| ~cli (void) | |
| value * | callsrc (const statstring &srcid, const value &cmd, int pos) |
| void | addsrc (const statstring &srcid, srcmethod m) |
| void | addsyntax (const string &cmd, hmethod m, const string &help) |
| void | addsyntax (const string &cmd, hmethod m) |
| void | addhelp (const string &path, const string &help) |
| void | fullexpand (visitor< value > &probe, value &cmd, int atpos, value &into) |
| void | setctrlmacro (char ctrlkey, const string &data, bool forceempty=false) |
| int | ctrlmacrohandler (int ki, termbuffer &tb) |
| int | tabhandler (int ki, termbuffer &tb) |
| void | run (const string &p) |
| bool | singlecmd (const string &c) |
| void | setprompt (const string &p) |
| void | sendconsole (const string &s) |
| void | printf (const char *fmt,...) |
Public Attributes | |
| terminal< cli< ctlclass > > | term |
Protected Attributes | |
| expandsource * | first |
| expandsource * | last |
| cmdhandler * | hfirst |
| cmdhandler * | hlast |
| value | cmdtree |
| value | ctrlmacros |
| string | prompt |
| ctlclass * | owner |
| statstring | curcmd |
| value | cmdline |
| string | linebuffer |
A vt100 command line interface and command parser module.
The parser's main principle is a syntax tree where certain nodes may be of a dynamic type. The end of a tree leads to a callback. Callbacks both for dynamic types and command execution are non-static methods of the ctlclass.
Here's an example of an application using a cli without dynamic lists:
#include <grace/application.h>
#include <grace/filesystem.h>
#include <grace/terminal.h>
class myshell : public application
{
public:
myshell (void) : application ("com.panelsix.apps.myshell"),
shell (this, fin, fout)
{
}
~myshell (void);
int cmdPrintVersion (const value &args)
{
fout.printf ("MyShell version 1.0\n");
return 0;
}
int cmdListFiles (const value &args)
{
value dir;
dir = fs.ls ();
foreach (file, dir)
{
fout.printf ("%s\n", file.id().str());
}
return 0;
}
int cmdExit (const value &args) { return 1; }
int main (void)
{
shell.addsyntax ("show version", &myshell::cmdPrintVersion);
shell.addsyntax ("show files", &myshell::cmdListFiles);
shell.addsyntax ("exit", &myshell::cmdExit);
shell.addhelp ("show", "Display information");
shell.addhelp ("show version", "Application version");
shell.addhelp ("show files", "Files in the directory");
shell.run ("myshell$ ");
return 0;
}
cli<myshell> shell;
};
The two built-in tokens '*' and '#' can be used to substitute generic string input. A word in a syntax rule containing a '*' will accept any non-whitespace input or input enclosed by full quotes. The '#' word can be appended at the end of a rule and indicates that the previous rule should be evaluated for each consecutive word in the command line. Here is an example:
#include <grace/application.h>
#include <grace/filesystem.h>
#include <grace/terminal.h>
class myshell : public application
{
public:
myshell (void) : application ("com.panelsix.apps.myshell"),
shell (this, fin, fout)
{
}
~myshell (void);
int cmdEcho (const value &args)
{
bool first = true;
value v = args;
v.rmindex (0);
foreach (arg, v)
{
if (! first) { first = true; fout.puts (" "); }
fout.puts (arg.sval());
}
fout.puts ("\n");
return 0;
}
int cmdCalc (const value &args)
{
int result;
caseselector (args[2])
{
incaseof ("+") :
result = args[1].ival() + args[3].ival();
break;
incaseof ("-"):
result = args[1].ival() - args[3].ival();
break;
defaultcase:
fout.printf ("%% Unknown operand\n");
return 0;
}
fout.printf ("%i\n", result);
return 0;
}
int cmdExit (const value &args) { return 1; }
int main (void)
{
shell.addsyntax ("echo *", &myshell::cmdEcho);
shell.addsyntax ("echo * #", &myshell::cmdEcho);
shell.addsyntax ("calc * + *", &myshell::cmdCalc);
shell.addsyntax ("calc * - *", &myshell::cmdCalc);
shell.addsyntax ("exit", &myshell::cmdExit);
shell.run ("myshell$ ");
return 0;
}
cli<myshell> shell;
};
| cli< ctlclass >::cli | ( | ctlclass * | p, | |
| file & | in, | |||
| file & | out, | |||
| int | _size = 4096, |
|||
| int | _wsize = 0 | |||
| ) | [inline] |
Constructor.
| p | The parent object to associate with callbacks. | |
| in | The application input stream. | |
| out | The application output stream. | |
| _size | The buffer size (default 4096). | |
| _wsize | THe window width (default auto). |
References terminal< ctlclass >::addkeyresponse(), cli< ctlclass >::first, cli< ctlclass >::hfirst, cli< ctlclass >::hlast, cli< ctlclass >::last, cli< ctlclass >::owner, and cli< ctlclass >::term.

Destructor.
Remove linked lists.
References cli< ctlclass >::first, cli< ctlclass >::hfirst, cli< ctlclass >::hlast, and cli< ctlclass >::last.
| void cli< ctlclass >::addhelp | ( | const string & | path, | |
| const string & | help | |||
| ) | [inline] |
Add a help text.
Dynamic lists/types can generate their own help data, but any static text words should be explained. So, if you declare the syntax "show fridge status", you should add help for "show", "show fridge" as well as "show fridge status".
| path | The command and its parameters. | |
| help | The help text for the final node. |
References cli< ctlclass >::cmdtree.
Referenced by cli< ctlclass >::addsyntax().
| void cli< ctlclass >::addsrc | ( | const statstring & | srcid, | |
| srcmethod | m | |||
| ) | [inline] |
Add a link to a dynamic list source.
A source should be a method to the parent class that returns a pointer to a new value object which contains a context- sensitive list of expansion options for a given command list at a given cursor position.
| srcid | The source id, including the leading '@'. | |
| m | The method to call on the parent object. |
References cli< ctlclass >::first, and cli< ctlclass >::last.
| void cli< ctlclass >::addsyntax | ( | const string & | cmd, | |
| hmethod | m | |||
| ) | [inline] |
Add a syntax rule.
| cmd | The command and its parameters. | |
| m | The method on the parent object to call. |
References cli< ctlclass >::cmdtree, cli< ctlclass >::hfirst, and cli< ctlclass >::hlast.
| void cli< ctlclass >::addsyntax | ( | const string & | cmd, | |
| hmethod | m, | |||
| const string & | help | |||
| ) | [inline] |
Add a syntax rule and help text.
A rule is a list of words separated by a single space. Words can be either:
| cmd | The command and its parameters. | |
| m | The method on the parent object to call. | |
| help | text for the final node of the command list. |
References cli< ctlclass >::addhelp().

| value* cli< ctlclass >::callsrc | ( | const statstring & | srcid, | |
| const value & | cmd, | |||
| int | pos | |||
| ) | [inline] |
Call a dynamic list source with a specific command line context.
| srcid | The source id, including the leading '@'. | |
| cmd | The command line. | |
| pos | The focused position in the command list. |
References cli< ctlclass >::first, and cli< ctlclass >::owner.
Referenced by cli< ctlclass >::fullexpand().
| void cli< ctlclass >::fullexpand | ( | visitor< value > & | probe, | |
| value & | cmd, | |||
| int | atpos, | |||
| value & | into | |||
| ) | [inline] |
Internal expansion method.
Given a visitor to the syntax tree, the array of input words, the current input word position, this method will gather a list of all possible completions for the currently entered characters at the position.
| probe | The syntax cursor. | |
| cmd | The command line. | |
| atpos | The word the cursor is in. | |
| into | The return array. Nodes will have the completed word as their id, the description as their value and the actual token represented by the match in the syntax tree inside the "node" attribute. |
References cli< ctlclass >::callsrc(), value::clear(), value::id, visitor< kind >::obj(), string::strlen(), string::strncmp(), and value::sval().
Referenced by cli< ctlclass >::tabhandler().

Start the command line interpreter.
| p | The prompt. |
References cli< ctlclass >::cmdline, value::count(), cli< ctlclass >::curcmd, cli< ctlclass >::hfirst, termbuffer::off(), cli< ctlclass >::owner, cli< ctlclass >::cmdhandler::path, cli< ctlclass >::prompt, terminal< ctlclass >::readline(), cli< ctlclass >::cmdhandler::runcmd(), cli< ctlclass >::setprompt(), string::strlen(), cli< ctlclass >::tabhandler(), cli< ctlclass >::term, terminal< ctlclass >::termbuf, and termbuffer::tprintf().

Send data to the console.
Can be used by other threads while the cli is in run() mode.
References terminal< ctlclass >::sendconsole(), and cli< ctlclass >::term.

Start the command line interpreter.
| p | The prompt. |
References cli< ctlclass >::cmdline, value::count(), cli< ctlclass >::curcmd, cli< ctlclass >::hfirst, cli< ctlclass >::owner, cli< ctlclass >::cmdhandler::path, cli< ctlclass >::cmdhandler::runcmd(), termbuffer::set(), cli< ctlclass >::tabhandler(), cli< ctlclass >::term, terminal< ctlclass >::termbuf, and termbuffer::tprintf().

| int cli< ctlclass >::tabhandler | ( | int | ki, | |
| termbuffer & | tb | |||
| ) | [inline] |
Keyhandler for tab expansion and the question mark key.
| ki | The pressed key, either '\t', '?' or 0, which is a special trigger to fully expand any abbreviated words to their full syntax tree equivalent. | |
| tb | The termbuffer. |
References value::attribexists(), value::clear(), cli< ctlclass >::cmdline, cli< ctlclass >::cmdtree, value::count(), termbuffer::crsrpos(), cli< ctlclass >::curcmd, visitor< kind >::enter(), visitor< kind >::exists(), cli< ctlclass >::fullexpand(), termbuffer::getline(), value::id, termbuffer::insert(), string::ltrim(), visitor< kind >::obj(), termbuffer::redraw(), string::rtrim(), cliutil::splitwords(), string::strchr(), value::strlen(), string::strlen(), value::sval(), termbuffer::tprintf(), and visitor< kind >::up().
Referenced by cli< ctlclass >::run(), and cli< ctlclass >::singlecmd().

1.6.1