Subversion Repositories tendra.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    		 Crown Copyright (c) 1997
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
15
 
16
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
19
 
20
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
22
        these conditions;
23
 
24
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
27
        it may be put.
28
*/
29
 
30
 
31
/**** arg-parse.h --- Command line argument parsing.
32
 *
33
 ** Author: Steve Folkes <smf@hermes.mod.uk>
34
 *
35
 **** Commentary:
36
 *
37
 ***=== INTRODUCTION =========================================================
38
 *
39
 * This file specifies the interface to a command line argument parsing
40
 * facility.  The facility has a standard behaviour, making it easier to have
41
 * a standard command line argument format.  The facility only parses command
42
 * line options, which it assumes precede the other arguments.  All options
43
 * must begin with an option character (either '+' or '-').  The facility
44
 * supports short (single character) options (should begin with '-' or '+')
45
 * and long (multiple character) options (should begin with '--' or '++').
46
 * Any arguments that begins with another character will terminate the parsing
47
 * without error (so that the program can deal with the remaining arguments).
48
 * In addition, the option '--' (or '++') will terminate the parse, so that a
49
 * user may specify non option arguments that begin with an option character.
50
 *
51
 * The parsing routines support a number of different option types, and deal
52
 * with shortest prefixes for non immediate options (an immediate option is
53
 * one where the data associated with it is part of the option string, and not
54
 * in a following word).
55
 *
56
 ***=== TYPES ================================================================
57
 *
58
 ** Type:	ArgTypeT
59
 ** Type:	ArgTypeP
60
 ** Repr:	enum {AT_SWITCH, AT_NEG_SWITCH, AT_PROC_SWITCH, AT_IMMEDIATE,
61
 *		      AT_EITHER, AT_FOLLOWING, AT_EMPTY, AT_FOLLOWING2}
62
 *
63
 * This is the type of the an option.  The constants have the following
64
 * meanings:
65
 *
66
 *	AT_SWITCH
67
 *
68
 * This is the type of a switch option.  The procedure value should be null.
69
 * The closure should be a pointer to a boolean.  If the option character is a
70
 * '-' then the boolean is set.  If the option character is '+' then the
71
 * boolean is reset.
72
 *
73
 *	AT_NEG_SWITCH
74
 *
75
 * This is the type of a negated switch option. The procedure value should be
76
 * null. The closure should be a pointer to a boolean.  If the option
77
 * character is a '-' then the boolean is reset.  If the option character is
78
 * '+' then the boolean is set.
79
 *
80
 *	AT_PROC_SWITCH
81
 *
82
 * This is the type of a switch option that needs some extra work to be
83
 * performed.  The procedure will be called with the option that was selected,
84
 * the error closure, the option closure, and a boolean (true if the option
85
 * character is '-', false otherwise).
86
 *
87
 *	AT_IMMEDIATE
88
 *
89
 * This is the type of an option with one immediate argument.  No shortest
90
 * prefix matching will be used for immediate arguments.  The procedure will
91
 * be called with the option that was selected, the error closure, the option
92
 * closure, and the argument to the option.  This type of argument should
93
 * appear at the end of the argument list that is passed to the
94
 * ``arg_parse_arguments'' function, as it may cause problems with shortest
95
 * prefix matching otherwise.
96
 *
97
 *	AT_EITHER
98
 *
99
 * This is the type of an option with one argument. If an immediate argument
100
 * exists, then that is used.  If no immediate argument exists, then the
101
 * following argument is used.  No shortest prefix matching will be used for
102
 * either arguments.  The procedure will be called with the option that was
103
 * selected, the error closure, the option closure, and the argument to the
104
 * option.  This type of argument should appear at the end of the argument
105
 * list that is passed to the ``arg_parse_arguments'' function, as it may
106
 * cause problems with shortest prefix matching otherwise.
107
 *
108
 *	AT_FOLLOWING
109
 *
110
 * This is the type of an option with one following argument.  The procedure
111
 * will be called with the option that was selected, the error closure, the
112
 * option closure, and the argument to the option.
113
 *
114
 *	AT_EMPTY
115
 *
116
 * This is the type of an option with no argument.  The procedure will be
117
 * called with the option that was selected, the error closure, and the option
118
 * closure.
119
 *
120
 *	AT_FOLLOWING2
121
 *
122
 * This is the type of an option with two following arguments.  The procedure
123
 * will be called with the option that was selected, the error closure, the
124
 * option closure, and the arguments to the option.
125
 *
126
 *	AT_FOLLOWING3
127
 *
128
 * This is the type of an option with three following arguments.  The
129
 * procedure will be called with the option that was selected, the error
130
 * closure, the option closure, and the arguments to the option.
131
 *
132
 * Note that if a matched option is a short option, then the current position
133
 * is passed to the option handling procedure as the option name.  For long
134
 * options, the entire option string is passed.  If the handler is interested
135
 * in the option name, it should check the start of this string: if it is '-'
136
 * or '+' it should be a long option; otherwise it should be a short option.
137
 *
138
 ** Type:	ArgProcP
139
 ** Repr:	void (*) (CStringP, ArgUsageP, GenericP, ...)
140
 *
141
 * This is the type of a procedure to be called to parse a complex option.
142
 * Because of union initialisation problems, the latter arguments of this
143
 * function are untyped.
144
 *
145
 ** Type:	ArgListT
146
 ** Type:	ArgListP
147
 ** Repr:	<private>
148
 *
149
 * This is the type of an entry in an option list.  A vector of such entries
150
 * should be passed to the ``arg_parse_arguments'' function, with the last
151
 * entry being the ``ARG_PARSE_END_LIST'' macro.  Each entry has the following
152
 * fields: a name field (the name of the option without the leading '--' or
153
 * '++'), a short name field (a character), a type field (the type of the
154
 * option), a procedure field (the procedure to handle the option), a closure
155
 * field (a pointer to some arbritary data used by the procedure), and a
156
 * description field (the name of a named string that describes how the option
157
 * is used - see the file "error.h" for more information on named strings).
158
 * The description field should be surrounded by the ``UB'' and ``UE'' macros
159
 * for union initialisation.  The named strings used in the description fields
160
 * should themselves be interned before the ``arg_parse_arguments'' function
161
 * is called.  A typical argument list definition would be something like the
162
 * following:
163
 *
164
 *	static ArgListT arg_list [] = {
165
 *	    {
166
 *		"option name", 'o', AT_PROC_SWITCH, (ArgProcP) arg_proc,
167
 *		NIL (GenericP),
168
 *		UB "option description name" UE
169
 *	    }, ARG_PARSE_END_LIST
170
 *	};
171
 *
172
 * If an option has only a short form, then the name should be NIL (CStringP);
173
 * if it has only a long form, then the character should be '\0'.  It is
174
 * illegal for an option to have neither a long form or a short form.
175
 *
176
 ** Type:	ArgUsageT
177
 ** Type:	ArgUsageP
178
 ** Repr:	struct {CStringP usage; ArgListP arg_list;}
179
 *
180
 * This is the type of argument to be passed to ``write_arg_usage''.
181
 *
182
 ***=== FUNCTIONS ============================================================
183
 *
184
 ** Function:	void			arg_parse_intern_descriptions
185
 *			PROTO_S ((ArgListP arg_list))
186
 ** Exceptions:	XX_dalloc_no_memory, XX_error_redefined_string
187
 *
188
 * This function should be called on all option lists that the program uses,
189
 * before they are passed to ``arg_parse_arguments''.  It replaces the
190
 * descrption name with the named string it represents.  It should only be
191
 * called once on each list.  The named strings used should be interned before
192
 * this function is called.
193
 *
194
 ** Function:	int			arg_parse_arguments
195
 *			PROTO_S ((ArgListP arg_list, EStringP usage, int argc,
196
 *				  char **argv))
197
 ** Exceptions:	XX_dalloc_no_memory, XX_ostream_write_error
198
 *
199
 * This function does the argument parsing.  The arg_list argument should
200
 * specify the valid options for the program.  The usage estring should be a
201
 * named string, whose content is a summary of the program's usage.  The argc
202
 * and argv arguments should specify the actual arguments passed to the
203
 * program.  The parsing starts from the first argument, so the first element
204
 * of the program's argument list (the program name) should not be passed to
205
 * this function.  The function returns the number of elements of the list
206
 * that it parsed.
207
 *
208
 ** Function:	void			write_arg_usage
209
 *			PROTO_S ((OStreamP ostream, ArgUsageP closure))
210
 ** Exceptions:	XX_dalloc_no_memory, XX_ostream_write_error
211
 *
212
 * This function can be used to write out a usage message based upon the usage
213
 * information supplied.
214
 *
215
 ***=== MACROS ===============================================================
216
 *
217
 ** Macro:	ARG_PARSE_END_LIST
218
 ** Exceptions:
219
 *
220
 * This macro should be used to terminate an option list.
221
 *
222
 **** Change Log:
223
 * $Log: arg-parse.h,v $
224
 * Revision 1.1.1.1  1998/01/17  15:57:45  release
225
 * First version to be checked into rolling release.
226
 *
227
 * Revision 1.2  1994/12/12  11:44:28  smf
228
 * Performing changes for 'CR94_178.sid+tld-update' - bringing in line with
229
 * OSSG C Coding Standards.
230
 *
231
 * Revision 1.1.1.1  1994/07/25  16:05:47  smf
232
 * Initial import of library shared files.
233
 *
234
**/
235
 
236
/****************************************************************************/
237
 
238
#ifndef H_ARG_PARSE
239
#define H_ARG_PARSE
240
 
241
#include "os-interface.h"
242
#include "cstring.h"
243
#include "error.h"
244
#include "ostream.h"
245
 
246
/*--------------------------------------------------------------------------*/
247
 
248
#ifdef FS_NO_ENUM
249
typedef int ArgTypeT, *ArgTypeP;
250
#define AT_SWITCH	(0)
251
#define AT_NEG_SWITCH	(1)
252
#define AT_PROC_SWITCH	(2)
253
#define AT_IMMEDIATE	(3)
254
#define AT_EITHER	(4)
255
#define AT_FOLLOWING	(5)
256
#define AT_EMPTY	(6)
257
#define AT_FOLLOWING2	(7)
258
#define AT_FOLLOWING3	(8)
259
#else
260
typedef enum {
261
    AT_SWITCH,
262
    AT_NEG_SWITCH,
263
    AT_PROC_SWITCH,
264
    AT_IMMEDIATE,
265
    AT_EITHER,
266
    AT_FOLLOWING,
267
    AT_EMPTY,
268
    AT_FOLLOWING2,
269
    AT_FOLLOWING3
270
} ArgTypeT, *ArgTypeP;
271
#endif /* defined (FS_NO_ENUM) */
272
 
273
struct ArgListT;
274
typedef struct ArgUsageT {
275
    CStringP			usage;
276
    struct ArgListT	       *arg_list;
277
} ArgUsageT, *ArgUsageP;
278
 
279
typedef void (*ArgProcP) PROTO_S ((CStringP, ArgUsageP, GenericP, ...));
280
 
281
typedef struct ArgListT {
282
    CStringP			name;
283
    char			short_name;
284
    ArgTypeT			type;
285
    ArgProcP			proc;
286
    GenericP			closure;
287
    UNION {
288
	CStringP		name;
289
	EStringP		message;
290
    } u;
291
} ArgListT, *ArgListP;
292
 
293
/*--------------------------------------------------------------------------*/
294
 
295
extern void			arg_parse_intern_descriptions
296
	PROTO_S ((ArgListP));
297
extern int			arg_parse_arguments
298
	PROTO_S ((ArgListP, EStringP, int, char **));
299
 
300
extern void			write_arg_usage
301
	PROTO_S ((OStreamP, ArgUsageP));
302
 
303
/*--------------------------------------------------------------------------*/
304
 
305
#define ARG_PARSE_END_LIST \
306
{NIL (CStringP), '\0', (ArgTypeT) 0, NIL (ArgProcP), NIL (GenericP), \
307
 UB NIL (CStringP) UE}
308
 
309
#endif /* !defined (H_ARG_PARSE) */
310
 
311
/*
312
 * Local variables(smf):
313
 * eval: (include::add-path-entry "../os-interface" "../generated")
314
 * end:
315
**/