summaryrefslogtreecommitdiff
path: root/libmailutils/tests/tesh.h
blob: dbab97c18e6b66583daa8e9b316f811f22f85ff7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/* Definitions of test shell functions for GNU Mailutils.
   Copyright (C) 2019 Free Software Foundation, Inc.

   GNU Mailutils is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   GNU Mailutils is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with GNU Mailutils.  If not, see <http://www.gnu.org/licenses/>. */

/* Test shell commands are implemented via mu_tesh_function_t functions.
   Arguments:
    argc    - argument count
    argv    - argument vector
    options - assoc of options
    env     - evaluation environment (closure)
*/
typedef int (*mu_tesh_function_t)(int argc, char **argv, mu_assoc_t options,
				  void *env);

/* Option argument types */
enum mu_tesh_arg
  {
    mu_tesh_noarg,         /* No argument allowed */
    mu_tesh_arg_required,  /* Argument is required */
    mu_tesh_arg_optional   /* Argument is optional */
  };

/* Test shell command definition */
struct mu_tesh_command
{
  /* The following fields must be filled by the caller */
  char *verb;              /* Command verb [1] */
  char *args;              /* Description of command arguments [2] */
  mu_tesh_function_t func; /* Command handler function */

  /* The fields below are computed and used by the shell itself.
     The caller MAY NOT initialize them.
  */

  int param_min;        /* Minimum number of parameters */
  int param_max;        /* Maximum number of parameters. -1 for variadic */
  mu_assoc_t options;   /* Assoc array of the allowed options, indexed by
			   option names without the leading dash. Values
			   are of enum mu_tesh_arg type. */
};

/* Notes:

   [1] The command verb "help" is implicitly defined. It produces a short
       summary of the available shell commands. The special commands

       The following special command verbs can be used:
	 __LINEPROC__
	    Called before word splitting. The entire command line is passed
	    as argv[0]. The argc is 1, and the options argument is NULL.

	    The function returns 0 to indicate that it has processed the
	    input. In this case, no further input handing will be performed
	    and the shell will proceed to next line from the input.
	    Otherwise, the shell will perform word splitting and initiate
	    further processing.

	    The function is free to modify or reassign argv[0] if it needs
	    so. The modified value will serve as input for further processing.
	    If the function chooses to reassing argv[0], it may not free the
	    current value, and the caller remains responsible for any memory
	    management needed. For example, if a newly allocated memory is
	    assigned to argv[0], this pointer must be saved somewhere in the
	    'env' to be subsequently freed by the __ENVFINI__ handler.

	 __NOCMD__
	    Called if the first token in the command line does not match
	    any defined command. The result of word splitting is passed in
	    argc and argv. The options argument is NULL. The function must
	    return 0 if it was able to process the input, and any non-zero
	    value otherwise. In the latter case, the shell will issue the
	    "no such command" diagnostics.

	 __ENVINIT__
	    Initialize the environment prior to running the command. The
	    argc, argv, and options arguments contain the result of command
	    line parsing.

	    The command must return 0 on success.

	 __ENVFINI__
	    Do any post-command cleanup of the environment. Arguments are
	    the same as to __ENVINIT__.

	    Return value is ignored.

	 __HELPINIT__
	    Print initial part of the help output. This function is called
	    by mu_tesh_help prior to printing the command summary.
	    The argc parameter is 0, argv and options are NULL.

	    Return value is ignored.

	 __HELPFINI__
	    Print final part of the help output. This function is called
	    by mu_tesh_help prior after printing the command summary.

	    Arguments are the same as for __HELPINIT__. Return value is
	    ignored.

       Apart from these, no command verbs may begin and end with two
       underscore characters.

   [2] The args field in the above structure serves two purposes. First,
       it describes the options and arguments to the shell command in
       unambiguous way and is used during command line parsing. Secondly,
       it is output by mu_tesh_help as a human-readable command line
       syntax summary.

       The syntax of this field is described by the BNF below:

	   <args> ::= <arglist> | <arglist> <ws> "..." |
		      <arglist> "..."
	   <arglist> ::= <argdef> | <arglist> <ws> <argdef>
	   <argdef> ::= <optdef> | <optarg> | STRING
	   <optdef> ::= "[-" STRING "]" |
			"[-" STRING "=" STRING "]" |
			"[-" STRING "[=" STRING "]]"
	   <optarg> ::= "[" string-list "]"
	   <string-list> ::= STRING | <string-list> <ws> STRING
	   <ws> ::= 1*WS

       STRING is any contiguous sequence of printable characters, other
       than whitespace, '[', or ']'. WS is horizontal space or tab
       character.

       Ellipis can appear immediately before the closing "]" of an <optdef>
       or <optarg>.

       The <optdef> token defines options that can be supplied to the
       command. The <optdef>s can be intermixed with other tokens in an
       <args> string. However, in actual command invocation, options must
       precede positional arguments. The "--" argument can be given to
       explicitly stop option processing.

       Both trailing ellipsis and <optarg> indicate variable number of
       arguments to the command.
*/


/* Initialize the shell. */
void mu_tesh_init (char const *argv0);

/* Main command evaluation loop.

   If argc > 0, commands are read from argv. They must be delimited by
   semicolons (obviously, if argc,argv are obtained from the shell command
   line, the user must take care to escape each ';' to prevent it from
   being processed by the shell). A semicolon may appear either as a separate
   argument or as a last character of command's argument, e.g. supposing that
   't' is a command line utility using tesh, both invocations below are valid:

      t foo bar \; baz qux
      t foo 'bar;' baz qux

   If argc == 0, commands are read from the standard input. The '#' character
   begins an inline comment.
 */
void mu_tesh_read_and_eval (int argc, char **argv,
			    struct mu_tesh_command *cmd,
			    void *env);

/* Print a short summary of shell commands. */
void mu_tesh_help (struct mu_tesh_command *cmd, void *env);

Return to:

Send suggestions and report system problems to the System administrator.