command.h 13.3 KB
Newer Older
1
2
/* command.h
 *
Niels Möller's avatar
Niels Möller committed
3
 * $Id$ */
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

/* lsh, an implementation of the ssh protocol
 *
 * Copyright (C) 1998 Niels Möller
 *
 * This program 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 2 of the
 * License, or (at your option) any later version.
 *
 * This program 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 this program; if not, write to the Free Software
Niels Möller's avatar
Niels Möller committed
21
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22
23
24
25
26
 */

#ifndef LSH_COMMAND_H_INCLUDED
#define LSH_COMMAND_H_INCLUDED

27
#include "lsh.h"
28

29
#include "exception.h"
Niels Möller's avatar
Niels Möller committed
30
#include "list.h"
31
/* #include "io.h" */
Niels Möller's avatar
Niels Möller committed
32
33
34

#include <stdarg.h>

35
#define GABA_DECLARE
36
#include "command.h.x"
37
#undef GABA_DECLARE
38
39
40
41

/* Continuation based command execution. A command can take one object
 * as argument, and returns one object. */

42
/* GABA:
43
44
45
   (class
     (name command_continuation)
     (vars
46
       (c method void "struct lsh_object *result")))
Niels Möller's avatar
Niels Möller committed
47
48
*/

49
50
#define COMMAND_RETURN(r, v) ((r)->c((r), (struct lsh_object *) (v)))

51
/* GABA:
52
53
54
   (class
     (name command)
     (vars
55
56
57
       (call method void "struct lsh_object *arg"
                         "struct command_continuation *c"
			 "struct exception_handler *e")))
58
59
*/

60
61
62
63
#define COMMAND_CALL(f, a, c, e) \
  ((void)&(f), ((f)->call((f), (struct lsh_object *) (a), (c), (e))))


64
/* GABA:
65
66
67
68
   (class
     (name command_simple)
     (super command)
     (vars
69
70
       ; Like call, but returns the value immediately rather than
       ; using a continuation function.
71
72
73
       (call_simple method "struct lsh_object *" "struct lsh_object *")))
*/

74

75
#define COMMAND_SIMPLE_CALL(f, a) \
76
  ((f)->call_simple((f), (struct lsh_object *)(a)))
77

78
/* FIXME: Delete, use DEFINE_COMMAND instead */
Niels Möller's avatar
Niels Möller committed
79
80
81
82
83
84
#define STATIC_COMMAND(f) { STATIC_HEADER, f }

#define STATIC_COMMAND_SIMPLE(f) \
{ STATIC_COMMAND(do_call_simple_command), f}


85
#define DEFINE_COMMAND_SIMPLE(cname, ARG)		\
86
static struct lsh_object *				\
87
do_simple_##cname(struct command_simple *,		\
88
89
90
91
92
93
94
		  struct lsh_object *a);		\
							\
struct command_simple cname =				\
STATIC_COMMAND_SIMPLE(do_simple_##cname);		\
							\
static struct lsh_object *				\
do_simple_##cname(struct command_simple *s UNUSED,	\
95
		  struct lsh_object *ARG)
96

97
#define DEFINE_COMMAND(cname)			\
98
static void					\
99
do_##cname(struct command *,			\
100
101
102
	   struct lsh_object *,			\
           struct command_continuation *,	\
           struct exception_handler *);		\
103
104
105
106
107
						\
struct command cname =				\
STATIC_COMMAND(do_##cname);			\
						\
static void					\
108
109
do_##cname

110
111
112
113
114
115
/* A command taking 2 arguments */
/* GABA:
   (class
     (name command_2)
     (super command)
     (vars
116
117
118
119
120
       (invoke method void
	       "struct lsh_object *a1"
	       "struct lsh_object *a2"
	       "struct command_continuation *c"
	       "struct exception_handler *e"))))
121
122
*/

123
124
125
#define COMMAND_2_INVOKE(s, a1, a2, c, e) \
((s)->invoke((s), (a1), (a2), (c), (e)))

126
127
128
129
130
131
132
133
134
135
136
137
void
do_command_2(struct command *s,
	     struct lsh_object *a1,
	     struct command_continuation *c,
	     struct exception_handler *e);

struct command *
make_command_2_invoke(struct command_2 *f,
		      struct lsh_object *a1);

#define DEFINE_COMMAND2(cname)				\
static void						\
138
139
do_##cname(struct command_2 *,				\
	   struct lsh_object *,				\
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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
	   struct lsh_object *,				\
	   struct command_continuation *,		\
	   struct exception_handler *);			\
							\
struct command_2 cname =				\
{ { STATIC_HEADER, do_command_2 }, do_##cname };	\
							\
static void						\
do_##cname

/* A command taking 3 arguments */
/* GABA:
   (class
     (name command_3)
     (super command)
     (vars
       (invoke pointer
         (function void "struct lsh_object *a1"
			"struct lsh_object *a2"
			"struct lsh_object *a3"
			"struct command_continuation *c"
			"struct exception_handler *e"))))
*/

void
do_command_3(struct command *s,
	     struct lsh_object *a1,
	     struct command_continuation *c,
	     struct exception_handler *e);

struct command *
make_command_3_invoke(struct command_3 *f,
		      struct lsh_object *a1);

struct command *
make_command_3_invoke_2(struct command_3 *f,
			struct lsh_object *a1,
			struct lsh_object *a2);

#define DEFINE_COMMAND3(cname)				\
static void						\
do_##cname(struct lsh_object *,				\
	   struct lsh_object *,				\
	   struct lsh_object *,				\
	   struct command_continuation *,		\
	   struct exception_handler *);			\
							\
struct command_3 cname =				\
{ { STATIC_HEADER, do_command_3 }, do_##cname };	\
							\
static void						\
do_##cname

193

Niels Möller's avatar
Niels Möller committed
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
/* A command taking 4 arguments */
/* GABA:
   (class
     (name command_4)
     (super command)
     (vars
       (invoke pointer
         (function void "struct lsh_object *a1"
			"struct lsh_object *a2"
			"struct lsh_object *a3"
			"struct lsh_object *a4"
			"struct command_continuation *c"
			"struct exception_handler *e"))))
*/

void
do_command_4(struct command *s,
	     struct lsh_object *a1,
	     struct command_continuation *c,
	     struct exception_handler *e);

struct command *
make_command_4_invoke(struct command_4 *f,
		      struct lsh_object *a1);

struct command *
make_command_4_invoke_2(struct command_4 *f,
			struct lsh_object *a1,
			struct lsh_object *a2);

struct command *
make_command_4_invoke_3(struct command_4 *f,
			struct lsh_object *a1,
			struct lsh_object *a2,
			struct lsh_object *a3);

#define DEFINE_COMMAND4(cname)				\
static void						\
do_##cname(struct lsh_object *,				\
	   struct lsh_object *,				\
	   struct lsh_object *,				\
	   struct lsh_object *,				\
	   struct command_continuation *,		\
	   struct exception_handler *);			\
							\
struct command_4 cname =				\
{ { STATIC_HEADER, do_command_4 }, do_##cname };	\
							\
static void						\
do_##cname

245

246
247
248
249
void do_call_simple_command(struct command *s,
			    struct lsh_object *arg,
			    struct command_continuation *c,
			    struct exception_handler *e);
250

251
struct command *make_parallell_progn(struct object_list *body);
252
extern struct command progn_command;
253

254
255
extern struct command_continuation discard_continuation;

Niels Möller's avatar
Niels Möller committed
256
257
#define CONTINUATION_USED_P(c) ((c) != &discard_continuation)

258
/* GABA:
259
260
261
262
   (class
     (name command_frame)
     (super command_continuation)
     (vars
263
264
265
266
267
268
       (up object command_continuation)
       (e object exception_handler)))
*/

/* Used when the execution context must be saved for later use.
 *
269
270
 * Primarily used in channel_commands.c.
 */
271
272
273
274
275
276
/* GABA:
   (class
     (name command_context)
     (vars
       (c object command_continuation)
       (e object exception_handler)))
277
278
*/

279
280
281
282
struct command_context *
make_command_context(struct command_continuation *c,
		     struct exception_handler *e);

283
284
285
286
287
288
289
290
291
292
293
/* catch command,
 *
 * (catch handler body x)
 */

/* GABA:
   (class
     (name catch_command)
     (super command_simple)
     (vars
       (mask . UINT32)
294
295
296
297
298
299
       (value . UINT32)

       ; Ignore return values from body. This means that the catch
       ; will return *only* if some exception is raised. Useful for
       ; reading until some EOF exception ir raised.
       (ignore_value . int))) */
300

Niels Möller's avatar
Niels Möller committed
301
302
303
304
305
306
307
308
309
struct catch_handler_info *
make_catch_handler_info(UINT32 mask, UINT32 value,
			int ignore_value,
			struct command *handler);

struct command *
make_catch_apply(struct catch_handler_info *info,
		 struct command *body);

310
311
312
313
struct lsh_object *
do_catch_simple(struct command_simple *s,
		struct lsh_object *a);

314
315
#define STATIC_CATCH_COMMAND(m, v, i) \
{ STATIC_COMMAND_SIMPLE(do_catch_simple), (m), (v), (i) }
316
317


318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
/* GABA:
   (class
     (name catch_report_collect)
     (super command_simple)
     (vars
       (info object report_exception_info)))
*/

struct command *
make_catch_report_apply(struct report_exception_info *info,
			struct command *body);

struct lsh_object *
do_catch_report_collect(struct command_simple *s,
			struct lsh_object *a);

#define STATIC_CATCH_REPORT(i) \
{ STATIC_COMMAND_SIMPLE(do_catch_report_collect), i }

       
338
339
340
/* Commands that need to collect some arguments before actually doing
 * anything. */

Niels Möller's avatar
Niels Möller committed
341
/* The collect_info_n classes keeps track about what to do with the
342
343
344
345
346
347
348
349
350
351
 * next argument. As long as we collect arguments without doing
 * anything, the f field in collect_info_n will point to the
 * constructor make_collect_state_n. */

/* GABA:
   (class
     (name collect_info_3)
     (vars
       (f method  "struct lsh_object *"
                  "struct lsh_object *" "struct lsh_object *"
Niels Möller's avatar
Niels Möller committed
352
		  "struct lsh_object *")))
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
*/

/* GABA:
   (class
     (name collect_info_2)
     (vars
       (f method  "struct lsh_object *"
                  "struct lsh_object *" "struct lsh_object *")
       (next object collect_info_3)))
*/

/* GABA:
   (class
     (name collect_info_1)
     (super command_simple)
     (vars
       (f method  "struct lsh_object *"
                  "struct lsh_object *")
       (next object collect_info_2)))
*/

374

375
376
377
struct lsh_object *
do_collect_1(struct command_simple *s, struct lsh_object *a);

378
379
380
381
382
383
384
385
386
struct lsh_object *
make_collect_state_1(struct collect_info_1 *info,
		     struct lsh_object *a);

struct lsh_object *
make_collect_state_2(struct collect_info_2 *info,
		     struct lsh_object *a,
		     struct lsh_object *b);

387
388
389
390
391
392
393
394
395
396
397
#define STATIC_COLLECT_1(next) \
{ { { STATIC_HEADER, do_call_simple_command }, do_collect_1}, \
  make_collect_state_1, next }

#define STATIC_COLLECT_2(next) \
{ STATIC_HEADER, make_collect_state_2, next }

#define STATIC_COLLECT_2_FINAL(f) \
{ STATIC_HEADER, f, NULL }

#define STATIC_COLLECT_3_FINAL(f) \
Niels Möller's avatar
Niels Möller committed
398
{ STATIC_HEADER, f }
399

400
extern struct command command_die_on_null;
401

Niels Möller's avatar
Niels Möller committed
402

403
#if DEBUG_TRACE
Niels Möller's avatar
Niels Möller committed
404
405
406
struct command *make_trace(const char *name, struct command *real);
struct lsh_object *collect_trace(const char *name, struct lsh_object *real);

407
408
#define MAKE_TRACE collect_trace
#else /* !DEBUG_TRACE */
Niels Möller's avatar
Niels Möller committed
409
#define MAKE_TRACE(name, real) (real)
410
#endif /* !DEBUG_TRACE */
Niels Möller's avatar
Niels Möller committed
411

412
413
/* Useful clobal commands */
#define PROG1 (&command_K.super.super)
414
#define PROGN (&progn_command.super)
Niels Möller's avatar
Niels Möller committed
415

416
417
/* The GABA_* macros are used by automatically generated evaluation code */

418
struct command_continuation *
419
420
421
make_apply(struct command *f,
	   struct command_continuation *c, struct exception_handler *e);

Niels Möller's avatar
Niels Möller committed
422
423
struct lsh_object *gaba_apply(struct lsh_object *f,
			      struct lsh_object *x);
424

425
#define GABA_APPLY gaba_apply
426

427
428
extern struct command command_I;
#define GABA_VALUE_I (&command_I.super)
429
#define GABA_APPLY_I_1(x) (x)
430

431
extern struct command_2 command_K;
432
433
434
struct command *make_command_K_1(struct lsh_object *x);

#define GABA_VALUE_K (&command_K.super.super)
435
436
#define GABA_APPLY_K_1(x) \
((struct lsh_object *) make_command_2_invoke(&command_K, (x)))
437

438
extern struct command_3 command_S;
439

440
441
442
443
444
#define GABA_VALUE_S (&command_S.super.super)
#define GABA_APPLY_S_1(f) \
((struct lsh_object *) make_command_3_invoke(&command_S, (f)))
#define GABA_APPLY_S_2(f, g) \
((struct lsh_object *) make_command_3_invoke_2(&command_S, (f), (g)))
445

Niels Möller's avatar
Niels Möller committed
446
extern struct command_4 command_Sp;
447

Niels Möller's avatar
Niels Möller committed
448
449
450
451
452
453
454
#define GABA_VALUE_Sp (&command_Sp.super.super)
#define GABA_APPLY_Sp_1(c) \
((struct lsh_object *) make_command_4_invoke(&command_Sp, (f)))
#define GABA_APPLY_Sp_2(c, f) \
((struct lsh_object *) make_command_4_invoke_2(&command_Sp, (c), (f)))
#define GABA_APPLY_Sp_3(c, f, g) \
((struct lsh_object *) make_command_4_invoke_3(&command_Sp, (c), (f), (g)))
Niels Möller's avatar
Niels Möller committed
455

Niels Möller's avatar
Niels Möller committed
456
extern struct command_3 command_B;
457

Niels Möller's avatar
Niels Möller committed
458
459
460
461
462
#define GABA_VALUE_B (&command_B.super.super)
#define GABA_APPLY_B_1(f) \
((struct lsh_object *) make_command_3_invoke(&command_B, (f)))
#define GABA_APPLY_B_2(f, g) \
((struct lsh_object *) make_command_3_invoke_2(&command_B, (f), (g)))
463

Niels Möller's avatar
Niels Möller committed
464
465
466
467
468
469
470
471
472
473
extern struct command_4 command_Bp;

#define GABA_VALUE_Bp (&command_Bp.super.super)
#define GABA_APPLY_Bp_1(c) \
((struct lsh_object *) make_command_4_invoke(&command_Bp, (c)))
#define GABA_APPLY_Bp_2(c, f) \
((struct lsh_object *) make_command_4_invoke_2(&command_Bp, (c), (f)))
#define GABA_APPLY_Bp_3(c, f, g) \
((struct lsh_object *) make_command_4_invoke_3(&command_Bp, (c), (f), (g)))

474
extern struct command_3 command_C;
475

476
477
478
479
480
#define GABA_VALUE_C (&command_C.super.super)
#define GABA_APPLY_C_1(f) \
((struct lsh_object *) make_command_3_invoke(&command_C, (f)))
#define GABA_APPLY_C_2(f, g) \
((struct lsh_object *) make_command_3_invoke_2(&command_C, (f), (g)))
481

482
#if 1
483
extern struct command_4 command_Cp;
484

485
486
487
488
489
490
491
#define GABA_VALUE_Cp (&command_Cp.super.super)
#define GABA_APPLY_Cp_1(c) \
((struct lsh_object *) make_command_4_invoke(&command_Cp, (c)))
#define GABA_APPLY_Cp_2(c, f) \
((struct lsh_object *) make_command_4_invoke_2(&command_Cp, (c), (f)))
#define GABA_APPLY_Cp_3(c, f, g) \
((struct lsh_object *) make_command_4_invoke_3(&command_Cp, (c), (f), (g)))
492
#else
493
494
495

extern struct collect_info_1 command_Cp;
extern struct collect_info_2 collect_info_Cp_2;
496
extern struct collect_info_3 collect_info_Cp_3;
497
498
499
500
501
502
503
504
505
506
507

struct command *
make_command_Cp_3(struct command *c,
		  struct command *f,
		  struct lsh_object *y);
struct lsh_object *
collect_Cp_3(struct collect_info_3 *info,
	     struct lsh_object *c,
	     struct lsh_object *f,
	     struct lsh_object *y);

508
#define GABA_VALUE_Cp (&command_Cp.super.super.super)
509
510
511
#define GABA_APPLY_Cp_1(c) (make_collect_state_1(&command_Cp, (c)))
#define GABA_APPLY_Cp_2(c, f) \
  (make_collect_state_2(&collect_info_Cp_2, (c), (f)))
512
#define GABA_APPLY_Cp_3(c, f, y) (collect_Cp_3(&collect_info_Cp_3, (c), (f), (y)))
Niels Möller's avatar
Niels Möller committed
513

514
515
#endif

516
#endif /* LSH_COMMAND_H_INCLUDED */