Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – tendra.SVN – Blame – /branches/algol60/src/utilities/sid/arg-parse.c – Rev 7

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
/*
7 7u83 2
 * Copyright (c) 2002-2005 The TenDRA Project <http://www.tendra.org/>.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
11
 *    this list of conditions and the following disclaimer in the documentation
12
 *    and/or other materials provided with the distribution.
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific, prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 *
29
 * $Id$
30
 */
31
/*
2 7u83 32
    		 Crown Copyright (c) 1997
7 7u83 33
 
2 7u83 34
    This TenDRA(r) Computer Program is subject to Copyright
35
    owned by the United Kingdom Secretary of State for Defence
36
    acting through the Defence Evaluation and Research Agency
37
    (DERA).  It is made available to Recipients with a
38
    royalty-free licence for its use, reproduction, transfer
39
    to other parties and amendment for any purpose not excluding
40
    product development provided that any such use et cetera
41
    shall be deemed to be acceptance of the following conditions:-
7 7u83 42
 
2 7u83 43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
7 7u83 45
 
2 7u83 46
        (2) Any amended version of it shall be clearly marked to
47
        show both the nature of and the organisation responsible
48
        for the relevant amendment or amendments;
7 7u83 49
 
2 7u83 50
        (3) Its onward transfer from a recipient to another
51
        party shall be deemed to be that party's acceptance of
52
        these conditions;
7 7u83 53
 
2 7u83 54
        (4) DERA gives no warranty or assurance as to its
55
        quality or suitability for any purpose and DERA accepts
56
        no liability whatsoever in relation to any use to which
57
        it may be put.
58
*/
59
 
60
 
61
/**** arg-parse.c --- Command line argument parsing.
62
 *
63
 ** Author: Steve Folkes <smf@hermes.mod.uk>
64
 *
65
 **** Commentary:
66
 *
67
 * This file implements the command line argument parsing routines specified
68
 * in "arg-parse.h".  See that file for more details.
69
 *
70
 **** Change Log:
71
 * $Log: arg-parse.c,v $
72
 * Revision 1.1.1.1  1998/01/17  15:57:43  release
73
 * First version to be checked into rolling release.
74
 *
75
 * Revision 1.3  1994/12/12  11:44:26  smf
76
 * Performing changes for 'CR94_178.sid+tld-update' - bringing in line with
77
 * OSSG C Coding Standards.
78
 *
79
 * Revision 1.2  1994/08/22  09:36:39  smf
80
 * Fixed bug DR114:ids-too-long.
81
 *
82
 * Revision 1.1.1.1  1994/07/25  16:05:47  smf
83
 * Initial import of library shared files.
84
 *
85
**/
86
 
87
/****************************************************************************/
88
 
89
#include "arg-parse.h"
90
#include "gen-errors.h"
91
 
92
/*--------------------------------------------------------------------------*/
93
 
94
void
7 7u83 95
arg_parse_intern_descriptions(ArgListP arg_list)
2 7u83 96
{
7 7u83 97
    while ((arg_list->name != NIL(CStringP)) ||
2 7u83 98
	   (arg_list->short_name != '\0')) {
7 7u83 99
	EStringP estring = error_lookup_string(arg_list->u.name);
2 7u83 100
 
7 7u83 101
	ASSERT(estring != NIL(EStringP));
2 7u83 102
	arg_list->u.message = estring;
7 7u83 103
	arg_list++;
2 7u83 104
    }
105
}
106
 
107
int
7 7u83 108
arg_parse_arguments(ArgListP arg_list, EStringP usage, int argc, char **argv)
2 7u83 109
{
110
    int       tmp_argc = argc;
111
    char    **tmp_argv = argv;
112
    ArgUsageT closure;
113
 
7 7u83 114
    closure.usage    = error_string_contents(usage);
2 7u83 115
    closure.arg_list = arg_list;
116
    while (tmp_argc) {
7 7u83 117
	CStringP option = (tmp_argv[0]);
118
	char     c      = (option[0]);
2 7u83 119
 
7 7u83 120
	if ((((c == '-') && (option[1] == '-')) ||
121
	    ((c == '+') && (option[1] == '+'))) && (option[2] == '\0')) {
122
	    return(argc - tmp_argc + 1);
123
	} else if (((c == '-') && (option[1] == '-')) ||
124
		   ((c == '+') && (option[1] == '+'))) {
2 7u83 125
	    ArgListP tmp_list  = arg_list;
7 7u83 126
	    ArgListP chosen    = NIL(ArgListP);
2 7u83 127
	    unsigned matches   = 0;
7 7u83 128
	    CStringP immediate = NIL(CStringP);
2 7u83 129
 
7 7u83 130
	    while ((tmp_list->name != NIL(CStringP)) ||
2 7u83 131
		   (tmp_list->short_name != '\0')) {
132
		CStringP opt = (tmp_list->name);
7 7u83 133
		CStringP arg = (&(option[2]));
2 7u83 134
 
7 7u83 135
		if (opt != NIL(CStringP)) {
2 7u83 136
		    char optch;
137
		    char argch;
138
 
139
		    do {
7 7u83 140
			optch = (*opt++);
141
			argch = (*arg++);
2 7u83 142
		    } while (optch && argch && (optch == argch));
143
		    if (optch == argch) {
144
			chosen    = tmp_list;
145
			matches   = 1;
146
			immediate = (arg - 1);
147
			break;
148
		    } else if ((optch == '\0') &&
149
			       (((tmp_list->type) == AT_IMMEDIATE) ||
150
				((tmp_list->type) == AT_EITHER))) {
151
			chosen    = tmp_list;
152
			matches   = 1;
153
			immediate = (arg - 1);
154
			break;
155
		    } else if (argch == '\0') {
156
			chosen = tmp_list;
7 7u83 157
			matches++;
2 7u83 158
		    }
159
		}
7 7u83 160
		tmp_list++;
2 7u83 161
	    }
162
	    if (matches == 0) {
7 7u83 163
		E_arg_parse_unknown_option(option, &closure);
2 7u83 164
		UNREACHED;
165
	    } else if (matches > 1) {
7 7u83 166
		E_arg_parse_ambiguous_option(option, &closure);
2 7u83 167
		UNREACHED;
168
	    } else {
7 7u83 169
		switch (chosen->type)EXHAUSTIVE {
2 7u83 170
		  case AT_SWITCH:
7 7u83 171
		   (*((BoolP)(chosen->closure))) = (c == '-');
2 7u83 172
		    break;
173
		  case AT_NEG_SWITCH:
7 7u83 174
		   (*((BoolP)(chosen->closure))) = (c == '+');
2 7u83 175
		    break;
176
		  case AT_PROC_SWITCH:
7 7u83 177
		   (*(chosen->proc))(option, &closure, chosen->closure,
178
				     c == '-');
2 7u83 179
		    break;
180
		  case AT_IMMEDIATE:
7 7u83 181
		    if (immediate != NIL(CStringP)) {
182
			(*(chosen->proc))(option, &closure, chosen->closure,
2 7u83 183
					   immediate);
184
		    } else {
7 7u83 185
			E_arg_parse_unknown_option(option, &closure);
2 7u83 186
			UNREACHED;
187
		    }
188
		    break;
189
		  case AT_EITHER:
7 7u83 190
		    if (immediate != NIL(CStringP)) {
191
			if (immediate[0]!= '\0') {
192
			   (*(chosen->proc))(option, &closure,
193
					     chosen->closure, immediate);
2 7u83 194
			} else if (tmp_argc > 1) {
7 7u83 195
			    tmp_argv++;
196
			    tmp_argc--;
197
			   (*(chosen->proc))(option, &closure,
198
					     chosen->closure, tmp_argv[0]);
2 7u83 199
			} else {
7 7u83 200
			    E_arg_parse_missing_argument(option, &closure);
2 7u83 201
			    UNREACHED;
202
			}
203
		    } else {
7 7u83 204
			E_arg_parse_unknown_option(option, &closure);
2 7u83 205
			UNREACHED;
206
		    }
207
		    break;
208
		  case AT_FOLLOWING:
209
		    if (tmp_argc > 1) {
7 7u83 210
			tmp_argv++;
211
			tmp_argc--;
212
			(*(chosen->proc))(option, &closure, chosen->closure,
213
					  tmp_argv[0]);
2 7u83 214
		    } else {
7 7u83 215
			E_arg_parse_missing_argument(option, &closure);
2 7u83 216
			UNREACHED;
217
		    }
218
		    break;
219
		  case AT_EMPTY:
7 7u83 220
		   (*(chosen->proc))(option, &closure, chosen->closure);
2 7u83 221
		    break;
222
		  case AT_FOLLOWING2:
223
		    if (tmp_argc > 2) {
224
			tmp_argv += 2;
225
			tmp_argc -= 2;
7 7u83 226
			(*(chosen->proc))(option, &closure, chosen->closure,
227
					  tmp_argv[-1], tmp_argv[0]);
2 7u83 228
		    } else {
7 7u83 229
			E_arg_parse_missing_argument(option, &closure);
2 7u83 230
			UNREACHED;
231
		    }
232
		    break;
233
		  case AT_FOLLOWING3:
234
		    if (tmp_argc > 3) {
235
			tmp_argv += 3;
236
			tmp_argc -= 3;
7 7u83 237
			(*(chosen->proc))(option, &closure, chosen->closure,
238
					  tmp_argv[-2], tmp_argv[-1],
239
					  tmp_argv[0]);
2 7u83 240
		    } else {
7 7u83 241
			E_arg_parse_missing_argument(option, &closure);
2 7u83 242
			UNREACHED;
243
		    }
244
		    break;
245
		}
246
	    }
7 7u83 247
	} else if (((c == '-') && (option[1] == '+')) ||
248
		   ((c == '+') && (option[1] == '-')) ||
249
		   ((c == '-') && (option[1] == '\0')) ||
250
		   ((c == '+') && (option[1] == '\0'))) {
251
	    E_arg_parse_unknown_option(option, &closure);
2 7u83 252
	    UNREACHED;
253
	} else if ((c == '-') || (c == '+')) {
7 7u83 254
	    CStringP opt = &(option[1]);
2 7u83 255
 
7 7u83 256
	    while ((opt != NIL(CStringP)) && (*opt != '\0')) {
2 7u83 257
		ArgListP tmp_list = arg_list;
7 7u83 258
		ArgListP chosen   = NIL(ArgListP);
2 7u83 259
 
7 7u83 260
		while ((tmp_list->name != NIL(CStringP)) ||
2 7u83 261
		       (tmp_list->short_name != '\0')) {
262
		    if (tmp_list->short_name == *opt) {
263
			chosen = tmp_list;
264
			break;
265
		    }
7 7u83 266
		    tmp_list++;
2 7u83 267
		}
268
		if (chosen) {
7 7u83 269
		    switch (chosen->type)EXHAUSTIVE {
2 7u83 270
		      case AT_SWITCH:
7 7u83 271
			(*((BoolP)(chosen->closure))) = (c == '-');
2 7u83 272
			break;
273
		      case AT_NEG_SWITCH:
7 7u83 274
			(*((BoolP)(chosen->closure))) = (c == '+');
2 7u83 275
			break;
276
		      case AT_PROC_SWITCH:
7 7u83 277
			(*(chosen->proc))(opt, &closure, chosen->closure,
278
					  c == '-');
2 7u83 279
			break;
280
		      case AT_IMMEDIATE:
7 7u83 281
			(*(chosen->proc))(opt, &closure, chosen->closure,
282
					  opt + 1);
283
			opt = NIL(CStringP);
2 7u83 284
			break;
285
		      case AT_EITHER:
7 7u83 286
			if (opt[1]!= '\0') {
287
			   (*(chosen->proc))(opt, &closure, chosen->closure,
288
					     opt + 1);
2 7u83 289
			} else if (tmp_argc > 1) {
7 7u83 290
			    tmp_argv++;
291
			    tmp_argc--;
292
			   (*(chosen->proc))(opt, &closure, chosen->closure,
293
					     tmp_argv[0]);
2 7u83 294
			} else {
7 7u83 295
			    E_arg_parse_missing_short_arg(option, opt,
296
							  &closure);
2 7u83 297
			    UNREACHED;
298
			}
7 7u83 299
			opt = NIL(CStringP);
2 7u83 300
			break;
301
		      case AT_FOLLOWING:
302
			if (tmp_argc > 1) {
7 7u83 303
			    tmp_argv++;
304
			    tmp_argc--;
305
			   (*(chosen->proc))(opt, &closure, chosen->closure,
306
					     tmp_argv[0]);
2 7u83 307
			} else {
7 7u83 308
			    E_arg_parse_missing_short_arg(option, opt,
309
							  &closure);
2 7u83 310
			    UNREACHED;
311
			}
312
			break;
313
		      case AT_EMPTY:
7 7u83 314
			(*(chosen->proc))(opt, &closure, chosen->closure);
2 7u83 315
			break;
316
		      case AT_FOLLOWING2:
317
			if (tmp_argc > 2) {
318
			    tmp_argv += 2;
319
			    tmp_argc -= 2;
7 7u83 320
			   (*(chosen->proc))(opt, &closure, chosen->closure,
321
					     tmp_argv[-1], tmp_argv[0]);
2 7u83 322
			} else {
7 7u83 323
			    E_arg_parse_missing_short_arg(option, opt,
324
							  &closure);
2 7u83 325
			    UNREACHED;
326
			}
327
			break;
328
		      case AT_FOLLOWING3:
329
			if (tmp_argc > 3) {
330
			    tmp_argv += 3;
331
			    tmp_argc -= 3;
7 7u83 332
			   (*(chosen->proc))(opt, &closure, chosen->closure,
333
					     tmp_argv[-2], tmp_argv[-1],
334
					     tmp_argv[0]);
2 7u83 335
			} else {
7 7u83 336
			    E_arg_parse_missing_short_arg(option, opt,
337
							  &closure);
2 7u83 338
			    UNREACHED;
339
			}
340
			break;
341
		    }
342
		} else {
7 7u83 343
		    E_arg_parse_unknown_short_opt(option, opt, &closure);
2 7u83 344
		    UNREACHED;
345
		}
346
		if (opt) {
7 7u83 347
		    opt++;
2 7u83 348
		}
349
	    }
350
	} else {
7 7u83 351
	    return(argc - tmp_argc);
2 7u83 352
	}
7 7u83 353
	tmp_argv++;
354
	tmp_argc--;
2 7u83 355
    }
7 7u83 356
    return(argc);
2 7u83 357
}
358
 
359
void
7 7u83 360
write_arg_usage(OStreamP ostream, ArgUsageP closure)
2 7u83 361
{
362
    CStringP usage    = (closure->usage);
363
    ArgListP arg_list = (closure->arg_list);
364
 
7 7u83 365
    write_cstring(ostream, usage);
366
    while ((arg_list->name != NIL(CStringP)) ||
2 7u83 367
	   (arg_list->short_name != '\0')) {
7 7u83 368
	CStringP desc = error_string_contents(arg_list->u.message);
2 7u83 369
 
370
	if (arg_list->name) {
7 7u83 371
	    write_newline(ostream);
372
	    write_cstring(ostream, "    {--|++}");
373
	    write_cstring(ostream, arg_list->name);
374
	    write_cstring(ostream, desc);
2 7u83 375
	}
376
	if (arg_list->short_name != '\0') {
7 7u83 377
	    write_newline(ostream);
378
	    write_cstring(ostream, "    {-|+}");
379
	    write_char(ostream, arg_list->short_name);
380
	    write_cstring(ostream, desc);
2 7u83 381
	}
7 7u83 382
	arg_list++;
2 7u83 383
    }
384
}
385
 
386
/*
387
 * Local variables(smf):
388
 * eval: (include::add-path-entry "../os-interface" "../generated")
389
 * end:
390
**/