SPRAAK
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
Data Structures | Macros | Enumerations | Functions | Variables
cmd.c File Reference

Simple command interpreter. More...

Data Structures

struct  SprCmdDesc
 
struct  SprCmdOptDesc
 
struct  SprCmdBuf
 

Macros

#define spr_cmd_aux(aux_array, array_el0,...)
 

Enumerations

enum  {
  SPR_CMD_CIO_PSPEC, SPR_CMD_CIO_WORD, SPR_CMD_CIO_STRING, SPR_CMD_CIO_EXPR,
  SPR_CMD_CIO_CSTRING, SPR_CMD_CIO_VAROP
}
 
enum  {
  SPR_CMD_CIO_USPEC, SPR_CMD_CIO_MSPEC, SPR_CMD_CIO_UNIQ, SPR_CMD_CIO_MULTI,
  SPR_CMD_CIO_FBACK, SPR_CMD_CIO_SCAT
}
 the option can be specified only once or multiple times More...
 
enum  { SPR_CMD_CIO_RSPEC, SPR_CMD_CIO_OPT, SPR_CMD_CIO_REQ }
 
enum  { SPR_CMD_CIO_SPC, SPR_CMD_CIO_NPRNT, SPR_CMD_CIO_CHECK }
 
enum  {
  SPR_CMD_CIO_EXCL1, SPR_CMD_CIO_EXCL2, SPR_CMD_CIO_EXCL3, SPR_CMD_CIO_EXCL4,
  SPR_CMD_CIO_EXCL5, SPR_CMD_CIO_EXCL6, SPR_CMD_CIO_EXCL7, SPR_CMD_CIO_EXCL8
}
 

Functions

char * spr_cmd_strccvt (char *str_in, int quoted_only)
 
char * spr_cmd_ci_skip_space (const char *str, const char *blancs)
 
char * spr_cmd_ci_skip_word (const char *str, const char *blancs)
 
char * spr_cmd_ci_skip_cstring (const char *str, const char *blancs)
 
char * spr_cmd_ci_skip_expression (const char *str, const char *blancs)
 
char * spr_cmd_ci_skip_varop (const char *str, const char *blancs, int *status)
 
char * spr_cmd_ci_next_word (const char **parse_ptr, int *len, const char *blancs)
 
int spr_cmd_ci_get_words (char **str_array, const char *str, const char *blancs)
 
int spr_cmd_ci_print_cmd (SprStream *fd, const char *cmd, const char *sep_str, const char *blancs)
 
int spr_cmd_ci_check_flag (const char *template_, const char *word, int len)
 
void spr_cmd_ci_print_opts (SprStream *fd, char *lm, void *dest_ptr, const SprCmdOptDesc *od, char *blancs)
 
int spr_cmd_ci_check_opts (void *dest_ptr, const SprCmdOptDesc *od, const char *cmd_str, int len, int opt_sep, const char *blancs, int flags)
 
int spr_cmd_ci_screen_width (SprStream *fd, int fdi, int def_width)
 
void spr_ci_print_optsyntax (SprStream *fd, const char *lm, const SprCmdOptDesc *od, int opt_sep)
 
void spr_cmd_ci_print_syntax (SprStream *fd, const SprCmdDesc *cmd, int detailed)
 
void spr_cmd_ci_print_syntax_ (SprStream *fd, const char *template_, const void *const *ext_info, int detailed)
 See ci_print_syntax(). More...
 
int spr_cmd_ci_hash (char *const *set, const char *elem, int len, int full_match)
 
int spr_cmd_ci_test_syntax (const char *Template, const void *const *ext_info, const char *cmd_str, const char *blancs)
 
SprCmdBufspr_cmd_ci_free_cnt (SprCmdBuf *cmdbuf)
 Free a previously allocated count buffer. More...
 
int spr_cmd_ci_init_cnt (const SprCmdDesc *cmd_list, SprCmdBuf *cmdbuf)
 
int spr_cmd_ci_check_cnt (SprCmdBuf *cmdbuf, int msg_level, SprMsgId *routine)
 
SprCmdBufspr_cmd_ci_init_cmdbuf (SprCmdBuf *cmdbuf)
 
SprCmdBufspr_cmd_ci_free_cmdbuf (SprCmdBuf *cmdbuf)
 
int spr_cmd_ci_init_find (const char *template_, const void *const *ext_info, const char *cmd_str, const char *blancs, SprCmdBuf *cmdbuf)
 
int spr_cmd_ci_decode (const SprCmdDesc *cmd_list, const char *cmd, const char *blancs, SprCmdBuf *cmdbuf)
 
int spr_cmd_ci_decode_ (const SprCmdDesc *cmd_list, const char *cmd, const char *blancs, SprCmdBuf *cmdbuf)
 The OLD, non dynamical counter part of ci_decode(). More...
 
void spr_cmd_ci_print_help_ (SprStream *fd, const SprCmdDesc *cmd_list, const char *matchstr, const char *blancs, int matchcnt, int help_level)
 
void spr_cmd_ci_print_help (SprStream *fd, const char *min_match, int help_level, SprCmdBuf *cmdbuf)
 Print help for a command. Only the command(s) that match min_match for all words specified in the string will be printed. The commands listed are those used in the last ci_decode() with the specified cmdbuf.
The amount of output is also controled by help_level More...
 
void spr_cmd_ci_online_help (SprStream *help_dest, int help_flag, SprCmdBuf *cmdbuf)
 
char * spr_cmd_ci_arg_ptr (SprCmdBuf *cmdbuf)
 
char * spr_cmd_ci_get_arg (const char *defval, SprCmdBuf *cmdbuf)
 
int spr_cmd_ci_get_flag (const char *defflag, SprCmdBuf *cmdbuf)
 
int spr_cmd_ci_get_enum (const char *defstr, SprCmdBuf *cmdbuf)
 
int spr_cmd_ci_get_opts (void *dest_ptr, SprCmdBuf *cmdbuf)
 
int spr_cmd_wait_for_child (int pid)
 
int spr_cmd_ci_exec (char *Stdin, char *Stdout, char *Stderr, const char *flags, const char *exec_str,...)
 
int spr_cmd_execute_string (int waitfor, char *string)
 returns child ID More...
 
int spr_cmd_ci_shell (const char *exec_str, const char *shell)
 
int spr_cmd_ci_system (const char *exec_str)
 
char * spr_cmd_ci_prompt (SprStream *fd_in, SprStream *fd_out, char buf[], int max_len, const char *prompt)
 

Variables

const char *const spr_cmd_yes_no_flags []
 
char spr_cmd_snull []
 
const SprCmdBuf spr_cmd_empty_cmdbuf
 empty cmdbuf More...
 

Detailed Description

Simple command interpreter.

Interprete a given command (or option) string using the command description in a command description list.

The command description list is an array of elements of the type Cmd. The list is terminated with a special end element. The elements are structures, with the following fields:

   int  command_nr;   // number that identifies this command
   char *template;    // template of the command syntax
   char *explanation; // one line explanation of the command
   void **ext_info;   // extra pointer to data structures

The last element should be:

  {-1,NULL,NULL,NULL}

The template is a string containing description fields separated by ONE space. The following fields are available:

  %s<str_name>          required string argument.
  %s[str_name]          optional string argument.
  %n<num_field>         required numerical argument.
  %n[num_field]         optional numerical argument.
  %F<flag1/flag2/...>   required flag (e.g. <on/off>).
  %F[flag1/flag2/...]   optional flag.
  %l+literal_text       literal text, no abbreviation or concatenation allowed.
  %l-literal_text       literal text, no abbreviation.
  %o<,explain>          a set of options, no spaces allowed; first character after '<' is the options delimiter.
  %o[,explain]          a set of options, spaces allowed, always the last option; first character after '[' is the options delimiter..
  %E<literal_enum>      required literal enumeration.
  %E[literal_enum]      optional literal enumeration.
  %e<literal_enum>      required abbreviated enumeration.
  %e[literal_enum]      optional abbreviated enumeration.
  key_word              key word in the command syntax; abbreviations allowed.

For an optional field the default value can be given by appending it between brackets after the description field, e.g.: %F[on/off](on).

A non standard parsing can be requested by starting the command description with a space, followed by some character flags, followed by the normal description. The following character flags are available:

o
The given command is optional (default). See also ci_check_cnt().
r
The given command is required. See also ci_check_cnt().
1
The given command may only be specified once. See also ci_check_cnt().
w
Parse the given command as a sequence of words. See ci_skip_word().
s
Parse the given command as a sequence of C-strings. See ci_skip_cstring().
c
Parse the given command as a sequence of C-strings. If the value of the field is surrounded by double quotes, it is converted by strccvt().
v
Parse the given command as a sequence of variable names and C-operators.
x
Parse the given command as a sequence of expressions. See ci_skip_expression().
S
Be silent (no error messages) when decoding the options.

The enumeration and optional fields requires some extra information. If one of these types is used, the <ext_info> field in the Cmd structure must point to an array containing pointers to some extra information for each enumeration and/or optional field in the description string. An enumeration field requires a NULL terminated array of strings with the names of all possible values (see also hash()). An optional field requires an option description array (see ci_check_opts()). The option separator used while decoding the options must be specified directely after the open bracket. A tab ('\t') indicates the default system blancs.

The command matching is straight forward: All fields in the command string should be separated by a white space characters (by default: space, tab, newline). The key-words are only checked up to the number of characters typed by the user, and are case insensitive. The flags are also case insensitive, but should match exactely, e.g.: 'SeT h On' matches the template 'set help %F<on/off>'. The literal text can not be abbreviated. For the concatenated case, the next option must not be (but may be) separated by one or more white space characters. The first command template that matches the given command string is selected (there is no requirement on the uniqueness of the match).

When scanning for the arguments, some pointers are required. These pointers are stored in a Cmdbuf structure. One can use ones own Cmdbuf structure, or use the internal buffer by specifying the NULL pointer for the Cmdbuf argument. Note that there is only one internal buffer, so if you are using the command interpreter in your main program and in a subroutine, at least one of them should have its specific Cmdbuf.

Whenever a default value should be given, the NULL pointer can be given. In that case, the default value given in the template is used (or NULL if no default value is available).

For simple task the following commands should suffice:

  ci_prompt:       prompt for input.
  ci_decode:       find a matching command template.
  ci_print_help:   give help information about a command.
  ci_get_arg:      get an argument after decoding.
  ci_get_flag:     get the value of a flag argument.
  ci_get_options:  get/decode the options.
  ci_get_enum:     get the value of a enumerate argument.
  ci_arg_ptr:      get the pointer to the remaining arguments.

Example:

enum {CMD_HELP,CMD_QUIT,CMD_HELP_ONOFF,CMD_DEBUG_ADD,
CMD_DEBUG_DEL, CMD_DEBUG_LIST,CMD_SEBUG_SET};
static const Cmd cmd_list[] =
{{CMD_HELP, "help %s[cmd_word1] ...", "Help command."},
{CMD_QUIT, "quit", "Exit program."},
{CMD_SYSTEM, "%l+! %s<cmd> %s[arg] ...","Invoke sh."},
{CMD_HELP_ONOFF,"set help %F<on/off>", "Online help on/off."},
{CMD_DEBUG_ADD, "debug add %s<str> ...", "Add ..."};
{CMD_DEBUG_DEL, "debug delete %s[str] ...","Delete ..."};
{CMD_DEBUG_LIST,"debug list", "Show DEBUG_IN list."},
{CMD_DEBUG_SET, "debug %n[level](20)", "Set DEBUG-level."},
{-1,NULL,NULL}
};
main(int argc,char *argv[])
{SPR_MSG_ID(routine,"my_prog");
char *word,cmd_txt[4096];
int ndx,len,help,exit_flag;
...
onlinehelp_flag = 1;
exit_flag = 0;
...
ci_prompt(stdin,stdout,cmd_txt,sizeof(cmd_txt),">> ");
switch(ci_decode(cmd_list,cmd_txt,NULL))
{case CMD_HELP:
ci_print_help(stdout,ci_arg_ptr(NULL),2+help_flag,NULL);
break;
case CMD_HELP_ONOFF:
onlinehelp_flag = ci_get_flag(NULL,NULL);
break;
case CMD_SYSTEM:
ci_system(ci_arg_ptr(NULL));
break;
case CMD_DEBUG_ADD:
break;
case CMD_DEBUG_DEL:
break;
case CMD_DEBUG_LIST:
{char *str;
fprintf(stdout,"debug_level = %i\n%s",spr_msg_get_lvl(),str=spr_msg_get_in());
spr_dynstr_free(str,routine,"spr_msg_get_in");
break;
case CMD_DEBUG_SET:
set_debuglevel(atoi(ci_get_arg(NULL,NULL)));
break;
case CMD_QUIT:
exit_flag = 1;
break;
default:
ci_online_help(NULL,stderr,onlinehelp_flag);
}
Date
01/95
Author
Kris Demuynck
Revision History:
09/95 - KD
Added the dynamical mode (allocation of string buffers instead of using static buffers.
10/96 - KD
Added the option list and enumerate possibilities.